Merge changes from upstream repository (r112367)

Change-Id: Ib88c8fd890e7c8c5597ea2b86cfa934438965c08
diff --git a/Android.mk b/Android.mk
index 78aca54..4f27749 100644
--- a/Android.mk
+++ b/Android.mk
@@ -11,7 +11,6 @@
 		lib/Sema	\
 		lib/CodeGen	\
 		lib/Analysis	\
-		lib/Index	\
 	))
 
 include $(LOCAL_PATH)/clang.mk
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1be646d..1ba2a62 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,10 +1,5 @@
 # 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})
 
@@ -28,12 +23,28 @@
   endif()
 endif()
 
-# Compute the Clang version from the contents of VER
-file(READ ${CMAKE_CURRENT_SOURCE_DIR}/VER CLANG_VERSION_DATA)
+# Compute the Clang version from the LLVM version.
 string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION 
-  ${CLANG_VERSION_DATA})
+  ${PACKAGE_VERSION})
 message(STATUS "Clang version: ${CLANG_VERSION}")
 
+string(REGEX REPLACE "([0-9]+)\\.[0-9]+(\\.[0-9]+)?" "\\1" CLANG_VERSION_MAJOR
+  ${CLANG_VERSION})
+string(REGEX REPLACE "[0-9]+\\.([0-9]+)(\\.[0-9]+)?" "\\1" CLANG_VERSION_MINOR
+  ${CLANG_VERSION})
+if (${CLANG_VERSION} MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+")
+  set(CLANG_HAS_VERSION_PATCHLEVEL 1)
+  string(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" CLANG_VERSION_PATCHLEVEL
+    ${CLANG_VERSION})
+else()
+  set(CLANG_HAS_VERSION_PATCHLEVEL 0)
+endif()
+
+# Configure the Version.inc file.
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/include/clang/Basic/Version.inc.in
+  ${CMAKE_CURRENT_BINARY_DIR}/include/clang/Basic/Version.inc)
+
 # Add appropriate flags for GCC
 if (CMAKE_COMPILER_IS_GNUCXX)
   # FIXME: Turn off exceptions, RTTI:
@@ -41,6 +52,10 @@
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common -Woverloaded-virtual -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings")
 endif ()
 
+if (APPLE)
+  set(CMAKE_MODULE_LINKER_FLAGS "-Wl,-flat_namespace -Wl,-undefined -Wl,suppress")
+endif ()
+
 macro(add_clang_library name)
   set(srcs ${ARGN})
   if(MSVC_IDE OR XCODE)
@@ -54,7 +69,9 @@
       ../../include/clang${dir}/*.def)
     set(srcs ${srcs} ${headers})
   endif(MSVC_IDE OR XCODE)
-  if (SHARED_LIBRARY)
+  if (MODULE)
+    set(libkind MODULE)
+  elseif (SHARED_LIBRARY)
     set(libkind SHARED)
   else()
     set(libkind)
diff --git a/Makefile b/Makefile
index f7e9e85..f871c25 100644
--- a/Makefile
+++ b/Makefile
@@ -1,14 +1,63 @@
-LEVEL = ../..
-DIRS := include lib tools docs
+##===- Makefile --------------------------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+# If CLANG_LEVEL is not set, then we are the top-level Makefile. Otherwise, we
+# are being included from a subdirectory makefile.
+
+ifndef CLANG_LEVEL
+
+IS_TOP_LEVEL := 1
+CLANG_LEVEL := .
+DIRS := include lib tools runtime docs
 
 PARALLEL_DIRS :=
 
 ifeq ($(BUILD_EXAMPLES),1)
   PARALLEL_DIRS += examples
 endif
+endif
 
+ifeq ($(MAKECMDGOALS),libs-only)
+  DIRS := $(filter-out tools docs, $(DIRS))
+  OPTIONAL_DIRS :=
+endif
+
+###
+# Common Makefile code, shared by all Clang Makefiles.
+
+# Set LLVM source root level.
+LEVEL := $(CLANG_LEVEL)/../..
+
+# Include LLVM common makefile.
 include $(LEVEL)/Makefile.common
 
+# Set common Clang build flags.
+CPP.Flags += -I$(PROJ_SRC_DIR)/$(CLANG_LEVEL)/include -I$(PROJ_OBJ_DIR)/$(CLANG_LEVEL)/include
+ifdef CLANG_VENDOR
+CPP.Flags += -DCLANG_VENDOR='"$(CLANG_VENDOR) "'
+endif
+
+# Disable -fstrict-aliasing. Darwin disables it by default (and LLVM doesn't
+# work with it enabled with GCC), Clang/llvm-gc don't support it yet, and newer
+# GCC's have false positive warnings with it on Linux (which prove a pain to
+# fix). For example:
+#   http://gcc.gnu.org/PR41874
+#   http://gcc.gnu.org/PR41838
+#
+# We can revisit this when LLVM/Clang support it.
+CXX.Flags += -fno-strict-aliasing
+
+###
+# Clang Top Level specific stuff.
+
+ifeq ($(IS_TOP_LEVEL),1)
+
 ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
 $(RecursiveTargets)::
 	$(Verb) if [ ! -f test/Makefile ]; then \
@@ -26,6 +75,8 @@
 clean::
 	@ $(MAKE) -C test clean
 
+libs-only: all
+
 tags::
 	$(Verb) etags `find . -type f -name '*.h' -or -name '*.cpp' | \
 	  grep -v /lib/Headers | grep -v /test/`
@@ -38,29 +89,4 @@
 
 .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/NOTES.txt b/NOTES.txt
index beceb7d..f66a961 100644
--- a/NOTES.txt
+++ b/NOTES.txt
@@ -13,8 +13,7 @@
 
 //===---------------------------------------------------------------------===//
 
-Creating and using a PTH file for performance measurement (use a release-asserts
-build).
+Creating and using a PTH file for performance measurement (use a release 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
diff --git a/README.txt b/README.txt
index 924ecc4..44ce723 100644
--- a/README.txt
+++ b/README.txt
@@ -4,7 +4,7 @@
 
 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.
+compiler infrastructure 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
diff --git a/VER b/VER
deleted file mode 100644
index c239c60..0000000
--- a/VER
+++ /dev/null
@@ -1 +0,0 @@
-1.5
diff --git a/bindings/python/README.txt b/bindings/python/README.txt
index ccc2619..742cf8f 100644
--- a/bindings/python/README.txt
+++ b/bindings/python/README.txt
@@ -2,10 +2,9 @@
 // Clang Python Bindings
 //===----------------------------------------------------------------------===//
 
-This directory implements Python bindings for Clang. Currently, only bindings
-for the CIndex C API exist.
+This directory implements Python bindings for Clang.
 
-You may need to alter LD_LIBRARY_PATH so that the CIndex library can be
+You may need to alter LD_LIBRARY_PATH so that the Clang library can be
 found. The unit tests are designed to be run with 'nosetests'. For example:
 --
 $ env PYTHONPATH=$(echo ~/llvm/tools/clang/bindings/python/) \
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index f4409ae..f0f81b5 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -71,11 +71,11 @@
     import platform
     name = platform.system()
     if name == 'Darwin':
-        return cdll.LoadLibrary('libCIndex.dylib')
+        return cdll.LoadLibrary('libclang.dylib')
     elif name == 'Windows':
-        return cdll.LoadLibrary('libCIndex.dll')
+        return cdll.LoadLibrary('libclang.dll')
     else:
-        return cdll.LoadLibrary('libCIndex.so')
+        return cdll.LoadLibrary('libclang.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
diff --git a/clang-tblgen-rules.mk b/clang-tblgen-rules.mk
index f740c09..c72c4fa 100644
--- a/clang-tblgen-rules.mk
+++ b/clang-tblgen-rules.mk
@@ -9,6 +9,27 @@
 
 intermediates := $(call local-intermediates-dir)
 
+ifneq ($(findstring AttrImpl.inc,$(TBLGEN_TABLES)),)
+LOCAL_GENERATED_SOURCES += $(intermediates)/clang/AST/AttrImpl.inc
+$(intermediates)/clang/AST/AttrImpl.inc: $(CLANG_ROOT_PATH)/include/clang/Basic/Attr.td $(TBLGEN)
+	@echo "Building Clang attribute implementations with tblgen"
+	$(call transform-host-td-to-out,clang-attr-impl)
+endif
+
+ifneq ($(findstring AttrList.inc,$(TBLGEN_TABLES)),)
+LOCAL_GENERATED_SOURCES += $(intermediates)/clang/Basic/AttrList.inc
+$(intermediates)/clang/Basic/AttrList.inc: $(CLANG_ROOT_PATH)/include/clang/Basic/Attr.td $(TBLGEN)
+	@echo "Building Clang attribute list with tblgen"
+	$(call transform-host-td-to-out,clang-attr-list)
+endif
+
+ifneq ($(findstring Attrs.inc,$(TBLGEN_TABLES)),)
+LOCAL_GENERATED_SOURCES += $(intermediates)/clang/AST/Attrs.inc
+$(intermediates)/clang/AST/Attrs.inc: $(CLANG_ROOT_PATH)/include/clang/Basic/Attr.td $(TBLGEN)
+	@echo "Building Clang attribute classes with tblgen"
+	$(call transform-host-td-to-out,clang-attr-classes)
+endif
+
 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)
@@ -23,6 +44,27 @@
 	$(call transform-host-td-to-out,clang-diag-groups)
 endif
 
+ifneq ($(findstring DeclNodes.inc,$(TBLGEN_TABLES)),)
+LOCAL_GENERATED_SOURCES += $(intermediates)/clang/AST/DeclNodes.inc
+$(intermediates)/clang/AST/DeclNodes.inc: $(CLANG_ROOT_PATH)/include/clang/Basic/DeclNodes.td $(TBLGEN)
+	@echo "Building Clang declaration node tables with tblgen"
+	$(call transform-host-td-to-out,clang-decl-nodes)
+endif
+
+ifneq ($(findstring StmtNodes.inc,$(TBLGEN_TABLES)),)
+LOCAL_GENERATED_SOURCES += $(intermediates)/clang/AST/StmtNodes.inc
+$(intermediates)/clang/AST/StmtNodes.inc: $(CLANG_ROOT_PATH)/include/clang/Basic/StmtNodes.td $(TBLGEN)
+	@echo "Building Clang statement node tables with tblgen"
+	$(call transform-host-td-to-out,clang-stmt-nodes)
+endif
+
+ifneq ($(findstring arm_neon.inc,$(TBLGEN_TABLES)),)
+LOCAL_GENERATED_SOURCES += $(intermediates)/clang/Basic/arm_neon.inc
+$(intermediates)/clang/Basic/arm_neon.inc: $(CLANG_ROOT_PATH)/include/clang/Basic/arm_neon.td $(TBLGEN)
+	@echo "Building Clang arm_neon.inc with tblgen"
+	$(call transform-host-td-to-out,arm-neon-sema)
+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)
diff --git a/clang.mk b/clang.mk
index 655e88f..587a510 100644
--- a/clang.mk
+++ b/clang.mk
@@ -4,3 +4,4 @@
 
 CLANG_HOST_BUILD_MK := $(CLANG_ROOT_PATH)/clang-host-build.mk
 CLANG_TBLGEN_RULES_MK := $(CLANG_ROOT_PATH)/clang-tblgen-rules.mk
+CLANG_VERSION_INC_MK := $(CLANG_ROOT_PATH)/clang-version-inc.mk
diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj
index 6556bb4..2db20f7 100644
--- a/clang.xcodeproj/project.pbxproj
+++ b/clang.xcodeproj/project.pbxproj
@@ -9,19 +9,12 @@
 /* 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 */; };
@@ -96,12 +89,9 @@
 		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 */; };
@@ -145,10 +135,16 @@
 		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 */; };
+		57AA9250121C8B9400B4AA6C /* ASTReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57AA924D121C8B9400B4AA6C /* ASTReader.cpp */; };
+		57AA9251121C8B9400B4AA6C /* ASTReaderDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57AA924E121C8B9400B4AA6C /* ASTReaderDecl.cpp */; };
+		57AA9252121C8B9400B4AA6C /* ASTReaderStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57AA924F121C8B9400B4AA6C /* ASTReaderStmt.cpp */; };
+		57EB566A121B034300ECA335 /* GeneratePCH.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57EB5662121B034300ECA335 /* GeneratePCH.cpp */; };
+		57EB566B121B034300ECA335 /* Makefile in Sources */ = {isa = PBXBuildFile; fileRef = 57EB5663121B034300ECA335 /* Makefile */; };
+		57F66612121B4DE600DCE3B7 /* ASTWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57F6660F121B4DE600DCE3B7 /* ASTWriter.cpp */; };
+		57F66613121B4DE600DCE3B7 /* ASTWriterDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57F66610121B4DE600DCE3B7 /* ASTWriterDecl.cpp */; };
+		57F66614121B4DE600DCE3B7 /* ASTWriterStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57F66611121B4DE600DCE3B7 /* ASTWriterStmt.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 */; };
@@ -162,7 +158,6 @@
 		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 */; };
@@ -171,15 +166,58 @@
 		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 */; };
+		BF9FEDF91225E67B003A8B71 /* Action.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF9FEDF81225E67B003A8B71 /* Action.cpp */; };
+		BF9FEDFB1225E6A9003A8B71 /* AttributeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF9FEDFA1225E6A9003A8B71 /* AttributeList.cpp */; };
+		BF9FEDFD1225E6C6003A8B71 /* DeclSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF9FEDFC1225E6C6003A8B71 /* DeclSpec.cpp */; };
+		BF9FEDFF1225E6DD003A8B71 /* TargetAttributesSema.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF9FEDFE1225E6DD003A8B71 /* TargetAttributesSema.cpp */; };
+		BF9FEE021225E73F003A8B71 /* ExprClassification.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF9FEE011225E73F003A8B71 /* ExprClassification.cpp */; };
+		BF9FEE041225E759003A8B71 /* ItaniumCXXABI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF9FEE031225E759003A8B71 /* ItaniumCXXABI.cpp */; };
+		BF9FEE061225E770003A8B71 /* MicrosoftCXXABI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF9FEE051225E770003A8B71 /* MicrosoftCXXABI.cpp */; };
+		BF9FEE2C1225E7EA003A8B71 /* BackendUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF9FEE2B1225E7EA003A8B71 /* BackendUtil.cpp */; };
+		BF9FEE311225E86C003A8B71 /* CodeGenAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF9FEE301225E86C003A8B71 /* CodeGenAction.cpp */; };
+		BF9FEE331225E898003A8B71 /* ItaniumCXXABI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF9FEE321225E898003A8B71 /* ItaniumCXXABI.cpp */; };
+		BF9FEE351225E8B1003A8B71 /* MicrosoftCXXABI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF9FEE341225E8B1003A8B71 /* MicrosoftCXXABI.cpp */; };
+		BF9FEE381225E925003A8B71 /* BoostConAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF9FEE371225E925003A8B71 /* BoostConAction.cpp */; };
+		BF9FEE521226FE9F003A8B71 /* ParseAST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BF9FEE511226FE9F003A8B71 /* ParseAST.cpp */; };
+		BFE2F6AB11DA955A0007EDC0 /* DeltaTree.d in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F67D11DA95590007EDC0 /* DeltaTree.d */; };
+		BFE2F6AC11DA955A0007EDC0 /* DeltaTree.o in Frameworks */ = {isa = PBXBuildFile; fileRef = BFE2F67E11DA955A0007EDC0 /* DeltaTree.o */; };
+		BFE2F6AD11DA955A0007EDC0 /* FixItRewriter.d in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F67F11DA955A0007EDC0 /* FixItRewriter.d */; };
+		BFE2F6AE11DA955A0007EDC0 /* FixItRewriter.o in Frameworks */ = {isa = PBXBuildFile; fileRef = BFE2F68011DA955A0007EDC0 /* FixItRewriter.o */; };
+		BFE2F6AF11DA955A0007EDC0 /* FrontendActions.d in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F68111DA955A0007EDC0 /* FrontendActions.d */; };
+		BFE2F6B011DA955A0007EDC0 /* FrontendActions.o in Frameworks */ = {isa = PBXBuildFile; fileRef = BFE2F68211DA955A0007EDC0 /* FrontendActions.o */; };
+		BFE2F6B111DA955A0007EDC0 /* HTMLPrint.d in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F68311DA955A0007EDC0 /* HTMLPrint.d */; };
+		BFE2F6B211DA955A0007EDC0 /* HTMLPrint.o in Frameworks */ = {isa = PBXBuildFile; fileRef = BFE2F68411DA955A0007EDC0 /* HTMLPrint.o */; };
+		BFE2F6B311DA955A0007EDC0 /* HTMLRewrite.d in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F68511DA955A0007EDC0 /* HTMLRewrite.d */; };
+		BFE2F6B411DA955A0007EDC0 /* HTMLRewrite.o in Frameworks */ = {isa = PBXBuildFile; fileRef = BFE2F68611DA955A0007EDC0 /* HTMLRewrite.o */; };
+		BFE2F6B511DA955A0007EDC0 /* RewriteMacros.d in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F68711DA955A0007EDC0 /* RewriteMacros.d */; };
+		BFE2F6B711DA955A0007EDC0 /* RewriteObjC.d in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F68911DA955A0007EDC0 /* RewriteObjC.d */; };
+		BFE2F6B911DA955A0007EDC0 /* Rewriter.d in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F68B11DA955A0007EDC0 /* Rewriter.d */; };
+		BFE2F6BF11DA955A0007EDC0 /* TokenRewriter.d in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F69111DA955A0007EDC0 /* TokenRewriter.d */; };
+		BFE2F6C011DA955A0007EDC0 /* TokenRewriter.o in Frameworks */ = {isa = PBXBuildFile; fileRef = BFE2F69211DA955A0007EDC0 /* TokenRewriter.o */; };
+		BFE2F6C111DA955A0007EDC0 /* DeltaTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F69311DA955A0007EDC0 /* DeltaTree.cpp */; };
+		BFE2F6C211DA955A0007EDC0 /* FixItRewriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F69411DA955A0007EDC0 /* FixItRewriter.cpp */; };
+		BFE2F6C311DA955A0007EDC0 /* FrontendActions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F69511DA955A0007EDC0 /* FrontendActions.cpp */; };
+		BFE2F6C411DA955A0007EDC0 /* HTMLPrint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F69611DA955A0007EDC0 /* HTMLPrint.cpp */; };
+		BFE2F6C511DA955A0007EDC0 /* HTMLRewrite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F69711DA955A0007EDC0 /* HTMLRewrite.cpp */; };
+		BFE2F6C611DA955A0007EDC0 /* Makefile in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F69811DA955A0007EDC0 /* Makefile */; };
+		BFE2F6C711DA955A0007EDC0 /* DeltaTree.d in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F69B11DA955A0007EDC0 /* DeltaTree.d */; };
+		BFE2F6C811DA955A0007EDC0 /* DeltaTree.o in Frameworks */ = {isa = PBXBuildFile; fileRef = BFE2F69C11DA955A0007EDC0 /* DeltaTree.o */; };
+		BFE2F6C911DA955A0007EDC0 /* HTMLRewrite.d in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F69D11DA955A0007EDC0 /* HTMLRewrite.d */; };
+		BFE2F6CA11DA955A0007EDC0 /* HTMLRewrite.o in Frameworks */ = {isa = PBXBuildFile; fileRef = BFE2F69E11DA955A0007EDC0 /* HTMLRewrite.o */; };
+		BFE2F6CB11DA955A0007EDC0 /* Rewriter.d in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F69F11DA955A0007EDC0 /* Rewriter.d */; };
+		BFE2F6CF11DA955A0007EDC0 /* TokenRewriter.d in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F6A311DA955A0007EDC0 /* TokenRewriter.d */; };
+		BFE2F6D011DA955A0007EDC0 /* TokenRewriter.o in Frameworks */ = {isa = PBXBuildFile; fileRef = BFE2F6A411DA955A0007EDC0 /* TokenRewriter.o */; };
+		BFE2F6D111DA955A0007EDC0 /* RewriteMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F6A511DA955A0007EDC0 /* RewriteMacros.cpp */; };
+		BFE2F6D211DA955A0007EDC0 /* RewriteObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F6A611DA955A0007EDC0 /* RewriteObjC.cpp */; };
+		BFE2F6D311DA955A0007EDC0 /* Rewriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F6A711DA955A0007EDC0 /* Rewriter.cpp */; };
+		BFE2F6D411DA955A0007EDC0 /* RewriteRope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F6A811DA955A0007EDC0 /* RewriteRope.cpp */; };
+		BFE2F6D511DA955A0007EDC0 /* RewriteTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F6A911DA955A0007EDC0 /* RewriteTest.cpp */; };
+		BFE2F6D611DA955A0007EDC0 /* TokenRewriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFE2F6AA11DA955A0007EDC0 /* TokenRewriter.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 */; };
@@ -190,13 +228,11 @@
 		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 */; };
@@ -220,10 +256,7 @@
 		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 */; };
@@ -249,10 +282,6 @@
 		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 */; };
@@ -295,9 +324,6 @@
 		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 */; };
@@ -330,8 +356,6 @@
 				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 */,
@@ -340,20 +364,15 @@
 				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 */,
@@ -381,19 +400,12 @@
 		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; };
@@ -417,7 +429,6 @@
 		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; };
@@ -438,46 +449,49 @@
 		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; };
+		1AA1D35611BECFF70089CC3F /* CC1AsOptions.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CC1AsOptions.td; path = clang/Driver/CC1AsOptions.td; sourceTree = "<group>"; };
+		1AA1D35711BECFF70089CC3F /* CC1Options.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CC1Options.td; path = clang/Driver/CC1Options.td; sourceTree = "<group>"; };
+		1AA1D35811BECFF70089CC3F /* Options.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Options.td; path = clang/Driver/Options.td; sourceTree = "<group>"; };
+		1AA1D35911BECFF70089CC3F /* OptParser.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = OptParser.td; path = clang/Driver/OptParser.td; sourceTree = "<group>"; };
 		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>"; };
+		1ABD23B11182449800A48E65 /* APValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = APValue.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23B21182449800A48E65 /* ASTConsumer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = ASTConsumer.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23B31182449800A48E65 /* ASTContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = ASTContext.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23B41182449800A48E65 /* ASTDiagnostic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = ASTDiagnostic.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23B51182449800A48E65 /* ASTImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = ASTImporter.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23B61182449800A48E65 /* AttrImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = AttrImpl.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23B71182449800A48E65 /* CXXInheritance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = CXXInheritance.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23B81182449800A48E65 /* Decl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = Decl.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23B91182449800A48E65 /* DeclarationName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclarationName.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23BA1182449800A48E65 /* DeclBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclBase.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23BB1182449800A48E65 /* DeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23BC1182449800A48E65 /* DeclFriend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclFriend.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23BD1182449800A48E65 /* DeclGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclGroup.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23BE1182449800A48E65 /* DeclObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclObjC.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23BF1182449800A48E65 /* DeclPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclPrinter.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23C01182449800A48E65 /* DeclTemplate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclTemplate.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23C11182449800A48E65 /* Expr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = Expr.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23C21182449800A48E65 /* ExprConstant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = ExprConstant.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23C31182449800A48E65 /* ExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = ExprCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23C41182449800A48E65 /* FullExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = FullExpr.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23C51182449800A48E65 /* InheritViz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = InheritViz.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23C61182449800A48E65 /* NestedNameSpecifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = NestedNameSpecifier.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23C71182449800A48E65 /* ParentMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = ParentMap.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23C81182449800A48E65 /* RecordLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = RecordLayout.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23C91182449800A48E65 /* RecordLayoutBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = RecordLayoutBuilder.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23CB1182449800A48E65 /* Stmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = Stmt.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23CC1182449800A48E65 /* StmtDumper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = StmtDumper.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23CD1182449800A48E65 /* StmtIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = StmtIterator.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23CE1182449800A48E65 /* StmtPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = StmtPrinter.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23CF1182449800A48E65 /* StmtProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = StmtProfile.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23D01182449800A48E65 /* StmtViz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = StmtViz.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23D11182449800A48E65 /* TemplateBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateBase.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23D21182449800A48E65 /* TemplateName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateName.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23D31182449800A48E65 /* Type.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = Type.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23D41182449800A48E65 /* TypeLoc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = TypeLoc.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		1ABD23D51182449800A48E65 /* TypePrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = TypePrinter.cpp; sourceTree = "<group>"; tabWidth = 2; };
 		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>"; };
@@ -491,15 +505,11 @@
 		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>"; };
@@ -520,7 +530,6 @@
 		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; };
@@ -529,9 +538,7 @@
 		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>"; };
@@ -585,11 +592,20 @@
 		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>"; };
+		574F4C25121B4EF000AEAC20 /* ASTWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTWriter.h; path = clang/Serialization/ASTWriter.h; sourceTree = "<group>"; };
+		57AA924D121C8B9400B4AA6C /* ASTReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTReader.cpp; sourceTree = "<group>"; };
+		57AA924E121C8B9400B4AA6C /* ASTReaderDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTReaderDecl.cpp; sourceTree = "<group>"; };
+		57AA924F121C8B9400B4AA6C /* ASTReaderStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTReaderStmt.cpp; sourceTree = "<group>"; };
+		57E15B21121C8D2B0051C2CC /* ASTDeserializationListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTDeserializationListener.h; path = clang/Serialization/ASTDeserializationListener.h; sourceTree = "<group>"; };
+		57E15B22121C8D2B0051C2CC /* ASTReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTReader.h; path = clang/Serialization/ASTReader.h; sourceTree = "<group>"; };
+		57EB5661121B034300ECA335 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
+		57EB5662121B034300ECA335 /* GeneratePCH.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GeneratePCH.cpp; sourceTree = "<group>"; };
+		57EB5663121B034300ECA335 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+		57F6660F121B4DE600DCE3B7 /* ASTWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTWriter.cpp; sourceTree = "<group>"; };
+		57F66610121B4DE600DCE3B7 /* ASTWriterDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTWriterDecl.cpp; sourceTree = "<group>"; };
+		57F66611121B4DE600DCE3B7 /* ASTWriterStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTWriterStmt.cpp; 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>"; };
@@ -601,8 +617,6 @@
 		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>"; };
@@ -637,10 +651,8 @@
 		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>"; };
@@ -652,26 +664,145 @@
 		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>"; };
+		BD59A948121496B9003A5A02 /* AnalysisBasedWarnings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnalysisBasedWarnings.h; path = clang/Sema/AnalysisBasedWarnings.h; sourceTree = "<group>"; };
+		BD59A949121496B9003A5A02 /* CodeCompleteConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CodeCompleteConsumer.h; path = clang/Sema/CodeCompleteConsumer.h; sourceTree = "<group>"; };
+		BD59A94A121496B9003A5A02 /* CXXFieldCollector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CXXFieldCollector.h; path = clang/Sema/CXXFieldCollector.h; sourceTree = "<group>"; };
+		BD59A94B121496B9003A5A02 /* ExternalSemaSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExternalSemaSource.h; path = clang/Sema/ExternalSemaSource.h; sourceTree = "<group>"; };
+		BD59A94C121496B9003A5A02 /* IdentifierResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IdentifierResolver.h; path = clang/Sema/IdentifierResolver.h; sourceTree = "<group>"; };
+		BD59A94D121496B9003A5A02 /* Initialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Initialization.h; path = clang/Sema/Initialization.h; sourceTree = "<group>"; };
+		BD59A94E121496B9003A5A02 /* Lookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Lookup.h; path = clang/Sema/Lookup.h; sourceTree = "<group>"; };
+		BD59A94F121496B9003A5A02 /* Overload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Overload.h; path = clang/Sema/Overload.h; sourceTree = "<group>"; };
+		BD59A951121496B9003A5A02 /* Sema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Sema.h; path = clang/Sema/Sema.h; sourceTree = "<group>"; };
+		BD59A952121496B9003A5A02 /* SemaConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SemaConsumer.h; path = clang/Sema/SemaConsumer.h; sourceTree = "<group>"; };
+		BD59A953121496B9003A5A02 /* SemaDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SemaDiagnostic.h; path = clang/Sema/SemaDiagnostic.h; sourceTree = "<group>"; };
+		BD59A954121496B9003A5A02 /* Template.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Template.h; path = clang/Sema/Template.h; 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>"; };
+		BF9FED6E1225DF55003A8B71 /* TemplateDeduction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemplateDeduction.h; path = clang/Sema/TemplateDeduction.h; sourceTree = "<group>"; };
+		BF9FED6F1225DF7F003A8B71 /* Action.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Action.h; path = clang/Sema/Action.h; sourceTree = "<group>"; };
+		BF9FED701225DFA1003A8B71 /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Sema/AttributeList.h; sourceTree = "<group>"; };
+		BF9FED711225DFD9003A8B71 /* DeclSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DeclSpec.h; path = clang/Sema/DeclSpec.h; sourceTree = "<group>"; };
+		BF9FED721225DFD9003A8B71 /* Designator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Designator.h; path = clang/Sema/Designator.h; sourceTree = "<group>"; };
+		BF9FED731225E005003A8B71 /* Ownership.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Ownership.h; path = clang/Sema/Ownership.h; sourceTree = "<group>"; };
+		BF9FED741225E005003A8B71 /* ParsedTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParsedTemplate.h; path = clang/Sema/ParsedTemplate.h; sourceTree = "<group>"; };
+		BF9FED751225E005003A8B71 /* Scope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Scope.h; path = clang/Sema/Scope.h; sourceTree = "<group>"; };
+		BF9FED761225E005003A8B71 /* ScopeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScopeInfo.h; path = clang/Sema/ScopeInfo.h; sourceTree = "<group>"; };
+		BF9FED771225E032003A8B71 /* ObjCMethodList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjCMethodList.h; path = clang/Sema/ObjCMethodList.h; sourceTree = "<group>"; };
+		BF9FED781225E041003A8B71 /* SemaInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SemaInternal.h; path = clang/Sema/SemaInternal.h; sourceTree = "<group>"; };
+		BF9FEDB21225E1D2003A8B71 /* CodeCompletionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeCompletionHandler.h; sourceTree = "<group>"; };
+		BF9FEDB31225E1E1003A8B71 /* ExternalPreprocessorSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExternalPreprocessorSource.h; sourceTree = "<group>"; };
+		BF9FEDB41225E1F3003A8B71 /* PreprocessingRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreprocessingRecord.h; sourceTree = "<group>"; };
+		BF9FEDB51225E213003A8B71 /* ParseAST.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParseAST.h; path = clang/Parse/ParseAST.h; sourceTree = "<group>"; };
+		BF9FEDB61225E252003A8B71 /* OperationKinds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OperationKinds.h; path = clang/AST/OperationKinds.h; sourceTree = "<group>"; };
+		BF9FEDB71225E26A003A8B71 /* RecursiveASTVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecursiveASTVisitor.h; path = clang/AST/RecursiveASTVisitor.h; sourceTree = "<group>"; };
+		BF9FEDB81225E2DE003A8B71 /* BackendUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BackendUtil.h; path = clang/CodeGen/BackendUtil.h; sourceTree = "<group>"; };
+		BF9FEDB91225E2DE003A8B71 /* CodeGenAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CodeGenAction.h; path = clang/CodeGen/CodeGenAction.h; sourceTree = "<group>"; };
+		BF9FEDBA1225E30E003A8B71 /* ASTBitCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTBitCodes.h; path = clang/Serialization/ASTBitCodes.h; sourceTree = "<group>"; };
+		BF9FEDBB1225E34B003A8B71 /* FixItRewriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FixItRewriter.h; path = clang/Rewrite/FixItRewriter.h; sourceTree = "<group>"; };
+		BF9FEDBC1225E34B003A8B71 /* FrontendActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrontendActions.h; path = clang/Rewrite/FrontendActions.h; sourceTree = "<group>"; };
+		BF9FEDBD1225E35F003A8B71 /* Rewriters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Rewriters.h; path = clang/Rewrite/Rewriters.h; sourceTree = "<group>"; };
+		BF9FEDBE1225E373003A8B71 /* ASTConsumers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTConsumers.h; path = clang/Rewrite/ASTConsumers.h; sourceTree = "<group>"; };
+		BF9FEDBF1225E392003A8B71 /* AnalyzerOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnalyzerOptions.h; path = clang/Frontend/AnalyzerOptions.h; sourceTree = "<group>"; };
+		BF9FEDC01225E3AB003A8B71 /* ChainedDiagnosticClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ChainedDiagnosticClient.h; path = clang/Frontend/ChainedDiagnosticClient.h; sourceTree = "<group>"; };
+		BF9FEDC11225E3AB003A8B71 /* CodeGenOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CodeGenOptions.h; path = clang/Frontend/CodeGenOptions.h; sourceTree = "<group>"; };
+		BF9FEDC21225E3C2003A8B71 /* CompilerInstance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompilerInstance.h; path = clang/Frontend/CompilerInstance.h; sourceTree = "<group>"; };
+		BF9FEDC31225E3C2003A8B71 /* CompilerInvocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompilerInvocation.h; path = clang/Frontend/CompilerInvocation.h; sourceTree = "<group>"; };
+		BF9FEDC41225E3DA003A8B71 /* DependencyOutputOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DependencyOutputOptions.h; path = clang/Frontend/DependencyOutputOptions.h; sourceTree = "<group>"; };
+		BF9FEDC51225E3DA003A8B71 /* DiagnosticOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DiagnosticOptions.h; path = clang/Frontend/DiagnosticOptions.h; sourceTree = "<group>"; };
+		BF9FEDC61225E3F6003A8B71 /* FrontendAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrontendAction.h; path = clang/Frontend/FrontendAction.h; sourceTree = "<group>"; };
+		BF9FEDC71225E3F6003A8B71 /* FrontendActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrontendActions.h; path = clang/Frontend/FrontendActions.h; sourceTree = "<group>"; };
+		BF9FEDC81225E40A003A8B71 /* FrontendOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrontendOptions.h; path = clang/Frontend/FrontendOptions.h; sourceTree = "<group>"; };
+		BF9FEDC91225E40A003A8B71 /* FrontendPluginRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrontendPluginRegistry.h; path = clang/Frontend/FrontendPluginRegistry.h; sourceTree = "<group>"; };
+		BF9FEDCA1225E40A003A8B71 /* HeaderSearchOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HeaderSearchOptions.h; path = clang/Frontend/HeaderSearchOptions.h; sourceTree = "<group>"; };
+		BF9FEDCB1225E40A003A8B71 /* LangStandard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LangStandard.h; path = clang/Frontend/LangStandard.h; sourceTree = "<group>"; };
+		BF9FEDCC1225E41D003A8B71 /* PreprocessorOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PreprocessorOptions.h; path = clang/Frontend/PreprocessorOptions.h; sourceTree = "<group>"; };
+		BF9FEDCD1225E41D003A8B71 /* PreprocessorOutputOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PreprocessorOutputOptions.h; path = clang/Frontend/PreprocessorOutputOptions.h; sourceTree = "<group>"; };
+		BF9FEDCE1225E42C003A8B71 /* VerifyDiagnosticsClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VerifyDiagnosticsClient.h; path = clang/Frontend/VerifyDiagnosticsClient.h; sourceTree = "<group>"; };
+		BF9FEDCF1225E443003A8B71 /* LangStandards.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LangStandards.def; path = clang/Frontend/LangStandards.def; sourceTree = "<group>"; };
+		BF9FEDE71225E488003A8B71 /* CC1AsOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CC1AsOptions.h; path = clang/Driver/CC1AsOptions.h; sourceTree = "<group>"; };
+		BF9FEDE81225E49D003A8B71 /* CC1Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CC1Options.h; path = clang/Driver/CC1Options.h; sourceTree = "<group>"; };
+		BF9FEDE91225E4BD003A8B71 /* OptSpecifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OptSpecifier.h; path = clang/Driver/OptSpecifier.h; sourceTree = "<group>"; };
+		BF9FEDEA1225E4BD003A8B71 /* OptTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OptTable.h; path = clang/Driver/OptTable.h; sourceTree = "<group>"; };
+		BF9FEDEB1225E4F2003A8B71 /* AttrKinds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AttrKinds.h; sourceTree = "<group>"; };
+		BF9FEDEC1225E514003A8B71 /* Version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Version.h; sourceTree = "<group>"; };
+		BF9FEDED1225E52F003A8B71 /* arm_neon.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = arm_neon.td; sourceTree = "<group>"; };
+		BF9FEDEE1225E52F003A8B71 /* Attr.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Attr.td; sourceTree = "<group>"; };
+		BF9FEDEF1225E55C003A8B71 /* BuiltinsARM.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BuiltinsARM.def; sourceTree = "<group>"; };
+		BF9FEDF01225E574003A8B71 /* Specifiers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Specifiers.h; sourceTree = "<group>"; };
+		BF9FEDF11225E574003A8B71 /* StmtNodes.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = StmtNodes.td; sourceTree = "<group>"; };
+		BF9FEDF21225E58B003A8B71 /* TargetOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TargetOptions.h; sourceTree = "<group>"; };
+		BF9FEDF31225E5B6003A8B71 /* DeclNodes.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DeclNodes.td; sourceTree = "<group>"; };
+		BF9FEDF41225E5D5003A8B71 /* Linkage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Linkage.h; sourceTree = "<group>"; };
+		BF9FEDF51225E5D5003A8B71 /* MacroBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroBuilder.h; sourceTree = "<group>"; };
+		BF9FEDF61225E5FB003A8B71 /* Version.inc.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Version.inc.in; sourceTree = "<group>"; };
+		BF9FEDF71225E613003A8B71 /* DiagnosticCategories.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticCategories.td; sourceTree = "<group>"; };
+		BF9FEDF81225E67B003A8B71 /* Action.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Action.cpp; path = lib/Sema/Action.cpp; sourceTree = "<group>"; };
+		BF9FEDFA1225E6A9003A8B71 /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = lib/Sema/AttributeList.cpp; sourceTree = "<group>"; };
+		BF9FEDFC1225E6C6003A8B71 /* DeclSpec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DeclSpec.cpp; path = lib/Sema/DeclSpec.cpp; sourceTree = "<group>"; };
+		BF9FEDFE1225E6DD003A8B71 /* TargetAttributesSema.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TargetAttributesSema.cpp; path = lib/Sema/TargetAttributesSema.cpp; sourceTree = "<group>"; };
+		BF9FEE001225E718003A8B71 /* CXXABI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CXXABI.h; sourceTree = "<group>"; };
+		BF9FEE011225E73F003A8B71 /* ExprClassification.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExprClassification.cpp; sourceTree = "<group>"; };
+		BF9FEE031225E759003A8B71 /* ItaniumCXXABI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ItaniumCXXABI.cpp; sourceTree = "<group>"; };
+		BF9FEE051225E770003A8B71 /* MicrosoftCXXABI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MicrosoftCXXABI.cpp; sourceTree = "<group>"; };
+		BF9FEE2B1225E7EA003A8B71 /* BackendUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BackendUtil.cpp; path = lib/CodeGen/BackendUtil.cpp; sourceTree = "<group>"; };
+		BF9FEE2D1225E80F003A8B71 /* CGCXXABI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CGCXXABI.h; path = lib/CodeGen/CGCXXABI.h; sourceTree = "<group>"; };
+		BF9FEE2E1225E82D003A8B71 /* CGException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CGException.h; path = lib/CodeGen/CGException.h; sourceTree = "<group>"; };
+		BF9FEE2F1225E854003A8B71 /* CGRecordLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CGRecordLayout.h; path = lib/CodeGen/CGRecordLayout.h; sourceTree = "<group>"; };
+		BF9FEE301225E86C003A8B71 /* CodeGenAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenAction.cpp; path = lib/CodeGen/CodeGenAction.cpp; sourceTree = "<group>"; };
+		BF9FEE321225E898003A8B71 /* ItaniumCXXABI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ItaniumCXXABI.cpp; path = lib/CodeGen/ItaniumCXXABI.cpp; sourceTree = "<group>"; };
+		BF9FEE341225E8B1003A8B71 /* MicrosoftCXXABI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MicrosoftCXXABI.cpp; path = lib/CodeGen/MicrosoftCXXABI.cpp; sourceTree = "<group>"; };
+		BF9FEE361225E8CF003A8B71 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.txt; path = lib/CodeGen/README.txt; sourceTree = "<group>"; };
+		BF9FEE371225E925003A8B71 /* BoostConAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BoostConAction.cpp; path = lib/Frontend/BoostConAction.cpp; sourceTree = "<group>"; };
+		BF9FEE451225EA24003A8B71 /* DelayedDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DelayedDiagnostic.h; path = clang/Sema/DelayedDiagnostic.h; sourceTree = "<group>"; };
+		BF9FEE511226FE9F003A8B71 /* ParseAST.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParseAST.cpp; path = lib/Parse/ParseAST.cpp; sourceTree = "<group>"; };
+		BF9FEE531226FEC1003A8B71 /* RAIIObjectsForParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RAIIObjectsForParser.h; path = lib/Parse/RAIIObjectsForParser.h; sourceTree = "<group>"; };
+		BFE2F67A11DA95590007EDC0 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
+		BFE2F67C11DA95590007EDC0 /* .dir */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .dir; sourceTree = "<group>"; };
+		BFE2F67D11DA95590007EDC0 /* DeltaTree.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = DeltaTree.d; sourceTree = "<group>"; };
+		BFE2F67E11DA955A0007EDC0 /* DeltaTree.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = DeltaTree.o; sourceTree = "<group>"; };
+		BFE2F67F11DA955A0007EDC0 /* FixItRewriter.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = FixItRewriter.d; sourceTree = "<group>"; };
+		BFE2F68011DA955A0007EDC0 /* FixItRewriter.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = FixItRewriter.o; sourceTree = "<group>"; };
+		BFE2F68111DA955A0007EDC0 /* FrontendActions.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = FrontendActions.d; sourceTree = "<group>"; };
+		BFE2F68211DA955A0007EDC0 /* FrontendActions.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = FrontendActions.o; sourceTree = "<group>"; };
+		BFE2F68311DA955A0007EDC0 /* HTMLPrint.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = HTMLPrint.d; sourceTree = "<group>"; };
+		BFE2F68411DA955A0007EDC0 /* HTMLPrint.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = HTMLPrint.o; sourceTree = "<group>"; };
+		BFE2F68511DA955A0007EDC0 /* HTMLRewrite.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = HTMLRewrite.d; sourceTree = "<group>"; };
+		BFE2F68611DA955A0007EDC0 /* HTMLRewrite.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = HTMLRewrite.o; sourceTree = "<group>"; };
+		BFE2F68711DA955A0007EDC0 /* RewriteMacros.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = RewriteMacros.d; sourceTree = "<group>"; };
+		BFE2F68911DA955A0007EDC0 /* RewriteObjC.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = RewriteObjC.d; sourceTree = "<group>"; };
+		BFE2F68B11DA955A0007EDC0 /* Rewriter.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = Rewriter.d; sourceTree = "<group>"; };
+		BFE2F69111DA955A0007EDC0 /* TokenRewriter.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = TokenRewriter.d; sourceTree = "<group>"; };
+		BFE2F69211DA955A0007EDC0 /* TokenRewriter.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = TokenRewriter.o; sourceTree = "<group>"; };
+		BFE2F69311DA955A0007EDC0 /* DeltaTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeltaTree.cpp; sourceTree = "<group>"; };
+		BFE2F69411DA955A0007EDC0 /* FixItRewriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FixItRewriter.cpp; sourceTree = "<group>"; };
+		BFE2F69511DA955A0007EDC0 /* FrontendActions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FrontendActions.cpp; sourceTree = "<group>"; };
+		BFE2F69611DA955A0007EDC0 /* HTMLPrint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLPrint.cpp; sourceTree = "<group>"; };
+		BFE2F69711DA955A0007EDC0 /* HTMLRewrite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLRewrite.cpp; sourceTree = "<group>"; };
+		BFE2F69811DA955A0007EDC0 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+		BFE2F69A11DA955A0007EDC0 /* .dir */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .dir; sourceTree = "<group>"; };
+		BFE2F69B11DA955A0007EDC0 /* DeltaTree.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = DeltaTree.d; sourceTree = "<group>"; };
+		BFE2F69C11DA955A0007EDC0 /* DeltaTree.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = DeltaTree.o; sourceTree = "<group>"; };
+		BFE2F69D11DA955A0007EDC0 /* HTMLRewrite.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = HTMLRewrite.d; sourceTree = "<group>"; };
+		BFE2F69E11DA955A0007EDC0 /* HTMLRewrite.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = HTMLRewrite.o; sourceTree = "<group>"; };
+		BFE2F69F11DA955A0007EDC0 /* Rewriter.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = Rewriter.d; sourceTree = "<group>"; };
+		BFE2F6A311DA955A0007EDC0 /* TokenRewriter.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = TokenRewriter.d; sourceTree = "<group>"; };
+		BFE2F6A411DA955A0007EDC0 /* TokenRewriter.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = TokenRewriter.o; sourceTree = "<group>"; };
+		BFE2F6A511DA955A0007EDC0 /* RewriteMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RewriteMacros.cpp; sourceTree = "<group>"; };
+		BFE2F6A611DA955A0007EDC0 /* RewriteObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RewriteObjC.cpp; sourceTree = "<group>"; };
+		BFE2F6A711DA955A0007EDC0 /* Rewriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Rewriter.cpp; sourceTree = "<group>"; };
+		BFE2F6A811DA955A0007EDC0 /* RewriteRope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RewriteRope.cpp; sourceTree = "<group>"; };
+		BFE2F6A911DA955A0007EDC0 /* RewriteTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RewriteTest.cpp; sourceTree = "<group>"; };
+		BFE2F6AA11DA955A0007EDC0 /* TokenRewriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TokenRewriter.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; };
@@ -682,13 +813,11 @@
 		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>"; };
@@ -700,8 +829,6 @@
 		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>"; };
@@ -731,10 +858,7 @@
 		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; };
@@ -761,7 +885,6 @@
 		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>"; };
@@ -774,14 +897,9 @@
 		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; };
@@ -805,44 +923,38 @@
 		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>"; };
+		DEDFE6480F7B3B830035BD10 /* Types.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Types.cpp; path = lib/Driver/Types.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE6490F7B3B830035BD10 /* Tools.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Tools.h; path = lib/Driver/Tools.h; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE64A0F7B3B830035BD10 /* Tools.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Tools.cpp; path = lib/Driver/Tools.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE64B0F7B3B830035BD10 /* ToolChains.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ToolChains.h; path = lib/Driver/ToolChains.h; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE64C0F7B3B830035BD10 /* Compilation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Compilation.cpp; path = lib/Driver/Compilation.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE64D0F7B3B830035BD10 /* ArgList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ArgList.cpp; path = lib/Driver/ArgList.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE64E0F7B3B830035BD10 /* Arg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Arg.cpp; path = lib/Driver/Arg.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE64F0F7B3B830035BD10 /* Action.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Action.cpp; path = lib/Driver/Action.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE6500F7B3B830035BD10 /* Phases.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Phases.cpp; path = lib/Driver/Phases.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE6510F7B3B830035BD10 /* OptTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = OptTable.cpp; path = lib/Driver/OptTable.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE6520F7B3B830035BD10 /* Option.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Option.cpp; path = lib/Driver/Option.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE6530F7B3B830035BD10 /* Job.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Job.cpp; path = lib/Driver/Job.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE6540F7B3B830035BD10 /* InputInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = InputInfo.h; path = lib/Driver/InputInfo.h; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE6550F7B3B830035BD10 /* ToolChains.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ToolChains.cpp; path = lib/Driver/ToolChains.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE6560F7B3B830035BD10 /* ToolChain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ToolChain.cpp; path = lib/Driver/ToolChain.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE6570F7B3B830035BD10 /* Tool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Tool.cpp; path = lib/Driver/Tool.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE6580F7B3B830035BD10 /* HostInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = HostInfo.cpp; path = lib/Driver/HostInfo.cpp; sourceTree = "<group>"; tabWidth = 2; };
+		DEDFE6590F7B3B830035BD10 /* Driver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Driver.cpp; path = lib/Driver/Driver.cpp; sourceTree = "<group>"; tabWidth = 2; };
 		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>"; };
@@ -855,13 +967,6 @@
 		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; };
@@ -881,6 +986,15 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				BFE2F6AC11DA955A0007EDC0 /* DeltaTree.o in Frameworks */,
+				BFE2F6AE11DA955A0007EDC0 /* FixItRewriter.o in Frameworks */,
+				BFE2F6B011DA955A0007EDC0 /* FrontendActions.o in Frameworks */,
+				BFE2F6B211DA955A0007EDC0 /* HTMLPrint.o in Frameworks */,
+				BFE2F6B411DA955A0007EDC0 /* HTMLRewrite.o in Frameworks */,
+				BFE2F6C011DA955A0007EDC0 /* TokenRewriter.o in Frameworks */,
+				BFE2F6C811DA955A0007EDC0 /* DeltaTree.o in Frameworks */,
+				BFE2F6CA11DA955A0007EDC0 /* HTMLRewrite.o in Frameworks */,
+				BFE2F6D011DA955A0007EDC0 /* TokenRewriter.o in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -902,6 +1016,8 @@
 		08FB7795FE84155DC02AAC07 /* Libraries */ = {
 			isa = PBXGroup;
 			children = (
+				57EB5660121B034300ECA335 /* Serialization */,
+				BFE2F67911DA95590007EDC0 /* Rewrite */,
 				90FD6D6C103C3D2D005F5B73 /* Index */,
 				DED7D7500A5242C7003AD0FB /* Basic */,
 				DED7D78C0A5242E6003AD0FB /* Lex */,
@@ -979,11 +1095,10 @@
 		352246E00F5C6BC000D0D279 /* Frontend */ = {
 			isa = PBXGroup;
 			children = (
+				BF9FEE371225E925003A8B71 /* BoostConAction.cpp */,
 				1AFDD8701161085D00AE030A /* ASTMerge.cpp */,
 				9012911C1048068D0083456D /* ASTUnit.cpp */,
-				1A2A54A40FD1DD1C00F4CE45 /* AnalysisConsumer.cpp */,
 				1A2A54A50FD1DD1C00F4CE45 /* ASTConsumers.cpp */,
-				1AFDD8711161085D00AE030A /* CodeGenAction.cpp */,
 				1A2A54A70FD1DD1C00F4CE45 /* CacheTokens.cpp */,
 				1ACB57DB1105820D0047B991 /* CompilerInstance.cpp */,
 				1ACB57DC1105820D0047B991 /* CompilerInvocation.cpp */,
@@ -991,31 +1106,16 @@
 				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 */,
@@ -1129,6 +1229,34 @@
 			name = Analyses;
 			sourceTree = "<group>";
 		};
+		57EB5654121B023900ECA335 /* Serialization */ = {
+			isa = PBXGroup;
+			children = (
+				BF9FEDBA1225E30E003A8B71 /* ASTBitCodes.h */,
+				57E15B21121C8D2B0051C2CC /* ASTDeserializationListener.h */,
+				57E15B22121C8D2B0051C2CC /* ASTReader.h */,
+				574F4C25121B4EF000AEAC20 /* ASTWriter.h */,
+			);
+			name = Serialization;
+			sourceTree = "<group>";
+		};
+		57EB5660121B034300ECA335 /* Serialization */ = {
+			isa = PBXGroup;
+			children = (
+				57AA924D121C8B9400B4AA6C /* ASTReader.cpp */,
+				57AA924E121C8B9400B4AA6C /* ASTReaderDecl.cpp */,
+				57AA924F121C8B9400B4AA6C /* ASTReaderStmt.cpp */,
+				57F6660F121B4DE600DCE3B7 /* ASTWriter.cpp */,
+				57F66610121B4DE600DCE3B7 /* ASTWriterDecl.cpp */,
+				57F66611121B4DE600DCE3B7 /* ASTWriterStmt.cpp */,
+				57EB5661121B034300ECA335 /* CMakeLists.txt */,
+				57EB5662121B034300ECA335 /* GeneratePCH.cpp */,
+				57EB5663121B034300ECA335 /* Makefile */,
+			);
+			name = Serialization;
+			path = lib/Serialization;
+			sourceTree = "<group>";
+		};
 		9012911210470FAF0083456D /* clang-c */ = {
 			isa = PBXGroup;
 			children = (
@@ -1196,7 +1324,6 @@
 				90FD6D76103C3D49005F5B73 /* IndexProvider.cpp */,
 				90FD6D77103C3D49005F5B73 /* Program.cpp */,
 				90FD6D78103C3D49005F5B73 /* ProgramImpl.h */,
-				90FD6D79103C3D49005F5B73 /* ResolveLocation.cpp */,
 				90FD6D7A103C3D49005F5B73 /* SelectorMap.cpp */,
 			);
 			name = Index;
@@ -1210,6 +1337,67 @@
 			name = "index-test";
 			sourceTree = "<group>";
 		};
+		BFE2F67911DA95590007EDC0 /* Rewrite */ = {
+			isa = PBXGroup;
+			children = (
+				BFE2F67A11DA95590007EDC0 /* CMakeLists.txt */,
+				BFE2F67B11DA95590007EDC0 /* Debug */,
+				BFE2F69311DA955A0007EDC0 /* DeltaTree.cpp */,
+				BFE2F69411DA955A0007EDC0 /* FixItRewriter.cpp */,
+				BFE2F69511DA955A0007EDC0 /* FrontendActions.cpp */,
+				BFE2F69611DA955A0007EDC0 /* HTMLPrint.cpp */,
+				BFE2F69711DA955A0007EDC0 /* HTMLRewrite.cpp */,
+				BFE2F69811DA955A0007EDC0 /* Makefile */,
+				BFE2F69911DA955A0007EDC0 /* Release-Asserts */,
+				BFE2F6A511DA955A0007EDC0 /* RewriteMacros.cpp */,
+				BFE2F6A611DA955A0007EDC0 /* RewriteObjC.cpp */,
+				BFE2F6A711DA955A0007EDC0 /* Rewriter.cpp */,
+				BFE2F6A811DA955A0007EDC0 /* RewriteRope.cpp */,
+				BFE2F6A911DA955A0007EDC0 /* RewriteTest.cpp */,
+				BFE2F6AA11DA955A0007EDC0 /* TokenRewriter.cpp */,
+			);
+			name = Rewrite;
+			path = lib/Rewrite;
+			sourceTree = "<group>";
+		};
+		BFE2F67B11DA95590007EDC0 /* Debug */ = {
+			isa = PBXGroup;
+			children = (
+				BFE2F67C11DA95590007EDC0 /* .dir */,
+				BFE2F67D11DA95590007EDC0 /* DeltaTree.d */,
+				BFE2F67E11DA955A0007EDC0 /* DeltaTree.o */,
+				BFE2F67F11DA955A0007EDC0 /* FixItRewriter.d */,
+				BFE2F68011DA955A0007EDC0 /* FixItRewriter.o */,
+				BFE2F68111DA955A0007EDC0 /* FrontendActions.d */,
+				BFE2F68211DA955A0007EDC0 /* FrontendActions.o */,
+				BFE2F68311DA955A0007EDC0 /* HTMLPrint.d */,
+				BFE2F68411DA955A0007EDC0 /* HTMLPrint.o */,
+				BFE2F68511DA955A0007EDC0 /* HTMLRewrite.d */,
+				BFE2F68611DA955A0007EDC0 /* HTMLRewrite.o */,
+				BFE2F68711DA955A0007EDC0 /* RewriteMacros.d */,
+				BFE2F68911DA955A0007EDC0 /* RewriteObjC.d */,
+				BFE2F68B11DA955A0007EDC0 /* Rewriter.d */,
+				BFE2F69111DA955A0007EDC0 /* TokenRewriter.d */,
+				BFE2F69211DA955A0007EDC0 /* TokenRewriter.o */,
+			);
+			path = Debug;
+			sourceTree = "<group>";
+		};
+		BFE2F69911DA955A0007EDC0 /* Release-Asserts */ = {
+			isa = PBXGroup;
+			children = (
+				BFE2F69A11DA955A0007EDC0 /* .dir */,
+				BFE2F69B11DA955A0007EDC0 /* DeltaTree.d */,
+				BFE2F69C11DA955A0007EDC0 /* DeltaTree.o */,
+				BFE2F69D11DA955A0007EDC0 /* HTMLRewrite.d */,
+				BFE2F69E11DA955A0007EDC0 /* HTMLRewrite.o */,
+				BFE2F69F11DA955A0007EDC0 /* Rewriter.d */,
+				BFE2F6A311DA955A0007EDC0 /* TokenRewriter.d */,
+				BFE2F6A411DA955A0007EDC0 /* TokenRewriter.o */,
+			);
+			path = "Release-Asserts";
+			sourceTree = "<group>";
+		};
 		C6859E8C029090F304C91782 /* Documentation */ = {
 			isa = PBXGroup;
 			children = (
@@ -1224,15 +1412,9 @@
 		DE1F21F20A7D84E800FBF588 /* Parse */ = {
 			isa = PBXGroup;
 			children = (
-				3551068E0E9A855F006A4E44 /* AccessSpecifier.h */,
-				84D9A88B0C1A581300AC7ABC /* AttributeList.h */,
-				DE06E8130A8FF9330050E87E /* Action.h */,
-				DE17336F0B068DC60080B521 /* DeclSpec.h */,
-				DE3B92230EB5152000D01046 /* Designator.h */,
-				DE1263C20EF2341900F56D2B /* Ownership.h */,
+				BF9FEDB51225E213003A8B71 /* ParseAST.h */,
 				DEA09A860F3175CA000C2258 /* ParseDiagnostic.h */,
 				DE1F22020A7D852A00FBF588 /* Parser.h */,
-				DE06BECA0A854E4B0050E87E /* Scope.h */,
 			);
 			name = Parse;
 			sourceTree = "<group>";
@@ -1240,10 +1422,7 @@
 		DE1F22600A7D8C9B00FBF588 /* Parse */ = {
 			isa = PBXGroup;
 			children = (
-				84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */,
-				DE17336D0B068DC20080B521 /* DeclSpec.cpp */,
-				DE3B90DE0EAC5EF200D01046 /* ExtensionRAIIObject.h */,
-				DE3461260AFE68BE00DBC861 /* MinimalAction.cpp */,
+				BF9FEE511226FE9F003A8B71 /* ParseAST.cpp */,
 				DE34600E0AFDCCCE00DBC861 /* ParseDecl.cpp */,
 				DE2255FB0C8004E600D370A5 /* ParseDeclCXX.cpp */,
 				DE3460120AFDCCDA00DBC861 /* ParseExpr.cpp */,
@@ -1257,6 +1436,7 @@
 				353959D40EE5F88A00E82461 /* ParseTemplate.cpp */,
 				3551068B0E9A8546006A4E44 /* ParseTentative.cpp */,
 				DE06D42F0A8BB52D0050E87E /* Parser.cpp */,
+				BF9FEE531226FEC1003A8B71 /* RAIIObjectsForParser.h */,
 			);
 			name = Parse;
 			sourceTree = "<group>";
@@ -1289,16 +1469,14 @@
 		DE67E7070C020EAB00F66BC5 /* Sema */ = {
 			isa = PBXGroup;
 			children = (
+				BF9FEDFE1225E6DD003A8B71 /* TargetAttributesSema.cpp */,
+				BF9FEDFC1225E6C6003A8B71 /* DeclSpec.cpp */,
+				BF9FEDFA1225E6A9003A8B71 /* AttributeList.cpp */,
+				BF9FEDF81225E67B003A8B71 /* Action.cpp */,
 				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 */,
@@ -1313,17 +1491,14 @@
 				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 */,
@@ -1337,11 +1512,30 @@
 		DE67E7260C02108300F66BC5 /* Sema */ = {
 			isa = PBXGroup;
 			children = (
-				7F270AFE107A90010031B377 /* CodeCompleteConsumer.h */,
-				9063F2210F9E8BDF002F7251 /* ExternalSemaSource.h */,
-				9063F2220F9E8BDF002F7251 /* SemaConsumer.h */,
-				DE67E7270C02109800F66BC5 /* ParseAST.h */,
-				DEA09A890F3175D9000C2258 /* SemaDiagnostic.h */,
+				BF9FEE451225EA24003A8B71 /* DelayedDiagnostic.h */,
+				BF9FED781225E041003A8B71 /* SemaInternal.h */,
+				BF9FED771225E032003A8B71 /* ObjCMethodList.h */,
+				BF9FED731225E005003A8B71 /* Ownership.h */,
+				BF9FED741225E005003A8B71 /* ParsedTemplate.h */,
+				BF9FED751225E005003A8B71 /* Scope.h */,
+				BF9FED761225E005003A8B71 /* ScopeInfo.h */,
+				BF9FED711225DFD9003A8B71 /* DeclSpec.h */,
+				BF9FED721225DFD9003A8B71 /* Designator.h */,
+				BF9FED701225DFA1003A8B71 /* AttributeList.h */,
+				BF9FED6F1225DF7F003A8B71 /* Action.h */,
+				BF9FED6E1225DF55003A8B71 /* TemplateDeduction.h */,
+				BD59A948121496B9003A5A02 /* AnalysisBasedWarnings.h */,
+				BD59A949121496B9003A5A02 /* CodeCompleteConsumer.h */,
+				BD59A94A121496B9003A5A02 /* CXXFieldCollector.h */,
+				BD59A94B121496B9003A5A02 /* ExternalSemaSource.h */,
+				BD59A94C121496B9003A5A02 /* IdentifierResolver.h */,
+				BD59A94D121496B9003A5A02 /* Initialization.h */,
+				BD59A94E121496B9003A5A02 /* Lookup.h */,
+				BD59A94F121496B9003A5A02 /* Overload.h */,
+				BD59A951121496B9003A5A02 /* Sema.h */,
+				BD59A952121496B9003A5A02 /* SemaConsumer.h */,
+				BD59A953121496B9003A5A02 /* SemaDiagnostic.h */,
+				BD59A954121496B9003A5A02 /* Template.h */,
 			);
 			name = Sema;
 			sourceTree = "<group>";
@@ -1349,6 +1543,14 @@
 		DE927FCC0C0557CD00231DA4 /* CodeGen */ = {
 			isa = PBXGroup;
 			children = (
+				BF9FEE361225E8CF003A8B71 /* README.txt */,
+				BF9FEE341225E8B1003A8B71 /* MicrosoftCXXABI.cpp */,
+				BF9FEE321225E898003A8B71 /* ItaniumCXXABI.cpp */,
+				BF9FEE301225E86C003A8B71 /* CodeGenAction.cpp */,
+				BF9FEE2F1225E854003A8B71 /* CGRecordLayout.h */,
+				BF9FEE2E1225E82D003A8B71 /* CGException.h */,
+				BF9FEE2D1225E80F003A8B71 /* CGCXXABI.h */,
+				BF9FEE2B1225E7EA003A8B71 /* BackendUtil.cpp */,
 				1A2193CB0F45EEB700C0713D /* ABIInfo.h */,
 				1A471AB40F437BC500753CE8 /* CGBlocks.cpp */,
 				1A649E1D0F9599D9005B965E /* CGBlocks.h */,
@@ -1401,6 +1603,8 @@
 		DE928B140C05659A00231DA4 /* CodeGen */ = {
 			isa = PBXGroup;
 			children = (
+				BF9FEDB81225E2DE003A8B71 /* BackendUtil.h */,
+				BF9FEDB91225E2DE003A8B71 /* CodeGenAction.h */,
 				DE928B1F0C0565B000231DA4 /* ModuleBuilder.h */,
 			);
 			name = CodeGen;
@@ -1409,6 +1613,8 @@
 		DEC8D98B0A9433BC00353FCA /* AST */ = {
 			isa = PBXGroup;
 			children = (
+				BF9FEDB71225E26A003A8B71 /* RecursiveASTVisitor.h */,
+				BF9FEDB61225E252003A8B71 /* OperationKinds.h */,
 				1A15C407118226980092260D /* ASTImporter.h */,
 				1A15C408118226980092260D /* ASTVector.h */,
 				1A15C409118226980092260D /* CharUnits.h */,
@@ -1441,7 +1647,6 @@
 				84AF36A00CB17A3B00C820A5 /* DeclObjC.h */,
 				35EE48AD0E0C4CB200715C54 /* DeclCXX.h */,
 				358D23090E8BEB850003DDCC /* DeclGroup.h */,
-				DEDFE5270F63A9230035BD10 /* DeclNodes.def */,
 				DEB076C90F3A221200F5A2BE /* DeclTemplate.h */,
 				DE0FCA620A95859D00248FD5 /* Expr.h */,
 				1A30A9E80B93A4C800201A91 /* ExprCXX.h */,
@@ -1453,7 +1658,6 @@
 				DE6951C60C4D1F5D00A5826B /* RecordLayout.h */,
 				DE3452800AEF1B1800DBC861 /* Stmt.h */,
 				DECB73550FA3EE5A00F5FBC7 /* StmtCXX.h */,
-				DE345F210AFD347900DBC861 /* StmtNodes.def */,
 				DECB734E0FA3ED8400F5FBC7 /* StmtObjC.h */,
 				DE345C190AFC658B00DBC861 /* StmtVisitor.h */,
 				35847BE30CC7DB9000C40FFF /* StmtIterator.h */,
@@ -1469,6 +1673,10 @@
 		DEC8D9920A9433F400353FCA /* AST */ = {
 			isa = PBXGroup;
 			children = (
+				BF9FEE051225E770003A8B71 /* MicrosoftCXXABI.cpp */,
+				BF9FEE031225E759003A8B71 /* ItaniumCXXABI.cpp */,
+				BF9FEE011225E73F003A8B71 /* ExprClassification.cpp */,
+				BF9FEE001225E718003A8B71 /* CXXABI.h */,
 				1ABD23B11182449800A48E65 /* APValue.cpp */,
 				1ABD23B21182449800A48E65 /* ASTConsumer.cpp */,
 				1ABD23B31182449800A48E65 /* ASTContext.cpp */,
@@ -1494,7 +1702,6 @@
 				1ABD23C71182449800A48E65 /* ParentMap.cpp */,
 				1ABD23C81182449800A48E65 /* RecordLayout.cpp */,
 				1ABD23C91182449800A48E65 /* RecordLayoutBuilder.cpp */,
-				1ABD23CA1182449800A48E65 /* RecordLayoutBuilder.h */,
 				1ABD23CB1182449800A48E65 /* Stmt.cpp */,
 				1ABD23CC1182449800A48E65 /* StmtDumper.cpp */,
 				1ABD23CD1182449800A48E65 /* StmtIterator.cpp */,
@@ -1521,6 +1728,7 @@
 				DE67E7260C02108300F66BC5 /* Sema */,
 				DE928B140C05659A00231DA4 /* CodeGen */,
 				356EF9AF0C8F7DA4006650F5 /* Analysis */,
+				57EB5654121B023900ECA335 /* Serialization */,
 				90FD6D5E103C3D03005F5B73 /* Index */,
 				DEF7D9F40C9C8B020001F598 /* Rewrite */,
 				DEF1615D0F65C7FC0098507F /* Frontend */,
@@ -1533,6 +1741,19 @@
 		DED7D7300A524295003AD0FB /* Basic */ = {
 			isa = PBXGroup;
 			children = (
+				BF9FEDF71225E613003A8B71 /* DiagnosticCategories.td */,
+				BF9FEDF61225E5FB003A8B71 /* Version.inc.in */,
+				BF9FEDF41225E5D5003A8B71 /* Linkage.h */,
+				BF9FEDF51225E5D5003A8B71 /* MacroBuilder.h */,
+				BF9FEDF31225E5B6003A8B71 /* DeclNodes.td */,
+				BF9FEDF21225E58B003A8B71 /* TargetOptions.h */,
+				BF9FEDF01225E574003A8B71 /* Specifiers.h */,
+				BF9FEDF11225E574003A8B71 /* StmtNodes.td */,
+				BF9FEDEF1225E55C003A8B71 /* BuiltinsARM.def */,
+				BF9FEDED1225E52F003A8B71 /* arm_neon.td */,
+				BF9FEDEE1225E52F003A8B71 /* Attr.td */,
+				BF9FEDEC1225E514003A8B71 /* Version.h */,
+				BF9FEDEB1225E4F2003A8B71 /* AttrKinds.h */,
 				DE37251C0FE4818000CF2CC2 /* Builtins.h */,
 				DE37252A0FE4818F00CF2CC2 /* Builtins.def */,
 				DE3725330FE4827200CF2CC2 /* BuiltinsPPC.def */,
@@ -1574,6 +1795,9 @@
 		DED7D7390A524295003AD0FB /* Lex */ = {
 			isa = PBXGroup;
 			children = (
+				BF9FEDB41225E1F3003A8B71 /* PreprocessingRecord.h */,
+				BF9FEDB31225E1E1003A8B71 /* ExternalPreprocessorSource.h */,
+				BF9FEDB21225E1D2003A8B71 /* CodeCompletionHandler.h */,
 				DE3450D60AEB543100DBC861 /* DirectoryLookup.h */,
 				DE704BD10D1647E7009C7762 /* HeaderMap.h */,
 				DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */,
@@ -1690,28 +1914,35 @@
 		DEF1615D0F65C7FC0098507F /* Frontend */ = {
 			isa = PBXGroup;
 			children = (
+				BF9FEDCE1225E42C003A8B71 /* VerifyDiagnosticsClient.h */,
+				BF9FEDCC1225E41D003A8B71 /* PreprocessorOptions.h */,
+				BF9FEDCD1225E41D003A8B71 /* PreprocessorOutputOptions.h */,
+				BF9FEDC81225E40A003A8B71 /* FrontendOptions.h */,
+				BF9FEDC91225E40A003A8B71 /* FrontendPluginRegistry.h */,
+				BF9FEDCA1225E40A003A8B71 /* HeaderSearchOptions.h */,
+				BF9FEDCB1225E40A003A8B71 /* LangStandard.h */,
+				BF9FEDC61225E3F6003A8B71 /* FrontendAction.h */,
+				BF9FEDC71225E3F6003A8B71 /* FrontendActions.h */,
+				BF9FEDC41225E3DA003A8B71 /* DependencyOutputOptions.h */,
+				BF9FEDC51225E3DA003A8B71 /* DiagnosticOptions.h */,
+				BF9FEDC21225E3C2003A8B71 /* CompilerInstance.h */,
+				BF9FEDC31225E3C2003A8B71 /* CompilerInvocation.h */,
+				BF9FEDC01225E3AB003A8B71 /* ChainedDiagnosticClient.h */,
+				BF9FEDC11225E3AB003A8B71 /* CodeGenOptions.h */,
+				BF9FEDBF1225E392003A8B71 /* AnalyzerOptions.h */,
 				90FD6D86103C3D80005F5B73 /* Analyses.def */,
-				90FD6D87103C3D80005F5B73 /* AnalysisConsumer.h */,
 				90FD6D88103C3D80005F5B73 /* ASTConsumers.h */,
 				90FD6D89103C3D80005F5B73 /* ASTUnit.h */,
 				90FD6D8A103C3D80005F5B73 /* CommandLineSourceLoc.h */,
 				90FD6D8B103C3D80005F5B73 /* DeclContextXML.def */,
 				90FD6D8C103C3D80005F5B73 /* DeclXML.def */,
 				90FD6D8D103C3D80005F5B73 /* DocumentXML.def */,
+				BF9FEDCF1225E443003A8B71 /* LangStandards.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 */,
 			);
@@ -1721,17 +1952,24 @@
 		DEF165020F8D46810098507F /* Driver */ = {
 			isa = PBXGroup;
 			children = (
+				BF9FEDE91225E4BD003A8B71 /* OptSpecifier.h */,
+				BF9FEDEA1225E4BD003A8B71 /* OptTable.h */,
+				BF9FEDE81225E49D003A8B71 /* CC1Options.h */,
+				BF9FEDE71225E488003A8B71 /* CC1AsOptions.h */,
 				DEF165160F8D46980098507F /* Action.h */,
 				DEF1651D0F8D46980098507F /* ArgList.h */,
 				DEF1651E0F8D46980098507F /* Arg.h */,
+				1AA1D35611BECFF70089CC3F /* CC1AsOptions.td */,
+				1AA1D35711BECFF70089CC3F /* CC1Options.td */,
 				DEF165170F8D46980098507F /* Compilation.h */,
 				DEF165240F8D46980098507F /* DriverDiagnostic.h */,
 				DEF165200F8D46980098507F /* Driver.h */,
 				DEF1651F0F8D46980098507F /* HostInfo.h */,
 				DEF165210F8D46980098507F /* Job.h */,
-				DEF165180F8D46980098507F /* Options.def */,
 				DEF165190F8D46980098507F /* Option.h */,
+				1AA1D35811BECFF70089CC3F /* Options.td */,
 				DEF1651C0F8D46980098507F /* Options.h */,
+				1AA1D35911BECFF70089CC3F /* OptParser.td */,
 				DEF165230F8D46980098507F /* Phases.h */,
 				DEF165140F8D46980098507F /* Tool.h */,
 				DEF165150F8D46980098507F /* Types.h */,
@@ -1745,6 +1983,10 @@
 		DEF7D9F40C9C8B020001F598 /* Rewrite */ = {
 			isa = PBXGroup;
 			children = (
+				BF9FEDBE1225E373003A8B71 /* ASTConsumers.h */,
+				BF9FEDBD1225E35F003A8B71 /* Rewriters.h */,
+				BF9FEDBB1225E34B003A8B71 /* FixItRewriter.h */,
+				BF9FEDBC1225E34B003A8B71 /* FrontendActions.h */,
 				DEFFECA30DB093D100B4E7C3 /* DeltaTree.h */,
 				35F2BE7B0DAC2963006E7668 /* HTMLRewrite.h */,
 				DEF7D9F60C9C8B1A0001F598 /* Rewriter.h */,
@@ -1827,8 +2069,6 @@
 				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 */,
@@ -1836,7 +2076,6 @@
 				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 */,
@@ -1844,7 +2083,6 @@
 				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 */,
@@ -1922,9 +2160,7 @@
 				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 */,
@@ -1949,28 +2185,14 @@
 				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 */,
@@ -1986,7 +2208,6 @@
 				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 */,
@@ -2023,7 +2244,6 @@
 				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 */,
@@ -2060,6 +2280,52 @@
 				1ABD23F71182449800A48E65 /* Type.cpp in Sources */,
 				1ABD23F81182449800A48E65 /* TypeLoc.cpp in Sources */,
 				1ABD23F91182449800A48E65 /* TypePrinter.cpp in Sources */,
+				BFE2F6AB11DA955A0007EDC0 /* DeltaTree.d in Sources */,
+				BFE2F6AD11DA955A0007EDC0 /* FixItRewriter.d in Sources */,
+				BFE2F6AF11DA955A0007EDC0 /* FrontendActions.d in Sources */,
+				BFE2F6B111DA955A0007EDC0 /* HTMLPrint.d in Sources */,
+				BFE2F6B311DA955A0007EDC0 /* HTMLRewrite.d in Sources */,
+				BFE2F6B511DA955A0007EDC0 /* RewriteMacros.d in Sources */,
+				BFE2F6B711DA955A0007EDC0 /* RewriteObjC.d in Sources */,
+				BFE2F6B911DA955A0007EDC0 /* Rewriter.d in Sources */,
+				BFE2F6BF11DA955A0007EDC0 /* TokenRewriter.d in Sources */,
+				BFE2F6C111DA955A0007EDC0 /* DeltaTree.cpp in Sources */,
+				BFE2F6C211DA955A0007EDC0 /* FixItRewriter.cpp in Sources */,
+				BFE2F6C311DA955A0007EDC0 /* FrontendActions.cpp in Sources */,
+				BFE2F6C411DA955A0007EDC0 /* HTMLPrint.cpp in Sources */,
+				BFE2F6C511DA955A0007EDC0 /* HTMLRewrite.cpp in Sources */,
+				BFE2F6C611DA955A0007EDC0 /* Makefile in Sources */,
+				BFE2F6C711DA955A0007EDC0 /* DeltaTree.d in Sources */,
+				BFE2F6C911DA955A0007EDC0 /* HTMLRewrite.d in Sources */,
+				BFE2F6CB11DA955A0007EDC0 /* Rewriter.d in Sources */,
+				BFE2F6CF11DA955A0007EDC0 /* TokenRewriter.d in Sources */,
+				BFE2F6D111DA955A0007EDC0 /* RewriteMacros.cpp in Sources */,
+				BFE2F6D211DA955A0007EDC0 /* RewriteObjC.cpp in Sources */,
+				BFE2F6D311DA955A0007EDC0 /* Rewriter.cpp in Sources */,
+				BFE2F6D411DA955A0007EDC0 /* RewriteRope.cpp in Sources */,
+				BFE2F6D511DA955A0007EDC0 /* RewriteTest.cpp in Sources */,
+				BFE2F6D611DA955A0007EDC0 /* TokenRewriter.cpp in Sources */,
+				57EB566A121B034300ECA335 /* GeneratePCH.cpp in Sources */,
+				57EB566B121B034300ECA335 /* Makefile in Sources */,
+				57F66612121B4DE600DCE3B7 /* ASTWriter.cpp in Sources */,
+				57F66613121B4DE600DCE3B7 /* ASTWriterDecl.cpp in Sources */,
+				57F66614121B4DE600DCE3B7 /* ASTWriterStmt.cpp in Sources */,
+				57AA9250121C8B9400B4AA6C /* ASTReader.cpp in Sources */,
+				57AA9251121C8B9400B4AA6C /* ASTReaderDecl.cpp in Sources */,
+				57AA9252121C8B9400B4AA6C /* ASTReaderStmt.cpp in Sources */,
+				BF9FEDF91225E67B003A8B71 /* Action.cpp in Sources */,
+				BF9FEDFB1225E6A9003A8B71 /* AttributeList.cpp in Sources */,
+				BF9FEDFD1225E6C6003A8B71 /* DeclSpec.cpp in Sources */,
+				BF9FEDFF1225E6DD003A8B71 /* TargetAttributesSema.cpp in Sources */,
+				BF9FEE021225E73F003A8B71 /* ExprClassification.cpp in Sources */,
+				BF9FEE041225E759003A8B71 /* ItaniumCXXABI.cpp in Sources */,
+				BF9FEE061225E770003A8B71 /* MicrosoftCXXABI.cpp in Sources */,
+				BF9FEE2C1225E7EA003A8B71 /* BackendUtil.cpp in Sources */,
+				BF9FEE311225E86C003A8B71 /* CodeGenAction.cpp in Sources */,
+				BF9FEE331225E898003A8B71 /* ItaniumCXXABI.cpp in Sources */,
+				BF9FEE351225E8B1003A8B71 /* MicrosoftCXXABI.cpp in Sources */,
+				BF9FEE381225E925003A8B71 /* BoostConAction.cpp in Sources */,
+				BF9FEE521226FE9F003A8B71 /* ParseAST.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/docs/InternalsManual.html b/docs/InternalsManual.html
index 5d75eaa..7aa26e0 100644
--- a/docs/InternalsManual.html
+++ b/docs/InternalsManual.html
@@ -118,8 +118,8 @@
 <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.
+(at the minimum) a unique ID, an English translation associated with it, a <a
+href="#SourceLocation">SourceLocation</a> to "put the caret", 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>
@@ -127,7 +127,7 @@
 <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>
+implemented.  A representative example of a diagnostic is:</p>
 
 <pre>
 t.c:38:15: error: invalid operands to binary expression ('int *' and '_Complex float')
@@ -145,13 +145,13 @@
 pieces, this section describes them and talks about best practices when adding
 a new diagnostic.</p>
 
-<!-- ============================ -->
-<h4>The DiagnosticKinds.def file</h4>
-<!-- ============================ -->
+<!-- ============================== -->
+<h4>The Diagnostic*Kinds.def files</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 
+<p>Diagnostics are created by adding an entry to one of the <tt>
+clang/Basic/Diagnostic*Kinds.def</tt> files, depending on what library will
+be using it.  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>
 
@@ -532,12 +532,12 @@
 </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>
+to encode two pieces of information about a location: its spelling location
+and its 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
@@ -709,7 +709,7 @@
 
 <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>
+interprets 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>
diff --git a/docs/LanguageExtensions.html b/docs/LanguageExtensions.html
index 9779c3f..838b65f 100644
--- a/docs/LanguageExtensions.html
+++ b/docs/LanguageExtensions.html
@@ -199,7 +199,44 @@
 <h2 id="builtinmacros">Builtin Macros</h2>
 <!-- ======================================================================= -->
 
-<p>__BASE_FILE__, __INCLUDE_LEVEL__, __TIMESTAMP__, __COUNTER__</p>
+<dl>
+  <dt><code>__BASE_FILE__</code></dt>
+  <dd>Defined to a string that contains the name of the main input
+  file passed to Clang.</dd> 
+
+  <dt><code>__COUNTER__</code></dt>
+  <dd>Defined to an integer value that starts at zero and is
+  incremented each time the <code>__COUNTER__</code> macro is
+  expanded.</dd> 
+    
+  <dt><code>__INCLUDE_LEVEL__</code></dt>
+  <dd>Defined to an integral value that is the include depth of the
+  file currently being translated. For the main file, this value is
+  zero.</dd> 
+
+  <dt><code>__TIMESTAMP__</code></dt>
+  <dd>Defined to the date and time of the last modification of the
+  current source file.</dd> 
+    
+  <dt><code>__clang__</code></dt>
+  <dd>Defined when compiling with Clang</dd>
+
+  <dt><code>__clang_major__</code></dt>
+  <dd>Defined to the major version number of Clang (e.g., the 2 in
+  2.0.1).</dd> 
+
+  <dt><code>__clang_minor__</code></dt>
+  <dd>Defined to the minor version number of Clang (e.g., the 0 in
+  2.0.1).</dd> 
+
+  <dt><code>__clang_patchlevel__</code></dt>
+  <dd>Defined to the patch level of Clang (e.g., the 1 in 2.0.1).</dd>
+
+  <dt><code>__clang_version__</code></dt>
+  <dd>Defined to a string that captures the Clang version, including
+  the Subversion tag or revision number, e.g., "1.5 (trunk
+  102332)".</dd> 
+</dl>
 
 <!-- ======================================================================= -->
 <h2 id="vectors">Vectors and Extended Vectors</h2>
diff --git a/docs/Makefile b/docs/Makefile
index e9bbb28..053b263 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -7,7 +7,7 @@
 # 
 ##===----------------------------------------------------------------------===##
 
-LEVEL      := ../../..
+CLANG_LEVEL := ..
 DIRS       := tools
 
 ifdef BUILD_FOR_WEBSITE
@@ -22,7 +22,7 @@
 	  -e 's/@abs_top_builddir@/../g' > $@
 endif
 
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
 
 HTML       := $(wildcard $(PROJ_SRC_DIR)/*.html) \
               $(wildcard $(PROJ_SRC_DIR)/*.css)
diff --git a/docs/PCHInternals.html b/docs/PCHInternals.html
index e21ec5e..109d5ed 100644
--- a/docs/PCHInternals.html
+++ b/docs/PCHInternals.html
@@ -144,6 +144,15 @@
 useful to determine whether the precompiled header implementation can
 be improved by making more of the implementation lazy.</p>
 
+<p>Precompiled headers can be chained. When you create a PCH while
+including an existing PCH, Clang can create the new PCH by referencing
+the original file and only writing the new data to the new file. For
+example, you could create a PCH out of all the headers that are very
+commonly used throughout your project, and then create a PCH for every
+single source file in the project that includes the code that is
+specific to that file, so that recompiling the file itself is very fast,
+without duplicating the data from the common headers for every file.</p>
+
 <h2 id="contents">Precompiled Header Contents</h2>
 
 <img src="PCHLayout.png" align="right" alt="Precompiled header layout">
@@ -209,6 +218,27 @@
 
 </dl>
 
+<p>A chained PCH file (that is, one that references another PCH) has
+a slightly different metadata block, which contains the following
+information:</p>
+
+<dl>
+  <dt>Referenced file</dt>
+  <dd>The name of the referenced PCH file. It is looked up like a file
+specified using -include-pch.</dd>
+
+  <dt>PCH version</dt>
+  <dd>This is the same as in normal PCH files.</dd>
+
+  <dt>Original file name</dt>
+  <dd>The full path of the header that was used to generate this
+precompiled header.</dd>
+
+</dl>
+
+<p>The language options, target architecture and predefines buffer data
+is taken from the end of the chain, since they have to match anyway.</p>
+
 <h3 id="sourcemgr">Source Manager Block</h3>
 
 <p>The source manager block contains the serialized representation of
diff --git a/docs/UsersManual.html b/docs/UsersManual.html
index 7d7f263..7524161 100644
--- a/docs/UsersManual.html
+++ b/docs/UsersManual.html
@@ -36,8 +36,10 @@
    <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_categories">Diagnostic Categories</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>
+   <li><a href="#analyzer_diagnositics">Controlling Static Analyzer Diagnostics</a></li>
    </ul>
   <li><a href="#precompiledheaders">Precompiled Headers</a></li>
   <li><a href="#codegen">Controlling Code Generation</a></li>
@@ -52,16 +54,6 @@
   <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>
@@ -260,12 +252,29 @@
 <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]
+  <b><font color="black">test.c:28:8: <font color="magenta">warning</font>: extra tokens at end of #endif directive [-Wextra-tokens]</font></b>
+  #endif bad
+         <font color="green">^</font>
+         <font color="green">//</font>
 </pre>
 
 </dd>
 
 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_fcolor_diagnostics"><b>-f[no-]color-diagnostics</b>: </dt>
+<dd>This option, which defaults to on when a color-capable terminal is
+  detected, controls whether or not Clang prints diagnostics in color.
+  When this option is enabled, Clang will use colors to highlight
+  specific parts of the diagnostic, e.g.,
+ 
+<pre>
+<test.c:2:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
+#endif bad
+       ^
+       //
+</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,
@@ -286,6 +295,30 @@
 diagnostic, either from the command line or through <a 
 href="#pragma_GCC_diagnostic">#pragma GCC diagnostic</a>.</dd>
 
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_fdiagnostics-show-category"><b>-fdiagnostics-show-category=none/id/name</b>:
+Enable printing category information in diagnostic line.</dt>
+<dd>This option, which defaults to "none",
+controls whether or not Clang prints the category associated with a diagnostic
+when emitting it.  Each diagnostic may or many not have an associated category,
+if it has one, it is listed in the diagnostic categorization field of the
+diagnostic line (in the []'s).</p>
+
+<p>For example, a format string warning will produce these three renditions
+based on the setting of this option:</p>
+
+<pre>
+  t.c:3:11: warning: conversion specifies type 'char *' but the argument has type 'int' [-Wformat]
+  t.c:3:11: warning: conversion specifies type 'char *' but the argument has type 'int' [-Wformat<b>,1</b>]
+  t.c:3:11: warning: conversion specifies type 'char *' but the argument has type 'int' [-Wformat<b>,Format String</b>]
+</pre>
+
+<p>This category can be used by clients that want to group diagnostics by
+category, so it should be a high level category.  We want dozens of these, not
+hundreds or thousands of them.</p>
+</dd>
+
+
 
 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 <dt id="opt_fdiagnostics-fixit-info"><b>-f[no-]diagnostics-fixit-info</b>:
@@ -326,6 +359,18 @@
 <p>The {}'s are generated by -fdiagnostics-print-source-range-info.</p>
 </dd>
 
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_fdiagnostics-parseable-fixits">
+<b>-fdiagnostics-parseable-fixits</b>:
+Print Fix-Its in a machine parseable form.</dt>
+<dd><p>This option makes Clang print available Fix-Its in a machine parseable format at the end of diagnostics. The following example illustrates the format:</p>
+
+<pre>
+ fix-it:"t.cpp":{7:25-7:29}:"Gamma"
+</pre>
+
+<p>The range printed is a half-open range, so in this example the characters at column 25 up to but not including column 29 on line 7 in t.cpp should be replaced with the string "Gamma". Either the range or the replacement string may be empty (representing strict insertions and strict erasures, respectively). Both the file name and the insertion string escape backslash (as "\\"), tabs (as "\t"), newlines (as "\n"), double quotes(as "\"") and non-printable characters (as octal "\xxx").</p>
+</dd>
 
 </dl>
 
@@ -361,6 +406,66 @@
  and <a href="">-Wbaz</a>.</p>
 </dd>
 
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_Wambiguous-member-template"><b>-Wambiguous-member-template</b>:
+Warn about unqualified uses of a member template whose name resolves
+to another template at the location of the use.</dt>
+<dd>This option, which defaults to on, enables a warning in the
+following code:</p>
+
+<pre>
+template&lt;typename T> struct set{};
+template&lt;typename T> struct trait { typedef const T& type; };
+struct Value {
+  template&lt;typename T> void set(typename trait&lt;T>::type value) {}
+};
+void foo() {
+  Value v;
+  v.set&lt;double>(3.2);
+}
+</pre>
+
+<p>C++ [basic.lookup.classref] requires this to be an error, but,
+because it's hard to work around, Clang downgrades it to a warning as
+an extension.</p>
+</dd>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_Wbind-to-temporary-copy"><b>-Wbind-to-temporary-copy</b>: Warn about
+an unusable copy constructor when binding a reference to a temporary.</dt>
+<dd>This option, which defaults to on, enables warnings about binding a
+reference to a temporary when the temporary doesn't have a usable copy
+constructor.  For example:</p>
+
+<pre>
+  struct NonCopyable {
+    NonCopyable();
+  private:
+    NonCopyable(const NonCopyable&);
+  };
+  void foo(const NonCopyable&);
+  void bar() {
+    foo(NonCopyable());  // Disallowed in C++98; allowed in C++0x.
+  }
+</pre>
+<pre>
+  struct NonCopyable2 {
+    NonCopyable2();
+    NonCopyable2(NonCopyable2&);
+  };
+  void foo(const NonCopyable2&);
+  void bar() {
+    foo(NonCopyable2());  // Disallowed in C++98; allowed in C++0x.
+  }
+</pre>
+
+<p>Note that if <tt>NonCopyable2::NonCopyable2()</tt> has a default
+argument whose instantiation produces a compile error, that error will
+still be a hard error in C++98 mode even if this warning is turned
+off.</p>
+
+</dd>
+
 </dl>
 
 <!-- ======================================================================= -->
@@ -393,6 +498,10 @@
 <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>A <a href="#diagnostics_categories">high-level category</a> for the
+    diagnostic for clients that want to group diagnostics by class (for
+    diagnostics that support it) [<a 
+   href="#opt_fdiagnostics-show-category">-fdiagnostics-show-category</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>
@@ -407,6 +516,7 @@
 <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>
@@ -420,7 +530,23 @@
 <li>Fatal</li>
 </ul></p>
 
-<h4 id="diagnostics_commandline">Controlling Diagnostics via Command Line Flags</h4>
+<h4 id="diagnostics_categories">Diagnostic Categories</h4>
+
+<p>Though not shown by default, diagnostics may each be associated with a
+   high-level category.  This category is intended to make it possible to triage
+   builds that produce a large number of errors or warnings in a grouped way.
+</p>
+
+<p>Categories are not shown by default, but they can be turned on with the
+<a href="#opt_fdiagnostics-show-category">-fdiagnostics-show-category</a> option.
+When set to "<tt>name</tt>", the category is printed textually in the diagnostic
+output.  When it is set to "<tt>id</tt>", a category number is printed.  The
+mapping of category names to category id's can be obtained by running '<tt>clang
+  --print-diagnostic-categories</tt>'.
+</p>
+
+<h4 id="diagnostics_commandline">Controlling Diagnostics via Command Line
+ Flags</h4>
 
 <p>-W flags, -pedantic, etc</p>
 
@@ -466,6 +592,42 @@
 compatible #pragmas there is no guarantee that they will have identical behaviour
 on both compilers. </p>
 
+<h4 id="analyzer_diagnositics">Controlling Static Analyzer Diagnostics</h4>
+
+<p>While not strictly part of the compiler, the diagnostics from Clang's <a
+href="http://clang-analyzer.llvm.org">static analyzer</a> can also be influenced
+by the user via changes to the source code.  This can be done in two ways:
+
+<ul>
+
+<li id="analyzer_annotations"><b>Annotations</b>: The static analyzer recognizes various GCC-style
+attributes (e.g., <tt>__attribute__((nonnull)))</tt>) that can either suppress
+static analyzer warnings or teach the analyzer about code invariants which
+enable it to find more bugs. While many of these attributes are standard GCC
+attributes, additional ones have added to Clang to specifically support the
+static analyzer. Detailed information on these annotations can be found in the
+<a href="http://clang-analyzer.llvm.org/annotations.html">analyzer's
+documentation</a>.</li>
+
+<li><b><tt>__clang_analyzer__</tt></b>: When the static analyzer is using Clang
+to parse source files, it implicitly defines the preprocessor macro
+<tt>__clang_analyzer__</tt>. While discouraged, code can use this macro to
+selectively exclude code the analyzer examines.  Here is an example:
+
+<pre>
+#ifndef __clang_analyzer__
+// Code not to be analyzed
+#endif
+</pre>
+
+In general, this usage is discouraged. Instead, we prefer that users file bugs
+against the analyzer when it flags false positives. There is also active
+discussion of allowing users in the future to selectively silence specific
+analyzer warnings (some which can already be done using <a
+href="analyzer_annotations">annotations</a>).</li>
+
+</ul>
+
 <!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
 <h3 id="precompiledheaders">Precompiled Headers</h3>
 <!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
@@ -671,21 +833,11 @@
 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
@@ -779,45 +931,6 @@
 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>
 <!-- ======================================================================= -->
 
diff --git a/docs/tools/Makefile b/docs/tools/Makefile
index 91bc447..5521d6b 100644
--- a/docs/tools/Makefile
+++ b/docs/tools/Makefile
@@ -37,10 +37,11 @@
 else
 
 # Otherwise, if not in BUILD_FOR_WEBSITE mode, use the project info.
-LEVEL := ../../../..
-include $(LEVEL)/Makefile.common
+CLANG_LEVEL := ../..
+include $(CLANG_LEVEL)/Makefile
 
-CLANG_VERSION := $(shell cat $(PROJ_SRC_DIR)/../../VER)
+CLANG_VERSION := $(word 3,$(shell grep "CLANG_VERSION " \
+	$(PROJ_OBJ_DIR)/$(CLANG_LEVEL)/include/clang/Basic/Version.inc))
 
 SRC_DOC_DIR=$(PROJ_SRC_DIR)/
 DST_HTML_DIR=$(PROJ_OBJ_DIR)/
diff --git a/docs/tools/clang.pod b/docs/tools/clang.pod
index 42cf8fa..bcf84b7 100644
--- a/docs/tools/clang.pod
+++ b/docs/tools/clang.pod
@@ -50,10 +50,13 @@
 =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.
+IR") and ultimately to machine code.  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.
+
+Clang also supports the use of an integrated assembler, in which the code
+generator produces object files directly. This avoids the overhead of generating
+the ".s" file and of calling the target assembler.
 
 =item B<Assembler>
 
@@ -325,17 +328,21 @@
 
 =item B<-Xclang> I<arg>
 
-Pass I<arg> to the clang compiler.
+Pass I<arg> to the clang compiler frontend.
 
 =item B<-Xlinker> I<arg>
 
 Pass I<arg> to the linker.
 
+=item B<-mllvm> I<arg>
+
+Pass I<arg> to the LLVM backend.
+
 =item B<-Xpreprocessor> I<arg>
 
 Pass I<arg> to the preprocessor.
 
-=item B<-o> I<file>               
+=item B<-o> I<file>
 
 Write output to I<file>.
 
@@ -359,6 +366,12 @@
 
 Save intermediate compilation results.
 
+=item B<-integrated-as> B<-no-integrated-as>
+
+Used to enable and disable, respectively, the use of the integrated
+assembler. Whether the integrated assembler is on by default is target
+dependent.
+
 =item B<-time>
 
 Time individual commands.
@@ -382,6 +395,7 @@
 B<-fshow-source-location>
 B<-fcaret-diagnostics>
 B<-fdiagnostics-fixit-info>
+B<-fdiagnostics-parseable-fixits>
 B<-fdiagnostics-print-source-range-info>
 B<-fprint-source-range-info>
 B<-fdiagnostics-show-option>
@@ -502,7 +516,6 @@
 
 =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.
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index d2738c6..9a32ee4 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,4 +1,3 @@
 add_subdirectory(clang-interpreter)
 add_subdirectory(PrintFunctionNames)
-add_subdirectory(wpa)
 
diff --git a/examples/Makefile b/examples/Makefile
index 869197d..8cb431d 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -7,8 +7,8 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../..
+CLANG_LEVEL := ..
 
-PARALLEL_DIRS := clang-interpreter PrintFunctionNames wpa
+PARALLEL_DIRS := clang-interpreter PrintFunctionNames
 
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
diff --git a/examples/PrintFunctionNames/CMakeLists.txt b/examples/PrintFunctionNames/CMakeLists.txt
index 49dd22a..5ea75db 100644
--- a/examples/PrintFunctionNames/CMakeLists.txt
+++ b/examples/PrintFunctionNames/CMakeLists.txt
@@ -1,26 +1,10 @@
-set(SHARED_LIBRARY TRUE)
+set(MODULE 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)
+  LINKER_LANGUAGE CXX
+  PREFIX "")
diff --git a/examples/PrintFunctionNames/Makefile b/examples/PrintFunctionNames/Makefile
index 57d3ba9..125ac48 100644
--- a/examples/PrintFunctionNames/Makefile
+++ b/examples/PrintFunctionNames/Makefile
@@ -7,21 +7,18 @@
 # 
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
+CLANG_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
+# If we don't need RTTI or EH, there's no reason to export anything
+# from the plugin.
+ifneq ($(REQUIRES_RTTI), 1)
+ifneq ($(REQUIRES_EH), 1)
+EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/PrintFunctionNames.exports
+endif
+endif
 
 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
+include $(CLANG_LEVEL)/Makefile
diff --git a/examples/PrintFunctionNames/PrintFunctionNames.cpp b/examples/PrintFunctionNames/PrintFunctionNames.cpp
index 5b7b66a..cc138f5 100644
--- a/examples/PrintFunctionNames/PrintFunctionNames.cpp
+++ b/examples/PrintFunctionNames/PrintFunctionNames.cpp
@@ -15,6 +15,7 @@
 #include "clang/Frontend/FrontendPluginRegistry.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/AST.h"
+#include "clang/Frontend/CompilerInstance.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
 
@@ -29,16 +30,40 @@
         llvm::errs() << "top-level-decl: \"" << ND->getNameAsString() << "\"\n";
     }
   }
-}; 
+};
 
-class PrintFunctionNamesAction : public ASTFrontendAction {
+class PrintFunctionNamesAction : public PluginASTAction {
 protected:
   ASTConsumer *CreateASTConsumer(CompilerInstance &CI, llvm::StringRef) {
     return new PrintFunctionsConsumer();
   }
+
+  bool ParseArgs(const CompilerInstance &CI,
+                 const std::vector<std::string>& args) {
+    for (unsigned i = 0, e = args.size(); i != e; ++i) {
+      llvm::errs() << "PrintFunctionNames arg = " << args[i] << "\n";
+
+      // Example error handling.
+      if (args[i] == "-an-error") {
+        Diagnostic &D = CI.getDiagnostics();
+        unsigned DiagID = D.getCustomDiagID(
+          Diagnostic::Error, "invalid argument '" + args[i] + "'");
+        D.Report(DiagID);
+        return false;
+      }
+    }
+    if (args.size() && args[0] == "help")
+      PrintHelp(llvm::errs());
+
+    return true;
+  }
+  void PrintHelp(llvm::raw_ostream& ros) {
+    ros << "Help for PrintFunctionNames plugin goes here\n";
+  }
+
 };
 
 }
 
-FrontendPluginRegistry::Add<PrintFunctionNamesAction>
+static FrontendPluginRegistry::Add<PrintFunctionNamesAction>
 X("print-fns", "print function names");
diff --git a/examples/PrintFunctionNames/PrintFunctionNames.exports b/examples/PrintFunctionNames/PrintFunctionNames.exports
new file mode 100644
index 0000000..0ff590d
--- /dev/null
+++ b/examples/PrintFunctionNames/PrintFunctionNames.exports
@@ -0,0 +1 @@
+_ZN4llvm8Registry*
diff --git a/examples/clang-interpreter/CMakeLists.txt b/examples/clang-interpreter/CMakeLists.txt
index 0f63b5f..73f28bb 100644
--- a/examples/clang-interpreter/CMakeLists.txt
+++ b/examples/clang-interpreter/CMakeLists.txt
@@ -2,10 +2,12 @@
 
 set(LLVM_USED_LIBS
     clangFrontend
+    clangSerialization
     clangDriver
     clangCodeGen
     clangSema
     clangChecker
+    clangIndex
     clangAnalysis
     clangRewrite
     clangAST
@@ -18,8 +20,10 @@
     jit
     interpreter
     nativecodegen
+    asmparser
     bitreader
     bitwriter
+    codegen
     ipo
     selectiondag
   )
diff --git a/examples/clang-interpreter/Makefile b/examples/clang-interpreter/Makefile
index fecc3f5..2f5e017 100644
--- a/examples/clang-interpreter/Makefile
+++ b/examples/clang-interpreter/Makefile
@@ -7,24 +7,18 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
+CLANG_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
+	selectiondag asmparser
+USEDLIBS = clangFrontend.a clangSerialization.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
+include $(CLANG_LEVEL)/Makefile
diff --git a/examples/clang-interpreter/main.cpp b/examples/clang-interpreter/main.cpp
index 8623954..2ccba8b 100644
--- a/examples/clang-interpreter/main.cpp
+++ b/examples/clang-interpreter/main.cpp
@@ -7,10 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/CodeGen/CodeGenAction.h"
 #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"
@@ -66,11 +66,11 @@
 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());
+  TextDiagnosticPrinter *DiagClient =
+    new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions());
 
-  Diagnostic Diags(&DiagClient);
-  Driver TheDriver(Path.getBasename(), Path.getDirname(),
-                   llvm::sys::getHostTriple(),
+  Diagnostic Diags(DiagClient);
+  Driver TheDriver(Path.str(), llvm::sys::getHostTriple(),
                    "a.out", /*IsProduction=*/false, /*CXXIsProduction=*/false,
                    Diags);
   TheDriver.setTitle("clang interpreter");
diff --git a/examples/wpa/CMakeLists.txt b/examples/wpa/CMakeLists.txt
index 8d443d6..13e4298 100644
--- a/examples/wpa/CMakeLists.txt
+++ b/examples/wpa/CMakeLists.txt
@@ -6,6 +6,9 @@
   clangDriver
   clangSema
   clangAnalysis
+  clangSerialization
+  clangChecker
+  clangRewrite
   clangAST
   clangParse
   clangLex
diff --git a/examples/wpa/Makefile b/examples/wpa/Makefile
index 6b7f407..0a70ea6 100644
--- a/examples/wpa/Makefile
+++ b/examples/wpa/Makefile
@@ -7,22 +7,17 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
+CLANG_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 := asmparser bitreader mc core
+USEDLIBS = clangChecker.a clangIndex.a clangFrontend.a clangDriver.a \
+	   clangSema.a clangAnalysis.a clangSerialization.a \
+           clangAST.a clangParse.a clangLex.a clangBasic.a
 
-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
+include $(CLANG_LEVEL)/Makefile
diff --git a/examples/wpa/clang-wpa.cpp b/examples/wpa/clang-wpa.cpp
index b515e33..41dca0d 100644
--- a/examples/wpa/clang-wpa.cpp
+++ b/examples/wpa/clang-wpa.cpp
@@ -14,9 +14,18 @@
 
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/Checker/PathSensitive/AnalysisManager.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Checker/PathSensitive/GRTransferFuncs.h"
+#include "clang/Checker/Checkers/LocalCheckers.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Index/CallGraph.h"
+#include "clang/Index/Indexer.h"
+#include "clang/Index/TranslationUnit.h"
+#include "clang/Index/DeclReferenceMap.h"
+#include "clang/Index/SelectorMap.h"
+#include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/raw_ostream.h"
@@ -26,11 +35,54 @@
 static llvm::cl::list<std::string>
 InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input AST files>"));
 
+static llvm::cl::opt<bool> 
+ViewCallGraph("view-call-graph", llvm::cl::desc("Display the call graph."));
+
+static llvm::cl::opt<std::string>
+AnalyzeFunction("analyze-function", 
+                llvm::cl::desc("Specify the entry function."));
+
+namespace {
+// A thin wrapper over ASTUnit implementing the TranslationUnit interface.
+class ASTUnitTU : public TranslationUnit {
+  ASTUnit *AST;
+  DeclReferenceMap DeclRefMap;
+  SelectorMap SelMap;
+  
+public:
+  ASTUnitTU(ASTUnit *ast) 
+    : AST(ast), DeclRefMap(AST->getASTContext()), SelMap(AST->getASTContext()) {
+  }
+
+  virtual ASTContext &getASTContext() {
+    return AST->getASTContext();
+  }
+  
+  virtual Preprocessor &getPreprocessor() {
+    return AST->getPreprocessor();
+  }
+
+  virtual Diagnostic &getDiagnostic() {
+    return AST->getDiagnostics();
+  }
+
+  virtual DeclReferenceMap &getDeclReferenceMap() {
+    return DeclRefMap;
+  }
+
+  virtual SelectorMap &getSelectorMap() {
+    return SelMap;
+  }
+};
+}
+
 int main(int argc, char **argv) {
   llvm::cl::ParseCommandLineOptions(argc, argv, "clang-wpa");
-  FileManager FileMgr;
   std::vector<ASTUnit*> ASTUnits;
 
+  Program Prog;
+  Indexer Idxer(Prog);
+
   if (InputFilenames.empty())
     return 0;
 
@@ -39,18 +91,60 @@
     = 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));
+    llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromASTFile(InFile, Diags));
     if (!AST)
       return 1;
 
     ASTUnits.push_back(AST.take());
   }
 
-  llvm::OwningPtr<CallGraph> CG;
-  CG.reset(new CallGraph());
+  if (ViewCallGraph) {
+    llvm::OwningPtr<CallGraph> CG;
+    CG.reset(new CallGraph(Prog));
 
-  for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i)
-    CG->addTU(ASTUnits[i]->getASTContext());
+    for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i)
+      CG->addTU(ASTUnits[i]->getASTContext());
 
-  CG->ViewCallGraph();
+    CG->ViewCallGraph();
+    return 0;
+  }
+
+  if (AnalyzeFunction.empty())
+    return 0;
+
+  // Feed all ASTUnits to the Indexer.
+  for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i) {
+    ASTUnitTU *TU = new ASTUnitTU(ASTUnits[i]);
+    Idxer.IndexAST(TU);
+  }
+
+  Entity Ent = Entity::get(AnalyzeFunction, Prog);
+  FunctionDecl *FD;
+  TranslationUnit *TU;
+  llvm::tie(FD, TU) = Idxer.getDefinitionFor(Ent);
+
+  if (!FD)
+    return 0;
+
+  // Create an analysis engine.
+  Preprocessor &PP = TU->getPreprocessor();
+
+  // Hard code options for now.
+  AnalysisManager AMgr(TU->getASTContext(), PP.getDiagnostics(),
+                       PP.getLangOptions(), /* PathDiagnostic */ 0,
+                       CreateRegionStoreManager,
+                       CreateRangeConstraintManager, &Idxer,
+                       /* MaxNodes */ 300000, /* MaxLoop */ 3,
+                       /* VisualizeEG */ false, /* VisualizeEGUbi */ false,
+                       /* PurgeDead */ true, /* EagerlyAssume */ false,
+                       /* TrimGraph */ false, /* InlineCall */ true, 
+                       /* UseUnoptimizedCFG */ false);
+
+  GRTransferFuncs* TF = MakeCFRefCountTF(AMgr.getASTContext(), /*GC*/false,
+                                         AMgr.getLangOptions());
+  GRExprEngine Eng(AMgr, TF);
+
+  Eng.ExecuteWorkList(AMgr.getStackFrame(FD, TU), AMgr.getMaxNodes());
+  
+  return 0;
 }
diff --git a/include/Makefile b/include/Makefile
index 47daabc..79b9adf 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -1,4 +1,4 @@
-LEVEL = ../../..
-DIRS := clang
+CLANG_LEVEL := ..
+DIRS := clang clang-c
 
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 1bf5a46..3f0dabf 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -98,6 +98,27 @@
 };
 
 /**
+ * \brief Describes the availability of a particular entity, which indicates
+ * whether the use of this entity will result in a warning or error due to
+ * it being deprecated or unavailable.
+ */
+enum CXAvailabilityKind {
+  /**
+   * \brief The entity is available.
+   */
+  CXAvailability_Available,
+  /**
+   * \brief The entity is available, but has been deprecated (and its use is
+   * not recommended).
+   */
+  CXAvailability_Deprecated,
+  /**
+   * \brief The entity is not available; any use of it will be an error.
+   */
+  CXAvailability_NotAvailable
+};
+  
+/**
  * \defgroup CINDEX_STRING String manipulation routines
  *
  * @{
@@ -635,11 +656,261 @@
                                              const char *ast_filename);
 
 /**
+ * \brief Flags that control the creation of translation units.
+ *
+ * The enumerators in this enumeration type are meant to be bitwise
+ * ORed together to specify which options should be used when
+ * constructing the translation unit.
+ */
+enum CXTranslationUnit_Flags {
+  /**
+   * \brief Used to indicate that no special translation-unit options are
+   * needed.
+   */
+  CXTranslationUnit_None = 0x0,
+
+  /**
+   * \brief Used to indicate that the parser should construct a "detailed"
+   * preprocessing record, including all macro definitions and instantiations.
+   *
+   * Constructing a detailed preprocessing record requires more memory
+   * and time to parse, since the information contained in the record
+   * is usually not retained. However, it can be useful for
+   * applications that require more detailed information about the
+   * behavior of the preprocessor.
+   */
+  CXTranslationUnit_DetailedPreprocessingRecord = 0x01,
+
+  /**
+   * \brief Used to indicate that the translation unit is incomplete.
+   *
+   * When a translation unit is considered "incomplete", semantic
+   * analysis that is typically performed at the end of the
+   * translation unit will be suppressed. For example, this suppresses
+   * the completion of tentative declarations in C and of
+   * instantiation of implicitly-instantiation function templates in
+   * C++. This option is typically used when parsing a header with the
+   * intent of producing a precompiled header.
+   */
+  CXTranslationUnit_Incomplete = 0x02,
+  
+  /**
+   * \brief Used to indicate that the translation unit should be built with an 
+   * implicit precompiled header for the preamble.
+   *
+   * An implicit precompiled header is used as an optimization when a
+   * particular translation unit is likely to be reparsed many times
+   * when the sources aren't changing that often. In this case, an
+   * implicit precompiled header will be built containing all of the
+   * initial includes at the top of the main file (what we refer to as
+   * the "preamble" of the file). In subsequent parses, if the
+   * preamble or the files in it have not changed, \c
+   * clang_reparseTranslationUnit() will re-use the implicit
+   * precompiled header to improve parsing performance.
+   */
+  CXTranslationUnit_PrecompiledPreamble = 0x04,
+  
+  /**
+   * \brief Used to indicate that the translation unit should cache some
+   * code-completion results with each reparse of the source file.
+   *
+   * Caching of code-completion results is a performance optimization that
+   * introduces some overhead to reparsing but improves the performance of
+   * code-completion operations.
+   */
+  CXTranslationUnit_CacheCompletionResults = 0x08
+};
+
+/**
+ * \brief Returns the set of flags that is suitable for parsing a translation
+ * unit that is being edited.
+ *
+ * The set of flags returned provide options for \c clang_parseTranslationUnit()
+ * to indicate that the translation unit is likely to be reparsed many times,
+ * either explicitly (via \c clang_reparseTranslationUnit()) or implicitly
+ * (e.g., by code completion (\c clang_codeCompletionAt())). The returned flag
+ * set contains an unspecified set of optimizations (e.g., the precompiled 
+ * preamble) geared toward improving the performance of these routines. The
+ * set of optimizations enabled may change from one version to the next.
+ */
+CINDEX_LINKAGE unsigned clang_defaultEditingTranslationUnitOptions(void);
+  
+/**
+ * \brief Parse the given source file and the translation unit corresponding
+ * to that file.
+ *
+ * This routine is the main entry point for the Clang C API, providing the
+ * ability to parse a source file into a translation unit that can then be
+ * queried by other functions in the API. This routine accepts a set of
+ * command-line arguments so that the compilation can be configured in the same
+ * way that the compiler is configured on the command line.
+ *
+ * \param CIdx The index object with which the translation unit will be 
+ * associated.
+ *
+ * \param source_filename The name of the source file to load, or NULL if the
+ * source file is included in \p clang_command_line_args.
+ *
+ * \param command_line_args The command-line arguments that would be
+ * passed to the \c clang executable if it were being invoked out-of-process.
+ * These command-line options will be parsed and will affect how the translation
+ * unit is parsed. Note that the following options are ignored: '-c', 
+ * '-emit-ast', '-fsyntex-only' (which is the default), and '-o <output file>'.
+ *
+ * \param num_command_line_args The number of command-line arguments in
+ * \p command_line_args.
+ *
+ * \param unsaved_files the files that have not yet been saved to disk
+ * but may be required for parsing, 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 num_unsaved_files the number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param options A bitmask of options that affects how the translation unit
+ * is managed but not its compilation. This should be a bitwise OR of the
+ * CXTranslationUnit_XXX flags.
+ *
+ * \returns A new translation unit describing the parsed code and containing
+ * any diagnostics produced by the compiler. If there is a failure from which
+ * the compiler cannot recover, returns NULL.
+ */
+CINDEX_LINKAGE CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
+                                                    const char *source_filename,
+                                                 const char **command_line_args,
+                                                      int num_command_line_args,
+                                            struct CXUnsavedFile *unsaved_files,
+                                                     unsigned num_unsaved_files,
+                                                            unsigned options);
+  
+/**
+ * \brief Flags that control how translation units are saved.
+ *
+ * The enumerators in this enumeration type are meant to be bitwise
+ * ORed together to specify which options should be used when
+ * saving the translation unit.
+ */
+enum CXSaveTranslationUnit_Flags {
+  /**
+   * \brief Used to indicate that no special saving options are needed.
+   */
+  CXSaveTranslationUnit_None = 0x0
+};
+
+/**
+ * \brief Returns the set of flags that is suitable for saving a translation
+ * unit.
+ *
+ * The set of flags returned provide options for
+ * \c clang_saveTranslationUnit() by default. The returned flag
+ * set contains an unspecified set of options that save translation units with
+ * the most commonly-requested data.
+ */
+CINDEX_LINKAGE unsigned clang_defaultSaveOptions(CXTranslationUnit TU);
+
+/**
+ * \brief Saves a translation unit into a serialized representation of
+ * that translation unit on disk.
+ *
+ * Any translation unit that was parsed without error can be saved
+ * into a file. The translation unit can then be deserialized into a
+ * new \c CXTranslationUnit with \c clang_createTranslationUnit() or,
+ * if it is an incomplete translation unit that corresponds to a
+ * header, used as a precompiled header when parsing other translation
+ * units.
+ *
+ * \param TU The translation unit to save.
+ *
+ * \param FileName The file to which the translation unit will be saved.
+ *
+ * \param options A bitmask of options that affects how the translation unit
+ * is saved. This should be a bitwise OR of the
+ * CXSaveTranslationUnit_XXX flags.
+ *
+ * \returns Zero if the translation unit was saved successfully, a
+ * non-zero value otherwise.
+ */
+CINDEX_LINKAGE int clang_saveTranslationUnit(CXTranslationUnit TU,
+                                             const char *FileName,
+                                             unsigned options);
+
+/**
  * \brief Destroy the specified CXTranslationUnit object.
  */
 CINDEX_LINKAGE void clang_disposeTranslationUnit(CXTranslationUnit);
 
 /**
+ * \brief Flags that control the reparsing of translation units.
+ *
+ * The enumerators in this enumeration type are meant to be bitwise
+ * ORed together to specify which options should be used when
+ * reparsing the translation unit.
+ */
+enum CXReparse_Flags {
+  /**
+   * \brief Used to indicate that no special reparsing options are needed.
+   */
+  CXReparse_None = 0x0
+};
+ 
+/**
+ * \brief Returns the set of flags that is suitable for reparsing a translation
+ * unit.
+ *
+ * The set of flags returned provide options for
+ * \c clang_reparseTranslationUnit() by default. The returned flag
+ * set contains an unspecified set of optimizations geared toward common uses
+ * of reparsing. The set of optimizations enabled may change from one version 
+ * to the next.
+ */
+CINDEX_LINKAGE unsigned clang_defaultReparseOptions(CXTranslationUnit TU);
+
+/**
+ * \brief Reparse the source files that produced this translation unit.
+ *
+ * This routine can be used to re-parse the source files that originally
+ * created the given translation unit, for example because those source files
+ * have changed (either on disk or as passed via \p unsaved_files). The
+ * source code will be reparsed with the same command-line options as it
+ * was originally parsed. 
+ *
+ * Reparsing a translation unit invalidates all cursors and source locations
+ * that refer into that translation unit. This makes reparsing a translation
+ * unit semantically equivalent to destroying the translation unit and then
+ * creating a new translation unit with the same command-line arguments.
+ * However, it may be more efficient to reparse a translation 
+ * unit using this routine.
+ *
+ * \param TU The translation unit whose contents will be re-parsed. The
+ * translation unit must originally have been built with 
+ * \c clang_createTranslationUnitFromSourceFile().
+ *
+ * \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 parsing, 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 options A bitset of options composed of the flags in CXReparse_Flags.
+ * The function \c clang_defaultReparseOptions() produces a default set of
+ * options recommended for most uses, based on the translation unit.
+ *
+ * \returns 0 if the sources could be reparsed. A non-zero value will be
+ * returned if reparsing was impossible, such that the translation unit is
+ * invalid. In such cases, the only valid call for \p TU is 
+ * \c clang_disposeTranslationUnit(TU).
+ */
+CINDEX_LINKAGE int clang_reparseTranslationUnit(CXTranslationUnit TU,
+                                                unsigned num_unsaved_files,
+                                          struct CXUnsavedFile *unsaved_files,
+                                                unsigned options);
+  
+/**
  * @}
  */
 
@@ -648,7 +919,6 @@
  */
 enum CXCursorKind {
   /* Declarations */
-  CXCursor_FirstDecl                     = 1,
   /**
    * \brief A declaration whose specific kind is not exposed via this
    * interface.
@@ -700,11 +970,15 @@
   CXCursor_ObjCCategoryImplDecl          = 19,
   /** \brief A typedef */
   CXCursor_TypedefDecl                   = 20,
-
   /** \brief A C++ class method. */
   CXCursor_CXXMethod                     = 21,
+  /** \brief A C++ namespace. */
+  CXCursor_Namespace                     = 22,
+  /** \brief A linkage specification, e.g. 'extern "C"'. */
+  CXCursor_LinkageSpec                   = 23,
 
-  CXCursor_LastDecl                      = 21,
+  CXCursor_FirstDecl                     = CXCursor_UnexposedDecl,
+  CXCursor_LastDecl                      = CXCursor_LinkageSpec,
 
   /* References */
   CXCursor_FirstRef                      = 40, /* Decl references */
@@ -727,7 +1001,8 @@
    * referenced by the type of size is the typedef for size_type.
    */
   CXCursor_TypeRef                       = 43,
-  CXCursor_LastRef                       = 43,
+  CXCursor_CXXBaseSpecifier              = 44,
+  CXCursor_LastRef                       = CXCursor_CXXBaseSpecifier,
 
   /* Error conditions */
   CXCursor_FirstInvalid                  = 70,
@@ -807,7 +1082,8 @@
 
   CXCursor_IBActionAttr                  = 401,
   CXCursor_IBOutletAttr                  = 402,
-  CXCursor_LastAttr                      = CXCursor_IBOutletAttr,
+  CXCursor_IBOutletCollectionAttr        = 403,
+  CXCursor_LastAttr                      = CXCursor_IBOutletCollectionAttr,
      
   /* Preprocessing */
   CXCursor_PreprocessingDirective        = 500,
@@ -945,6 +1221,16 @@
 CINDEX_LINKAGE enum CXLinkageKind clang_getCursorLinkage(CXCursor cursor);
 
 /**
+ * \brief Determine the availability of the entity that this cursor refers to.
+ *
+ * \param cursor The cursor to query.
+ *
+ * \returns The availability of the cursor.
+ */
+CINDEX_LINKAGE enum CXAvailabilityKind 
+clang_getCursorAvailability(CXCursor cursor);
+
+/**
  * \brief Describe the "language" of the entity referred to by a cursor.
  */
 CINDEX_LINKAGE enum CXLanguageKind {
@@ -1019,6 +1305,184 @@
 /**
  * @}
  */
+    
+/**
+ * \defgroup CINDEX_TYPES Type information for CXCursors
+ *
+ * @{
+ */
+
+/**
+ * \brief Describes the kind of type
+ */
+enum CXTypeKind {
+  /**
+   * \brief Reprents an invalid type (e.g., where no type is available).
+   */
+  CXType_Invalid = 0,
+
+  /**
+   * \brief A type whose specific kind is not exposed via this
+   * interface.
+   */
+  CXType_Unexposed = 1,
+
+  /* Builtin types */
+  CXType_Void = 2,
+  CXType_Bool = 3,
+  CXType_Char_U = 4,
+  CXType_UChar = 5,
+  CXType_Char16 = 6,
+  CXType_Char32 = 7,
+  CXType_UShort = 8,
+  CXType_UInt = 9,
+  CXType_ULong = 10,
+  CXType_ULongLong = 11,
+  CXType_UInt128 = 12,
+  CXType_Char_S = 13,
+  CXType_SChar = 14,
+  CXType_WChar = 15,
+  CXType_Short = 16,
+  CXType_Int = 17,
+  CXType_Long = 18,
+  CXType_LongLong = 19,
+  CXType_Int128 = 20,
+  CXType_Float = 21,
+  CXType_Double = 22,
+  CXType_LongDouble = 23,
+  CXType_NullPtr = 24,
+  CXType_Overload = 25,
+  CXType_Dependent = 26,
+  CXType_ObjCId = 27,
+  CXType_ObjCClass = 28,
+  CXType_ObjCSel = 29,
+  CXType_FirstBuiltin = CXType_Void,
+  CXType_LastBuiltin  = CXType_ObjCSel,
+
+  CXType_Complex = 100,
+  CXType_Pointer = 101,
+  CXType_BlockPointer = 102,
+  CXType_LValueReference = 103,
+  CXType_RValueReference = 104,
+  CXType_Record = 105,
+  CXType_Enum = 106,
+  CXType_Typedef = 107,
+  CXType_ObjCInterface = 108,
+  CXType_ObjCObjectPointer = 109,
+  CXType_FunctionNoProto = 110,
+  CXType_FunctionProto = 111
+};
+
+/**
+ * \brief The type of an element in the abstract syntax tree.
+ *
+ */
+typedef struct {
+  enum CXTypeKind kind;
+  void *data[2];
+} CXType;
+
+/**
+ * \brief Retrieve the type of a CXCursor (if any).
+ */
+CINDEX_LINKAGE CXType clang_getCursorType(CXCursor C);
+
+/**
+ * \determine Determine whether two CXTypes represent the same type.
+ *
+ * \returns non-zero if the CXTypes represent the same type and 
+            zero otherwise.
+ */
+CINDEX_LINKAGE unsigned clang_equalTypes(CXType A, CXType B);
+
+/**
+ * \brief Return the canonical type for a CXType.
+ *
+ * Clang's type system explicitly models typedefs and all the ways
+ * a specific type can be represented.  The canonical type is the underlying
+ * type with all the "sugar" removed.  For example, if 'T' is a typedef
+ * for 'int', the canonical type for 'T' would be 'int'.
+ */
+CINDEX_LINKAGE CXType clang_getCanonicalType(CXType T);
+
+/**
+ * \brief For pointer types, returns the type of the pointee.
+ *
+ */
+CINDEX_LINKAGE CXType clang_getPointeeType(CXType T);
+
+/**
+ * \brief Return the cursor for the declaration of the given type.
+ */
+CINDEX_LINKAGE CXCursor clang_getTypeDeclaration(CXType T);
+
+
+/**
+ * \brief Retrieve the spelling of a given CXTypeKind.
+ */
+CINDEX_LINKAGE CXString clang_getTypeKindSpelling(enum CXTypeKind K);
+
+/**
+ * \brief Retrieve the result type associated with a function type.
+ */
+CINDEX_LINKAGE CXType clang_getResultType(CXType T);
+
+/**
+ * \brief Retrieve the result type associated with a given cursor.  This only
+ *  returns a valid type of the cursor refers to a function or method.
+ */
+CINDEX_LINKAGE CXType clang_getCursorResultType(CXCursor C);
+
+/**
+ * \brief Return 1 if the CXType is a POD (plain old data) type, and 0
+ *  otherwise.
+ */
+CINDEX_LINKAGE unsigned clang_isPODType(CXType T);
+
+/**
+ * \brief Returns 1 if the base class specified by the cursor with kind
+ *   CX_CXXBaseSpecifier is virtual.
+ */
+CINDEX_LINKAGE unsigned clang_isVirtualBase(CXCursor);
+    
+/**
+ * \brief Represents the C++ access control level to a base class for a
+ * cursor with kind CX_CXXBaseSpecifier.
+ */
+enum CX_CXXAccessSpecifier {
+  CX_CXXInvalidAccessSpecifier,
+  CX_CXXPublic,
+  CX_CXXProtected,
+  CX_CXXPrivate
+};
+
+/**
+ * \brief Returns the access control level for the C++ base specifier
+ *  represented by a cursor with kind CX_CXXBaseSpecifier.
+ */
+CINDEX_LINKAGE enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor);
+
+/**
+ * @}
+ */
+  
+/**
+ * \defgroup CINDEX_ATTRIBUTES Information for attributes
+ *
+ * @{
+ */
+
+
+/**
+ * \brief For cursors representing an iboutletcollection attribute,
+ *  this function returns the collection element type.
+ *
+ */
+CINDEX_LINKAGE CXType clang_getIBOutletCollectionType(CXCursor);
+
+/**
+ * @}
+ */
 
 /**
  * \defgroup CINDEX_CURSOR_TRAVERSAL Traversing the AST with cursors
@@ -1220,6 +1684,24 @@
  */
 
 /**
+ * \defgroup CINDEX_CPP C++ AST introspection
+ *
+ * The routines in this group provide access information in the ASTs specific
+ * to C++ language features.
+ *
+ * @{
+ */
+
+/**
+ * \brief Determine if a C++ member function is declared 'static'.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C);
+
+/**
+ * @}
+ */
+
+/**
  * \defgroup CINDEX_LEX Token extraction and manipulation
  *
  * The routines in this group provide access to the tokens within a
@@ -1649,6 +2131,32 @@
 clang_getNumCompletionChunks(CXCompletionString completion_string);
 
 /**
+ * \brief Determine the priority of this code completion.
+ *
+ * The priority of a code completion indicates how likely it is that this 
+ * particular completion is the completion that the user will select. The
+ * priority is selected by various internal heuristics.
+ *
+ * \param completion_string The completion string to query.
+ *
+ * \returns The priority of this completion string. Smaller values indicate
+ * higher-priority (more likely) completions.
+ */
+CINDEX_LINKAGE unsigned
+clang_getCompletionPriority(CXCompletionString completion_string);
+  
+/**
+ * \brief Determine the availability of the entity that this code-completion
+ * string refers to.
+ *
+ * \param completion_string The completion string to query.
+ *
+ * \returns The availability of the completion string.
+ */
+CINDEX_LINKAGE enum CXAvailabilityKind 
+clang_getCompletionAvailability(CXCompletionString completion_string);
+
+/**
  * \brief Contains the results of code-completion.
  *
  * This data structure contains the results of code completion, as
@@ -1762,11 +2270,126 @@
                                           unsigned complete_column);
 
 /**
+ * \brief Flags that can be passed to \c clang_codeCompleteAt() to
+ * modify its behavior.
+ *
+ * The enumerators in this enumeration can be bitwise-OR'd together to
+ * provide multiple options to \c clang_codeCompleteAt().
+ */
+enum CXCodeComplete_Flags {
+  /**
+   * \brief Whether to include macros within the set of code
+   * completions returned.
+   */
+  CXCodeComplete_IncludeMacros = 0x01,
+
+  /**
+   * \brief Whether to include code patterns for language constructs
+   * within the set of code completions, e.g., for loops.
+   */
+  CXCodeComplete_IncludeCodePatterns = 0x02
+};
+
+/**
+ * \brief Returns a default set of code-completion options that can be
+ * passed to\c clang_codeCompleteAt(). 
+ */
+CINDEX_LINKAGE unsigned clang_defaultCodeCompleteOptions(void);
+
+/**
+ * \brief Perform code completion at a given location in a translation unit.
+ *
+ * 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 TU The translation unit in which code-completion should
+ * occur. The source files for this translation unit need not be
+ * completely up-to-date (and the contents of those source files may
+ * be overridden via \p unsaved_files). Cursors referring into the
+ * translation unit may be invalidated by this invocation.
+ *
+ * \param complete_filename The name of the source file where code
+ * completion should be performed. This filename may be any file
+ * included in the translation unit.
+ *
+ * \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 unsaved_files the Tiles that have not yet been saved to disk
+ * but may be required for parsing or 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 num_unsaved_files The number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param options Extra options that control the behavior of code
+ * completion, expressed as a bitwise OR of the enumerators of the
+ * CXCodeComplete_Flags enumeration. The 
+ * \c clang_defaultCodeCompleteOptions() function returns a default set
+ * of code-completion options.
+ *
+ * \returns If successful, a new \c 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_codeCompleteAt(CXTranslationUnit TU,
+                                            const char *complete_filename,
+                                            unsigned complete_line,
+                                            unsigned complete_column,
+                                            struct CXUnsavedFile *unsaved_files,
+                                            unsigned num_unsaved_files,
+                                            unsigned options);
+
+/**
+ * \brief Sort the code-completion results in case-insensitive alphabetical 
+ * order.
+ *
+ * \param Results The set of results to sort.
+ * \param NumResults The number of results in \p Results.
+ */
+CINDEX_LINKAGE
+void clang_sortCodeCompletionResults(CXCompletionResult *Results,
+                                     unsigned NumResults);
+  
+/**
  * \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.
diff --git a/include/clang-c/Makefile b/include/clang-c/Makefile
new file mode 100644
index 0000000..98ea719
--- /dev/null
+++ b/include/clang-c/Makefile
@@ -0,0 +1,31 @@
+CLANG_LEVEL := ../..
+DIRS :=
+
+include $(CLANG_LEVEL)/Makefile
+
+install-local::
+	$(Echo) Installing Clang C API include files
+	$(Verb) $(MKDIR) $(DESTDIR)$(PROJ_includedir)
+	$(Verb) if test -d "$(PROJ_SRC_ROOT)/tools/clang/include/clang-c" ; then \
+	  cd $(PROJ_SRC_ROOT)/tools/clang/include && \
+	  for  hdr in `find clang-c -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/clang-c" ; then \
+	  cd $(PROJ_OBJ_ROOT)/tools/clang/include && \
+	  for hdr in `find clang-c -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/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 53bb785..84833c0 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -16,10 +16,12 @@
 
 namespace clang {
   class ASTContext;
+  class CXXRecordDecl;
   class DeclGroupRef;
-  class TagDecl;
   class HandleTagDeclDefinition;
+  class ASTDeserializationListener; // layering violation because void* is ugly
   class SemaConsumer; // layering violation required for safe SemaConsumer
+  class TagDecl;
   class VarDecl;
 
 /// ASTConsumer - This is an abstract interface that should be implemented by
@@ -47,6 +49,11 @@
   /// elements). Use Decl::getNextDeclarator() to walk the chain.
   virtual void HandleTopLevelDecl(DeclGroupRef D);
 
+  /// HandleInterestingDecl - Handle the specified interesting declaration. This
+  /// is called by the AST reader when deserializing things that might interest
+  /// the consumer. The default implementation forwards to HandleTopLevelDecl.
+  virtual void HandleInterestingDecl(DeclGroupRef D);
+
   /// HandleTranslationUnit - This method is called when the ASTs for entire
   /// translation unit have been parsed.
   virtual void HandleTranslationUnit(ASTContext &Ctx) {}
@@ -68,6 +75,23 @@
   /// modified by the introduction of an implicit zero initializer.
   virtual void CompleteTentativeDefinition(VarDecl *D) {}
 
+  /// \brief Callback involved at the end of a translation unit to
+  /// notify the consumer that a vtable for the given C++ class is
+  /// required.
+  ///
+  /// \param RD The class whose vtable was used.
+  ///
+  /// \param DefinitionRequired Whether a definition of this vtable is
+  /// required in this translation unit; otherwise, it is only needed if
+  /// it was actually used.
+  virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {}
+
+  /// \brief If the consumer is interested in entities being deserialized from
+  /// AST files, it should return a pointer to a ASTDeserializationListener here
+  ///
+  /// The return type is void* because ASTDS lives in Frontend.
+  virtual ASTDeserializationListener *GetASTDeserializationListener() { return 0; }
+
   /// PrintStats - If desired, print any statistics.
   virtual void PrintStats() {}
 
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index b4aa03d..20c8d1f 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -18,7 +18,6 @@
 #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"
@@ -50,6 +49,7 @@
   class SelectorTable;
   class SourceManager;
   class TargetInfo;
+  class CXXABI;
   // Decls
   class DeclContext;
   class CXXMethodDecl;
@@ -62,6 +62,7 @@
   class RecordDecl;
   class StoredDeclsMap;
   class TagDecl;
+  class TemplateTemplateParmDecl;
   class TemplateTypeParmDecl;
   class TranslationUnitDecl;
   class TypeDecl;
@@ -75,6 +76,8 @@
 /// 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 {
+  ASTContext &this_() { return *this; }
+
   std::vector<Type*> Types;
   llvm::FoldingSet<ExtQuals> ExtQualNodes;
   llvm::FoldingSet<ComplexType> ComplexTypes;
@@ -95,12 +98,14 @@
   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::ContextualFoldingSet<TemplateSpecializationType, ASTContext&>
+    TemplateSpecializationTypes;
   llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
+  llvm::FoldingSet<DependentNameType> DependentNameTypes;
+  llvm::ContextualFoldingSet<DependentTemplateSpecializationType, ASTContext&>
+    DependentTemplateSpecializationTypes;
+  llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
+  llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
 
   llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
   llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
@@ -123,6 +128,30 @@
   /// \brief Mapping from ObjCContainers to their ObjCImplementations.
   llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;
 
+  /// \brief Representation of a "canonical" template template parameter that
+  /// is used in canonical template names.
+  class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode {
+    TemplateTemplateParmDecl *Parm;
+    
+  public:
+    CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm) 
+      : Parm(Parm) { }
+    
+    TemplateTemplateParmDecl *getParam() const { return Parm; }
+    
+    void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Parm); }
+    
+    static void Profile(llvm::FoldingSetNodeID &ID, 
+                        TemplateTemplateParmDecl *Parm);
+  };
+  llvm::FoldingSet<CanonicalTemplateTemplateParm> CanonTemplateTemplateParms;
+  
+  TemplateTemplateParmDecl *getCanonicalTemplateTemplateParmDecl(
+                                               TemplateTemplateParmDecl *TTP);
+
+  /// \brief Whether __[u]int128_t identifier is installed.
+  bool IsInt128Installed;
+
   /// BuiltinVaListType - built-in va list type.
   /// This is initially null and set by Sema::LazilyCreateBuiltin when
   /// a builtin that takes a valist is encountered.
@@ -163,11 +192,13 @@
   /// \brief Type for the Block descriptor for Blocks CodeGen.
   RecordDecl *BlockDescriptorExtendedType;
 
+  TypeSourceInfo NullTypeSourceInfo;
+
   /// \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;
+  llvm::DenseMap<const Decl*, AttrVec> DeclAttrs;
 
   /// \brief Keeps track of the static data member templates from which
   /// static data members of class template specializations were instantiated.
@@ -244,13 +275,18 @@
   ///  this ASTContext object.
   LangOptions LangOpts;
 
-  /// MallocAlloc/BumpAlloc - The allocator objects used to create AST objects.
-  bool FreeMemory;
-  llvm::MallocAllocator MallocAlloc;
+  /// \brief The allocator used to create AST objects.
+  ///
+  /// AST objects are never destructed; rather, all memory associated with the
+  /// AST objects will be released when the ASTContext itself is destroyed.
   llvm::BumpPtrAllocator BumpAlloc;
 
   /// \brief Allocator for partial diagnostics.
   PartialDiagnostic::StorageAllocator DiagAllocator;
+
+  /// \brief The current C++ ABI.
+  llvm::OwningPtr<CXXABI> ABI;
+  CXXABI *createCXXABI(const TargetInfo &T);
   
 public:
   const TargetInfo &Target;
@@ -270,13 +306,9 @@
   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);
+    return BumpAlloc.Allocate(Size, Align);
   }
-  void Deallocate(void *Ptr) {
-    if (FreeMemory)
-      MallocAlloc.Deallocate(Ptr);
-  }
+  void Deallocate(void *Ptr) { }
   
   PartialDiagnostic::StorageAllocator &getDiagAllocator() {
     return DiagAllocator;
@@ -289,7 +321,7 @@
   }
 
   /// \brief Retrieve the attributes for the given declaration.
-  Attr*& getDeclAttrs(const Decl *D) { return DeclAttrs[D]; }
+  AttrVec& getDeclAttrs(const Decl *D) { return DeclAttrs[D]; }
 
   /// \brief Erase the attributes corresponding to the given declaration.
   void eraseDeclAttrs(const Decl *D) { DeclAttrs.erase(D); }
@@ -303,7 +335,8 @@
   /// \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);
+                                           TemplateSpecializationKind TSK,
+                        SourceLocation PointOfInstantiation = SourceLocation());
 
   /// \brief If the given using decl is an instantiation of a
   /// (possibly unresolved) using decl from a template instantiation,
@@ -330,6 +363,8 @@
   overridden_cxx_method_iterator
   overridden_methods_end(const CXXMethodDecl *Method) const;
 
+  unsigned overridden_methods_size(const CXXMethodDecl *Method) const;
+
   /// \brief Note that the given C++ \p Method overrides the given \p
   /// Overridden method.
   void addOverriddenMethod(const CXXMethodDecl *Method, 
@@ -359,7 +394,7 @@
   ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t,
              IdentifierTable &idents, SelectorTable &sels,
              Builtin::Context &builtins,
-             bool FreeMemory = true, unsigned size_reserve=0);
+             unsigned size_reserve);
 
   ~ASTContext();
 
@@ -483,10 +518,10 @@
   /// 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);
+                            llvm::SmallVectorImpl<const Expr *> &Layout);
 
   /// This builds the struct used for __block variables.
-  QualType BuildByRefType(const char *DeclName, QualType Ty);
+  QualType BuildByRefType(llvm::StringRef DeclName, QualType Ty);
 
   /// Returns true iff we need copy/dispose helpers for the given type.
   bool BlockRequiresCopying(QualType Ty);
@@ -535,7 +570,7 @@
   /// 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);
+                         VectorType::AltiVecSpecific AltiVecSpec);
 
   /// getExtVectorType - Return the unique reference to an extended vector type
   /// of the specified element type and size.  VectorType must be a built-in
@@ -586,7 +621,11 @@
 
   /// getTypedefType - Return the unique reference to the type for the
   /// specified typename decl.
-  QualType getTypedefType(const TypedefDecl *Decl);
+  QualType getTypedefType(const TypedefDecl *Decl, QualType Canon = QualType());
+
+  QualType getRecordType(const RecordDecl *Decl);
+
+  QualType getEnumType(const EnumDecl *Decl);
 
   QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST);
 
@@ -600,42 +639,48 @@
   QualType getTemplateSpecializationType(TemplateName T,
                                          const TemplateArgument *Args,
                                          unsigned NumArgs,
-                                         QualType Canon = QualType(),
-                                         bool IsCurrentInstantiation = false);
+                                         QualType Canon = QualType());
+
+  QualType getCanonicalTemplateSpecializationType(TemplateName T,
+                                                  const TemplateArgument *Args,
+                                                  unsigned NumArgs);
 
   QualType getTemplateSpecializationType(TemplateName T,
                                          const TemplateArgumentListInfo &Args,
-                                         QualType Canon = QualType(),
-                                         bool IsCurrentInstantiation = false);
+                                         QualType Canon = QualType());
 
   TypeSourceInfo *
   getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc,
                                     const TemplateArgumentListInfo &Args,
                                     QualType Canon = QualType());
 
-  QualType getQualifiedNameType(NestedNameSpecifier *NNS,
-                                QualType NamedType);
+  QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
+                             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);
+  QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+                                                  NestedNameSpecifier *NNS,
+                                                  const IdentifierInfo *Name,
+                                          const TemplateArgumentListInfo &Args);
+  QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+                                                  NestedNameSpecifier *NNS,
+                                                  const IdentifierInfo *Name,
+                                                  unsigned NumArgs,
+                                                  const TemplateArgument *Args);
 
-  /// 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);
+  QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl);
+
+  QualType getObjCObjectType(QualType Base,
+                             ObjCProtocolDecl * const *Protocols,
+                             unsigned NumProtocols);
+
+  /// getObjCObjectPointerType - Return a ObjCObjectPointerType type
+  /// for the given ObjCObjectType.
+  QualType getObjCObjectPointerType(QualType OIT);
 
   /// getTypeOfType - GCC extension.
   QualType getTypeOfExprType(Expr *e);
@@ -783,6 +828,10 @@
   /// purpose in characters.
   CharUnits getObjCEncodingTypeSize(QualType t);
 
+  /// \brief Whether __[u]int128_t identifier is installed.
+  bool isInt128Installed() const { return IsInt128Installed; }
+  void setInt128Installed() { IsInt128Installed = true; }
+
   /// 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; }
@@ -825,7 +874,8 @@
     return getExtQualType(T, Qs);
   }
 
-  DeclarationName getNameForTemplate(TemplateName Name);
+  DeclarationNameInfo getNameForTemplate(TemplateName Name,
+                                         SourceLocation NameLoc);
 
   TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin,
                                          UnresolvedSetIterator End);
@@ -861,6 +911,11 @@
   ///
   Qualifiers::GC getObjCGCAttrKind(const QualType &Ty) const;
 
+  /// areCompatibleVectorTypes - Return true if the given vector types either
+  /// are of the same unqualified type or if one is GCC and other - equivalent
+  /// AltiVec vector type.
+  bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec);
+
   /// isObjCNSObjectType - Return true if this is an NSObject object with
   /// its NSObject attribute set.
   bool isObjCNSObjectType(QualType Ty) const;
@@ -913,6 +968,9 @@
   CharUnits getTypeAlignInChars(QualType T);
   CharUnits getTypeAlignInChars(const Type *T);
 
+  std::pair<CharUnits, CharUnits> getTypeInfoInChars(const Type *T);
+  std::pair<CharUnits, CharUnits> getTypeInfoInChars(QualType 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
@@ -943,23 +1001,20 @@
   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:
+  /// getKeyFunction - Get the key function for the given record decl, or NULL
+  /// if there isn't one.  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);
+  
+  void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
+                            llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+  
   unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI);
   void CollectInheritedProtocols(const Decl *CDecl,
                           llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
@@ -1016,8 +1071,8 @@
     return UnqualT1 == UnqualT2;
   }
 
-  /// \brief Retrieves the "canonical" declaration of
-
+  bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2);
+  
   /// \brief Retrieves the "canonical" nested name specifier for a
   /// given nested name specifier.
   ///
@@ -1167,7 +1222,8 @@
   //===--------------------------------------------------------------------===//
 
   /// Compatibility predicates used to check assignment expressions.
-  bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1
+  bool typesAreCompatible(QualType T1, QualType T2, 
+                          bool CompareUnqualified = false); // C99 6.2.7p1
 
   bool typesAreBlockPointerCompatible(QualType, QualType); 
 
@@ -1184,26 +1240,37 @@
   bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
                                          bool ForCompare);
 
+  bool ObjCQualifiedClassTypesAreCompatible(QualType LHS, QualType RHS);
+  
   // 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 canAssignObjCInterfaces(const ObjCObjectType *LHS,
+                               const ObjCObjectType *RHS);
   bool canAssignObjCInterfacesInBlockPointer(
                                           const ObjCObjectPointerType *LHSOPT,
                                           const ObjCObjectPointerType *RHSOPT);
   bool areComparableObjCPointerTypes(QualType LHS, QualType RHS);
   QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT,
                                    const ObjCObjectPointerType *RHSOPT);
-  
+  bool canBindObjCObjectType(QualType To, QualType From);
+
   // Functions for calculating composite types
-  QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false);
-  QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false);
+  QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false,
+                      bool Unqualified = false);
+  QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
+                              bool Unqualified = false);
+  
+  QualType mergeObjCGCQualifiers(QualType, QualType);
 
   /// 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);
+  
+  void ResetObjCLayout(const ObjCContainerDecl *CD) {
+    ObjCLayouts[CD] = 0;
+  }
 
   //===--------------------------------------------------------------------===//
   //                    Integer Predicates
@@ -1273,6 +1340,60 @@
   TypeSourceInfo *
   getTrivialTypeSourceInfo(QualType T, SourceLocation Loc = SourceLocation());
 
+  TypeSourceInfo *getNullTypeSourceInfo() { return &NullTypeSourceInfo; }
+
+  /// \brief Add a deallocation callback that will be invoked when the 
+  /// ASTContext is destroyed.
+  ///
+  /// \brief Callback A callback function that will be invoked on destruction.
+  ///
+  /// \brief Data Pointer data that will be provided to the callback function
+  /// when it is called.
+  void AddDeallocation(void (*Callback)(void*), void *Data);
+
+  GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD);
+  GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
+
+  /// \brief Determines if the decl can be CodeGen'ed or deserialized from PCH
+  /// lazily, only when used; this is only relevant for function or file scoped
+  /// var definitions.
+  ///
+  /// \returns true if the function/var must be CodeGen'ed/deserialized even if
+  /// it is not used.
+  bool DeclMustBeEmitted(const Decl *D);
+
+  //===--------------------------------------------------------------------===//
+  //                    Statistics
+  //===--------------------------------------------------------------------===//
+
+  /// \brief The number of implicitly-declared default constructors.
+  static unsigned NumImplicitDefaultConstructors;
+  
+  /// \brief The number of implicitly-declared default constructors for 
+  /// which declarations were built.
+  static unsigned NumImplicitDefaultConstructorsDeclared;
+
+  /// \brief The number of implicitly-declared copy constructors.
+  static unsigned NumImplicitCopyConstructors;
+  
+  /// \brief The number of implicitly-declared copy constructors for 
+  /// which declarations were built.
+  static unsigned NumImplicitCopyConstructorsDeclared;
+
+  /// \brief The number of implicitly-declared copy assignment operators.
+  static unsigned NumImplicitCopyAssignmentOperators;
+  
+  /// \brief The number of implicitly-declared copy assignment operators for 
+  /// which declarations were built.
+  static unsigned NumImplicitCopyAssignmentOperatorsDeclared;
+
+  /// \brief The number of implicitly-declared destructors.
+  static unsigned NumImplicitDestructors;
+  
+  /// \brief The number of implicitly-declared destructors for which 
+  /// declarations were built.
+  static unsigned NumImplicitDestructorsDeclared;
+  
 private:
   ASTContext(const ASTContext&); // DO NOT IMPLEMENT
   void operator=(const ASTContext&); // DO NOT IMPLEMENT
@@ -1287,16 +1408,26 @@
                                   const FieldDecl *Field,
                                   bool OutermostType = false,
                                   bool EncodingProperty = false);
-
+ 
   const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D,
                                        const ObjCImplementationDecl *Impl);
-  
+
 private:
+  /// \brief A set of deallocations that should be performed when the 
+  /// ASTContext is destroyed.
+  llvm::SmallVector<std::pair<void (*)(void*), void *>, 16> Deallocations;
+                                       
   // 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;
+
+  /// \brief A counter used to uniquely identify "blocks".
+  unsigned int UniqueBlockByRefTypeID;
+  unsigned int UniqueBlockParmTypeID;
+  
   friend class DeclContext;
+  friend class DeclarationNameTable;
   void ReleaseDeclContextMaps();
 };
   
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
index 2d31491..7cbf3a5 100644
--- a/include/clang/AST/ASTDiagnostic.h
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -15,7 +15,7 @@
 namespace clang {
   namespace diag {
     enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
 #define ASTSTART
 #include "clang/Basic/DiagnosticASTKinds.inc"
 #undef DIAG
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index 7975c43..9380058 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -14,8 +14,8 @@
 #ifndef LLVM_CLANG_AST_ASTIMPORTER_H
 #define LLVM_CLANG_AST_ASTIMPORTER_H
 
-#include "clang/AST/Type.h"
 #include "clang/AST/DeclarationName.h"
+#include "clang/AST/Type.h"
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 1974493..62ca49f 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -15,7 +15,11 @@
 #define LLVM_CLANG_AST_ATTR_H
 
 #include "llvm/Support/Casting.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "clang/Basic/AttrKinds.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/SourceLocation.h"
 #include <cassert>
 #include <cstring>
 #include <algorithm>
@@ -23,92 +27,42 @@
 
 namespace clang {
   class ASTContext;
+  class IdentifierInfo;
+  class ObjCInterfaceDecl;
+  class Expr;
+  class QualType;
+  class FunctionDecl;
+  class TypeSourceInfo;
 }
 
-
 // Defined in ASTContext.h
 void *operator new(size_t Bytes, clang::ASTContext &C,
                    size_t Alignment = 16) throw ();
+// FIXME: Being forced to not have a default argument here due to redeclaration
+//        rules on default arguments sucks
+void *operator new[](size_t Bytes, clang::ASTContext &C,
+                     size_t Alignment) 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 ();
+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;
+  SourceLocation Loc;
+  unsigned AttrKind : 16;
   bool Inherited : 1;
 
 protected:
+  virtual ~Attr();
+  
   void* operator new(size_t bytes) throw() {
     assert(0 && "Attrs cannot be allocated with regular 'new'.");
     return 0;
@@ -117,41 +71,36 @@
     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);
+  // Forward so that the regular new and delete do not hide global ones.
+  void* operator new(size_t Bytes, ASTContext &C,
+                     size_t Alignment = 16) throw() {
+    return ::operator new(Bytes, C, Alignment);
+  }
+  void operator delete(void *Ptr, ASTContext &C,
+                       size_t Alignment) throw() {
+    return ::operator delete(Ptr, C, Alignment);
+  }
+
+protected:
+  Attr(attr::Kind AK, SourceLocation L)
+    : Loc(L), AttrKind(AK), Inherited(false) {}
+
+public:
 
   /// \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;
+  attr::Kind getKind() const {
+    return static_cast<attr::Kind>(AttrKind);
   }
 
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
   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;
-  }
+  void setInherited(bool I) { Inherited = I; }
 
   // Clone this attribute.
   virtual Attr* clone(ASTContext &C) const = 0;
@@ -159,428 +108,114 @@
   // 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; }             \
+#include "clang/AST/Attrs.inc"
+
+/// AttrVec - A vector of Attr, which is how they are stored on the AST.
+typedef llvm::SmallVector<Attr*, 2> AttrVec;
+typedef llvm::SmallVector<const Attr*, 2> ConstAttrVec;
+
+/// DestroyAttrs - Destroy the contents of an AttrVec.
+inline void DestroyAttrs (AttrVec& V, ASTContext &C) {
 }
 
-DEF_SIMPLE_ATTR(Packed);
+/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
+/// providing attributes that are of a specifc type.
+template <typename SpecificAttr>
+class specific_attr_iterator {
+  /// Current - The current, underlying iterator.
+  /// In order to ensure we don't dereference an invalid iterator unless
+  /// specifically requested, we don't necessarily advance this all the
+  /// way. Instead, we advance it when an operation is requested; if the
+  /// operation is acting on what should be a past-the-end iterator,
+  /// then we offer no guarantees, but this way we do not dererence a
+  /// past-the-end iterator when we move to a past-the-end position.
+  mutable AttrVec::const_iterator Current;
 
-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;
+  void AdvanceToNext() const {
+    while (!llvm::isa<SpecificAttr>(*Current))
+      ++Current;
   }
-  static bool classof(const PragmaPackAttr *A) { return true; }
-};
 
-class AlignedAttr : public Attr {
-  unsigned Alignment;
+  void AdvanceToNext(AttrVec::const_iterator I) const {
+    while (Current != I && !llvm::isa<SpecificAttr>(*Current))
+      ++Current;
+  }
+
 public:
-  AlignedAttr(unsigned alignment)
-    : Attr(Aligned), Alignment(alignment) {}
+  typedef SpecificAttr*             value_type;
+  typedef SpecificAttr*             reference;
+  typedef SpecificAttr*             pointer;
+  typedef std::forward_iterator_tag iterator_category;
+  typedef std::ptrdiff_t            difference_type;
 
-  /// 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);
+  specific_attr_iterator() : Current() { }
+  explicit specific_attr_iterator(AttrVec::const_iterator i) : Current(i) { }
+
+  reference operator*() const {
+    AdvanceToNext();
+    return llvm::cast<SpecificAttr>(*Current);
+  }
+  pointer operator->() const {
+    AdvanceToNext();
+    return llvm::cast<SpecificAttr>(*Current);
+  }
+
+  specific_attr_iterator& operator++() {
+    ++Current;
+    return *this;
+  }
+  specific_attr_iterator operator++(int) {
+    specific_attr_iterator Tmp(*this);
+    ++(*this);
+    return Tmp;
+  }
+
+  friend bool operator==(specific_attr_iterator Left,
+                         specific_attr_iterator Right) {
+    if (Left.Current < Right.Current)
+      Left.AdvanceToNext(Right.Current); 
     else
-      return Alignment;
+      Right.AdvanceToNext(Left.Current);
+    return Left.Current == Right.Current;
   }
-
-  virtual Attr* clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == Aligned;
+  friend bool operator!=(specific_attr_iterator Left,
+                         specific_attr_iterator Right) {
+    return !(Left == Right);
   }
-  static bool classof(const AlignedAttr *A) { return true; }
 };
 
-class AnnotateAttr : public AttrWithString {
-public:
-  AnnotateAttr(ASTContext &C, llvm::StringRef ann)
-    : AttrWithString(Annotate, C, ann) {}
+template <typename T>
+inline specific_attr_iterator<T> specific_attr_begin(const AttrVec& vec) {
+  return specific_attr_iterator<T>(vec.begin());
+}
+template <typename T>
+inline specific_attr_iterator<T> specific_attr_end(const AttrVec& vec) {
+  return specific_attr_iterator<T>(vec.end());
+}
 
-  llvm::StringRef getAnnotation() const { return getString(); }
+template <typename T>
+inline bool hasSpecificAttr(const AttrVec& vec) {
+  return specific_attr_begin<T>(vec) != specific_attr_end<T>(vec);
+}
+template <typename T>
+inline T *getSpecificAttr(const AttrVec& vec) {
+  specific_attr_iterator<T> i = specific_attr_begin<T>(vec);
+  if (i != specific_attr_end<T>(vec))
+    return *i;
+  else
+    return 0;
+}
 
-  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
+/// getMaxAlignment - Returns the highest alignment value found among
+/// AlignedAttrs in an AttrVec, or 0 if there are none.
+inline unsigned getMaxAttrAlignment(const AttrVec& V, ASTContext &Ctx) {
+  unsigned Align = 0;
+  specific_attr_iterator<AlignedAttr> i(V.begin()), e(V.end());
+  for(; i != e; ++i)
+    Align = std::max(Align, i->getAlignment(Ctx));
+  return Align;
+}
 
 }  // end namespace clang
 
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
new file mode 100644
index 0000000..800c583
--- /dev/null
+++ b/include/clang/AST/CMakeLists.txt
@@ -0,0 +1,24 @@
+set(LLVM_TARGET_DEFINITIONS ../Basic/Attr.td)
+tablegen(Attrs.inc
+         -gen-clang-attr-classes
+         -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrClasses
+  DEPENDS Attrs.inc)
+
+tablegen(AttrImpl.inc
+         -gen-clang-attr-impl
+         -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrImpl
+  DEPENDS AttrImpl.inc)
+
+set(LLVM_TARGET_DEFINITIONS ../Basic/StmtNodes.td)
+tablegen(StmtNodes.inc
+         -gen-clang-stmt-nodes)
+add_custom_target(ClangStmtNodes
+  DEPENDS StmtNodes.inc)
+
+set(LLVM_TARGET_DEFINITIONS ../Basic/DeclNodes.td)
+tablegen(DeclNodes.inc
+         -gen-clang-decl-nodes)
+add_custom_target(ClangDeclNodes
+  DEPENDS DeclNodes.inc)
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index edd633e..5a84e40 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -196,7 +196,7 @@
   /// \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);
+  bool isAmbiguous(CanQualType BaseType);
   
   /// \brief Whether we are finding multiple paths to detect ambiguities.
   bool isFindingAmbiguities() const { return FindAmbiguities; }
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 93dcad7..dad4dfc 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -247,6 +247,7 @@
   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, isIntegralOrEnumerationType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
@@ -269,8 +270,13 @@
   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, isArrayType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
@@ -643,6 +649,24 @@
 };
 
 template<>
+struct CanProxyAdaptor<ObjCObjectType>
+  : public CanProxyBase<ObjCObjectType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
+                                      getInterface)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
+
+  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)
+};
+
+template<>
 struct CanProxyAdaptor<ObjCObjectPointerType>
   : public CanProxyBase<ObjCObjectPointerType> {
   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
@@ -679,9 +703,9 @@
 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!");
+  Result.Stored = QualType::getFromOpaquePtr(Ptr);
+  assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
+          Result.Stored.isCanonical()) && "Type is not canonical!");
   return Result;
 }
 
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 626657d..407ee3d 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -28,6 +28,8 @@
 class Stmt;
 class CompoundStmt;
 class StringLiteral;
+class NestedNameSpecifier;
+class TemplateParameterList;
 class TemplateArgumentList;
 class MemberSpecializationInfo;
 class FunctionTemplateSpecializationInfo;
@@ -55,7 +57,7 @@
   QualType getType() const { return Ty; }
 
   /// \brief Return the TypeLoc wrapper for the type source info.
-  TypeLoc getTypeLoc() const;
+  TypeLoc getTypeLoc() const; // implemented in TypeLoc.h
 };
 
 /// TranslationUnitDecl - The top declaration context.
@@ -116,16 +118,6 @@
     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
@@ -138,6 +130,8 @@
   // FIXME: Deprecated, move clients to getName().
   std::string getNameAsString() const { return Name.getAsString(); }
 
+  void printName(llvm::raw_ostream &os) const { return Name.printName(os); }
+
   /// getDeclName - Get the actual, stored name of the declaration,
   /// which may be a special name.
   DeclarationName getDeclName() const { return Name; }
@@ -214,7 +208,7 @@
 
   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; }
+  static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; }
 };
 
 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
@@ -235,7 +229,7 @@
   // 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.
+  // OrigNamespace of the first namespace decl points to its anonymous namespace
   NamespaceDecl *NextNamespace;
 
   /// \brief A pointer to either the original namespace definition for
@@ -260,23 +254,28 @@
   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:
+  /// \code
   //   namespace {
   //     ...
   //   };
+  // \endcode
   // q.v. C++ [namespace.unnamed]
   bool isAnonymousNamespace() const {
     return !getIdentifier();
   }
 
+  /// \brief Return the next extended namespace declaration or null if there
+  /// is none.
   NamespaceDecl *getNextNamespace() { return NextNamespace; }
   const NamespaceDecl *getNextNamespace() const { return NextNamespace; }
+
+  /// \brief Set the next extended namespace declaration.
   void setNextNamespace(NamespaceDecl *ND) { NextNamespace = ND; }
 
+  /// \brief Get the original (first) namespace declaration.
   NamespaceDecl *getOriginalNamespace() const {
     if (OrigOrAnonNamespace.getInt())
       return const_cast<NamespaceDecl *>(this);
@@ -284,6 +283,14 @@
     return OrigOrAnonNamespace.getPointer();
   }
 
+  /// \brief Return true if this declaration is an original (first) declaration
+  /// of the namespace. This is false for non-original (subsequent) namespace
+  /// declarations and anonymous namespaces.
+  bool isOriginalNamespace() const {
+    return getOriginalNamespace() == this;
+  }
+
+  /// \brief Set the original (first) namespace declaration.
   void setOriginalNamespace(NamespaceDecl *ND) { 
     if (ND != this) {
       OrigOrAnonNamespace.setPointer(ND);
@@ -325,6 +332,9 @@
   static NamespaceDecl *castFromDeclContext(const DeclContext *DC) {
     return static_cast<NamespaceDecl *>(const_cast<DeclContext*>(DC));
   }
+  
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 /// ValueDecl - Represent the declaration of a variable (in which case it is
@@ -344,7 +354,36 @@
   // 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; }
+  static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; }
+};
+
+/// QualifierInfo - A struct with extended info about a syntactic
+/// name qualifier, to be used for the case of out-of-line declarations.
+struct QualifierInfo {
+  /// NNS - The syntactic name qualifier.
+  NestedNameSpecifier *NNS;
+  /// NNSRange - The source range for the qualifier.
+  SourceRange NNSRange;
+  /// NumTemplParamLists - The number of template parameter lists
+  /// that were matched against the template-ids occurring into the NNS.
+  unsigned NumTemplParamLists;
+  /// TemplParamLists - A new-allocated array of size NumTemplParamLists,
+  /// containing pointers to the matched template parameter lists.
+  TemplateParameterList** TemplParamLists;
+
+  /// Default constructor.
+  QualifierInfo()
+    : NNS(0), NNSRange(), NumTemplParamLists(0), TemplParamLists(0) {}
+  /// setTemplateParameterListsInfo - Sets info about matched template
+  /// parameter lists.
+  void setTemplateParameterListsInfo(ASTContext &Context,
+                                     unsigned NumTPLists,
+                                     TemplateParameterList **TPLists);
+  
+private:
+  // Copy constructor and copy assignment are disabled.
+  QualifierInfo(const QualifierInfo&);
+  QualifierInfo& operator=(const QualifierInfo&);
 };
 
 /// \brief Represents a ValueDecl that came out of a declarator.
@@ -352,10 +391,8 @@
 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 {
+  struct ExtInfo : public QualifierInfo {
     TypeSourceInfo *TInfo;
-    NestedNameSpecifier *NNS;
-    SourceRange NNSRange;
   };
 
   llvm::PointerUnion<TypeSourceInfo*, ExtInfo*> DeclInfo;
@@ -370,37 +407,57 @@
     : 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
+      ? getExtInfo()->TInfo
       : DeclInfo.get<TypeSourceInfo*>();
   }
   void setTypeSourceInfo(TypeSourceInfo *TI) {
     if (hasExtInfo())
-      DeclInfo.get<ExtInfo*>()->TInfo = TI;
+      getExtInfo()->TInfo = TI;
     else
       DeclInfo = TI;
   }
 
+  /// getInnerLocStart - Return SourceLocation representing start of source
+  /// range ignoring outer template declarations.
+  virtual SourceLocation getInnerLocStart() const { return getLocation(); }
+
+  /// getOuterLocStart - Return SourceLocation representing start of source
+  /// range taking into account any outer template declarations.
+  SourceLocation getOuterLocStart() const;
+  SourceRange getSourceRange() const {
+    return SourceRange(getOuterLocStart(), getLocation());
+  }
+
   NestedNameSpecifier *getQualifier() const {
-    return hasExtInfo() ? DeclInfo.get<ExtInfo*>()->NNS : 0;
+    return hasExtInfo() ? getExtInfo()->NNS : 0;
   }
   SourceRange getQualifierRange() const {
-    return hasExtInfo() ? DeclInfo.get<ExtInfo*>()->NNSRange : SourceRange();
+    return hasExtInfo() ? getExtInfo()->NNSRange : SourceRange();
   }
   void setQualifierInfo(NestedNameSpecifier *Qualifier,
                         SourceRange QualifierRange);
 
+  unsigned getNumTemplateParameterLists() const {
+    return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
+  }
+  TemplateParameterList *getTemplateParameterList(unsigned index) const {
+    assert(index < getNumTemplateParameterLists());
+    return getExtInfo()->TemplParamLists[index];
+  }
+  void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists,
+                                     TemplateParameterList **TPLists) {
+    getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
+  }
+
   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;
+    return K >= firstDeclarator && K <= lastDeclarator;
   }
 };
 
@@ -433,36 +490,11 @@
   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
-  };
+  typedef clang::StorageClass StorageClass;
 
   /// getStorageClassSpecifierString - Return the string used to
   /// specify the storage class \arg SC.
@@ -494,10 +526,14 @@
   bool ThreadSpecified : 1;
   bool HasCXXDirectInit : 1;
 
-  /// DeclaredInCondition - Whether this variable was declared in a
-  /// condition, e.g., if (int x = foo()) { ... }.
-  bool DeclaredInCondition : 1;
-
+  /// \brief Whether this variable is the exception variable in a C++ catch
+  /// or an Objective-C @catch statement.
+  bool ExceptionVar : 1;
+  
+  /// \brief Whether this local variable could be allocated in the return
+  /// slot of its function, enabling the named return value optimization (NRVO).
+  bool NRVOVariable : 1;
+  
   friend class StmtIteratorBase;
 protected:
   VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
@@ -505,7 +541,7 @@
           StorageClass SCAsWritten)
     : DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(),
       ThreadSpecified(false), HasCXXDirectInit(false),
-      DeclaredInCondition(false) {
+      ExceptionVar(false), NRVOVariable(false) {
     SClass = SC;
     SClassAsWritten = SCAsWritten;
   }
@@ -527,17 +563,21 @@
                          QualType T, TypeSourceInfo *TInfo, StorageClass S,
                          StorageClass SCAsWritten);
 
-  virtual void Destroy(ASTContext& C);
-  virtual ~VarDecl();
-
+  virtual SourceLocation getInnerLocStart() const;
   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 setStorageClass(StorageClass SC) {
+    assert(isLegalForVariable(SC));
+    SClass = SC;
+  }
+  void setStorageClassAsWritten(StorageClass SC) {
+    assert(isLegalForVariable(SC));
+    SClassAsWritten = SC;
+  }
 
   void setThreadSpecified(bool T) { ThreadSpecified = T; }
   bool isThreadSpecified() const {
@@ -547,25 +587,26 @@
   /// hasLocalStorage - Returns true if a variable with function scope
   ///  is a non-static local variable.
   bool hasLocalStorage() const {
-    if (getStorageClass() == None)
+    if (getStorageClass() == SC_None)
       return !isFileVarDecl();
 
     // Return true for:  Auto, Register.
     // Return false for: Extern, Static, PrivateExtern.
 
-    return getStorageClass() <= Register;
+    return getStorageClass() >= SC_Auto;
   }
 
   /// isStaticLocal - Returns true if a variable with function scope is a 
   /// static local variable.
   bool isStaticLocal() const {
-    return getStorageClass() == Static && !isFileVarDecl();
+    return getStorageClass() == SC_Static && !isFileVarDecl();
   }
   
   /// hasExternStorage - Returns true if a variable has extern or
   /// __private_extern__ storage.
   bool hasExternalStorage() const {
-    return getStorageClass() == Extern || getStorageClass() == PrivateExtern;
+    return getStorageClass() == SC_Extern ||
+           getStorageClass() == SC_PrivateExtern;
   }
 
   /// hasGlobalStorage - Returns true for all variables that do not
@@ -613,7 +654,7 @@
   /// \endcode
   bool isStaticDataMember() const {
     // If it wasn't static, it would be a FieldDecl.
-    return getDeclContext()->isRecord();
+    return getKind() != Decl::ParmVar && getDeclContext()->isRecord();
   }
 
   virtual VarDecl *getCanonicalDecl();
@@ -660,11 +701,10 @@
   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 (getDeclContext()->getLookupContext()->isFileContext())
+      return true;
+    
     if (isStaticDataMember())
       return true;
 
@@ -829,17 +869,25 @@
     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;
+  /// \brief Determine whether this variable is the exception variable in a
+  /// C++ catch statememt or an Objective-C @catch statement.
+  bool isExceptionVariable() const {
+    return ExceptionVar;
   }
-  void setDeclaredInCondition(bool InCondition) {
-    DeclaredInCondition = InCondition;
-  }
+  void setExceptionVariable(bool EV) { ExceptionVar = EV; }
+  
+  /// \brief Determine whether this local variable can be used with the named
+  /// return value optimization (NRVO).
+  ///
+  /// The named return value optimization (NRVO) works by marking certain
+  /// non-volatile local variables of class type as NRVO objects. These
+  /// locals can be allocated within the return slot of their containing
+  /// function, in which case there is no need to copy the object to the
+  /// return slot when returning from the function. Within the function body,
+  /// each return that returns the NRVO object will have this variable as its
+  /// NRVO candidate.
+  bool isNRVOVariable() const { return NRVOVariable; }
+  void setNRVOVariable(bool NRVO) { NRVOVariable = NRVO; }
   
   /// \brief If this variable is an instantiated static data member of a
   /// class template specialization, returns the templated static data member
@@ -863,14 +911,14 @@
   // 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; }
+  static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }
 };
 
 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) {}
+    : VarDecl(DK, DC, L, Id, Tw, /*TInfo=*/0, SC_None, SC_None) {}
 public:
   static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
                                    SourceLocation L, IdentifierInfo *Id,
@@ -1014,8 +1062,15 @@
 class FunctionDecl : public DeclaratorDecl, public DeclContext,
                      public Redeclarable<FunctionDecl> {
 public:
-  enum StorageClass {
-    None, Extern, Static, PrivateExtern
+  typedef clang::StorageClass StorageClass;
+
+  /// \brief The kind of templated function a FunctionDecl can be.
+  enum TemplatedKind {
+    TK_NonTemplate,
+    TK_FunctionTemplate,
+    TK_MemberSpecialization,
+    TK_FunctionTemplateSpecialization,
+    TK_DependentFunctionTemplateSpecialization
   };
 
 private:
@@ -1067,11 +1122,15 @@
                       DependentFunctionTemplateSpecializationInfo *>
     TemplateOrSpecialization;
 
+  /// DNLoc - Provides source/type location info for the
+  /// declaration name embedded in the DeclaratorDecl base class.
+  DeclarationNameLoc DNLoc;
+
 protected:
-  FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L,
-               DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+  FunctionDecl(Kind DK, DeclContext *DC, const DeclarationNameInfo &NameInfo,
+               QualType T, TypeSourceInfo *TInfo,
                StorageClass S, StorageClass SCAsWritten, bool isInline)
-    : DeclaratorDecl(DK, DC, L, N, T, TInfo),
+    : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo),
       DeclContext(DK),
       ParamInfo(0), Body(),
       SClass(S), SClassAsWritten(SCAsWritten), IsInline(isInline),
@@ -1079,10 +1138,9 @@
       HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
       IsCopyAssignment(false),
       HasImplicitReturnZero(false),
-      EndRangeLoc(L), TemplateOrSpecialization() {}
-
-  virtual ~FunctionDecl() {}
-  virtual void Destroy(ASTContext& C);
+      EndRangeLoc(NameInfo.getEndLoc()),
+      TemplateOrSpecialization(),
+      DNLoc(NameInfo.getInfo()) {}
 
   typedef Redeclarable<FunctionDecl> redeclarable_base;
   virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
@@ -1099,27 +1157,57 @@
   static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
                               DeclarationName N, QualType T,
                               TypeSourceInfo *TInfo,
-                              StorageClass S = None,
-                              StorageClass SCAsWritten = None,
+                              StorageClass S = SC_None,
+                              StorageClass SCAsWritten = SC_None,
+                              bool isInline = false,
+                              bool hasWrittenPrototype = true) {
+    DeclarationNameInfo NameInfo(N, L);
+    return FunctionDecl::Create(C, DC, NameInfo, T, TInfo, S, SCAsWritten,
+                                isInline, hasWrittenPrototype);
+  }
+
+  static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
+                              const DeclarationNameInfo &NameInfo,
+                              QualType T, TypeSourceInfo *TInfo,
+                              StorageClass S = SC_None,
+                              StorageClass SCAsWritten = SC_None,
                               bool isInline = false,
                               bool hasWrittenPrototype = true);
 
+  DeclarationNameInfo getNameInfo() const {
+    return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
+  }
+
   virtual void getNameForDiagnostic(std::string &S,
                                     const PrintingPolicy &Policy,
                                     bool Qualified) const;
 
   virtual SourceRange getSourceRange() const {
-    return SourceRange(getLocation(), EndRangeLoc);
+    return SourceRange(getOuterLocStart(), EndRangeLoc);
   }
   void setLocEnd(SourceLocation E) {
     EndRangeLoc = E;
   }
 
+  /// \brief Returns true if the function has a body (definition). 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).
+  bool hasBody(const FunctionDecl *&Definition) const;
+
+  virtual bool hasBody() const {
+    const FunctionDecl* Definition;
+    return hasBody(Definition);
+  }
+
   /// 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).
+  /// NOTE: For checking if there is a body, use hasBody() instead, to avoid
+  /// unnecessary AST de-serialization of the body.
   Stmt *getBody(const FunctionDecl *&Definition) const;
 
   virtual Stmt *getBody() const {
@@ -1138,6 +1226,9 @@
   void setBody(Stmt *B);
   void setLazyBody(uint64_t Offset) { Body = Offset; }
 
+  /// Whether this function is variadic.
+  bool isVariadic() const;
+
   /// Whether this function is marked as virtual explicitly.
   bool isVirtualAsWritten() const { return IsVirtualAsWritten; }
   void setVirtualAsWritten(bool V) { IsVirtualAsWritten = V; }
@@ -1253,13 +1344,25 @@
   QualType getResultType() const {
     return getType()->getAs<FunctionType>()->getResultType();
   }
+  
+  /// \brief Determine the type of an expression that calls this function.
+  QualType getCallResultType() const {
+    return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
+  }
+                       
   StorageClass getStorageClass() const { return StorageClass(SClass); }
-  void setStorageClass(StorageClass SC) { SClass = SC; }
+  void setStorageClass(StorageClass SC) {
+    assert(isLegalForFunction(SC));
+    SClass = SC;
+  }
 
   StorageClass getStorageClassAsWritten() const {
     return StorageClass(SClassAsWritten);
   }
-  void setStorageClassAsWritten(StorageClass SC) { SClassAsWritten = SC; }
+  void setStorageClassAsWritten(StorageClass SC) {
+    assert(isLegalForFunction(SC));
+    SClassAsWritten = SC;
+  }
 
   /// \brief Determine whether the "inline" keyword was specified for this
   /// function.
@@ -1307,6 +1410,9 @@
   /// X<int>::A is required, it will be instantiated from the
   /// declaration returned by getInstantiatedFromMemberFunction().
   FunctionDecl *getInstantiatedFromMemberFunction() const;
+  
+  /// \brief What kind of templated function this is.
+  TemplatedKind getTemplatedKind() const;
 
   /// \brief If this function is an instantiation of a member function of a
   /// class template specialization, retrieves the member specialization
@@ -1376,11 +1482,19 @@
   /// returns NULL.
   const TemplateArgumentList *getTemplateSpecializationArgs() const;
 
+  /// \brief Retrieve the template argument list as written in the sources,
+  /// if any.
+  ///
+  /// If this function declaration is not a function template specialization
+  /// or if it had no explicit template argument list, returns NULL.
+  /// Note that it an explicit template argument list may be written empty,
+  /// e.g., template<> void foo<>(char* s);
+  const TemplateArgumentListInfo*
+  getTemplateSpecializationArgsAsWritten() 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.
   ///
@@ -1392,10 +1506,53 @@
   /// be inserted.
   ///
   /// \param TSK the kind of template specialization this is.
+  ///
+  /// \param TemplateArgsAsWritten location info of template arguments.
+  ///
+  /// \param PointOfInstantiation point at which the function template
+  /// specialization was first instantiated. 
   void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
                                       const TemplateArgumentList *TemplateArgs,
                                          void *InsertPos,
-                    TemplateSpecializationKind TSK = TSK_ImplicitInstantiation);
+                    TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
+                    const TemplateArgumentListInfo *TemplateArgsAsWritten = 0,
+                    SourceLocation PointOfInstantiation = SourceLocation());
+
+  /// \brief Specify that this function declaration is actually a function
+  /// template specialization.
+  ///
+  /// \param Template the function template that this function template
+  /// specialization specializes.
+  ///
+  /// \param NumTemplateArgs number of template arguments that produced this
+  /// function template specialization from the template.
+  ///
+  /// \param TemplateArgs array of template arguments that produced this
+  /// function template specialization from the template.
+  ///
+  /// \param TSK the kind of template specialization this is.
+  ///
+  /// \param NumTemplateArgsAsWritten number of template arguments that produced
+  /// this function template specialization from the template.
+  ///
+  /// \param TemplateArgsAsWritten array of location info for the template
+  /// arguments.
+  ///
+  /// \param LAngleLoc location of left angle token.
+  ///
+  /// \param RAngleLoc location of right angle token.
+  ///
+  /// \param PointOfInstantiation point at which the function template
+  /// specialization was first instantiated. 
+  void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
+                                         unsigned NumTemplateArgs,
+                                         const TemplateArgument *TemplateArgs,
+                                         TemplateSpecializationKind TSK,
+                                         unsigned NumTemplateArgsAsWritten,
+                                     TemplateArgumentLoc *TemplateArgsAsWritten,
+                                          SourceLocation LAngleLoc,
+                                          SourceLocation RAngleLoc,
+                                          SourceLocation PointOfInstantiation);
 
   /// \brief Specifies that this function declaration is actually a
   /// dependent function template specialization.
@@ -1434,7 +1591,7 @@
   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;
+    return K >= firstFunction && K <= lastFunction;
   }
   static DeclContext *castToDeclContext(const FunctionDecl *D) {
     return static_cast<DeclContext *>(const_cast<FunctionDecl*>(D));
@@ -1442,6 +1599,9 @@
   static FunctionDecl *castFromDeclContext(const DeclContext *DC) {
     return static_cast<FunctionDecl *>(const_cast<DeclContext*>(DC));
   }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 
@@ -1497,7 +1657,7 @@
   // 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; }
+  static bool classofKind(Kind K) { return K >= firstField && K <= lastField; }
 };
 
 /// EnumConstantDecl - An instance of this object exists for each enum constant
@@ -1513,7 +1673,6 @@
                    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,
@@ -1521,8 +1680,6 @@
                                   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; }
@@ -1566,7 +1723,7 @@
   // 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; }
+  static bool classofKind(Kind K) { return K >= firstType && K <= lastType; }
 };
 
 
@@ -1578,8 +1735,18 @@
               IdentifierInfo *Id, TypeSourceInfo *TInfo)
     : TypeDecl(Typedef, DC, L, Id), TInfo(TInfo) {}
 
-  virtual ~TypedefDecl();
+protected:
+  typedef Redeclarable<TypedefDecl> redeclarable_base;
+  virtual TypedefDecl *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 TypedefDecl *Create(ASTContext &C, DeclContext *DC,
                              SourceLocation L, IdentifierInfo *Id,
@@ -1617,11 +1784,7 @@
   : 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;
+  typedef TagTypeKind TagKind;
 
 private:
   // FIXME: This can be packed into the bitfields in Decl.
@@ -1632,20 +1795,26 @@
   /// it is a declaration ("struct foo;").
   bool IsDefinition : 1;
 
+  /// IsBeingDefined - True if this is currently being defined.
+  bool IsBeingDefined : 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;
 
+protected:
+  // These are used by (and only defined for) EnumDecl.
+  unsigned NumPositiveBits : 8;
+  unsigned NumNegativeBits : 8;
+
+private:
   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;
-  };
+  typedef QualifierInfo ExtInfo;
 
   /// TypedefDeclOrQualifier - If the (out-of-line) tag declaration name
   /// is qualified, it points to the qualifier info (nns and range);
@@ -1666,9 +1835,11 @@
           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");
+    assert((DK != Enum || TK == TTK_Enum) &&
+           "EnumDecl not matched with TTK_Enum");
     TagDeclKind = TK;
     IsDefinition = false;
+    IsBeingDefined = false;
     IsEmbeddedInDeclarator = false;
     setPreviousDeclaration(PrevDecl);
   }
@@ -1677,8 +1848,6 @@
   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();
@@ -1693,6 +1862,13 @@
   SourceLocation getTagKeywordLoc() const { return TagKeywordLoc; }
   void setTagKeywordLoc(SourceLocation TKL) { TagKeywordLoc = TKL; }
 
+  /// getInnerLocStart - Return SourceLocation representing start of source
+  /// range ignoring outer template declarations.
+  virtual SourceLocation getInnerLocStart() const { return TagKeywordLoc; }
+
+  /// getOuterLocStart - Return SourceLocation representing start of source
+  /// range taking into account any outer template declarations.
+  SourceLocation getOuterLocStart() const;
   virtual SourceRange getSourceRange() const;
 
   virtual TagDecl* getCanonicalDecl();
@@ -1705,6 +1881,11 @@
     return IsDefinition;
   }
 
+  /// isBeingDefined - Return true if this decl is currently being defined.
+  bool isBeingDefined() const {
+    return IsBeingDefined;
+  }
+
   bool isEmbeddedInDeclarator() const {
     return IsEmbeddedInDeclarator;
   }
@@ -1739,45 +1920,51 @@
   void setDefinition(bool V) { IsDefinition = V; }
 
   const char *getKindName() const {
-    return ElaboratedType::getNameForTagKind(getTagKind());
+    return TypeWithKeyword::getTagTypeKindName(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; }
+  bool isStruct() const { return getTagKind() == TTK_Struct; }
+  bool isClass()  const { return getTagKind() == TTK_Class; }
+  bool isUnion()  const { return getTagKind() == TTK_Union; }
+  bool isEnum()   const { return getTagKind() == TTK_Enum; }
 
   TypedefDecl *getTypedefForAnonDecl() const {
     return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get<TypedefDecl*>();
   }
-  void setTypedefForAnonDecl(TypedefDecl *TDD) { TypedefDeclOrQualifier = TDD; }
+
+  void setTypedefForAnonDecl(TypedefDecl *TDD);
 
   NestedNameSpecifier *getQualifier() const {
-    return hasExtInfo() ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNS : 0;
+    return hasExtInfo() ? getExtInfo()->NNS : 0;
   }
   SourceRange getQualifierRange() const {
-    return hasExtInfo()
-      ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNSRange
-      : SourceRange();
+    return hasExtInfo() ? getExtInfo()->NNSRange : SourceRange();
   }
   void setQualifierInfo(NestedNameSpecifier *Qualifier,
                         SourceRange QualifierRange);
 
+  unsigned getNumTemplateParameterLists() const {
+    return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
+  }
+  TemplateParameterList *getTemplateParameterList(unsigned i) const {
+    assert(i < getNumTemplateParameterLists());
+    return getExtInfo()->TemplParamLists[i];
+  }
+  void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists,
+                                     TemplateParameterList **TPLists) {
+    getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
+  }
+
   // 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 bool classofKind(Kind K) { return K >= firstTag && K <= lastTag; }
 
   static DeclContext *castToDeclContext(const TagDecl *D) {
     return static_cast<DeclContext *>(const_cast<TagDecl*>(D));
@@ -1785,6 +1972,9 @@
   static TagDecl *castFromDeclContext(const DeclContext *DC) {
     return static_cast<TagDecl *>(const_cast<DeclContext*>(DC));
   }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 /// EnumDecl - Represents an enum.  As an extension, we allow forward-declared
@@ -1806,10 +1996,19 @@
   /// enumeration declared within the template.
   EnumDecl *InstantiatedFrom;
 
+  // The number of positive and negative bits required by the
+  // enumerators are stored in the SubclassBits field.
+  enum {
+    NumBitsWidth = 8,
+    NumBitsMask = (1 << NumBitsWidth) - 1
+  };
+
   EnumDecl(DeclContext *DC, SourceLocation L,
            IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL)
-    : TagDecl(Enum, TK_enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
+    : TagDecl(Enum, TTK_Enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
       IntegerType = QualType();
+      NumNegativeBits = 0;
+      NumPositiveBits = 0;
     }
 public:
   EnumDecl *getCanonicalDecl() {
@@ -1819,11 +2018,17 @@
     return cast<EnumDecl>(TagDecl::getCanonicalDecl());
   }
 
+  const EnumDecl *getPreviousDeclaration() const {
+    return cast_or_null<EnumDecl>(TagDecl::getPreviousDeclaration());
+  }
+  EnumDecl *getPreviousDeclaration() {
+    return cast_or_null<EnumDecl>(TagDecl::getPreviousDeclaration());
+  }
+
   static EnumDecl *Create(ASTContext &C, DeclContext *DC,
                           SourceLocation L, IdentifierInfo *Id,
                           SourceLocation TKL, EnumDecl *PrevDecl);
-
-  virtual void Destroy(ASTContext& C);
+  static EnumDecl *Create(ASTContext &C, EmptyShell Empty);
 
   /// completeDefinition - When created, the EnumDecl corresponds to a
   /// forward-declared enum. This method is used to mark the
@@ -1831,18 +2036,26 @@
   /// added (via DeclContext::addDecl). NewType is the new underlying
   /// type of the enumeration type.
   void completeDefinition(QualType NewType,
-                          QualType PromotionType);
+                          QualType PromotionType,
+                          unsigned NumPositiveBits,
+                          unsigned NumNegativeBits);
 
   // 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());
+    const EnumDecl *E = cast_or_null<EnumDecl>(getDefinition());
+    if (!E)
+      E = this;
+    return enumerator_iterator(E->decls_begin());
   }
 
   enumerator_iterator enumerator_end() const {
-    return enumerator_iterator(this->decls_end());
+    const EnumDecl *E = cast_or_null<EnumDecl>(getDefinition());
+    if (!E)
+      E = this;
+    return enumerator_iterator(E->decls_end());
   }
 
   /// getPromotionType - Return the integer type that enumerators
@@ -1859,6 +2072,32 @@
   /// \brief Set the underlying integer type.
   void setIntegerType(QualType T) { IntegerType = T; }
 
+  /// \brief Returns the width in bits requred to store all the
+  /// non-negative enumerators of this enum.
+  unsigned getNumPositiveBits() const {
+    return NumPositiveBits;
+  }
+  void setNumPositiveBits(unsigned Num) {
+    NumPositiveBits = Num;
+    assert(NumPositiveBits == Num && "can't store this bitcount");
+  }
+
+  /// \brief Returns the width in bits requred to store all the
+  /// negative enumerators of this enum.  These widths include
+  /// the rightmost leading 1;  that is:
+  /// 
+  /// MOST NEGATIVE ENUMERATOR     PATTERN     NUM NEGATIVE BITS
+  /// ------------------------     -------     -----------------
+  ///                       -1     1111111                     1
+  ///                      -10     1110110                     5
+  ///                     -101     1001011                     8
+  unsigned getNumNegativeBits() const {
+    return NumNegativeBits;
+  }
+  void setNumNegativeBits(unsigned Num) {
+    NumNegativeBits = Num;
+  }
+
   /// \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.
@@ -1898,15 +2137,20 @@
   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);
+  static RecordDecl *Create(ASTContext &C, EmptyShell Empty);
 
-  virtual void Destroy(ASTContext& C);
+  const RecordDecl *getPreviousDeclaration() const {
+    return cast_or_null<RecordDecl>(TagDecl::getPreviousDeclaration());
+  }
+  RecordDecl *getPreviousDeclaration() {
+    return cast_or_null<RecordDecl>(TagDecl::getPreviousDeclaration());
+  }
 
   bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
   void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
@@ -1928,6 +2172,11 @@
     AnonymousStructOrUnion = Anon;
   }
 
+  ValueDecl *getAnonymousStructOrUnionObject();
+  const ValueDecl *getAnonymousStructOrUnionObject() const {
+    return const_cast<RecordDecl*>(this)->getAnonymousStructOrUnionObject();
+  }
+
   bool hasObjectMember() const { return HasObjectMember; }
   void setHasObjectMember (bool val) { HasObjectMember = val; }
 
@@ -1982,7 +2231,7 @@
   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;
+    return K >= firstRecord && K <= lastRecord;
   }
 };
 
@@ -2009,7 +2258,7 @@
 ///
 class BlockDecl : public Decl, public DeclContext {
   // FIXME: This can be packed into the bitfields in Decl.
-  bool isVariadic : 1;
+  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.
@@ -2017,27 +2266,29 @@
   unsigned NumParams;
 
   Stmt *Body;
+  TypeSourceInfo *SignatureAsWritten;
 
 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);
+      IsVariadic(false), ParamInfo(0), NumParams(0), Body(0),
+      SignatureAsWritten(0) {}
 
 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; }
+  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; }
 
+  void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; }
+  TypeSourceInfo *getSignatureAsWritten() const { return SignatureAsWritten; }
+
   // Iterator access to formal parameters.
   unsigned param_size() const { return getNumParams(); }
   typedef ParmVarDecl **param_iterator;
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index a9b948e..d973a1d 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -68,14 +68,20 @@
 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"
+#define DECL(DERIVED, BASE) DERIVED,
+#define ABSTRACT_DECL(DECL)
+#define DECL_RANGE(BASE, START, END) \
+        first##BASE = START, last##BASE = END,
+#define LAST_DECL_RANGE(BASE, START, END) \
+        first##BASE = START, last##BASE = END
+#include "clang/AST/DeclNodes.inc"
   };
 
+  /// \brief A placeholder type used to construct an empty shell of a
+  /// decl-derived type that will be filled in later (e.g., by some
+  /// deserialization method).
+  struct EmptyShell { };
+
   /// IdentifierNamespace - The different namespaces in which
   /// declarations may appear.  According to C99 6.2.3, there are
   /// four namespaces, labels, tags, members and ordinary
@@ -86,7 +92,7 @@
   /// 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.
+  /// Decl currently provides 15 bits of IDNS bits.
   enum IdentifierNamespace {
     /// Labels, declared with 'x:' and referenced with 'goto x'.
     IDNS_Label               = 0x0001,
@@ -216,13 +222,15 @@
   // 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.
+
+  /// PCHLevel - the "level" of AST file from which this declaration was built.
   unsigned PCHLevel : 2;
-  
+
+  /// ChangedAfterLoad - if this declaration has changed since being loaded
+  bool ChangedAfterLoad : 1;
+
   /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
-  unsigned IdentifierNamespace : 16;
+  unsigned IdentifierNamespace : 15;
 
 private:
 #ifndef NDEBUG
@@ -237,9 +245,17 @@
     : NextDeclInContext(0), DeclCtx(DC),
       Loc(L), DeclKind(DK), InvalidDecl(0),
       HasAttrs(false), Implicit(false), Used(false),
-      Access(AS_none), PCHLevel(0),
+      Access(AS_none), PCHLevel(0), ChangedAfterLoad(false),
       IdentifierNamespace(getIdentifierNamespaceForKind(DK)) {
-    if (Decl::CollectingStats()) addDeclKind(DK);
+    if (Decl::CollectingStats()) add(DK);
+  }
+
+  Decl(Kind DK, EmptyShell Empty)
+    : NextDeclInContext(0), DeclKind(DK), InvalidDecl(0),
+      HasAttrs(false), Implicit(false), Used(false),
+      Access(AS_none), PCHLevel(0), ChangedAfterLoad(false),
+      IdentifierNamespace(getIdentifierNamespaceForKind(DK)) {
+    if (Decl::CollectingStats()) add(DK);
   }
 
   virtual ~Decl();
@@ -291,23 +307,52 @@
   }
 
   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 setAttrs(const AttrVec& Attrs);
+  AttrVec& getAttrs() {
+    return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
   }
+  const AttrVec &getAttrs() const;
   void swapAttrs(Decl *D);
-  void invalidateAttrs();
+  void dropAttrs();
 
-  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;
+  void addAttr(Attr *A) {
+    if (hasAttrs())
+      getAttrs().push_back(A);
+    else
+      setAttrs(AttrVec(1, A));
   }
 
+  typedef AttrVec::const_iterator attr_iterator;
+
+  // FIXME: Do not rely on iterators having comparable singular values.
+  //        Note that this should error out if they do not.
+  attr_iterator attr_begin() const {
+    return hasAttrs() ? getAttrs().begin() : 0;
+  }
+  attr_iterator attr_end() const {
+    return hasAttrs() ? getAttrs().end() : 0;
+  }
+
+  template <typename T>
+  specific_attr_iterator<T> specific_attr_begin() const {
+    return specific_attr_iterator<T>(attr_begin());
+  }
+  template <typename T>
+  specific_attr_iterator<T> specific_attr_end() const {
+    return specific_attr_iterator<T>(attr_end());
+  }
+
+  template<typename T> T *getAttr() const {
+    return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : 0;
+  }
   template<typename T> bool hasAttr() const {
-    return getAttr<T>() != 0;
+    return hasAttrs() && hasSpecificAttr<T>(getAttrs());
+  }
+
+  /// getMaxAlignment - return the maximum alignment specified by attributes
+  /// on this decl, 0 if there are none.
+  unsigned getMaxAlignment() const {
+    return hasAttrs() ? getMaxAttrAlignment(getAttrs(), getASTContext()) : 0;
   }
 
   /// setInvalidDecl - Indicates the Decl had a semantic error. This
@@ -323,30 +368,46 @@
 
   /// \brief Whether this declaration was used, meaning that a definition
   /// is required.
-  bool isUsed() const;
-  
+  ///
+  /// \param CheckUsedAttr When true, also consider the "used" attribute
+  /// (in addition to the "used" bit set by \c setUsed()) when determining
+  /// whether the function is used.
+  bool isUsed(bool CheckUsedAttr = true) 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. 
+  /// from. A PCH level of 0 indicates that the declaration was parsed from
+  /// source. A PCH level of 1 indicates that the declaration was loaded from
+  /// a top-level AST file. A PCH level 2 indicates that the declaration was
+  /// loaded from a PCH file the AST file depends on, 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");
+    assert(Level <= MaxPCHLevel && "PCH level exceeds the maximum");
     PCHLevel = Level;
   }
-  
+
+  /// \brief Query whether this declaration was changed in a significant way
+  /// since being loaded from an AST file.
+  ///
+  /// In an epic violation of layering, what is "significant" is entirely
+  /// up to the serialization system, but implemented in AST and Sema.
+  bool isChangedSinceDeserialization() const { return ChangedAfterLoad; }
+
+  /// \brief Mark this declaration as having changed since deserialization, or
+  /// reset the flag.
+  void setChangedSinceDeserialization(bool Changed) {
+    ChangedAfterLoad = Changed;
+  }
+
   unsigned getIdentifierNamespace() const {
     return IdentifierNamespace;
   }
@@ -469,15 +530,16 @@
   ///  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;
+  /// \brief Returns true if this Decl represents a declaration for a body of
+  /// code, such as a function or method definition.
+  virtual bool hasBody() const { return getBody() != 0; }
 
   /// 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 void add(Kind k);
   static bool CollectingStats(bool Enable = false);
   static void PrintStats();
 
@@ -552,9 +614,6 @@
   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;
@@ -583,6 +642,29 @@
   virtual void print(llvm::raw_ostream &OS) const;
 };
 
+class DeclContextLookupResult
+  : public std::pair<NamedDecl**,NamedDecl**> {
+public:
+  DeclContextLookupResult(NamedDecl **I, NamedDecl **E)
+    : std::pair<NamedDecl**,NamedDecl**>(I, E) {}
+  DeclContextLookupResult()
+    : std::pair<NamedDecl**,NamedDecl**>() {}
+
+  using std::pair<NamedDecl**,NamedDecl**>::operator=;
+};
+
+class DeclContextLookupConstResult
+  : public std::pair<NamedDecl*const*, NamedDecl*const*> {
+public:
+  DeclContextLookupConstResult(std::pair<NamedDecl**,NamedDecl**> R)
+    : std::pair<NamedDecl*const*, NamedDecl*const*>(R) {}
+  DeclContextLookupConstResult(NamedDecl * const *I, NamedDecl * const *E)
+    : std::pair<NamedDecl*const*, NamedDecl*const*>(I, E) {}
+  DeclContextLookupConstResult()
+    : std::pair<NamedDecl*const*, NamedDecl*const*>() {}
+
+  using std::pair<NamedDecl*const*,NamedDecl*const*>::operator=;
+};
 
 /// 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
@@ -626,14 +708,14 @@
   /// another pointer.
   mutable Decl *LastDecl;
 
+  friend class ExternalASTSource;
+
 protected:
    DeclContext(Decl::Kind K)
      : DeclKind(K), ExternalLexicalStorage(false),
        ExternalVisibleStorage(false), LookupPtr(0), FirstDecl(0),
        LastDecl(0) { }
 
-  void DestroyDecls(ASTContext &C);
-
 public:
   ~DeclContext();
 
@@ -682,7 +764,7 @@
     case Decl::ObjCMethod:
       return true;
     default:
-      return DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast;
+      return DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction;
     }
   }
 
@@ -695,7 +777,7 @@
   }
 
   bool isRecord() const {
-    return DeclKind >= Decl::RecordFirst && DeclKind <= Decl::RecordLast;
+    return DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord;
   }
 
   bool isNamespace() const {
@@ -823,6 +905,12 @@
   decl_iterator decls_end() const;
   bool decls_empty() const;
 
+  /// noload_decls_begin/end - Iterate over the declarations stored in this
+  /// context that are currently loaded; don't attempt to retrieve anything
+  /// from an external source.
+  decl_iterator noload_decls_begin() const;
+  decl_iterator noload_decls_end() 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
@@ -998,9 +1086,8 @@
   /// 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;
+  typedef DeclContextLookupResult lookup_result;
+  typedef DeclContextLookupConstResult 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
@@ -1030,6 +1117,14 @@
   /// the declaration chains.
   void makeDeclVisibleInContext(NamedDecl *D, bool Recoverable = true);
 
+  /// \brief Deserialize all the visible declarations from external storage.
+  ///
+  /// Name lookup deserializes visible declarations lazily, thus a DeclContext
+  /// may not have a complete name lookup table. This function deserializes
+  /// the rest of visible declarations from the external storage and completes
+  /// the name lookup table.
+  void MaterializeVisibleDeclsFromExternalStorage();
+
   /// udir_iterator - Iterates through the using-directives stored
   /// within this context.
   typedef UsingDirectiveDecl * const * udir_iterator;
@@ -1078,15 +1173,15 @@
 
   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"
+#define DECL(NAME, BASE)
+#define DECL_CONTEXT(NAME) \
+  static bool classof(const NAME##Decl *D) { return true; }
+#include "clang/AST/DeclNodes.inc"
 
   void dumpDeclContext() const;
 
 private:
   void LoadLexicalDeclsFromExternalStorage() const;
-  void LoadVisibleDeclsFromExternalStorage() const;
 
   friend class DependentDiagnostic;
   StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
@@ -1100,7 +1195,6 @@
          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>
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 5e791c3..b529cf0 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -17,6 +17,7 @@
 
 #include "clang/AST/Expr.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/AST/UnresolvedSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -92,6 +93,53 @@
 
 namespace clang {
 
+/// AccessSpecDecl - An access specifier followed by colon ':'.
+///
+/// An objects of this class represents sugar for the syntactic occurrence
+/// of an access specifier followed by a colon in the list of member
+/// specifiers of a C++ class definition.
+///
+/// Note that they do not represent other uses of access specifiers,
+/// such as those occurring in a list of base specifiers.
+/// Also note that this class has nothing to do with so-called
+/// "access declarations" (C++98 11.3 [class.access.dcl]).
+class AccessSpecDecl : public Decl {
+  /// ColonLoc - The location of the ':'.
+  SourceLocation ColonLoc;
+
+  AccessSpecDecl(AccessSpecifier AS, DeclContext *DC,
+                 SourceLocation ASLoc, SourceLocation ColonLoc)
+    : Decl(AccessSpec, DC, ASLoc), ColonLoc(ColonLoc) {
+    setAccess(AS);
+  }
+public:
+  /// getAccessSpecifierLoc - The location of the access specifier.
+  SourceLocation getAccessSpecifierLoc() const { return getLocation(); }
+  /// setAccessSpecifierLoc - Sets the location of the access specifier.
+  void setAccessSpecifierLoc(SourceLocation ASLoc) { setLocation(ASLoc); }
+
+  /// getColonLoc - The location of the colon following the access specifier.
+  SourceLocation getColonLoc() const { return ColonLoc; }
+  /// setColonLoc - Sets the location of the colon.
+  void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
+
+  SourceRange getSourceRange() const {
+    return SourceRange(getAccessSpecifierLoc(), getColonLoc());
+  }
+
+  static AccessSpecDecl *Create(ASTContext &C, AccessSpecifier AS,
+                                DeclContext *DC, SourceLocation ASLoc,
+                                SourceLocation ColonLoc) {
+    return new (C) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const AccessSpecDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == AccessSpec; }
+};
+
+
 /// CXXBaseSpecifier - A base class of a C++ class.
 ///
 /// Each CXXBaseSpecifier represents a single, direct base class (or
@@ -112,7 +160,6 @@
   /// 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.
@@ -130,15 +177,17 @@
   /// 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;
+  /// BaseTypeInfo - The type of the base class. This will be a class or struct
+  /// (or a typedef of such). The source code range does not include the
+  /// "virtual" or access specifier.
+  TypeSourceInfo *BaseTypeInfo;
 
 public:
   CXXBaseSpecifier() { }
 
-  CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A, QualType T)
-    : Range(R), Virtual(V), BaseOfClass(BC), Access(A), BaseType(T) { }
+  CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A,
+                   TypeSourceInfo *TInfo)
+    : Range(R), Virtual(V), BaseOfClass(BC), Access(A), BaseTypeInfo(TInfo) { }
 
   /// getSourceRange - Retrieves the source range that contains the
   /// entire base specifier.
@@ -148,7 +197,7 @@
   /// class (or not).
   bool isVirtual() const { return Virtual; }
 
-  /// \brief Determine whether this base class if a base of a class declared
+  /// \brief Determine whether this base class is a base of a class declared
   /// with the 'class' keyword (vs. one declared with the 'struct' keyword).
   bool isBaseOfClass() const { return BaseOfClass; }
   
@@ -174,7 +223,10 @@
 
   /// getType - Retrieves the type of the base class. This type will
   /// always be an unqualified class type.
-  QualType getType() const { return BaseType; }
+  QualType getType() const { return BaseTypeInfo->getType(); }
+
+  /// getTypeLoc - Retrieves the type and source location of the base class.
+  TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
 };
 
 /// CXXRecordDecl - Represents a C++ struct/union/class.
@@ -271,7 +323,20 @@
     /// ComputedVisibleConversions - True when visible conversion functions are
     /// already computed and are available.
     bool ComputedVisibleConversions : 1;
-  
+
+    /// \brief Whether we have already declared the default constructor or 
+    /// do not need to have one declared.
+    bool DeclaredDefaultConstructor : 1;
+
+    /// \brief Whether we have already declared the copy constructor.
+    bool DeclaredCopyConstructor : 1;
+    
+    /// \brief Whether we have already declared the copy-assignment operator.
+    bool DeclaredCopyAssignment : 1;
+    
+    /// \brief Whether we have already declared a destructor within the class.
+    bool DeclaredDestructor : 1;
+    
     /// Bases - Base classes of this class.
     /// FIXME: This is wasted space for a union.
     CXXBaseSpecifier *Bases;
@@ -340,8 +405,6 @@
                 CXXRecordDecl *PrevDecl,
                 SourceLocation TKL = SourceLocation());
 
-  ~CXXRecordDecl();
-
 public:
   /// base_class_iterator - Iterator that traverses the base classes
   /// of a class.
@@ -367,6 +430,13 @@
   virtual const CXXRecordDecl *getCanonicalDecl() const {
     return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
   }
+  
+  const CXXRecordDecl *getPreviousDeclaration() const {
+    return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDeclaration());
+  }
+  CXXRecordDecl *getPreviousDeclaration() {
+    return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDeclaration());
+  }
 
   CXXRecordDecl *getDefinition() const {
     if (!DefinitionData) return 0;
@@ -380,8 +450,7 @@
                                SourceLocation TKL = SourceLocation(),
                                CXXRecordDecl* PrevDecl=0,
                                bool DelayTypeCreation = false);
-
-  virtual void Destroy(ASTContext& C);
+  static CXXRecordDecl *Create(ASTContext &C, EmptyShell Empty);
 
   bool isDynamicClass() const {
     return data().Polymorphic || data().NumVBases != 0;
@@ -476,6 +545,20 @@
     return data().FirstFriend != 0;
   }
 
+  /// \brief Determine whether this class has had its default constructor 
+  /// declared implicitly or does not need one declared implicitly.
+  ///
+  /// This value is used for lazy creation of default constructors.
+  bool hasDeclaredDefaultConstructor() const {
+    return data().DeclaredDefaultConstructor;
+  }
+  
+  /// \brief Note whether this class has already had its default constructor 
+  /// implicitly declared or doesn't need one.
+  void setDeclaredDefaultConstructor(bool DDC) {
+    data().DeclaredDefaultConstructor = DDC;
+  }
+  
   /// hasConstCopyConstructor - Determines whether this class has a
   /// copy constructor that accepts a const-qualified argument.
   bool hasConstCopyConstructor(ASTContext &Context) const;
@@ -484,12 +567,18 @@
   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;
-
+  /// \brief Retrieve the copy-assignment operator for this class, if available.
+  ///
+  /// This routine attempts to find the copy-assignment operator for this 
+  /// class, using a simplistic form of overload resolution.
+  ///
+  /// \param ArgIsConst Whether the argument to the copy-assignment operator
+  /// is const-qualified.
+  ///
+  /// \returns The copy-assignment operator that can be invoked, or NULL if
+  /// a unique copy-assignment operator could not be found.
+  CXXMethodDecl *getCopyAssignmentOperator(bool ArgIsConst) 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.
@@ -509,9 +598,23 @@
     return data().UserDeclaredCopyConstructor;
   }
 
+  /// \brief Determine whether this class has had its copy constructor 
+  /// declared, either via the user or via an implicit declaration.
+  ///
+  /// This value is used for lazy creation of copy constructors.
+  bool hasDeclaredCopyConstructor() const {
+    return data().DeclaredCopyConstructor;
+  }
+  
+  /// \brief Note whether this class has already had its copy constructor 
+  /// declared.
+  void setDeclaredCopyConstructor(bool DCC) {
+    data().DeclaredCopyConstructor = DCC;
+  }
+  
   /// 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.
+  /// class based on which operators have been added.
   void addedAssignmentOperator(ASTContext &Context, CXXMethodDecl *OpDecl);
 
   /// hasUserDeclaredCopyAssignment - Whether this class has a
@@ -521,6 +624,20 @@
     return data().UserDeclaredCopyAssignment;
   }
 
+  /// \brief Determine whether this class has had its copy assignment operator 
+  /// declared, either via the user or via an implicit declaration.
+  ///
+  /// This value is used for lazy creation of copy assignment operators.
+  bool hasDeclaredCopyAssignment() const {
+    return data().DeclaredCopyAssignment;
+  }
+  
+  /// \brief Note whether this class has already had its copy assignment 
+  /// operator declared.
+  void setDeclaredCopyAssignment(bool DCA) {
+    data().DeclaredCopyAssignment = DCA;
+  }
+  
   /// hasUserDeclaredDestructor - Whether this class has a
   /// user-declared destructor. When false, a destructor will be
   /// implicitly declared.
@@ -533,8 +650,21 @@
   /// fully defined, a destructor will be implicitly declared.
   void setUserDeclaredDestructor(bool UCD) {
     data().UserDeclaredDestructor = UCD;
+    if (UCD)
+      data().DeclaredDestructor = true;
   }
 
+  /// \brief Determine whether this class has had its destructor declared,
+  /// either via the user or via an implicit declaration.
+  ///
+  /// This value is used for lazy creation of destructors.
+  bool hasDeclaredDestructor() const { return data().DeclaredDestructor; }
+  
+  /// \brief Note whether this class has already had its destructor declared.
+  void setDeclaredDestructor(bool DD) {
+    data().DeclaredDestructor = DD;
+  }
+  
   /// getConversions - Retrieve the overload set containing all of the
   /// conversion functions in this class.
   UnresolvedSetImpl *getConversionFunctions() {
@@ -726,10 +856,10 @@
   void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
   
   /// getDefaultConstructor - Returns the default constructor for this class
-  CXXConstructorDecl *getDefaultConstructor(ASTContext &Context);
+  CXXConstructorDecl *getDefaultConstructor();
 
   /// getDestructor - Returns the destructor decl for this class.
-  CXXDestructorDecl *getDestructor(ASTContext &Context) const;
+  CXXDestructorDecl *getDestructor() const;
 
   /// isLocalClass - If the class is a local class [class.local], returns
   /// the enclosing function declaration.
@@ -920,35 +1050,37 @@
 
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) {
-    return K == CXXRecord ||
-           K == ClassTemplateSpecialization ||
-           K == ClassTemplatePartialSpecialization;
+    return K >= firstCXXRecord && K <= lastCXXRecord;
   }
   static bool classof(const CXXRecordDecl *D) { return true; }
   static bool classof(const ClassTemplateSpecializationDecl *D) {
     return true;
   }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 /// 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,
+  CXXMethodDecl(Kind DK, CXXRecordDecl *RD,
+                const DeclarationNameInfo &NameInfo,
+                QualType T, TypeSourceInfo *TInfo,
                 bool isStatic, StorageClass SCAsWritten, bool isInline)
-    : FunctionDecl(DK, RD, L, N, T, TInfo, (isStatic ? Static : None),
+    : FunctionDecl(DK, RD, NameInfo, T, TInfo, (isStatic ? SC_Static : SC_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);
+                               const DeclarationNameInfo &NameInfo,
+                               QualType T, TypeSourceInfo *TInfo,
+                               bool isStatic = false,
+                               StorageClass SCAsWritten = SC_None,
+                               bool isInline = false);
 
-  bool isStatic() const { return getStorageClass() == Static; }
+  bool isStatic() const { return getStorageClass() == SC_Static; }
   bool isInstance() const { return !isStatic(); }
 
   bool isVirtual() const {
@@ -966,6 +1098,10 @@
   /// delete or delete[] operator with a particular signature.
   bool isUsualDeallocationFunction() const;
   
+  /// \brief Determine whether this is a copy-assignment operator, regardless
+  /// of whether it was declared implicitly or explicitly.
+  bool isCopyAssignmentOperator() const;
+  
   const CXXMethodDecl *getCanonicalDecl() const {
     return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
   }
@@ -980,6 +1116,7 @@
 
   method_iterator begin_overridden_methods() const;
   method_iterator end_overridden_methods() const;
+  unsigned size_overridden_methods() const;
 
   /// getParent - Returns the parent of this method declaration, which
   /// is the class in which this method is defined.
@@ -1008,7 +1145,7 @@
   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;
+    return K >= firstCXXMethod && K <= lastCXXMethod;
   }
 };
 
@@ -1057,10 +1194,6 @@
   /// 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;
@@ -1068,6 +1201,28 @@
   /// RParenLoc - Location of the right paren of the ctor-initializer.
   SourceLocation RParenLoc;
 
+  /// IsVirtual - If the initializer is a base initializer, this keeps track
+  /// of whether the base is virtual or not.
+  bool IsVirtual : 1;
+
+  /// IsWritten - Whether or not the initializer is explicitly written
+  /// in the sources.
+  bool IsWritten : 1;
+  /// SourceOrderOrNumArrayIndices - If IsWritten is true, then this
+  /// number keeps track of the textual order of this initializer in the
+  /// original sources, counting from 0; otherwise, if IsWritten is false,
+  /// it stores the number of array index variables stored after this
+  /// object in memory.
+  unsigned SourceOrderOrNumArrayIndices : 14;
+
+  CXXBaseOrMemberInitializer(ASTContext &Context,
+                             FieldDecl *Member, SourceLocation MemberLoc,
+                             SourceLocation L,
+                             Expr *Init,
+                             SourceLocation R,
+                             VarDecl **Indices,
+                             unsigned NumIndices);
+  
 public:
   /// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
   explicit
@@ -1085,9 +1240,17 @@
                              Expr *Init,
                              SourceLocation R);
 
-  /// \brief Destroy the base or member initializer.
-  void Destroy(ASTContext &Context);
-
+  /// \brief Creates a new member initializer that optionally contains 
+  /// array indices used to describe an elementwise initialization.
+  static CXXBaseOrMemberInitializer *Create(ASTContext &Context,
+                                            FieldDecl *Member, 
+                                            SourceLocation MemberLoc,
+                                            SourceLocation L,
+                                            Expr *Init,
+                                            SourceLocation R,
+                                            VarDecl **Indices,
+                                            unsigned NumIndices);
+  
   /// isBaseInitializer - Returns true when this initializer is
   /// initializing a base class.
   bool isBaseInitializer() const { return BaseOrMember.is<TypeSourceInfo*>(); }
@@ -1121,7 +1284,7 @@
   /// getMember - If this is a member initializer, returns the
   /// declaration of the non-static data member being
   /// initialized. Otherwise, returns NULL.
-  FieldDecl *getMember() {
+  FieldDecl *getMember() const {
     if (isMemberInitializer())
       return BaseOrMember.get<FieldDecl*>();
     else
@@ -1142,6 +1305,30 @@
   
   /// \brief Determine the source range covering the entire initializer.
   SourceRange getSourceRange() const;
+
+  /// isWritten - Returns true if this initializer is explicitly written
+  /// in the source code.
+  bool isWritten() const { return IsWritten; }
+
+  /// \brief Return the source position of the initializer, counting from 0.
+  /// If the initializer was implicit, -1 is returned.
+  int getSourceOrder() const {
+    return IsWritten ? static_cast<int>(SourceOrderOrNumArrayIndices) : -1;
+  }
+
+  /// \brief Set the source order of this initializer. This method can only
+  /// be called once for each initializer; it cannot be called on an
+  /// initializer having a positive number of (implicit) array indices.
+  void setSourceOrder(int pos) {
+    assert(!IsWritten &&
+           "calling twice setSourceOrder() on the same initializer");
+    assert(SourceOrderOrNumArrayIndices == 0 &&
+           "setSourceOrder() used when there are implicit array indices");
+    assert(pos >= 0 &&
+           "setSourceOrder() used to make an initializer implicit");
+    IsWritten = true;
+    SourceOrderOrNumArrayIndices = static_cast<unsigned>(pos);
+  }
   
   FieldDecl *getAnonUnionMember() const {
     return AnonUnionMember;
@@ -1150,10 +1337,32 @@
     AnonUnionMember = anonMember;
   }
 
+  
   SourceLocation getLParenLoc() const { return LParenLoc; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
 
-  Expr *getInit() { return static_cast<Expr *>(Init); }
+  /// \brief Determine the number of implicit array indices used while
+  /// described an array member initialization.
+  unsigned getNumArrayIndices() const {
+    return IsWritten ? 0 : SourceOrderOrNumArrayIndices;
+  }
+
+  /// \brief Retrieve a particular array index variable used to 
+  /// describe an array member initialization.
+  VarDecl *getArrayIndex(unsigned I) {
+    assert(I < getNumArrayIndices() && "Out of bounds member array index");
+    return reinterpret_cast<VarDecl **>(this + 1)[I];
+  }
+  const VarDecl *getArrayIndex(unsigned I) const {
+    assert(I < getNumArrayIndices() && "Out of bounds member array index");
+    return reinterpret_cast<const VarDecl * const *>(this + 1)[I];
+  }
+  void setArrayIndex(unsigned I, VarDecl *Index) {
+    assert(I < getNumArrayIndices() && "Out of bounds member array index");
+    reinterpret_cast<VarDecl **>(this + 1)[I] = Index;
+  }
+  
+  Expr *getInit() const { return static_cast<Expr *>(Init); }
 };
 
 /// CXXConstructorDecl - Represents a C++ constructor within a
@@ -1184,21 +1393,21 @@
   CXXBaseOrMemberInitializer **BaseOrMemberInitializers;
   unsigned NumBaseOrMemberInitializers;
 
-  CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L,
-                     DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+  CXXConstructorDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo,
+                     QualType T, TypeSourceInfo *TInfo,
                      bool isExplicitSpecified, bool isInline, 
                      bool isImplicitlyDeclared)
-    : CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false,
-                    FunctionDecl::None, isInline),
+    : CXXMethodDecl(CXXConstructor, RD, NameInfo, T, TInfo, false,
+                    SC_None, isInline),
       IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
       BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
     setImplicit(isImplicitlyDeclared);
   }
-  virtual void Destroy(ASTContext& C);
 
 public:
+  static CXXConstructorDecl *Create(ASTContext &C, EmptyShell Empty);
   static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
-                                    SourceLocation L, DeclarationName N,
+                                    const DeclarationNameInfo &NameInfo,
                                     QualType T, TypeSourceInfo *TInfo,
                                     bool isExplicit,
                                     bool isInline, bool isImplicitlyDeclared);
@@ -1307,6 +1516,9 @@
   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; }
+  
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 /// CXXDestructorDecl - Represents a C++ destructor within a
@@ -1329,18 +1541,18 @@
 
   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),
+  CXXDestructorDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo,
+                    QualType T, bool isInline, bool isImplicitlyDeclared)
+    : CXXMethodDecl(CXXDestructor, RD, NameInfo, T, /*TInfo=*/0, false,
+                    SC_None, isInline),
       ImplicitlyDefined(false), OperatorDelete(0) {
     setImplicit(isImplicitlyDeclared);
   }
 
 public:
+  static CXXDestructorDecl *Create(ASTContext& C, EmptyShell Empty);
   static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
-                                   SourceLocation L, DeclarationName N,
+                                   const DeclarationNameInfo &NameInfo,
                                    QualType T, bool isInline,
                                    bool isImplicitlyDeclared);
 
@@ -1369,6 +1581,9 @@
   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; }
+  
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 /// CXXConversionDecl - Represents a C++ conversion function within a
@@ -1386,16 +1601,17 @@
   /// explicitly wrote a cast. This is a C++0x feature.
   bool IsExplicitSpecified : 1;
 
-  CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L,
-                    DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+  CXXConversionDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo,
+                    QualType T, TypeSourceInfo *TInfo,
                     bool isInline, bool isExplicitSpecified)
-    : CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false,
-                    FunctionDecl::None, isInline),
+    : CXXMethodDecl(CXXConversion, RD, NameInfo, T, TInfo, false,
+                    SC_None, isInline),
       IsExplicitSpecified(isExplicitSpecified) { }
 
 public:
+  static CXXConversionDecl *Create(ASTContext &C, EmptyShell Empty);
   static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
-                                   SourceLocation L, DeclarationName N,
+                                   const DeclarationNameInfo &NameInfo,
                                    QualType T, TypeSourceInfo *TInfo,
                                    bool isInline, bool isExplicit);
 
@@ -1422,6 +1638,9 @@
   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; }
+  
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 /// LinkageSpecDecl - This represents a linkage specification.  For example:
@@ -1434,8 +1653,10 @@
   /// 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 };
+  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;
@@ -1453,12 +1674,20 @@
                                  SourceLocation L, LanguageIDs Lang,
                                  bool Braces);
 
+  /// \brief Return the language specified by this linkage specification.
   LanguageIDs getLanguage() const { return Language; }
 
-  /// hasBraces - Determines whether this linkage specification had
-  /// braces in its syntactic form.
+  /// \brief Set the language specified by this linkage specification.
+  void setLanguage(LanguageIDs L) { Language = L; }
+
+  /// \brief Determines whether this linkage specification had braces in
+  /// its syntactic form.
   bool hasBraces() const { return HadBraces; }
 
+  /// \brief Set whether this linkage specification has braces in its
+  /// syntactic form.
+  void setHasBraces(bool B) { HadBraces = B; }
+
   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; }
@@ -1515,7 +1744,7 @@
                      SourceLocation IdentLoc,
                      NamedDecl *Nominated,
                      DeclContext *CommonAncestor)
-    : NamedDecl(Decl::UsingDirective, DC, L, getName()),
+    : NamedDecl(UsingDirective, DC, L, getName()),
       NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange),
       Qualifier(Qualifier), IdentLoc(IdentLoc),
       NominatedNamespace(Nominated),
@@ -1524,13 +1753,21 @@
 
 public:
   /// \brief Retrieve the source range of the nested-name-specifier
-  /// that qualifiers the namespace name.
+  /// that qualifies the namespace name.
   SourceRange getQualifierRange() const { return QualifierRange; }
 
+  /// \brief Set the source range of the nested-name-specifier that
+  /// qualifies the namespace name.
+  void setQualifierRange(SourceRange R) { QualifierRange = R; }
+
   /// \brief Retrieve the nested-name-specifier that qualifies the
   /// name of the namespace.
   NestedNameSpecifier *getQualifier() const { return Qualifier; }
 
+  /// \brief Set the nested-name-specifier that qualifes the name of the
+  /// namespace.
+  void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
+
   NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
   const NamedDecl *getNominatedNamespaceAsWritten() const {
     return NominatedNamespace;
@@ -1543,17 +1780,32 @@
     return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
   }
 
-  /// getCommonAncestor - returns common ancestor context of using-directive,
-  /// and nominated by it namespace.
+  /// setNominatedNamespace - Set the namespace nominataed by the
+  /// using-directive.
+  void setNominatedNamespace(NamedDecl* NS);
+
+  /// \brief Returns the common ancestor context of this using-directive and
+  /// its nominated namespace.
   DeclContext *getCommonAncestor() { return CommonAncestor; }
   const DeclContext *getCommonAncestor() const { return CommonAncestor; }
 
+  /// \brief Set the common ancestor context of this using-directive and its
+  /// nominated namespace.
+  void setCommonAncestor(DeclContext* Cxt) { CommonAncestor = Cxt; }
+
+  // FIXME: Could omit 'Key' in name.
   /// getNamespaceKeyLocation - Returns location of namespace keyword.
   SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
 
+  /// setNamespaceKeyLocation - Set the the location of the namespacekeyword.
+  void setNamespaceKeyLocation(SourceLocation L) { NamespaceLoc = L; }
+
   /// getIdentLocation - Returns location of identifier.
   SourceLocation getIdentLocation() const { return IdentLoc; }
 
+  /// setIdentLocation - set the location of the identifier.
+  void setIdentLocation(SourceLocation L) { IdentLoc = L; }
+
   static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
                                     SourceLocation L,
                                     SourceLocation NamespaceLoc,
@@ -1565,7 +1817,7 @@
 
   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; }
+  static bool classofKind(Kind K) { return K == UsingDirective; }
 
   // Friend for getUsingDirectiveName.
   friend class DeclContext;
@@ -1587,7 +1839,7 @@
   /// name, if any.
   NestedNameSpecifier *Qualifier;
 
-  /// IdentLoc - Location of namespace identifier.
+  /// IdentLoc - Location of namespace identifier. Accessed by TargetNameLoc.
   SourceLocation IdentLoc;
 
   /// Namespace - The Decl that this alias points to. Can either be a
@@ -1599,7 +1851,7 @@
                      SourceRange QualifierRange,
                      NestedNameSpecifier *Qualifier,
                      SourceLocation IdentLoc, NamedDecl *Namespace)
-    : NamedDecl(Decl::NamespaceAlias, DC, L, Alias), AliasLoc(AliasLoc),
+    : NamedDecl(NamespaceAlias, DC, L, Alias), AliasLoc(AliasLoc),
       QualifierRange(QualifierRange), Qualifier(Qualifier),
       IdentLoc(IdentLoc), Namespace(Namespace) { }
 
@@ -1608,10 +1860,19 @@
   /// that qualifiers the namespace name.
   SourceRange getQualifierRange() const { return QualifierRange; }
 
+  /// \brief Set the source range of the nested-name-specifier that qualifies
+  /// the namespace name.
+  void setQualifierRange(SourceRange R) { QualifierRange = R; }
+
   /// \brief Retrieve the nested-name-specifier that qualifies the
   /// name of the namespace.
   NestedNameSpecifier *getQualifier() const { return Qualifier; }
 
+  /// \brief Set the nested-name-specifier that qualifies the name of the
+  /// namespace.
+  void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
+
+  /// \brief Retrieve the namespace declaration aliased by this directive.
   NamespaceDecl *getNamespace() {
     if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace))
       return AD->getNamespace();
@@ -1627,16 +1888,31 @@
   /// "namespace foo = ns::bar;".
   SourceLocation getAliasLoc() const { return AliasLoc; }
 
+  /// Set the location o;f the alias name, e.e., 'foo' in
+  /// "namespace foo = ns::bar;".
+  void setAliasLoc(SourceLocation L) { AliasLoc = L; }
+
   /// 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; }
 
+  /// Set the location of the identifier in the named namespace.
+  void setTargetNameLoc(SourceLocation L) { IdentLoc = L; }
+
   /// \brief Retrieve the namespace that this alias refers to, which
   /// may either be a NamespaceDecl or a NamespaceAliasDecl.
   NamedDecl *getAliasedNamespace() const { return Namespace; }
 
+  /// \brief Set the namespace or namespace alias pointed to by this
+  /// alias decl.
+  void setAliasedNamespace(NamedDecl *ND) {
+    assert((isa<NamespaceAliasDecl>(ND) || isa<NamespaceDecl>(ND)) &&
+      "expecting namespace or namespace alias decl");
+      Namespace = ND;
+  }
+
   static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
                                     SourceLocation L, SourceLocation AliasLoc,
                                     IdentifierInfo *Alias,
@@ -1647,7 +1923,7 @@
 
   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; }
+  static bool classofKind(Kind K) { return K == NamespaceAlias; }
 };
 
 /// UsingShadowDecl - Represents a shadow declaration introduced into
@@ -1670,9 +1946,12 @@
 
   UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
                   NamedDecl *Target)
-    : NamedDecl(UsingShadow, DC, Loc, Target->getDeclName()),
+    : NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
       Underlying(Target), Using(Using) {
-    IdentifierNamespace = Target->getIdentifierNamespace();
+    if (Target) {
+      setDeclName(Target->getDeclName());
+      IdentifierNamespace = Target->getIdentifierNamespace();
+    }
     setImplicit();
   }
 
@@ -1683,16 +1962,24 @@
     return new (C) UsingShadowDecl(DC, Loc, Using, Target);
   }
 
-  /// Gets the underlying declaration which has been brought into the
+  /// \brief Gets the underlying declaration which has been brought into the
   /// local scope.
-  NamedDecl *getTargetDecl() const {
-    return Underlying;
+  NamedDecl *getTargetDecl() const { return Underlying; }
+
+  /// \brief Sets the underlying declaration which has been brought into the
+  /// local scope.
+  void setTargetDecl(NamedDecl* ND) {
+    assert(ND && "Target decl is null!");
+    Underlying = ND;
+    IdentifierNamespace = ND->getIdentifierNamespace();
   }
 
-  /// Gets the using declaration to which this declaration is tied.
-  UsingDecl *getUsingDecl() const {
-    return Using;
-  }
+  /// \brief Gets the using declaration to which this declaration is tied.
+  UsingDecl *getUsingDecl() const { return Using; }
+
+  /// \brief Sets the using declaration that introduces this target
+  /// declaration.
+  void setUsingDecl(UsingDecl* UD) { Using = UD; }
 
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classof(const UsingShadowDecl *D) { return true; }
@@ -1712,6 +1999,10 @@
   /// \brief Target nested name specifier.
   NestedNameSpecifier* TargetNestedName;
 
+  /// DNLoc - Provides source/type location info for the
+  /// declaration name embedded in the ValueDecl base class.
+  DeclarationNameLoc DNLoc;
+
   /// \brief The collection of shadow declarations associated with
   /// this using declaration.  This set can change as a class is
   /// processed.
@@ -1720,30 +2011,49 @@
   // \brief Has 'typename' keyword.
   bool IsTypeName;
 
-  UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR,
+  UsingDecl(DeclContext *DC, SourceRange NNR,
             SourceLocation UL, NestedNameSpecifier* TargetNNS,
-            DeclarationName Name, bool IsTypeNameArg)
-    : NamedDecl(Decl::Using, DC, L, Name),
+            const DeclarationNameInfo &NameInfo, bool IsTypeNameArg)
+    : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
       NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS),
-      IsTypeName(IsTypeNameArg) {
+      DNLoc(NameInfo.getInfo()), IsTypeName(IsTypeNameArg) {
   }
 
 public:
   /// \brief Returns the source range that covers the nested-name-specifier
   /// preceding the namespace name.
-  SourceRange getNestedNameRange() { return NestedNameRange; }
+  SourceRange getNestedNameRange() const { return NestedNameRange; }
 
-  /// \brief Returns the source location of the "using" location itself.
-  SourceLocation getUsingLocation() { return UsingLocation; }
+  /// \brief Set the source range of the nested-name-specifier.
+  void setNestedNameRange(SourceRange R) { NestedNameRange = R; }
 
-  /// \brief Get target nested name declaration.
-  NestedNameSpecifier* getTargetNestedNameDecl() {
+  // FIXME: Naming is inconsistent with other get*Loc functions.
+  /// \brief Returns the source location of the "using" keyword.
+  SourceLocation getUsingLocation() const { return UsingLocation; }
+
+  /// \brief Set the source location of the 'using' keyword.
+  void setUsingLocation(SourceLocation L) { UsingLocation = L; }
+
+  /// \brief Get the target nested name declaration.
+  NestedNameSpecifier* getTargetNestedNameDecl() const {
     return TargetNestedName;
   }
 
-  /// isTypeName - Return true if using decl has 'typename'.
+  /// \brief Set the target nested name declaration.
+  void setTargetNestedNameDecl(NestedNameSpecifier *NNS) {
+    TargetNestedName = NNS;
+  }
+
+  DeclarationNameInfo getNameInfo() const {
+    return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
+  }
+
+  /// \brief Return true if the using declaration has 'typename'.
   bool isTypeName() const { return IsTypeName; }
 
+  /// \brief Sets whether the using declaration has 'typename'.
+  void setTypeName(bool TN) { IsTypeName = TN; }
+
   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(); }
@@ -1761,13 +2071,24 @@
     }
   }
 
+  /// \brief Return the number of shadowed declarations associated with this
+  /// using declaration.
+  unsigned getNumShadowDecls() const {
+    return Shadows.size();
+  }
+
   static UsingDecl *Create(ASTContext &C, DeclContext *DC,
-      SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
-      NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
+                           SourceRange NNR, SourceLocation UsingL,
+                           NestedNameSpecifier* TargetNNS,
+                           const DeclarationNameInfo &NameInfo,
+                           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; }
+  static bool classofKind(Kind K) { return K == Using; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 /// UnresolvedUsingValueDecl - Represents a dependent using
@@ -1788,14 +2109,18 @@
 
   NestedNameSpecifier *TargetNestedNameSpecifier;
 
+  /// DNLoc - Provides source/type location info for the
+  /// declaration name embedded in the ValueDecl base class.
+  DeclarationNameLoc DNLoc;
+
   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)
+                           const DeclarationNameInfo &NameInfo)
+    : ValueDecl(UnresolvedUsingValue, DC,
+                NameInfo.getLoc(), NameInfo.getName(), Ty),
+      TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
+      TargetNestedNameSpecifier(TargetNNS), DNLoc(NameInfo.getInfo())
   { }
 
 public:
@@ -1803,22 +2128,38 @@
   /// preceding the namespace name.
   SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
 
+  /// \brief Set the source range coverting the nested-name-specifier preceding
+  /// the namespace name.
+  void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
+
   /// \brief Get target nested name declaration.
-  NestedNameSpecifier* getTargetNestedNameSpecifier() {
+  NestedNameSpecifier* getTargetNestedNameSpecifier() const {
     return TargetNestedNameSpecifier;
   }
 
+  /// \brief Set the nested name declaration.
+  void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
+    TargetNestedNameSpecifier = NNS;
+  }
+
   /// \brief Returns the source location of the 'using' keyword.
   SourceLocation getUsingLoc() const { return UsingLocation; }
 
+  /// \brief Set the source location of the 'using' keyword.
+  void setUsingLoc(SourceLocation L) { UsingLocation = L; }
+
+  DeclarationNameInfo getNameInfo() const {
+    return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
+  }
+
   static UnresolvedUsingValueDecl *
     Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
            SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
-           SourceLocation TargetNameLoc, DeclarationName TargetName);
+           const DeclarationNameInfo &NameInfo);
 
   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; }
+  static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
 };
 
 /// UnresolvedUsingTypenameDecl - Represents a dependent using
@@ -1847,7 +2188,7 @@
                     SourceLocation TypenameLoc,
                     SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
                     SourceLocation TargetNameLoc, IdentifierInfo *TargetName)
-  : TypeDecl(Decl::UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
+  : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
     TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
     TypenameLocation(TypenameLoc), TargetNestedNameSpecifier(TargetNNS)
   { }
@@ -1857,17 +2198,32 @@
   /// preceding the namespace name.
   SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
 
+  /// \brief Set the source range coverting the nested-name-specifier preceding
+  /// the namespace name.
+  void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
+
   /// \brief Get target nested name declaration.
   NestedNameSpecifier* getTargetNestedNameSpecifier() {
     return TargetNestedNameSpecifier;
   }
 
+  /// \brief Set the nested name declaration.
+  void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
+    TargetNestedNameSpecifier = NNS;
+  }
+
   /// \brief Returns the source location of the 'using' keyword.
   SourceLocation getUsingLoc() const { return UsingLocation; }
 
+  /// \brief Set the source location of the 'using' keyword.
+  void setUsingLoc(SourceLocation L) { UsingLocation = L; }
+
   /// \brief Returns the source location of the 'typename' keyword.
   SourceLocation getTypenameLoc() const { return TypenameLocation; }
 
+  /// \brief Set the source location of the 'typename' keyword.
+  void setTypenameLoc(SourceLocation L) { TypenameLocation = L; }
+
   static UnresolvedUsingTypenameDecl *
     Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
            SourceLocation TypenameLoc,
@@ -1876,7 +2232,7 @@
 
   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; }
+  static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; }
 };
 
 /// StaticAssertDecl - Represents a C++0x static_assert declaration.
@@ -1899,12 +2255,11 @@
   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; }
+  static bool classofKind(Kind K) { return K == StaticAssert; }
+
+  friend class ASTDeclReader;
 };
 
 /// Insertion operator for diagnostics.  This allows sending AccessSpecifier's
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index 2a4b12a..97da6ca 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -29,108 +29,54 @@
 /// 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;
+  /// DeclsTy - When in vector form, this is what the Data pointer points to.
+  typedef llvm::SmallVector<NamedDecl *, 4> DeclsTy;
 
-  /// \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;
+  /// \brief The stored data, which will be either a pointer to a NamedDecl,
+  /// or a pointer to a vector.
+  llvm::PointerUnion<NamedDecl *, DeclsTy *> Data;
 
 public:
-  StoredDeclsList() : Data(0) {}
+  StoredDeclsList() {}
 
   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);
-    }
+    if (DeclsTy *RHSVec = RHS.getAsVector())
+      Data = new DeclsTy(*RHSVec);
   }
 
   ~StoredDeclsList() {
     // If this is a vector-form, free the vector.
-    if (VectorTy *Vector = getAsVector())
+    if (DeclsTy *Vector = getAsVector())
       delete Vector;
   }
 
   StoredDeclsList &operator=(const StoredDeclsList &RHS) {
-    if (VectorTy *Vector = getAsVector())
+    if (DeclsTy *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);
-    }
+    if (DeclsTy *RHSVec = RHS.getAsVector())
+      Data = new DeclsTy(*RHSVec);
     return *this;
   }
 
-  bool isNull() const { return (Data & ~0x03) == 0; }
+  bool isNull() const { return Data.isNull(); }
 
   NamedDecl *getAsDecl() const {
-    if ((Data & 0x03) != DK_Decl)
-      return 0;
-
-    return reinterpret_cast<NamedDecl *>(Data & ~0x03);
+    return Data.dyn_cast<NamedDecl *>();
   }
 
-  VectorTy *getAsVector() const {
-    if ((Data & 0x03) != DK_ID_Vector && (Data & 0x03) != DK_Decl_Vector)
-      return 0;
-
-    return reinterpret_cast<VectorTy *>(Data & ~0x03);
+  DeclsTy *getAsVector() const {
+    return Data.dyn_cast<DeclsTy *>();
   }
 
   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;
+    Data = ND;
+    // Make sure that Data is a plain NamedDecl* so we can use its address
+    // at getLookupResult.
+    assert(*(NamedDecl **)&Data == ND &&
+           "PointerUnion mangles the NamedDecl pointer!");
   }
 
   void remove(NamedDecl *D) {
@@ -138,28 +84,25 @@
     if (NamedDecl *Singleton = getAsDecl()) {
       assert(Singleton == D && "list is different singleton");
       (void)Singleton;
-      Data = 0;
+      Data = (NamedDecl *)0;
       return;
     }
 
-    VectorTy &Vec = *getAsVector();
-    VectorTy::iterator I = std::find(Vec.begin(), Vec.end(),
-                                     reinterpret_cast<uintptr_t>(D));
+    DeclsTy &Vec = *getAsVector();
+    DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), 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))
+    assert(std::find(Vec.begin(), Vec.end(), 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) {
+  DeclContext::lookup_result getLookupResult() {
     if (isNull())
-      return DeclContext::lookup_result(0, 0);
-
-    if (hasDeclarationIDs())
-      materializeDecls(Context);
+      return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
+                                        DeclContext::lookup_iterator(0));
 
     // If we have a single NamedDecl, return it.
     if (getAsDecl()) {
@@ -171,19 +114,15 @@
     }
 
     assert(getAsVector() && "Must have a vector at this point");
-    VectorTy &Vector = *getAsVector();
+    DeclsTy &Vector = *getAsVector();
 
     // Otherwise, we have a range result.
-    return DeclContext::lookup_result((NamedDecl **)&Vector[0],
-                                      (NamedDecl **)&Vector[0]+Vector.size());
+    return DeclContext::lookup_result(&Vector[0], &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);
-
+  bool HandleRedeclaration(NamedDecl *D) {
     // Most decls only have one entry in their list, special case it.
     if (NamedDecl *OldD = getAsDecl()) {
       if (!D->declarationReplaces(OldD))
@@ -193,12 +132,12 @@
     }
 
     // Determine if this declaration is actually a redeclaration.
-    VectorTy &Vec = *getAsVector();
-    for (VectorTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
+    DeclsTy &Vec = *getAsVector();
+    for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
          OD != ODEnd; ++OD) {
-      NamedDecl *OldD = reinterpret_cast<NamedDecl *>(*OD);
+      NamedDecl *OldD = *OD;
       if (D->declarationReplaces(OldD)) {
-        *OD = reinterpret_cast<uintptr_t>(D);
+        *OD = D;
         return true;
       }
     }
@@ -210,17 +149,15 @@
   /// 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;
+      DeclsTy *VT = new DeclsTy();
+      VT->push_back(OldD);
+      Data = VT;
     }
 
-    VectorTy &Vec = *getAsVector();
+    DeclsTy &Vec = *getAsVector();
 
     // Using directives end up in a special entry which contains only
     // other using directives, so all this logic is wasted for them.
@@ -231,32 +168,30 @@
     // 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));
+      Vec.push_back(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();
+      DeclsTy::iterator I = Vec.begin();
       if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
         while (I != Vec.end() &&
-               reinterpret_cast<NamedDecl *>(*I)
-                 ->getIdentifierNamespace() == Decl::IDNS_Using)
+               (*I)->getIdentifierNamespace() == Decl::IDNS_Using)
           ++I;
       }
-      Vec.insert(I, reinterpret_cast<uintptr_t>(D));
+      Vec.insert(I, 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);
+    } else if (Vec.back()->hasTagIdentifierNamespace()) {
+      NamedDecl *TagD = Vec.back();
+      Vec.back() = D;
       Vec.push_back(TagD);
     } else
-      Vec.push_back(reinterpret_cast<uintptr_t>(D));
+      Vec.push_back(D);
   }
 };
 
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index a20625d..75289fa 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -59,10 +59,14 @@
       FriendLoc(FriendL) {
   }
 
+  explicit FriendDecl(EmptyShell Empty)
+    : Decl(Decl::Friend, Empty), NextFriend(0) { }
+
 public:
   static FriendDecl *Create(ASTContext &C, DeclContext *DC,
                             SourceLocation L, FriendUnion Friend_,
                             SourceLocation FriendL);
+  static FriendDecl *Create(ASTContext &C, EmptyShell Empty);
 
   /// If this friend declaration names an (untemplated but
   /// possibly dependent) type, return the type;  otherwise
@@ -87,6 +91,9 @@
   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; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 /// An iterator over the friend declarations of a class.
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
index e1fae8f..030291e 100644
--- a/include/clang/AST/DeclGroup.h
+++ b/include/clang/AST/DeclGroup.h
@@ -34,7 +34,6 @@
 
 public:
   static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls);
-  void Destroy(ASTContext& C);
 
   unsigned size() const { return NumDecls; }
 
diff --git a/include/clang/AST/DeclNodes.def b/include/clang/AST/DeclNodes.def
deleted file mode 100644
index 5b03ff8..0000000
--- a/include/clang/AST/DeclNodes.def
+++ /dev/null
@@ -1,165 +0,0 @@
-//===-- 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
index 18bb607..da1278c 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -21,7 +21,6 @@
 class Expr;
 class Stmt;
 class FunctionDecl;
-class AttributeList;
 class RecordDecl;
 class ObjCIvarDecl;
 class ObjCMethodDecl;
@@ -29,6 +28,7 @@
 class ObjCCategoryDecl;
 class ObjCPropertyDecl;
 class ObjCPropertyImplDecl;
+class CXXBaseOrMemberInitializer;
 
 class ObjCListBase {
   void operator=(const ObjCListBase &);     // DO NOT IMPLEMENT
@@ -40,12 +40,6 @@
 
 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; }
 
@@ -91,7 +85,6 @@
 
   void set(ObjCProtocolDecl* const* InList, unsigned Elts, 
            const SourceLocation *Locs, ASTContext &Ctx);
-  void Destroy(ASTContext &Ctx);
 };
 
 
@@ -127,6 +120,9 @@
 
   // Synthesized declaration method for a property setter/getter
   bool IsSynthesized : 1;
+  
+  // Method has a definition.
+  bool IsDefined : 1;
 
   // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
   /// @required/@optional
@@ -170,29 +166,25 @@
                  bool isInstance = true,
                  bool isVariadic = false,
                  bool isSynthesized = false,
+                 bool isDefined = false,
                  ImplementationControl impControl = None,
                  unsigned numSelectorArgs = 0)
   : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
     DeclContext(ObjCMethod),
     IsInstance(isInstance), IsVariadic(isVariadic),
     IsSynthesized(isSynthesized),
+    IsDefined(isDefined),
     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,
@@ -202,6 +194,7 @@
                                 bool isInstance = true,
                                 bool isVariadic = false,
                                 bool isSynthesized = false,
+                                bool isDefined = false,
                                 ImplementationControl impControl = None,
                                 unsigned numSelectorArgs = 0);
 
@@ -238,6 +231,12 @@
   QualType getResultType() const { return MethodDeclType; }
   void setResultType(QualType T) { MethodDeclType = T; }
 
+  /// \brief Determine the type of an expression that sends a message to this 
+  /// function.
+  QualType getSendResultType() const {
+    return getResultType().getNonLValueExprType(getASTContext());
+  }
+  
   TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; }
   void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; }
 
@@ -289,6 +288,9 @@
 
   bool isSynthesized() const { return IsSynthesized; }
   void setSynthesized(bool isSynth) { IsSynthesized = isSynth; }
+  
+  bool isDefined() const { return IsDefined; }
+  void setDefined(bool isDefined) { IsDefined = isDefined; }
 
   // Related to protocols declared in  @protocol
   void setDeclImplementation(ImplementationControl ic) {
@@ -319,21 +321,6 @@
   }
 };
 
-/// 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.
@@ -348,8 +335,6 @@
                     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 {
@@ -416,8 +401,8 @@
   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;
+    return K >= firstObjCContainer &&
+           K <= lastObjCContainer;
   }
 
   static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
@@ -464,6 +449,10 @@
   /// List of categories defined for this class.
   /// FIXME: Why is this a linked list??
   ObjCCategoryDecl *CategoryList;
+  
+  /// IvarList - List of all ivars defined by this class; including class
+  /// extensions and implementation. This list is built lazily.
+  ObjCIvarDecl *IvarList;
 
   bool ForwardDecl:1; // declared with @class.
   bool InternalInterface:1; // true - no @interface for @implementation
@@ -475,13 +464,7 @@
   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,
@@ -524,7 +507,10 @@
     return std::distance(ivar_begin(), ivar_end());
   }
   bool ivar_empty() const { return ivar_begin() == ivar_end(); }
-
+  
+  ObjCIvarDecl  *all_declared_ivar_begin();
+  void setIvarList(ObjCIvarDecl *ivar) { IvarList = ivar; }
+  
   /// setProtocolList - Set the list of protocols that this interface
   /// implements.
   void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
@@ -549,8 +535,8 @@
   void setCategoryList(ObjCCategoryDecl *category) {
     CategoryList = category;
   }
-
-  ObjCCategoryDecl* getClassExtension() const;
+  
+  ObjCCategoryDecl* getFirstClassExtension() const;
 
   ObjCPropertyDecl
     *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
@@ -643,21 +629,26 @@
 
 private:
   ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation L, IdentifierInfo *Id,
-               QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW)
+               QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
+               bool synthesized)
     : FieldDecl(ObjCIvar, DC, L, Id, T, TInfo, BW, /*Mutable=*/false),
-      DeclAccess(ac) {}
+      NextIvar(0), DeclAccess(ac),  Synthesized(synthesized) {}
 
 public:
   static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
                               SourceLocation L, IdentifierInfo *Id, QualType T,
                               TypeSourceInfo *TInfo,
-                              AccessControl ac, Expr *BW = NULL);
+                              AccessControl ac, Expr *BW = NULL,
+                              bool synthesized=false);
 
   /// \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;
+  
+  ObjCIvarDecl *getNextIvar() { return NextIvar; }
+  void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
 
   void setAccessControl(AccessControl ac) { DeclAccess = ac; }
 
@@ -667,13 +658,21 @@
     return DeclAccess == None ? Protected : AccessControl(DeclAccess);
   }
 
+  void setSynthesize(bool synth) { Synthesized = synth; }
+  bool getSynthesize() const { return Synthesized; }
+  
   // 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:
+  /// NextIvar - Next Ivar in the list of ivars declared in class; class's 
+  /// extensions and class's implementation
+  ObjCIvarDecl *NextIvar;
+  
   // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
   unsigned DeclAccess : 3;
+  unsigned Synthesized : 1;
 };
 
 
@@ -693,8 +692,6 @@
                                      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; }
@@ -738,15 +735,10 @@
       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;
   }
@@ -815,12 +807,7 @@
   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,
@@ -853,7 +840,6 @@
   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,
@@ -867,9 +853,6 @@
     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(); }
@@ -921,6 +904,9 @@
   /// FIXME: this should not be a singly-linked list.  Move storage elsewhere.
   ObjCCategoryDecl *NextClassCategory;
 
+  /// true of class extension has at least one bitfield ivar.
+  bool HasSynthBitfield : 1;
+  
   /// \brief The location of the '@' in '@interface'
   SourceLocation AtLoc;
 
@@ -931,8 +917,8 @@
                    SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
                    IdentifierInfo *Id)
     : ObjCContainerDecl(ObjCCategory, DC, ClassNameLoc, Id),
-      ClassInterface(0), NextClassCategory(0), AtLoc(AtLoc), 
-      CategoryNameLoc(CategoryNameLoc) {
+      ClassInterface(0), NextClassCategory(0), HasSynthBitfield(false),
+      AtLoc(AtLoc), CategoryNameLoc(CategoryNameLoc) {
   }
 public:
 
@@ -982,6 +968,10 @@
   }
 
   bool IsClassExtension() const { return getIdentifier() == 0; }
+  const ObjCCategoryDecl *getNextClassExtension() const;
+  
+  bool hasSynthBitfield() const { return HasSynthBitfield; }
+  void setHasSynthBitfield (bool val) { HasSynthBitfield = val; }
   
   typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
   ivar_iterator ivar_begin() const {
@@ -1024,8 +1014,6 @@
       ClassInterface(classInterface) {}
 
 public:
-  virtual ~ObjCImplDecl() {}
-
   const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
   ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
   void setClassInterface(ObjCInterfaceDecl *IFace);
@@ -1058,7 +1046,7 @@
   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;
+    return K >= firstObjCImpl && K <= lastObjCImpl;
   }
 };
 
@@ -1152,18 +1140,61 @@
 class ObjCImplementationDecl : public ObjCImplDecl {
   /// Implementation Class's super class.
   ObjCInterfaceDecl *SuperClass;
-
+  /// Support for ivar initialization.
+  /// IvarInitializers - The arguments used to initialize the ivars
+  CXXBaseOrMemberInitializer **IvarInitializers;
+  unsigned NumIvarInitializers;
+  
+  /// true of class extension has at least one bitfield ivar.
+  bool HasSynthBitfield : 1;
+  
   ObjCImplementationDecl(DeclContext *DC, SourceLocation L,
                          ObjCInterfaceDecl *classInterface,
                          ObjCInterfaceDecl *superDecl)
     : ObjCImplDecl(ObjCImplementation, DC, L, classInterface),
-       SuperClass(superDecl){}
+       SuperClass(superDecl), IvarInitializers(0), NumIvarInitializers(0),
+       HasSynthBitfield(false) {}
 public:
   static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
                                         SourceLocation L,
                                         ObjCInterfaceDecl *classInterface,
                                         ObjCInterfaceDecl *superDecl);
-
+  
+  /// init_iterator - Iterates through the ivar initializer list.
+  typedef CXXBaseOrMemberInitializer **init_iterator;
+  
+  /// init_const_iterator - Iterates through the ivar initializer list.
+  typedef CXXBaseOrMemberInitializer * const * init_const_iterator;
+  
+  /// init_begin() - Retrieve an iterator to the first initializer.
+  init_iterator       init_begin()       { return IvarInitializers; }
+  /// begin() - Retrieve an iterator to the first initializer.
+  init_const_iterator init_begin() const { return IvarInitializers; }
+  
+  /// init_end() - Retrieve an iterator past the last initializer.
+  init_iterator       init_end()       {
+    return IvarInitializers + NumIvarInitializers;
+  }
+  /// end() - Retrieve an iterator past the last initializer.
+  init_const_iterator init_end() const {
+    return IvarInitializers + NumIvarInitializers;
+  }
+  /// getNumArgs - Number of ivars which must be initialized.
+  unsigned getNumIvarInitializers() const {
+    return NumIvarInitializers;
+  }
+  
+  void setNumIvarInitializers(unsigned numNumIvarInitializers) {
+    NumIvarInitializers = numNumIvarInitializers;
+  }
+  
+  void setIvarInitializers(ASTContext &C,
+                           CXXBaseOrMemberInitializer ** initializers,
+                           unsigned numInitializers);
+  
+  bool hasSynthBitfield() const { return HasSynthBitfield; }
+  void setHasSynthBitfield (bool val) { HasSynthBitfield = val; }
+    
   /// getIdentifier - Get the identifier that names the class
   /// interface associated with this implementation.
   IdentifierInfo *getIdentifier() const {
@@ -1218,6 +1249,9 @@
   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; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
@@ -1269,9 +1303,9 @@
   enum PropertyControl { None, Required, Optional };
 private:
   SourceLocation AtLoc;   // location of @property
-  QualType DeclType;
+  TypeSourceInfo *DeclType;
   unsigned PropertyAttributes : 8;
-
+  unsigned PropertyAttributesAsWritten : 8;
   // @required/@optional
   unsigned PropertyImplementation : 2;
 
@@ -1283,9 +1317,11 @@
   ObjCIvarDecl *PropertyIvarDecl;   // Synthesize ivar for this property
 
   ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
-                   SourceLocation AtLocation, QualType T)
+                   SourceLocation AtLocation, TypeSourceInfo *T)
     : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), DeclType(T),
-      PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None),
+      PropertyAttributes(OBJC_PR_noattr), 
+      PropertyAttributesAsWritten(OBJC_PR_noattr),
+      PropertyImplementation(None),
       GetterName(Selector()),
       SetterName(Selector()),
       GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {}
@@ -1293,13 +1329,14 @@
   static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
                                   SourceLocation L,
                                   IdentifierInfo *Id, SourceLocation AtLocation,
-                                  QualType T,
+                                  TypeSourceInfo *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; }
+  TypeSourceInfo *getTypeSourceInfo() const { return DeclType; }
+  QualType getType() const { return DeclType->getType(); }
+  void setType(TypeSourceInfo *T) { DeclType = T; }
 
   PropertyAttributeKind getPropertyAttributes() const {
     return PropertyAttributeKind(PropertyAttributes);
@@ -1308,6 +1345,14 @@
     PropertyAttributes |= PRVal;
   }
 
+  PropertyAttributeKind getPropertyAttributesAsWritten() const {
+    return PropertyAttributeKind(PropertyAttributesAsWritten);
+  }
+  
+  void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
+    PropertyAttributesAsWritten = PRVal;
+  }
+  
  void makeitReadWriteAttribute(void) {
     PropertyAttributes &= ~OBJC_PR_readonly;
     PropertyAttributes |= OBJC_PR_readwrite;
@@ -1384,13 +1429,21 @@
 
   /// Null for @dynamic. Required for @synthesize.
   ObjCIvarDecl *PropertyIvarDecl;
+  
+  /// Null for @dynamic. Non-null if property must be copy-constructed in getter
+  Expr *GetterCXXConstructor;
+  
+  /// Null for @dynamic. Non-null if property has assignment operator to call
+  /// in Setter synthesis.
+  Expr *SetterCXXAssignment;
 
   ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
                        ObjCPropertyDecl *property,
                        Kind PK,
                        ObjCIvarDecl *ivarDecl)
     : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
-      PropertyDecl(property), PropertyIvarDecl(ivarDecl) {
+      PropertyDecl(property), PropertyIvarDecl(ivarDecl),
+      GetterCXXConstructor(0), SetterCXXAssignment(0) {
     assert (PK == Dynamic || PropertyIvarDecl);
   }
 
@@ -1420,7 +1473,21 @@
     return PropertyIvarDecl;
   }
   void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; }
+  
+  Expr *getGetterCXXConstructor() const {
+    return GetterCXXConstructor;
+  }
+  void setGetterCXXConstructor(Expr *getterCXXConstructor) {
+    GetterCXXConstructor = getterCXXConstructor;
+  }
 
+  Expr *getSetterCXXAssignment() const {
+    return SetterCXXAssignment;
+  }
+  void setSetterCXXAssignment(Expr *setterCXXAssignment) {
+    SetterCXXAssignment = setterCXXAssignment;
+  }
+  
   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; }
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 2bb971d..3861cd9 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -23,6 +23,7 @@
 
 class TemplateParameterList;
 class TemplateDecl;
+class RedeclarableTemplateDecl;
 class FunctionTemplateDecl;
 class ClassTemplateDecl;
 class ClassTemplatePartialSpecializationDecl;
@@ -112,7 +113,7 @@
   unsigned MaxStructuredArgs;
   unsigned NumStructuredArgs;
 
-  TemplateArgument *FlatArgs;
+  llvm::SmallVector<TemplateArgument, 4> FlatArgs;
   unsigned MaxFlatArgs;
   unsigned NumFlatArgs;
 
@@ -127,18 +128,12 @@
   MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
   AddingToPack(false), PackBeginIndex(0) { }
 
-  void Append(const TemplateArgument& Arg);
+  void Append(const TemplateArgument &Arg);
   void BeginPack();
   void EndPack();
 
-  void ReleaseArgs();
-
-  unsigned flatSize() const {
-    return NumFlatArgs;
-  }
-  const TemplateArgument *getFlatArguments() const {
-    return FlatArgs;
-  }
+  unsigned flatSize() const { return FlatArgs.size(); }
+  const TemplateArgument *getFlatArguments() const { return FlatArgs.data(); }
 
   unsigned structuredSize() const {
     // If we don't have any structured args, just reuse the flat size.
@@ -165,7 +160,7 @@
   /// \brief The template argument list.
   ///
   /// The integer value will be non-zero to indicate that this
-  /// template argument list does not own the pointer.
+  /// template argument list does own the pointer.
   llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
 
   /// \brief The number of template arguments in this template
@@ -175,15 +170,33 @@
   llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
   unsigned NumStructuredArguments;
 
+  TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL
+  void operator=(const TemplateArgumentList &Other); // DO NOT IMPL
 public:
+  /// TemplateArgumentList - If this constructor is passed "true" for 'TakeArgs'
+  /// it copies them into a locally new[]'d array.  If passed "false", then it
+  /// just references the array passed in.  This is only safe if the builder
+  /// outlives it, but saves a copy.
   TemplateArgumentList(ASTContext &Context,
                        TemplateArgumentListBuilder &Builder,
                        bool TakeArgs);
 
-  /// \brief Produces a shallow copy of the given template argument list
-  TemplateArgumentList(const TemplateArgumentList &Other);
-  
-  ~TemplateArgumentList();
+  /// TemplateArgumentList - It copies the template arguments into a locally
+  /// new[]'d array.
+  TemplateArgumentList(ASTContext &Context,
+                       const TemplateArgument *Args, unsigned NumArgs);
+
+  /// Produces a shallow copy of the given template argument list.  This
+  /// assumes that the input argument list outlives it.  This takes the list as
+  /// a pointer to avoid looking like a copy constructor, since this really
+  /// really isn't safe to use that way.
+  explicit TemplateArgumentList(const TemplateArgumentList *Other);
+
+  TemplateArgumentList() : NumFlatArguments(0), NumStructuredArguments(0) { }
+
+  /// \brief Copies the template arguments into a locally new[]'d array.
+  void init(ASTContext &Context,
+            const TemplateArgument *Args, unsigned NumArgs);
 
   /// \brief Retrieve the template argument at a given index.
   const TemplateArgument &get(unsigned Idx) const {
@@ -236,8 +249,6 @@
     : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
       TemplateParams(Params) { }
 public:
-  ~TemplateDecl();
-
   /// Get the list of template parameters
   TemplateParameterList *getTemplateParameters() const {
     return TemplateParams;
@@ -249,16 +260,32 @@
   // 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 RedeclarableTemplateDecl *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;
+    return K >= firstTemplate && K <= lastTemplate;
+  }
+
+  SourceRange getSourceRange() const {
+    return SourceRange(TemplateParams->getTemplateLoc(),
+                       TemplatedDecl->getSourceRange().getEnd());
   }
 
 protected:
   NamedDecl *TemplatedDecl;
   TemplateParameterList* TemplateParams;
+  
+public:
+  /// \brief Initialize the underlying templated declaration and
+  /// template parameters.
+  void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
+    assert(TemplatedDecl == 0 && "TemplatedDecl already set!");
+    assert(TemplateParams == 0 && "TemplateParams already set!");
+    TemplatedDecl = templatedDecl;
+    TemplateParams = templateParams;
+  }
 };
 
 /// \brief Provides information about a function template specialization,
@@ -280,6 +307,9 @@
   /// specialization from the function template.
   const TemplateArgumentList *TemplateArguments;
 
+  /// \brief The template arguments as written in the sources, if provided.
+  const TemplateArgumentListInfo *TemplateArgumentsAsWritten;
+
   /// \brief The point at which this function template specialization was
   /// first instantiated. 
   SourceLocation PointOfInstantiation;
@@ -342,8 +372,9 @@
   
 public:
   explicit 
-  MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK)
-    : MemberAndTSK(IF, TSK - 1), PointOfInstantiation() {
+  MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
+                           SourceLocation POI = SourceLocation())
+    : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
     assert(TSK != TSK_Undeclared && 
            "Cannot encode undeclared template specializations for members");
   }
@@ -452,120 +483,179 @@
   }
 };
   
-/// 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) { }
+/// Declaration of a redeclarable template.
+class RedeclarableTemplateDecl : public TemplateDecl {
 
-    /// \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);
+  RedeclarableTemplateDecl *getPreviousDeclarationImpl() {
+    return CommonOrPrev.dyn_cast<RedeclarableTemplateDecl*>();
   }
 
-  /// \brief Retrieve the set of function template specializations of this
-  /// function template.
-  llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
-    return getCommonPtr()->Specializations;
-  }
+  RedeclarableTemplateDecl *getCanonicalDeclImpl();
 
-  /// \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*>();
-  }
+  void setPreviousDeclarationImpl(RedeclarableTemplateDecl *Prev);
 
-  /// \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() {
+  RedeclarableTemplateDecl *getInstantiatedFromMemberTemplateImpl() {
     return getCommonPtr()->InstantiatedFromMember.getPointer();
   }
 
-  void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *FTD) {
+  void setInstantiatedFromMemberTemplateImpl(RedeclarableTemplateDecl *TD) {
     assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
-    getCommonPtr()->InstantiatedFromMember.setPointer(FTD);
+    getCommonPtr()->InstantiatedFromMember.setPointer(TD);
+  }
+
+protected:
+  template <typename EntryType> struct SpecEntryTraits {
+    typedef EntryType DeclType;
+
+    static DeclType *getMostRecentDeclaration(EntryType *D) {
+      return D->getMostRecentDeclaration();
+    }
+  };
+
+  template <typename EntryType,
+            typename _SETraits = SpecEntryTraits<EntryType>,
+            typename _DeclType = typename _SETraits::DeclType>
+  class SpecIterator : public std::iterator<std::forward_iterator_tag,
+                                            _DeclType*, ptrdiff_t,
+                                            _DeclType*, _DeclType*> {
+    typedef _SETraits SETraits;
+    typedef _DeclType DeclType;
+
+    typedef typename llvm::FoldingSet<EntryType>::iterator SetIteratorType;
+
+    SetIteratorType SetIter;
+
+  public:
+    SpecIterator() : SetIter() {}
+    SpecIterator(SetIteratorType SetIter) : SetIter(SetIter) {}
+
+    DeclType *operator*() const {
+      return SETraits::getMostRecentDeclaration(&*SetIter);
+    }
+    DeclType *operator->() const { return **this; }
+
+    SpecIterator &operator++() { ++SetIter; return *this; }
+    SpecIterator operator++(int) {
+      SpecIterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    bool operator==(SpecIterator Other) const {
+      return SetIter == Other.SetIter;
+    }
+    bool operator!=(SpecIterator Other) const {
+      return SetIter != Other.SetIter;
+    }
+  };
+
+  template <typename EntryType>
+  SpecIterator<EntryType> makeSpecIterator(llvm::FoldingSet<EntryType> &Specs,
+                                           bool isEnd) {
+    return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
+  }
+
+  template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
+  findSpecializationImpl(llvm::FoldingSet<EntryType> &Specs,
+                         const TemplateArgument *Args, unsigned NumArgs,
+                         void *&InsertPos);
+
+  struct CommonBase {
+    CommonBase() : InstantiatedFromMember(0, false) { }
+
+    /// \brief The template from which this was most
+    /// directly instantiated (or null).
+    ///
+    /// The boolean value indicates whether this template
+    /// was explicitly specialized.
+    llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
+      InstantiatedFromMember;
+
+    /// \brief The latest declaration of this template.
+    RedeclarableTemplateDecl *Latest;
+  };
+
+  /// \brief A pointer to the previous declaration (if this is a redeclaration)
+  /// or to the data that is common to all declarations of this template.
+  llvm::PointerUnion<CommonBase*, RedeclarableTemplateDecl*> CommonOrPrev;
+
+  /// \brief Retrieves the "common" pointer shared by all (re-)declarations of
+  /// the same template. Calling this routine may implicitly allocate memory
+  /// for the common pointer.
+  CommonBase *getCommonPtr();
+
+  virtual CommonBase *newCommon() = 0;
+
+  // Construct a template decl with name, parameters, and templated element.
+  RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
+                           DeclarationName Name, TemplateParameterList *Params,
+                           NamedDecl *Decl)
+    : TemplateDecl(DK, DC, L, Name, Params, Decl),
+      CommonOrPrev((CommonBase*)0) { }
+
+public:
+  template <class decl_type> friend class RedeclarableTemplate;
+
+  RedeclarableTemplateDecl *getCanonicalDecl() {
+    return getCanonicalDeclImpl();
+  }
+
+  /// \brief Retrieve the previous declaration of this template, or
+  /// NULL if no such declaration exists.
+  RedeclarableTemplateDecl *getPreviousDeclaration() {
+    return getPreviousDeclarationImpl();
+  }
+
+  /// \brief Retrieve the previous declaration of this template, or
+  /// NULL if no such declaration exists.
+  const RedeclarableTemplateDecl *getPreviousDeclaration() const {
+    return
+      const_cast<RedeclarableTemplateDecl*>(this)->getPreviousDeclaration();
+  }
+
+  /// \brief Retrieve the first declaration of this template, or itself
+  /// if this the first one.
+  RedeclarableTemplateDecl *getFirstDeclaration() {
+    return getCanonicalDecl();
+  }
+
+  /// \brief Retrieve the first declaration of this template, or itself
+  /// if this the first one.
+  const RedeclarableTemplateDecl *getFirstDeclaration() const {
+    return
+      const_cast<RedeclarableTemplateDecl*>(this)->getFirstDeclaration();
+  }
+
+  /// \brief Retrieve the most recent declaration of this template, or itself
+  /// if this the most recent one.
+  RedeclarableTemplateDecl *getMostRecentDeclaration() {
+    return getCommonPtr()->Latest;
+  }
+
+  /// \brief Retrieve the most recent declaration of this template, or itself
+  /// if this the most recent one.
+  const RedeclarableTemplateDecl *getMostRecentDeclaration() const {
+    return
+      const_cast<RedeclarableTemplateDecl*>(this)->getMostRecentDeclaration();
   }
 
   /// \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.
+  /// In the following example, the function template \c X<int>::f and the
+  /// member template \c X<int>::Inner are member specializations.
   ///
   /// \code
   /// template<typename T>
   /// struct X {
   ///   template<typename U> void f(T, U);
+  ///   template<typename U> struct Inner;
   /// };
   ///
   /// template<> template<typename T>
   /// void X<int>::f(int, T);
+  /// template<> template<typename T>
+  /// struct X<int>::Inner { /* ... */ };
   /// \endcode
   bool isMemberSpecialization() {
     return getCommonPtr()->InstantiatedFromMember.getInt();
@@ -578,6 +668,191 @@
     getCommonPtr()->InstantiatedFromMember.setInt(true);
   }
   
+  /// \brief Retrieve the previous declaration of this template, or
+  /// NULL if no such declaration exists.
+  RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() {
+    return getInstantiatedFromMemberTemplateImpl();
+  }
+
+  virtual RedeclarableTemplateDecl *getNextRedeclaration();
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const RedeclarableTemplateDecl *D) { return true; }
+  static bool classof(const FunctionTemplateDecl *D) { return true; }
+  static bool classof(const ClassTemplateDecl *D) { return true; }
+  static bool classofKind(Kind K) {
+    return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
+  }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+template <class decl_type>
+class RedeclarableTemplate {
+  RedeclarableTemplateDecl *thisDecl() {
+    return static_cast<decl_type*>(this);
+  }
+
+public:
+  /// \brief Retrieve the previous declaration of this function template, or
+  /// NULL if no such declaration exists.
+  decl_type *getPreviousDeclaration() {
+    return static_cast<decl_type*>(thisDecl()->getPreviousDeclarationImpl());
+  }
+
+  /// \brief Retrieve the previous declaration of this function template, or
+  /// NULL if no such declaration exists.
+  const decl_type *getPreviousDeclaration() const {
+    return const_cast<RedeclarableTemplate*>(this)->getPreviousDeclaration();
+  }
+
+  /// \brief Set the previous declaration of this function template.
+  void setPreviousDeclaration(decl_type *Prev) {
+    thisDecl()->setPreviousDeclarationImpl(Prev);
+  }
+
+  decl_type *getCanonicalDecl() {
+    return static_cast<decl_type*>(thisDecl()->getCanonicalDeclImpl());
+  }
+
+  const decl_type *getCanonicalDecl() const {
+    return const_cast<RedeclarableTemplate*>(this)->getCanonicalDecl();
+  }
+
+  /// \brief Retrieve the member template that this template was instantiated
+  /// from.
+  ///
+  /// This routine will return non-NULL for member templates of
+  /// class templates.  For example, given:
+  ///
+  /// \code
+  /// template <typename T>
+  /// struct X {
+  ///   template <typename U> void f();
+  ///   template <typename U> struct A {};
+  /// };
+  /// \endcode
+  ///
+  /// X<int>::f<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).
+  ///
+  /// 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 ClassTemplateDecl (whose parent is again
+  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
+  /// X<T>::A<U>, a ClassTemplateDecl (whose parent is X<T>, also a CTD).
+  ///
+  /// \returns NULL if this is not an instantiation of a member template.
+  decl_type *getInstantiatedFromMemberTemplate() {
+    return static_cast<decl_type*>(
+             thisDecl()->getInstantiatedFromMemberTemplateImpl());
+  }
+
+  void setInstantiatedFromMemberTemplate(decl_type *TD) {
+    thisDecl()->setInstantiatedFromMemberTemplateImpl(TD);
+  }
+};
+
+template <> struct RedeclarableTemplateDecl::
+SpecEntryTraits<FunctionTemplateSpecializationInfo> {
+  typedef FunctionDecl DeclType;
+
+  static DeclType *
+  getMostRecentDeclaration(FunctionTemplateSpecializationInfo *I) {
+    return I->Function->getMostRecentDeclaration();
+  }
+};
+
+/// Declaration of a template function.
+class FunctionTemplateDecl : public RedeclarableTemplateDecl,
+                             public RedeclarableTemplate<FunctionTemplateDecl> {
+  static void DeallocateCommon(void *Ptr);
+
+protected:
+  typedef RedeclarableTemplate<FunctionTemplateDecl> redeclarable_base;
+
+  /// \brief Data that is common to all of the declarations of a given
+  /// function template.
+  struct Common : CommonBase {
+    /// \brief The function template specializations for this function
+    /// template, including explicit specializations and instantiations.
+    llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
+  };
+
+  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
+                       TemplateParameterList *Params, NamedDecl *Decl)
+    : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
+
+  CommonBase *newCommon();
+
+  Common *getCommonPtr() {
+    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
+  }
+
+  friend void FunctionDecl::setFunctionTemplateSpecialization(
+                                       FunctionTemplateDecl *Template,
+                                       const TemplateArgumentList *TemplateArgs,
+                                       void *InsertPos,
+                                       TemplateSpecializationKind TSK,
+                          const TemplateArgumentListInfo *TemplateArgsAsWritten,
+                                       SourceLocation PointOfInstantiation);
+
+  /// \brief Retrieve the set of function template specializations of this
+  /// function template.
+  llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
+    return getCommonPtr()->Specializations;
+  }
+  
+public:
+  /// Get the underlying function declaration of the template.
+  FunctionDecl *getTemplatedDecl() const {
+    return static_cast<FunctionDecl*>(TemplatedDecl);
+  }
+
+  /// \brief Return the specialization with the provided arguments if it exists,
+  /// otherwise return the insertion point.
+  FunctionDecl *findSpecialization(const TemplateArgument *Args,
+                                   unsigned NumArgs, void *&InsertPos);
+
+  FunctionTemplateDecl *getCanonicalDecl() {
+    return redeclarable_base::getCanonicalDecl();
+  }
+  const FunctionTemplateDecl *getCanonicalDecl() const {
+    return redeclarable_base::getCanonicalDecl();
+  }
+
+  /// \brief Retrieve the previous declaration of this function template, or
+  /// NULL if no such declaration exists.
+  FunctionTemplateDecl *getPreviousDeclaration() {
+    return redeclarable_base::getPreviousDeclaration();
+  }
+
+  /// \brief Retrieve the previous declaration of this function template, or
+  /// NULL if no such declaration exists.
+  const FunctionTemplateDecl *getPreviousDeclaration() const {
+    return redeclarable_base::getPreviousDeclaration();
+  }
+
+  FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
+    return redeclarable_base::getInstantiatedFromMemberTemplate();
+  }
+
+  typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
+
+  spec_iterator spec_begin() {
+    return makeSpecIterator(getSpecializations(), false);
+  }
+
+  spec_iterator spec_end() {
+    return makeSpecIterator(getSpecializations(), true);
+  }
+
   /// Create a template function node.
   static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
                                       SourceLocation L,
@@ -589,6 +864,9 @@
   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; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 //===----------------------------------------------------------------------===//
@@ -621,9 +899,11 @@
 public:
   /// Get the nesting depth of the template parameter.
   unsigned getDepth() const { return Depth; }
+  void setDepth(unsigned D) { Depth = D; }
 
   /// Get the position of the template parameter within its parameter list.
   unsigned getPosition() const { return Position; }
+  void setPosition(unsigned P) { Position = P; }
 
   /// Get the index of the template parameter within its parameter list.
   unsigned getIndex() const { return Position; }
@@ -662,6 +942,7 @@
                                       SourceLocation L, unsigned D, unsigned P,
                                       IdentifierInfo *Id, bool Typename,
                                       bool ParameterPack);
+  static TemplateTypeParmDecl *Create(ASTContext &C, EmptyShell Empty);
 
   /// \brief Whether this template type parameter was declared with
   /// the 'typename' keyword. If not, it was declared with the 'class'
@@ -698,6 +979,13 @@
     DefaultArgument = 0;
     InheritedDefault = false;
   }
+  
+  /// \brief Set whether this template type parameter was declared with
+  /// the 'typename' or 'class' keyword.
+  void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
+
+  /// \brief Set whether this is a parameter pack.
+  void setParameterPack(bool isParamPack) { ParameterPack = isParamPack; }
 
   /// \brief Retrieve the depth of the template parameter.
   unsigned getDepth() const;
@@ -721,15 +1009,15 @@
 /// @endcode
 class NonTypeTemplateParmDecl
   : public VarDecl, protected TemplateParmPosition {
-  /// \brief The default template argument, if any.
-  Expr *DefaultArgument;
+  /// \brief The default template argument, if any, and whether or not
+  /// it was inherited.
+  llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited;
 
   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)
+    : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, SC_None, SC_None),
+      TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false)
   { }
 
 public:
@@ -738,22 +1026,43 @@
          unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo);
 
   using TemplateParmPosition::getDepth;
+  using TemplateParmPosition::setDepth;
   using TemplateParmPosition::getPosition;
+  using TemplateParmPosition::setPosition;
   using TemplateParmPosition::getIndex;
 
   /// \brief Determine whether this template parameter has a default
   /// argument.
-  bool hasDefaultArgument() const { return DefaultArgument; }
+  bool hasDefaultArgument() const {
+    return DefaultArgumentAndInherited.getPointer() != 0;
+  }
 
   /// \brief Retrieve the default argument, if any.
-  Expr *getDefaultArgument() const { return DefaultArgument; }
+  Expr *getDefaultArgument() const {
+    return DefaultArgumentAndInherited.getPointer();
+  }
 
   /// \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;
+  /// \brief Determines whether the default argument was inherited
+  /// from a previous declaration of this template.
+  bool defaultArgumentWasInherited() const {
+    return DefaultArgumentAndInherited.getInt();
+  }
+
+  /// \brief Set the default argument for this template parameter, and
+  /// whether that default argument was inherited from another
+  /// declaration.
+  void setDefaultArgument(Expr *DefArg, bool Inherited) {
+    DefaultArgumentAndInherited.setPointer(DefArg);
+    DefaultArgumentAndInherited.setInt(Inherited);
+  }
+
+  /// \brief Removes the default argument of this template parameter.
+  void removeDefaultArgument() {
+    DefaultArgumentAndInherited.setPointer(0);
+    DefaultArgumentAndInherited.setInt(false);
   }
 
   // Implement isa/cast/dyncast/etc.
@@ -772,14 +1081,17 @@
 class TemplateTemplateParmDecl
   : public TemplateDecl, protected TemplateParmPosition {
 
-  /// \brief The default template argument, if any.
+  /// DefaultArgument - The default template argument, if any.
   TemplateArgumentLoc DefaultArgument;
+  /// Whether or not the default argument was inherited.
+  bool DefaultArgumentWasInherited;
 
   TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
                            unsigned D, unsigned P,
                            IdentifierInfo *Id, TemplateParameterList *Params)
     : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
-      TemplateParmPosition(D, P), DefaultArgument()
+      TemplateParmPosition(D, P), DefaultArgument(),
+      DefaultArgumentWasInherited(false)
     { }
 
 public:
@@ -794,24 +1106,45 @@
 
   /// \brief Determine whether this template parameter has a default
   /// argument.
-  bool hasDefaultArgument() const { 
-    return !DefaultArgument.getArgument().isNull(); 
+  bool hasDefaultArgument() const {
+    return !DefaultArgument.getArgument().isNull();
   }
 
   /// \brief Retrieve the default argument, if any.
-  const TemplateArgumentLoc &getDefaultArgument() const { 
-    return DefaultArgument; 
+  const TemplateArgumentLoc &getDefaultArgument() const {
+    return DefaultArgument;
   }
 
-  /// \brief Set the default argument for this template parameter.
-  void setDefaultArgument(const TemplateArgumentLoc &DefArg) {
+  /// \brief Retrieve the location of the default argument, if any.
+  SourceLocation getDefaultArgumentLoc() const;
+
+  /// \brief Determines whether the default argument was inherited
+  /// from a previous declaration of this template.
+  bool defaultArgumentWasInherited() const {
+    return DefaultArgumentWasInherited;
+  }
+
+  /// \brief Set the default argument for this template parameter, and
+  /// whether that default argument was inherited from another
+  /// declaration.
+  void setDefaultArgument(const TemplateArgumentLoc &DefArg, bool Inherited) {
     DefaultArgument = DefArg;
+    DefaultArgumentWasInherited = Inherited;
+  }
+
+  /// \brief Removes the default argument of this template parameter.
+  void removeDefaultArgument() {
+    DefaultArgument = TemplateArgumentLoc();
+    DefaultArgumentWasInherited = false;
   }
 
   // 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; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 /// \brief Represents a class template specialization, which refers to
@@ -847,9 +1180,22 @@
   llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
     SpecializedTemplate;
 
-  /// \brief The type-as-written of an explicit template specialization.
+  /// \brief Further info for explicit template specialization/instantiation.
+  struct ExplicitSpecializationInfo {
+    /// \brief The type-as-written.
+    TypeSourceInfo *TypeAsWritten;
+    /// \brief The location of the extern keyword.
+    SourceLocation ExternLoc;
+    /// \brief The location of the template keyword.
+    SourceLocation TemplateKeywordLoc;
+
+    ExplicitSpecializationInfo()
+      : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
+  };
+
+  /// \brief Further info for explicit template specialization/instantiation.
   /// Does not apply to implicit specializations.
-  TypeSourceInfo *TypeAsWritten;
+  ExplicitSpecializationInfo *ExplicitInfo;
 
   /// \brief The template arguments used to describe this specialization.
   TemplateArgumentList TemplateArgs;
@@ -862,25 +1208,38 @@
   unsigned SpecializationKind : 3;
 
 protected:
-  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
+  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
                                   DeclContext *DC, SourceLocation L,
                                   ClassTemplateDecl *SpecializedTemplate,
                                   TemplateArgumentListBuilder &Builder,
                                   ClassTemplateSpecializationDecl *PrevDecl);
 
+  explicit ClassTemplateSpecializationDecl(Kind DK);
+
 public:
   static ClassTemplateSpecializationDecl *
-  Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
+  Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L,
          ClassTemplateDecl *SpecializedTemplate,
          TemplateArgumentListBuilder &Builder,
          ClassTemplateSpecializationDecl *PrevDecl);
-
-  virtual void Destroy(ASTContext& C);
+  static ClassTemplateSpecializationDecl *
+  Create(ASTContext &Context, EmptyShell Empty);
 
   virtual void getNameForDiagnostic(std::string &S,
                                     const PrintingPolicy &Policy,
                                     bool Qualified) const;
 
+  ClassTemplateSpecializationDecl *getMostRecentDeclaration() {
+    CXXRecordDecl *Recent
+        = cast<CXXRecordDecl>(CXXRecordDecl::getMostRecentDeclaration());
+    if (!isa<ClassTemplateSpecializationDecl>(Recent)) {
+      // FIXME: Does injected class name need to be in the redeclarations chain?
+      assert(Recent->isInjectedClassName() && Recent->getPreviousDeclaration());
+      Recent = Recent->getPreviousDeclaration();
+    }
+    return cast<ClassTemplateSpecializationDecl>(Recent);
+  }
+
   /// \brief Retrieve the template that this specialization specializes.
   ClassTemplateDecl *getSpecializedTemplate() const;
 
@@ -890,6 +1249,14 @@
     return TemplateArgs;
   }
 
+  /// \brief Initialize the template arguments of the class template
+  /// specialization.
+  void initTemplateArgs(TemplateArgument *Args, unsigned NumArgs) {
+    assert(TemplateArgs.flat_size() == 0 &&
+           "Template arguments already initialized!");
+    TemplateArgs.init(getASTContext(), Args, NumArgs);
+  }
+
   /// \brief Determine the kind of specialization that this
   /// declaration represents.
   TemplateSpecializationKind getSpecializationKind() const {
@@ -930,6 +1297,19 @@
                              SpecializedTemplate.get<ClassTemplateDecl*>());
   }
 
+  /// \brief Retrieve the class template or class template partial
+  /// specialization which was specialized by this.
+  llvm::PointerUnion<ClassTemplateDecl *,
+                     ClassTemplatePartialSpecializationDecl *>
+  getSpecializedTemplateOrPartial() const {
+    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
@@ -954,6 +1334,8 @@
   /// template arguments have been deduced.
   void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
                           TemplateArgumentList *TemplateArgs) {
+    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
+           "Already set to a class template partial specialization!");
     SpecializedPartialSpecialization *PS
       = new (getASTContext()) SpecializedPartialSpecialization();
     PS->PartialSpecialization = PartialSpec;
@@ -961,18 +1343,63 @@
     SpecializedTemplate = PS;
   }
 
+  /// \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,
+                          TemplateArgument *TemplateArgs,
+                          unsigned NumTemplateArgs) {
+    ASTContext &Ctx = getASTContext();
+    setInstantiationOf(PartialSpec,
+                       new (Ctx) TemplateArgumentList(Ctx, TemplateArgs,
+                                                      NumTemplateArgs));
+  }
+
+  /// \brief Note that this class template specialization is an instantiation
+  /// of the given class template.
+  void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
+    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
+           "Previously set to a class template partial specialization!");
+    SpecializedTemplate = TemplDecl;
+  }
+
   /// \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;
+    if (!ExplicitInfo)
+      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
+    ExplicitInfo->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;
+    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
   }
 
+  /// \brief Gets the location of the extern keyword, if present.
+  SourceLocation getExternLoc() const {
+    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
+  }
+  /// \brief Sets the location of the extern keyword.
+  void setExternLoc(SourceLocation Loc) {
+    if (!ExplicitInfo)
+      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
+    ExplicitInfo->ExternLoc = Loc;
+  }
+
+  /// \brief Sets the location of the template keyword.
+  void setTemplateKeywordLoc(SourceLocation Loc) {
+    if (!ExplicitInfo)
+      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
+    ExplicitInfo->TemplateKeywordLoc = Loc;
+  }
+  /// \brief Gets the location of the template keyword, if present.
+  SourceLocation getTemplateKeywordLoc() const {
+    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
+  }
+
+  SourceLocation getInnerLocStart() const { return getTemplateKeywordLoc(); }
+
   void Profile(llvm::FoldingSetNodeID &ID) const {
     Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
             getASTContext());
@@ -988,8 +1415,8 @@
 
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) {
-    return K == ClassTemplateSpecialization ||
-           K == ClassTemplatePartialSpecialization;
+    return K >= firstClassTemplateSpecialization &&
+           K <= lastClassTemplateSpecialization;
   }
 
   static bool classof(const ClassTemplateSpecializationDecl *) {
@@ -1011,6 +1438,11 @@
   TemplateArgumentLoc *ArgsAsWritten;
   unsigned NumArgsAsWritten;
 
+  /// \brief Sequence number indicating when this class template partial
+  /// specialization was added to the set of partial specializations for
+  /// its owning class template.
+  unsigned SequenceNumber;
+    
   /// \brief The class template partial specialization from which this 
   /// class template partial specialization was instantiated.
   ///
@@ -1019,46 +1451,75 @@
   llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
       InstantiatedFromMember;
     
-  ClassTemplatePartialSpecializationDecl(ASTContext &Context,
+  ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
                                          DeclContext *DC, SourceLocation L,
                                          TemplateParameterList *Params,
                                          ClassTemplateDecl *SpecializedTemplate,
                                          TemplateArgumentListBuilder &Builder,
                                          TemplateArgumentLoc *ArgInfos,
                                          unsigned NumArgInfos,
-                               ClassTemplatePartialSpecializationDecl *PrevDecl)
+                               ClassTemplatePartialSpecializationDecl *PrevDecl,
+                                         unsigned SequenceNumber)
     : ClassTemplateSpecializationDecl(Context,
                                       ClassTemplatePartialSpecialization,
-                                      DC, L, SpecializedTemplate, Builder,
+                                      TK, DC, L, SpecializedTemplate, Builder,
                                       PrevDecl),
       TemplateParams(Params), ArgsAsWritten(ArgInfos),
-      NumArgsAsWritten(NumArgInfos), InstantiatedFromMember(0, false) { }
+      NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
+      InstantiatedFromMember(0, false) { }
+  
+  ClassTemplatePartialSpecializationDecl()
+    : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
+      TemplateParams(0), ArgsAsWritten(0),
+      NumArgsAsWritten(0), SequenceNumber(0),
+      InstantiatedFromMember(0, false) { }
 
 public:
   static ClassTemplatePartialSpecializationDecl *
-  Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
+  Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
          TemplateParameterList *Params,
          ClassTemplateDecl *SpecializedTemplate,
          TemplateArgumentListBuilder &Builder,
          const TemplateArgumentListInfo &ArgInfos,
          QualType CanonInjectedType,
-         ClassTemplatePartialSpecializationDecl *PrevDecl);
+         ClassTemplatePartialSpecializationDecl *PrevDecl,
+         unsigned SequenceNumber);
+
+  static ClassTemplatePartialSpecializationDecl *
+  Create(ASTContext &Context, EmptyShell Empty);
+
+  ClassTemplatePartialSpecializationDecl *getMostRecentDeclaration() {
+    return cast<ClassTemplatePartialSpecializationDecl>(
+                   ClassTemplateSpecializationDecl::getMostRecentDeclaration());
+  }
 
   /// Get the list of template parameters
   TemplateParameterList *getTemplateParameters() const {
     return TemplateParams;
   }
 
+  void initTemplateParameters(TemplateParameterList *Params) {
+    assert(TemplateParams == 0 && "TemplateParams already set");
+    TemplateParams = Params;
+  }
+
   /// Get the template arguments as written.
   TemplateArgumentLoc *getTemplateArgsAsWritten() const {
     return ArgsAsWritten;
   }
 
+  void initTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgInfos);
+
   /// Get the number of template arguments as written.
   unsigned getNumTemplateArgsAsWritten() const {
     return NumArgsAsWritten;
   }
 
+  /// \brief Get the sequence number for this class template partial
+  /// specialization.
+  unsigned getSequenceNumber() const { return SequenceNumber; }
+  void setSequenceNumber(unsigned N) { SequenceNumber = N; }
+    
   /// \brief Retrieve the member class template partial specialization from
   /// which this particular class template partial specialization was
   /// instantiated.
@@ -1145,13 +1606,16 @@
 };
 
 /// Declaration of a class template.
-class ClassTemplateDecl : public TemplateDecl {
+class ClassTemplateDecl : public RedeclarableTemplateDecl,
+                          public RedeclarableTemplate<ClassTemplateDecl> {
+  static void DeallocateCommon(void *Ptr);
+  
 protected:
+  typedef RedeclarableTemplate<ClassTemplateDecl> redeclarable_base;
+
   /// \brief Data that is common to all of the declarations of a given
   /// class template.
-  struct Common {
-    Common() : InstantiatedFromMember(0, 0) {}
-
+  struct Common : CommonBase {
     /// \brief The class template specializations for this class
     /// template, including explicit specializations and instantiations.
     llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
@@ -1163,35 +1627,29 @@
 
     /// \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 Retrieve the set of specializations of this class template.
+  llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
+    return getCommonPtr()->Specializations;
+  }
 
-  /// \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;
+  /// \brief Retrieve the set of partial specializations of this class
+  /// template.
+  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
+  getPartialSpecializations() {
+    return getCommonPtr()->PartialSpecializations;
+  }
 
   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) { }
+                    TemplateParameterList *Params, NamedDecl *Decl)
+    : RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
 
-  ~ClassTemplateDecl();
+  CommonBase *newCommon();
+
+  Common *getCommonPtr() {
+    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
+  }
 
 public:
   /// Get the underlying class declarations of the template.
@@ -1199,13 +1657,6 @@
     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,
@@ -1214,27 +1665,84 @@
                                    NamedDecl *Decl,
                                    ClassTemplateDecl *PrevDecl);
 
-  /// \brief Retrieve the set of specializations of this class template.
-  llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
-    return CommonPtr->Specializations;
+  /// \brief Return the specialization with the provided arguments if it exists,
+  /// otherwise return the insertion point.
+  ClassTemplateSpecializationDecl *
+  findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
+                     void *&InsertPos);
+
+  /// \brief Insert the specified specialization knowing that it is not already
+  /// in. InsertPos must be obtained from findSpecialization.
+  void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos) {
+    getSpecializations().InsertNode(D, InsertPos);
   }
 
-  /// \brief Retrieve the set of partial specializations of this class
-  /// template.
-  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
-  getPartialSpecializations() {
-    return CommonPtr->PartialSpecializations;
+  ClassTemplateDecl *getCanonicalDecl() {
+    return redeclarable_base::getCanonicalDecl();
+  }
+  const ClassTemplateDecl *getCanonicalDecl() const {
+    return redeclarable_base::getCanonicalDecl();
   }
 
+  /// \brief Retrieve the previous declaration of this class template, or
+  /// NULL if no such declaration exists.
+  ClassTemplateDecl *getPreviousDeclaration() {
+    return redeclarable_base::getPreviousDeclaration();
+  }
+
+  /// \brief Retrieve the previous declaration of this class template, or
+  /// NULL if no such declaration exists.
+  const ClassTemplateDecl *getPreviousDeclaration() const {
+    return redeclarable_base::getPreviousDeclaration();
+  }
+
+  ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
+    return redeclarable_base::getInstantiatedFromMemberTemplate();
+  }
+
+  /// \brief Return the partial specialization with the provided arguments if it
+  /// exists, otherwise return the insertion point.
+  ClassTemplatePartialSpecializationDecl *
+  findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
+                            void *&InsertPos);
+
+  /// \brief Insert the specified partial specialization knowing that it is not
+  /// already in. InsertPos must be obtained from findPartialSpecialization.
+  void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
+                                void *InsertPos) {
+    getPartialSpecializations().InsertNode(D, InsertPos);
+  }
+
+  /// \brief Return the next partial specialization sequence number.
+  unsigned getNextPartialSpecSequenceNumber() {
+    return getPartialSpecializations().size();
+  }
+
+  /// \brief Retrieve the partial specializations as an ordered list.
+  void getPartialSpecializations(
+          llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
+  
   /// \brief Find a class template partial specialization with the given
   /// type T.
   ///
-  /// \brief A dependent type that names a specialization of this class
+  /// \param T 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 Find a class template partial specialization which was instantiated
+  /// from the given member partial specialization.
+  ///
+  /// \param D a member class template partial specialization.
+  ///
+  /// \returns the class template partial specialization which was instantiated
+  /// from the given member partial specialization, or NULL if no such partial
+  /// specialization exists.
+  ClassTemplatePartialSpecializationDecl *
+  findPartialSpecInstantiatedFromMember(
+                                     ClassTemplatePartialSpecializationDecl *D);
 
   /// \brief Retrieve the template specialization type of the
   /// injected-class-name for this class template.
@@ -1250,69 +1758,36 @@
   ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
   /// };
   /// \endcode
-  QualType getInjectedClassNameSpecialization(ASTContext &Context);
+  QualType getInjectedClassNameSpecialization();
 
-  /// \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();
+  typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
+
+  spec_iterator spec_begin() {
+    return makeSpecIterator(getSpecializations(), false);
   }
 
-  void setInstantiatedFromMemberTemplate(ClassTemplateDecl *CTD) {
-    assert(!CommonPtr->InstantiatedFromMember.getPointer());
-    CommonPtr->InstantiatedFromMember.setPointer(CTD);
+  spec_iterator spec_end() {
+    return makeSpecIterator(getSpecializations(), true);
   }
 
-  /// \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();
+  typedef SpecIterator<ClassTemplatePartialSpecializationDecl>
+          partial_spec_iterator;
+
+  partial_spec_iterator partial_spec_begin() {
+    return makeSpecIterator(getPartialSpecializations(), false);
   }
-  
-  /// \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);
+
+  partial_spec_iterator partial_spec_end() {
+    return makeSpecIterator(getPartialSpecializations(), 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);
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 /// Declaration of a friend template.  For example:
@@ -1351,6 +1826,12 @@
       FriendLoc(FriendLoc)
   {}
 
+  FriendTemplateDecl(EmptyShell Empty)
+    : Decl(Decl::FriendTemplate, Empty),
+      NumParams(0),
+      Params(0)
+  {}
+
 public:
   static FriendTemplateDecl *Create(ASTContext &Context,
                                     DeclContext *DC, SourceLocation Loc,
@@ -1359,6 +1840,8 @@
                                     FriendUnion Friend,
                                     SourceLocation FriendLoc);
 
+  static FriendTemplateDecl *Create(ASTContext &Context, EmptyShell Empty);
+
   /// If this friend declaration names a templated type (or
   /// a dependent member type of a templated type), return that
   /// type;  otherwise return null.
@@ -1391,6 +1874,8 @@
   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; }
+
+  friend class ASTDeclReader;
 };
 
 /// Implementation of inline functions that require the template declarations
diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h
index 140e5c0..aee1998 100644
--- a/include/clang/AST/DeclVisitor.h
+++ b/include/clang/AST/DeclVisitor.h
@@ -30,20 +30,19 @@
 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"
+      default: assert(false && "Decl that isn't part of DeclNodes.inc!");
+#define DECL(DERIVED, BASE) \
+      case Decl::DERIVED: DISPATCH(DERIVED##Decl, DERIVED##Decl);
+#define ABSTRACT_DECL(DECL)
+#include "clang/AST/DeclNodes.inc"
     }
   }
 
   // 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"
+#define DECL(DERIVED, BASE) \
+  RetTy Visit##DERIVED##Decl(DERIVED##Decl *D) { DISPATCH(BASE, BASE); }
+#include "clang/AST/DeclNodes.inc"
 
   RetTy VisitDecl(Decl *D) { return RetTy(); }
 };
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 9401786..8bb6275 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -30,6 +30,7 @@
   class IdentifierInfo;
   class MultiKeywordSelector;
   class UsingDirectiveDecl;
+  class TypeSourceInfo;
 
 /// DeclarationName - The name of a declaration. In the common case,
 /// this just stores an IdentifierInfo pointer to a normal
@@ -314,15 +315,16 @@
 /// retrieved using its member functions (e.g.,
 /// getCXXConstructorName).
 class DeclarationNameTable {
+  ASTContext &Ctx;
   void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
   CXXOperatorIdName *CXXOperatorNames; // Operator names
-  void *CXXLiteralOperatorNames; // Actually a FoldingSet<...> *
+  void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
 
   DeclarationNameTable(const DeclarationNameTable&);            // NONCOPYABLE
   DeclarationNameTable& operator=(const DeclarationNameTable&); // NONCOPYABLE
 
 public:
-  DeclarationNameTable();
+  DeclarationNameTable(ASTContext &C);
   ~DeclarationNameTable();
 
   /// getIdentifier - Create a declaration name that is a simple
@@ -366,6 +368,146 @@
   DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
 };
 
+/// DeclarationNameLoc - Additional source/type location info
+/// for a declaration name. Needs a DeclarationName in order
+/// to be interpreted correctly.
+struct DeclarationNameLoc {
+  union {
+    // The source location for identifier stored elsewhere.
+    // struct {} Identifier;
+
+    // Type info for constructors, destructors and conversion functions.
+    // Locations (if any) for the tilde (destructor) or operator keyword
+    // (conversion) are stored elsewhere.
+    struct {
+      TypeSourceInfo* TInfo;
+    } NamedType;
+
+    // The location (if any) of the operator keyword is stored elsewhere.
+    struct {
+      unsigned BeginOpNameLoc;
+      unsigned EndOpNameLoc;
+    } CXXOperatorName;
+
+    // The location (if any) of the operator keyword is stored elsewhere.
+    struct {
+      unsigned OpNameLoc;
+    } CXXLiteralOperatorName;
+
+    // struct {} CXXUsingDirective;
+    // struct {} ObjCZeroArgSelector;
+    // struct {} ObjCOneArgSelector;
+    // struct {} ObjCMultiArgSelector;
+  };
+
+  DeclarationNameLoc(DeclarationName Name);
+  // FIXME: this should go away once all DNLocs are properly initialized.
+  DeclarationNameLoc() { NamedType.TInfo = 0; }
+}; // struct DeclarationNameLoc
+
+
+/// DeclarationNameInfo - A collector data type for bundling together
+/// a DeclarationName and the correspnding source/type location info.
+struct DeclarationNameInfo {
+private:
+  /// Name - The declaration name, also encoding name kind.
+  DeclarationName Name;
+  /// Loc - The main source location for the declaration name.
+  SourceLocation NameLoc;
+  /// Info - Further source/type location info for special kinds of names.
+  DeclarationNameLoc LocInfo;
+
+public:
+  // FIXME: remove it.
+  DeclarationNameInfo() {}
+
+  DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc)
+    : Name(Name), NameLoc(NameLoc), LocInfo(Name) {}
+
+  DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc,
+                      DeclarationNameLoc LocInfo)
+    : Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {}
+
+  /// getName - Returns the embedded declaration name.
+  DeclarationName getName() const { return Name; }
+  /// setName - Sets the embedded declaration name.
+  void setName(DeclarationName N) { Name = N; }
+
+  /// getLoc - Returns the main location of the declaration name.
+  SourceLocation getLoc() const { return NameLoc; }
+  /// setLoc - Sets the main location of the declaration name.
+  void setLoc(SourceLocation L) { NameLoc = L; }
+
+  const DeclarationNameLoc &getInfo() const { return LocInfo; }
+  DeclarationNameLoc &getInfo() { return LocInfo; }
+  void setInfo(const DeclarationNameLoc &Info) { LocInfo = Info; }
+
+  /// getNamedTypeInfo - Returns the source type info associated to
+  /// the name. Assumes it is a constructor, destructor or conversion.
+  TypeSourceInfo *getNamedTypeInfo() const {
+    assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
+           Name.getNameKind() == DeclarationName::CXXDestructorName ||
+           Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
+    return LocInfo.NamedType.TInfo;
+  }
+  /// setNamedTypeInfo - Sets the source type info associated to
+  /// the name. Assumes it is a constructor, destructor or conversion.
+  void setNamedTypeInfo(TypeSourceInfo *TInfo) {
+    assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
+           Name.getNameKind() == DeclarationName::CXXDestructorName ||
+           Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
+    LocInfo.NamedType.TInfo = TInfo;
+  }
+
+  /// getCXXOperatorNameRange - Gets the range of the operator name
+  /// (without the operator keyword). Assumes it is a (non-literal) operator.
+  SourceRange getCXXOperatorNameRange() const {
+    assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
+    return SourceRange(
+     SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.BeginOpNameLoc),
+     SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
+                       );
+  }
+  /// setCXXOperatorNameRange - Sets the range of the operator name
+  /// (without the operator keyword). Assumes it is a C++ operator.
+  void setCXXOperatorNameRange(SourceRange R) {
+    assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
+    LocInfo.CXXOperatorName.BeginOpNameLoc = R.getBegin().getRawEncoding();
+    LocInfo.CXXOperatorName.EndOpNameLoc = R.getEnd().getRawEncoding();
+  }
+
+  /// getCXXLiteralOperatorNameLoc - Returns the location of the literal
+  /// operator name (not the operator keyword).
+  /// Assumes it is a literal operator.
+  SourceLocation getCXXLiteralOperatorNameLoc() const {
+    assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
+    return SourceLocation::
+      getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
+  }
+  /// setCXXLiteralOperatorNameLoc - Sets the location of the literal
+  /// operator name (not the operator keyword).
+  /// Assumes it is a literal operator.
+  void setCXXLiteralOperatorNameLoc(SourceLocation Loc) {
+    assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
+    LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
+  }
+
+  /// getAsString - 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;
+
+  /// getBeginLoc - Retrieve the location of the first token.
+  SourceLocation getBeginLoc() const { return NameLoc; }
+  /// getEndLoc - Retrieve the location of the last token.
+  SourceLocation getEndLoc() const;
+  /// getSourceRange - The range of the declaration name.
+  SourceRange getSourceRange() const {
+    return SourceRange(getBeginLoc(), getEndLoc());
+  }
+};
+
 /// Insertion operator for diagnostics.  This allows sending DeclarationName's
 /// into a diagnostic with <<.
 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
@@ -384,6 +526,12 @@
   return PD;
 }
 
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                                     DeclarationNameInfo DNInfo) {
+  DNInfo.printName(OS);
+  return OS;
+}
+
 }  // end namespace clang
 
 namespace llvm {
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index d824a56..9ec1451 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -18,6 +18,7 @@
 #include "clang/AST/Stmt.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/DeclAccessPair.h"
+#include "clang/AST/OperationKinds.h"
 #include "clang/AST/ASTVector.h"
 #include "clang/AST/UsuallyTinyPtrVector.h"
 #include "llvm/ADT/APSInt.h"
@@ -42,7 +43,7 @@
   class TemplateArgumentListInfo;
 
 /// \brief A simple array of base specifiers.
-typedef UsuallyTinyPtrVector<const CXXBaseSpecifier> CXXBaseSpecifierArray;
+typedef llvm::SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
 
 /// 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
@@ -51,6 +52,7 @@
 class Expr : public Stmt {
   QualType TR;
 
+  virtual void ANCHOR(); // key function.
 protected:
   /// TypeDependent - Whether this expression is type-dependent
   /// (C++ [temp.dep.expr]).
@@ -60,8 +62,14 @@
   /// (C++ [temp.dep.constexpr]).
   bool ValueDependent : 1;
 
+  /// ValueKind - The value classification of this expression.
+  /// Only actually used by certain subclasses.
+  unsigned ValueKind : 2;
+
+  enum { BitsRemaining = 28 };
+
   Expr(StmtClass SC, QualType T, bool TD, bool VD)
-    : Stmt(SC), TypeDependent(TD), ValueDependent(VD) {
+    : Stmt(SC), TypeDependent(TD), ValueDependent(VD), ValueKind(0) {
     setType(T);
   }
 
@@ -161,9 +169,6 @@
   };
   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,
@@ -193,6 +198,94 @@
   isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
                                               SourceLocation *Loc = 0) const;
 
+  /// \brief The return type of classify(). Represents the C++0x expression
+  ///        taxonomy.
+  class Classification {
+  public:
+    /// \brief The various classification results. Most of these mean prvalue.
+    enum Kinds {
+      CL_LValue,
+      CL_XValue,
+      CL_Function, // Functions cannot be lvalues in C.
+      CL_Void, // Void cannot be an lvalue in C.
+      CL_DuplicateVectorComponents, // A vector shuffle with dupes.
+      CL_MemberFunction, // An expression referring to a member function
+      CL_SubObjCPropertySetting,
+      CL_ClassTemporary, // A prvalue of class type
+      CL_PRValue // A prvalue for any other reason, of any other type
+    };
+    /// \brief The results of modification testing.
+    enum ModifiableType {
+      CM_Untested, // testModifiable was false.
+      CM_Modifiable,
+      CM_RValue, // Not modifiable because it's an rvalue
+      CM_Function, // Not modifiable because it's a function; C++ only
+      CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext
+      CM_NotBlockQualified, // Not captured in the closure
+      CM_NoSetterProperty,// Implicit assignment to ObjC property without setter
+      CM_ConstQualified,
+      CM_ArrayType,
+      CM_IncompleteType
+    };
+
+  private:
+    friend class Expr;
+
+    unsigned short Kind;
+    unsigned short Modifiable;
+
+    explicit Classification(Kinds k, ModifiableType m)
+      : Kind(k), Modifiable(m)
+    {}
+
+  public:
+    Classification() {}
+
+    Kinds getKind() const { return static_cast<Kinds>(Kind); }
+    ModifiableType getModifiable() const {
+      assert(Modifiable != CM_Untested && "Did not test for modifiability.");
+      return static_cast<ModifiableType>(Modifiable);
+    }
+    bool isLValue() const { return Kind == CL_LValue; }
+    bool isXValue() const { return Kind == CL_XValue; }
+    bool isGLValue() const { return Kind <= CL_XValue; }
+    bool isPRValue() const { return Kind >= CL_Function; }
+    bool isRValue() const { return Kind >= CL_XValue; }
+    bool isModifiable() const { return getModifiable() == CM_Modifiable; }
+  };
+  /// \brief classify - Classify this expression according to the C++0x
+  ///        expression taxonomy.
+  ///
+  /// C++0x defines ([basic.lval]) a new taxonomy of expressions to replace the
+  /// old lvalue vs rvalue. This function determines the type of expression this
+  /// is. There are three expression types:
+  /// - lvalues are classical lvalues as in C++03.
+  /// - prvalues are equivalent to rvalues in C++03.
+  /// - xvalues are expressions yielding unnamed rvalue references, e.g. a
+  ///   function returning an rvalue reference.
+  /// lvalues and xvalues are collectively referred to as glvalues, while
+  /// prvalues and xvalues together form rvalues.
+  Classification Classify(ASTContext &Ctx) const {
+    return ClassifyImpl(Ctx, 0);
+  }
+
+  /// \brief classifyModifiable - Classify this expression according to the
+  ///        C++0x expression taxonomy, and see if it is valid on the left side
+  ///        of an assignment.
+  ///
+  /// This function extends classify in that it also tests whether the
+  /// expression is modifiable (C99 6.3.2.1p1).
+  /// \param Loc A source location that might be filled with a relevant location
+  ///            if the expression is not modifiable.
+  Classification ClassifyModifiable(ASTContext &Ctx, SourceLocation &Loc) const{
+    return ClassifyImpl(Ctx, &Loc);
+  }
+
+private:
+  Classification ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const;
+
+public:
+
   /// \brief If this expression refers to a bit-field, retrieve the
   /// declaration of that bit-field.
   FieldDecl *getBitField();
@@ -223,7 +316,7 @@
   }
   /// isConstantInitializer - Returns true if this expression is a constant
   /// initializer, which can be emitted at compile-time.
-  bool isConstantInitializer(ASTContext &Ctx) const;
+  bool isConstantInitializer(ASTContext &Ctx, bool ForRef) const;
 
   /// EvalResult is a struct with detailed info about an evaluated expression.
   struct EvalResult {
@@ -247,6 +340,15 @@
     SourceLocation DiagLoc;
 
     EvalResult() : HasSideEffects(false), Diag(0), DiagExpr(0) {}
+
+    // isGlobalLValue - Return true if the evaluated lvalue expression
+    // is global.
+    bool isGlobalLValue() const;
+    // hasSideEffects - Return true if the evaluated expression has
+    // side effects.
+    bool hasSideEffects() const {
+      return HasSideEffects;
+    }
   };
 
   /// Evaluate - Return true if this is a constant which we can fold using
@@ -255,10 +357,6 @@
   /// 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.
@@ -282,8 +380,7 @@
   /// 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.
+  /// EvaluateAsLValue - Evaluate an expression to see if it's a lvalue.
   bool EvaluateAsAnyLValue(EvalResult &Result, ASTContext &Ctx) const;
 
   /// \brief Enumeration used to describe how \c isNullPointerConstant()
@@ -321,6 +418,10 @@
   /// or CastExprs, returning their operand.
   Expr *IgnoreParenCasts();
 
+  /// IgnoreParenImpCasts - Ignore parentheses and implicit casts.  Strip off any
+  /// ParenExpr or ImplicitCastExprs, returning their operand.
+  Expr *IgnoreParenImpCasts();
+
   /// 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.
@@ -405,6 +506,7 @@
 
   void initializeFrom(const TemplateArgumentListInfo &List);
   void copyInto(TemplateArgumentListInfo &List) const;
+  static std::size_t sizeFor(unsigned NumTemplateArgs);
   static std::size_t sizeFor(const TemplateArgumentListInfo &List);
 };
   
@@ -425,10 +527,14 @@
   // (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;
 
+  /// DNLoc - Provides source/type location info for the
+  /// declaration name embedded in DecoratedD.
+  DeclarationNameLoc DNLoc;
+
   /// \brief Retrieve the qualifier that preceded the declaration name, if any.
   NameQualifier *getNameQualifier() {
     if ((DecoratedD.getInt() & HasQualifierFlag) == 0)
@@ -441,51 +547,31 @@
   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);
+
+  DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
+              ValueDecl *D, const DeclarationNameInfo &NameInfo,
+              const TemplateArgumentListInfo *TemplateArgs,
+              QualType T);
+
+  /// \brief Construct an empty declaration reference expression.
+  explicit DeclRefExpr(EmptyShell Empty)
+    : Expr(DeclRefExprClass, Empty) { }
   
-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,
@@ -493,11 +579,27 @@
                              SourceLocation NameLoc,
                              QualType T,
                              const TemplateArgumentListInfo *TemplateArgs = 0);
+
+  static DeclRefExpr *Create(ASTContext &Context,
+                             NestedNameSpecifier *Qualifier,
+                             SourceRange QualifierRange,
+                             ValueDecl *D,
+                             const DeclarationNameInfo &NameInfo,
+                             QualType T,
+                             const TemplateArgumentListInfo *TemplateArgs = 0);
+
+  /// \brief Construct an empty declaration reference expression.
+  static DeclRefExpr *CreateEmpty(ASTContext &Context,
+                                  bool HasQualifier, unsigned NumTemplateArgs);
   
   ValueDecl *getDecl() { return DecoratedD.getPointer(); }
   const ValueDecl *getDecl() const { return DecoratedD.getPointer(); }
   void setDecl(ValueDecl *NewD) { DecoratedD.setPointer(NewD); }
 
+  DeclarationNameInfo getNameInfo() const {
+    return DeclarationNameInfo(getDecl()->getDeclName(), Loc, DNLoc);
+  }
+
   SourceLocation getLocation() const { return Loc; }
   void setLocation(SourceLocation L) { Loc = L; }
   virtual SourceRange getSourceRange() const;
@@ -525,53 +627,77 @@
     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;
+  bool hasExplicitTemplateArgs() const {
+    return (DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag);
+  }
+  
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name.
+  ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+    assert(hasExplicitTemplateArgs());
+
+    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.
+  const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+    return const_cast<DeclRefExpr *>(this)->getExplicitTemplateArgs();
   }
 
+  /// \brief Retrieves the optional explicit template arguments.
+  /// This points to the same data as getExplicitTemplateArgs(), but
+  /// returns null if there are no explicit template arguments.
+  const ExplicitTemplateArgumentList *getExplicitTemplateArgsOpt() const {
+    if (!hasExplicitTemplateArgs()) return 0;
+    return &getExplicitTemplateArgs();
+  }
+  
   /// \brief Copies the template arguments (if present) into the given
   /// structure.
   void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
-    if (hasExplicitTemplateArgumentList())
-      getExplicitTemplateArgumentList()->copyInto(List);
+    if (hasExplicitTemplateArgs())
+      getExplicitTemplateArgs().copyInto(List);
   }
   
   /// \brief Retrieve the location of the left angle bracket following the
   /// member name ('<'), if any.
   SourceLocation getLAngleLoc() const {
-    if (!hasExplicitTemplateArgumentList())
+    if (!hasExplicitTemplateArgs())
       return SourceLocation();
     
-    return getExplicitTemplateArgumentList()->LAngleLoc;
+    return getExplicitTemplateArgs().LAngleLoc;
   }
   
   /// \brief Retrieve the template arguments provided as part of this
   /// template-id.
   const TemplateArgumentLoc *getTemplateArgs() const {
-    if (!hasExplicitTemplateArgumentList())
+    if (!hasExplicitTemplateArgs())
       return 0;
     
-    return getExplicitTemplateArgumentList()->getTemplateArgs();
+    return getExplicitTemplateArgs().getTemplateArgs();
   }
   
   /// \brief Retrieve the number of template arguments provided as part of this
   /// template-id.
   unsigned getNumTemplateArgs() const {
-    if (!hasExplicitTemplateArgumentList())
+    if (!hasExplicitTemplateArgs())
       return 0;
     
-    return getExplicitTemplateArgumentList()->NumTemplateArgs;
+    return getExplicitTemplateArgs().NumTemplateArgs;
   }
   
   /// \brief Retrieve the location of the right angle bracket following the
   /// template arguments ('>').
   SourceLocation getRAngleLoc() const {
-    if (!hasExplicitTemplateArgumentList())
+    if (!hasExplicitTemplateArgs())
       return SourceLocation();
     
-    return getExplicitTemplateArgumentList()->RAngleLoc;
+    return getExplicitTemplateArgs().RAngleLoc;
   }
   
   static bool classof(const Stmt *T) {
@@ -582,6 +708,9 @@
   // Iterators
   virtual child_iterator child_begin();
   virtual child_iterator child_end();
+  
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
 };
 
 /// PredefinedExpr - [C99 6.4.2.2] - A predefined identifier such as __func__.
@@ -628,28 +757,84 @@
   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 Used by IntegerLiteral/FloatingLiteral to store the numeric without
+/// leaking memory.
+///
+/// For large floats/integers, APFloat/APInt will allocate memory from the heap
+/// to represent these numbers.  Unfortunately, when we use a BumpPtrAllocator
+/// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
+/// the APFloat/APInt values will never get freed. APNumericStorage uses
+/// ASTContext's allocator for memory allocation.
+class APNumericStorage {
+  unsigned BitWidth;
+  union {
+    uint64_t VAL;    ///< Used to store the <= 64 bits integer value.
+    uint64_t *pVal;  ///< Used to store the >64 bits integer value.
+  };
+
+  bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
+
+  APNumericStorage(const APNumericStorage&); // do not implement
+  APNumericStorage& operator=(const APNumericStorage&); // do not implement
+
+protected:
+  APNumericStorage() : BitWidth(0), VAL(0) { }
+
+  llvm::APInt getIntValue() const {
+    unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
+    if (NumWords > 1)
+      return llvm::APInt(BitWidth, NumWords, pVal);
+    else
+      return llvm::APInt(BitWidth, VAL);
   }
+  void setIntValue(ASTContext &C, const llvm::APInt &Val);
+};
+
+class APIntStorage : public APNumericStorage {
+public:  
+  llvm::APInt getValue() const { return getIntValue(); } 
+  void setValue(ASTContext &C, const llvm::APInt &Val) { setIntValue(C, Val); }
+};
+
+class APFloatStorage : public APNumericStorage {
+public:  
+  llvm::APFloat getValue() const { return llvm::APFloat(getIntValue()); } 
+  void setValue(ASTContext &C, const llvm::APFloat &Val) {
+    setIntValue(C, Val.bitcastToAPInt());
+  }
+};
+
+class IntegerLiteral : public Expr {
+  APIntStorage Num;
+  SourceLocation Loc;
 
   /// \brief Construct an empty integer literal.
   explicit IntegerLiteral(EmptyShell Empty)
     : Expr(IntegerLiteralClass, Empty) { }
 
-  const llvm::APInt &getValue() const { return Value; }
+public:
+  // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
+  // or UnsignedLongLongTy
+  IntegerLiteral(ASTContext &C, const llvm::APInt &V,
+                 QualType type, SourceLocation l)
+    : Expr(IntegerLiteralClass, type, false, false), Loc(l) {
+    assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
+    setValue(C, V);
+  }
+
+  // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
+  // or UnsignedLongLongTy
+  static IntegerLiteral *Create(ASTContext &C, const llvm::APInt &V,
+                                QualType type, SourceLocation l);
+  static IntegerLiteral *Create(ASTContext &C, EmptyShell Empty);
+
+  llvm::APInt getValue() const { return Num.getValue(); }
   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 setValue(ASTContext &C, const llvm::APInt &Val) { Num.setValue(C, Val); }
   void setLocation(SourceLocation Location) { Loc = Location; }
 
   static bool classof(const Stmt *T) {
@@ -698,21 +883,30 @@
 };
 
 class FloatingLiteral : public Expr {
-  llvm::APFloat Value;
+  APFloatStorage Num;
   bool IsExact : 1;
   SourceLocation Loc;
-public:
-  FloatingLiteral(const llvm::APFloat &V, bool isexact,
+
+  FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact,
                   QualType Type, SourceLocation L)
-    : Expr(FloatingLiteralClass, Type, false, false), Value(V),
-      IsExact(isexact), Loc(L) {}
+    : Expr(FloatingLiteralClass, Type, false, false),
+      IsExact(isexact), Loc(L) {
+    setValue(C, V);
+  }
 
   /// \brief Construct an empty floating-point literal.
   explicit FloatingLiteral(EmptyShell Empty)
-    : Expr(FloatingLiteralClass, Empty), Value(0.0) { }
+    : Expr(FloatingLiteralClass, Empty), IsExact(false) { }
 
-  const llvm::APFloat &getValue() const { return Value; }
-  void setValue(const llvm::APFloat &Val) { Value = Val; }
+public:
+  static FloatingLiteral *Create(ASTContext &C, const llvm::APFloat &V,
+                                 bool isexact, QualType Type, SourceLocation L);
+  static FloatingLiteral *Create(ASTContext &C, EmptyShell Empty);
+
+  llvm::APFloat getValue() const { return Num.getValue(); }
+  void setValue(ASTContext &C, const llvm::APFloat &Val) {
+    Num.setValue(C, Val);
+  }
 
   bool isExact() const { return IsExact; }
   void setExact(bool E) { IsExact = E; }
@@ -792,9 +986,6 @@
 
   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.
@@ -815,8 +1006,7 @@
   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.
@@ -912,40 +1102,27 @@
 ///   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
-  };
+  typedef UnaryOperatorKind Opcode;
+
 private:
-  Stmt *Val;
-  Opcode Opc;
+  unsigned Opc : 5;
   SourceLocation Loc;
+  Stmt *Val;
 public:
 
   UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l)
     : Expr(UnaryOperatorClass, type,
-           input->isTypeDependent() && opc != OffsetOf,
+           input->isTypeDependent() || type->isDependentType(),
            input->isValueDependent()),
-      Val(input), Opc(opc), Loc(l) {}
+      Opc(opc), Loc(l), Val(input) {}
 
   /// \brief Build an empty unary operator.
   explicit UnaryOperator(EmptyShell Empty)
-    : Expr(UnaryOperatorClass, Empty), Opc(AddrOf) { }
+    : Expr(UnaryOperatorClass, Empty), Opc(UO_AddrOf) { }
 
-  Opcode getOpcode() const { return Opc; }
+  Opcode getOpcode() const { return static_cast<Opcode>(Opc); }
   void setOpcode(Opcode O) { Opc = O; }
 
   Expr *getSubExpr() const { return cast<Expr>(Val); }
@@ -957,21 +1134,26 @@
 
   /// isPostfix - Return true if this is a postfix operation, like x++.
   static bool isPostfix(Opcode Op) {
-    return Op == PostInc || Op == PostDec;
+    return Op == UO_PostInc || Op == UO_PostDec;
   }
 
   /// isPostfix - Return true if this is a prefix operation, like --x.
   static bool isPrefix(Opcode Op) {
-    return Op == PreInc || Op == PreDec;
+    return Op == UO_PreInc || Op == UO_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); }
+  bool isPrefix() const { return isPrefix(getOpcode()); }
+  bool isPostfix() const { return isPostfix(getOpcode()); }
+  bool isIncrementOp() const {
+    return Opc == UO_PreInc || Opc == UO_PostInc;
+  }
+  bool isIncrementDecrementOp() const {
+    return Opc <= UO_PreDec;
+  }
+  static bool isArithmeticOp(Opcode Op) {
+    return Op >= UO_Plus && Op <= UO_LNot;
+  }
+  bool isArithmeticOp() const { return isArithmeticOp(getOpcode()); }
 
   /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
   /// corresponds to, e.g. "sizeof" or "[pre]++"
@@ -1003,6 +1185,205 @@
   virtual child_iterator child_end();
 };
 
+/// OffsetOfExpr - [C99 7.17] - This represents an expression of the form
+/// offsetof(record-type, member-designator). For example, given:
+/// @code
+/// struct S {
+///   float f;
+///   double d;    
+/// };
+/// struct T {
+///   int i;
+///   struct S s[10];
+/// };
+/// @endcode
+/// we can represent and evaluate the expression @c offsetof(struct T, s[2].d). 
+
+class OffsetOfExpr : public Expr {
+public:
+  // __builtin_offsetof(type, identifier(.identifier|[expr])*)
+  class OffsetOfNode {
+  public:
+    /// \brief The kind of offsetof node we have.
+    enum Kind {
+      /// \brief An index into an array.
+      Array = 0x00,
+      /// \brief A field.
+      Field = 0x01,
+      /// \brief A field in a dependent type, known only by its name.
+      Identifier = 0x02,
+      /// \brief An implicit indirection through a C++ base class, when the
+      /// field found is in a base class.
+      Base = 0x03
+    };
+
+  private:
+    enum { MaskBits = 2, Mask = 0x03 };
+    
+    /// \brief The source range that covers this part of the designator.
+    SourceRange Range;
+    
+    /// \brief The data describing the designator, which comes in three
+    /// different forms, depending on the lower two bits.
+    ///   - An unsigned index into the array of Expr*'s stored after this node 
+    ///     in memory, for [constant-expression] designators.
+    ///   - A FieldDecl*, for references to a known field.
+    ///   - An IdentifierInfo*, for references to a field with a given name
+    ///     when the class type is dependent.
+    ///   - A CXXBaseSpecifier*, for references that look at a field in a 
+    ///     base class.
+    uintptr_t Data;
+    
+  public:
+    /// \brief Create an offsetof node that refers to an array element.
+    OffsetOfNode(SourceLocation LBracketLoc, unsigned Index, 
+                 SourceLocation RBracketLoc)
+      : Range(LBracketLoc, RBracketLoc), Data((Index << 2) | Array) { }
+    
+    /// \brief Create an offsetof node that refers to a field.
+    OffsetOfNode(SourceLocation DotLoc, FieldDecl *Field, 
+                 SourceLocation NameLoc)
+      : Range(DotLoc.isValid()? DotLoc : NameLoc, NameLoc), 
+        Data(reinterpret_cast<uintptr_t>(Field) | OffsetOfNode::Field) { }
+    
+    /// \brief Create an offsetof node that refers to an identifier.
+    OffsetOfNode(SourceLocation DotLoc, IdentifierInfo *Name,
+                 SourceLocation NameLoc)
+      : Range(DotLoc.isValid()? DotLoc : NameLoc, NameLoc), 
+        Data(reinterpret_cast<uintptr_t>(Name) | Identifier) { }
+
+    /// \brief Create an offsetof node that refers into a C++ base class.
+    explicit OffsetOfNode(const CXXBaseSpecifier *Base)
+      : Range(), Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {}
+    
+    /// \brief Determine what kind of offsetof node this is.
+    Kind getKind() const { 
+      return static_cast<Kind>(Data & Mask);
+    }
+    
+    /// \brief For an array element node, returns the index into the array
+    /// of expressions.
+    unsigned getArrayExprIndex() const {
+      assert(getKind() == Array);
+      return Data >> 2;
+    }
+
+    /// \brief For a field offsetof node, returns the field.
+    FieldDecl *getField() const {
+      assert(getKind() == Field);
+      return reinterpret_cast<FieldDecl *>(Data & ~(uintptr_t)Mask);
+    }
+    
+    /// \brief For a field or identifier offsetof node, returns the name of
+    /// the field.
+    IdentifierInfo *getFieldName() const;
+    
+    /// \brief For a base class node, returns the base specifier.
+    CXXBaseSpecifier *getBase() const {
+      assert(getKind() == Base);
+      return reinterpret_cast<CXXBaseSpecifier *>(Data & ~(uintptr_t)Mask);      
+    }
+    
+    /// \brief Retrieve the source range that covers this offsetof node.
+    ///
+    /// For an array element node, the source range contains the locations of
+    /// the square brackets. For a field or identifier node, the source range
+    /// contains the location of the period (if there is one) and the 
+    /// identifier.
+    SourceRange getRange() const { return Range; }
+  };
+
+private:
+  
+  SourceLocation OperatorLoc, RParenLoc;
+  // Base type;
+  TypeSourceInfo *TSInfo;
+  // Number of sub-components (i.e. instances of OffsetOfNode).
+  unsigned NumComps;
+  // Number of sub-expressions (i.e. array subscript expressions).
+  unsigned NumExprs;
+  
+  OffsetOfExpr(ASTContext &C, QualType type, 
+               SourceLocation OperatorLoc, TypeSourceInfo *tsi,
+               OffsetOfNode* compsPtr, unsigned numComps, 
+               Expr** exprsPtr, unsigned numExprs,
+               SourceLocation RParenLoc);
+
+  explicit OffsetOfExpr(unsigned numComps, unsigned numExprs)
+    : Expr(OffsetOfExprClass, EmptyShell()),
+      TSInfo(0), NumComps(numComps), NumExprs(numExprs) {}  
+
+public:
+  
+  static OffsetOfExpr *Create(ASTContext &C, QualType type, 
+                              SourceLocation OperatorLoc, TypeSourceInfo *tsi, 
+                              OffsetOfNode* compsPtr, unsigned numComps, 
+                              Expr** exprsPtr, unsigned numExprs,
+                              SourceLocation RParenLoc);
+
+  static OffsetOfExpr *CreateEmpty(ASTContext &C, 
+                                   unsigned NumComps, unsigned NumExprs);
+
+  /// getOperatorLoc - Return the location of the operator.
+  SourceLocation getOperatorLoc() const { return OperatorLoc; }
+  void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
+
+  /// \brief Return the location of the right parentheses.
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation R) { RParenLoc = R; }
+  
+  TypeSourceInfo *getTypeSourceInfo() const {
+    return TSInfo;
+  }
+  void setTypeSourceInfo(TypeSourceInfo *tsi) {
+    TSInfo = tsi;
+  }
+  
+  const OffsetOfNode &getComponent(unsigned Idx) {
+    assert(Idx < NumComps && "Subscript out of range");
+    return reinterpret_cast<OffsetOfNode *> (this + 1)[Idx];
+  }
+
+  void setComponent(unsigned Idx, OffsetOfNode ON) {
+    assert(Idx < NumComps && "Subscript out of range");
+    reinterpret_cast<OffsetOfNode *> (this + 1)[Idx] = ON;
+  }
+  
+  unsigned getNumComponents() const {
+    return NumComps;
+  }
+
+  Expr* getIndexExpr(unsigned Idx) {
+    assert(Idx < NumExprs && "Subscript out of range");
+    return reinterpret_cast<Expr **>(
+                    reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx];
+  }
+
+  void setIndexExpr(unsigned Idx, Expr* E) {
+    assert(Idx < NumComps && "Subscript out of range");
+    reinterpret_cast<Expr **>(
+                reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx] = E;
+  }
+  
+  unsigned getNumExpressions() const {
+    return NumExprs;
+  }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(OperatorLoc, RParenLoc);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OffsetOfExprClass;
+  }
+
+  static bool classof(const OffsetOfExpr *) { 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 {
@@ -1014,9 +1395,6 @@
   } Argument;
   SourceLocation OpLoc, RParenLoc;
 
-protected:
-  virtual void DoDestroy(ASTContext& C);
-
 public:
   SizeOfAlignOfExpr(bool issizeof, TypeSourceInfo *TInfo,
                     QualType resultType, SourceLocation op,
@@ -1189,8 +1567,6 @@
   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);
@@ -1198,8 +1574,6 @@
   /// \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; }
@@ -1269,13 +1643,10 @@
   }
 
   static bool classof(const Stmt *T) {
-    return T->getStmtClass() == CallExprClass ||
-           T->getStmtClass() == CXXOperatorCallExprClass ||
-           T->getStmtClass() == CXXMemberCallExprClass;
+    return T->getStmtClass() >= firstCallExprConstant &&
+           T->getStmtClass() <= lastCallExprConstant;
   }
   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();
@@ -1301,6 +1672,10 @@
   /// MemberLoc - This is the location of the member name.
   SourceLocation MemberLoc;
 
+  /// MemberDNLoc - Provides source/type location info for the
+  /// declaration name embedded in MemberDecl.
+  DeclarationNameLoc MemberDNLoc;
+
   /// IsArrow - True if this is "X->F", false if this is "X.F".
   bool IsArrow : 1;
 
@@ -1328,42 +1703,33 @@
     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,
+             const DeclarationNameInfo &NameInfo, QualType ty)
+    : Expr(MemberExprClass, ty,
+           base->isTypeDependent(), base->isValueDependent()),
+      Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()),
+      MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow),
+      HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {
+    assert(memberdecl->getDeclName() == NameInfo.getName());
+  }
+
+  // NOTE: this constructor should be used only when it is known that
+  // the member name can not provide additional syntactic info
+  // (i.e., source locations for C++ operator names or type source info
+  // for constructors, destructors and conversion oeprators).
+  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),
+      Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(),
+      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,
+                            DeclarationNameInfo MemberNameInfo,
                             const TemplateArgumentListInfo *targs,
                             QualType ty);
 
@@ -1412,15 +1778,42 @@
 
   /// \brief Determines whether this member expression actually had a C++
   /// template argument list explicitly specified, e.g., x.f<int>.
-  bool hasExplicitTemplateArgumentList() const {
+  bool hasExplicitTemplateArgs() const {
     return HasExplicitTemplateArgumentList;
   }
 
   /// \brief Copies the template arguments (if present) into the given
   /// structure.
   void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
-    if (hasExplicitTemplateArgumentList())
-      getExplicitTemplateArgumentList()->copyInto(List);
+    if (hasExplicitTemplateArgs())
+      getExplicitTemplateArgs().copyInto(List);
+  }
+
+  /// \brief Retrieve the explicit template argument list that
+  /// follow the member template name.  This must only be called on an
+  /// expression with explicit template arguments.
+  ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+    assert(HasExplicitTemplateArgumentList);
+    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.  This must only be called on
+  /// an expression with explicit template arguments.
+  const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+    return const_cast<MemberExpr *>(this)->getExplicitTemplateArgs();
+  }
+
+  /// \brief Retrieves the optional explicit template arguments.
+  /// This points to the same data as getExplicitTemplateArgs(), but
+  /// returns null if there are no explicit template arguments.
+  const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() const {
+    if (!hasExplicitTemplateArgs()) return 0;
+    return &getExplicitTemplateArgs();
   }
   
   /// \brief Retrieve the location of the left angle bracket following the
@@ -1429,7 +1822,7 @@
     if (!HasExplicitTemplateArgumentList)
       return SourceLocation();
 
-    return getExplicitTemplateArgumentList()->LAngleLoc;
+    return getExplicitTemplateArgs().LAngleLoc;
   }
 
   /// \brief Retrieve the template arguments provided as part of this
@@ -1438,7 +1831,7 @@
     if (!HasExplicitTemplateArgumentList)
       return 0;
 
-    return getExplicitTemplateArgumentList()->getTemplateArgs();
+    return getExplicitTemplateArgs().getTemplateArgs();
   }
 
   /// \brief Retrieve the number of template arguments provided as part of this
@@ -1447,7 +1840,7 @@
     if (!HasExplicitTemplateArgumentList)
       return 0;
 
-    return getExplicitTemplateArgumentList()->NumTemplateArgs;
+    return getExplicitTemplateArgs().NumTemplateArgs;
   }
 
   /// \brief Retrieve the location of the right angle bracket following the
@@ -1456,7 +1849,13 @@
     if (!HasExplicitTemplateArgumentList)
       return SourceLocation();
 
-    return getExplicitTemplateArgumentList()->RAngleLoc;
+    return getExplicitTemplateArgs().RAngleLoc;
+  }
+
+  /// \brief Retrieve the member declaration name info.
+  DeclarationNameInfo getMemberNameInfo() const {
+    return DeclarationNameInfo(MemberDecl->getDeclName(),
+                               MemberLoc, MemberDNLoc);
   }
 
   bool isArrow() const { return IsArrow; }
@@ -1470,9 +1869,8 @@
   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 EndLoc = (HasExplicitTemplateArgumentList)
+      ? getRAngleLoc() : getMemberNameInfo().getEndLoc();
 
     SourceLocation BaseLoc = getBase()->getLocStart();
     if (BaseLoc.isInvalid())
@@ -1555,106 +1953,13 @@
 /// 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
-
-  };
+  typedef clang::CastKind CastKind;
 
 private:
-  CastKind Kind;
+  unsigned Kind : 5;
+  unsigned BasePathSize : BitsRemaining - 5;
   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()) {
@@ -1663,12 +1968,13 @@
     case CK_DerivedToBaseMemberPointer:
     case CK_BaseToDerived:
     case CK_BaseToDerivedMemberPointer:
-      assert(!BasePath.empty() && "Cast kind should have a base path!");
+      assert(!path_empty() && "Cast kind should have a base path!");
       break;
 
     // These should not have an inheritance path.
     case CK_Unknown:
     case CK_BitCast:
+    case CK_LValueBitCast:
     case CK_NoOp:
     case CK_Dynamic:
     case CK_ToUnion:
@@ -1688,15 +1994,21 @@
     case CK_MemberPointerToBoolean:
     case CK_AnyPointerToObjCPointerCast:
     case CK_AnyPointerToBlockPointerCast:
-      assert(BasePath.empty() && "Cast kind should not have a base path!");
+    case CK_ObjCObjectLValueCast:
+      assert(path_empty() && "Cast kind should not have a base path!");
       break;
     }
 #endif
   }
 
+  const CXXBaseSpecifier * const *path_buffer() const {
+    return const_cast<CastExpr*>(this)->path_buffer();
+  }
+  CXXBaseSpecifier **path_buffer();
+
 protected:
   CastExpr(StmtClass SC, QualType ty, const CastKind kind, Expr *op,
-           CXXBaseSpecifierArray BasePath) :
+           unsigned BasePathSize) :
     Expr(SC, ty,
          // Cast expressions are type-dependent if the type is
          // dependent (C++ [temp.dep.expr]p3).
@@ -1704,18 +2016,16 @@
          // 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();
-    }
+    Kind(kind), BasePathSize(BasePathSize), Op(op) {
+    CheckBasePath();
+  }
 
   /// \brief Construct an empty cast.
-  CastExpr(StmtClass SC, EmptyShell Empty)
-    : Expr(SC, Empty) { }
-
-  virtual void DoDestroy(ASTContext &C);
+  CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
+    : Expr(SC, Empty), BasePathSize(BasePathSize) { }
 
 public:
-  CastKind getCastKind() const { return Kind; }
+  CastKind getCastKind() const { return static_cast<CastKind>(Kind); }
   void setCastKind(CastKind K) { Kind = K; }
   const char *getCastKindName() const;
 
@@ -1731,17 +2041,20 @@
     return const_cast<CastExpr *>(this)->getSubExprAsWritten();
   }
 
-  const CXXBaseSpecifierArray& getBasePath() const { return BasePath; }
+  typedef CXXBaseSpecifier **path_iterator;
+  typedef const CXXBaseSpecifier * const *path_const_iterator;
+  bool path_empty() const { return BasePathSize == 0; }
+  unsigned path_size() const { return BasePathSize; }
+  path_iterator path_begin() { return path_buffer(); }
+  path_iterator path_end() { return path_buffer() + path_size(); }
+  path_const_iterator path_begin() const { return path_buffer(); }
+  path_const_iterator path_end() const { return path_buffer() + path_size(); }
+
+  void setCastPath(const CXXCastPath &Path);
 
   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;
+    return T->getStmtClass() >= firstCastExprConstant &&
+           T->getStmtClass() <= lastCastExprConstant;
   }
   static bool classof(const CastExpr *) { return true; }
 
@@ -1757,38 +2070,57 @@
 ///
 /// 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:
+/// an lvalue or xvalue. For example:
 ///
 /// @code
 /// class Base { };
 /// class Derived : public Base { };
+/// Derived &&ref();
 /// void f(Derived d) {
-///   Base& b = d; // initializer is an ImplicitCastExpr to an lvalue of type Base
+///   Base& b = d; // initializer is an ImplicitCastExpr
+///                // to an lvalue of type Base
+///   Base&& r = ref(); // initializer is an ImplicitCastExpr
+///                     // to an xvalue 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) { }
+private:
+  ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
+                   unsigned BasePathLength, ExprValueKind VK)
+    : CastExpr(ImplicitCastExprClass, ty, kind, op, BasePathLength) {
+    ValueKind = VK;
+  }
 
   /// \brief Construct an empty implicit cast.
-  explicit ImplicitCastExpr(EmptyShell Shell)
-    : CastExpr(ImplicitCastExprClass, Shell) { }
+  explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize)
+    : CastExpr(ImplicitCastExprClass, Shell, PathSize) { }
+
+public:
+  enum OnStack_t { OnStack };
+  ImplicitCastExpr(OnStack_t _, QualType ty, CastKind kind, Expr *op,
+                   ExprValueKind VK)
+    : CastExpr(ImplicitCastExprClass, ty, kind, op, 0) {
+    ValueKind = VK;
+  }
+
+  static ImplicitCastExpr *Create(ASTContext &Context, QualType T,
+                                  CastKind Kind, Expr *Operand,
+                                  const CXXCastPath *BasePath,
+                                  ExprValueKind Cat);
+
+  static ImplicitCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize);
 
   virtual SourceRange getSourceRange() const {
     return getSubExpr()->getSourceRange();
   }
 
-  /// isLvalueCast - Whether this cast produces an lvalue.
-  bool isLvalueCast() const { return LvalueCast; }
+  /// getValueKind - The value kind that this cast produces.
+  ExprValueKind getValueKind() const {
+    return static_cast<ExprValueKind>(ValueKind);
+  }
 
-  /// setLvalueCast - Set whether this cast produces an lvalue.
-  void setLvalueCast(bool Lvalue) { LvalueCast = Lvalue; }
+  /// setValueKind - Set the value kind this cast produces.
+  void setValueKind(ExprValueKind Cat) { ValueKind = Cat; }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == ImplicitCastExprClass;
@@ -1810,8 +2142,8 @@
 /// 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.
+/// expression will be an lvalue or xvalue. 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.
@@ -1819,13 +2151,12 @@
 
 protected:
   ExplicitCastExpr(StmtClass SC, QualType exprTy, CastKind kind,
-                   Expr *op, CXXBaseSpecifierArray BasePath,
-                   TypeSourceInfo *writtenTy)
-    : CastExpr(SC, exprTy, kind, op, BasePath), TInfo(writtenTy) {}
+                   Expr *op, unsigned PathSize, TypeSourceInfo *writtenTy)
+    : CastExpr(SC, exprTy, kind, op, PathSize), TInfo(writtenTy) {}
 
   /// \brief Construct an empty explicit cast.
-  ExplicitCastExpr(StmtClass SC, EmptyShell Shell)
-    : CastExpr(SC, Shell) { }
+  ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
+    : CastExpr(SC, Shell, PathSize) { }
 
 public:
   /// getTypeInfoAsWritten - Returns the type source info for the type
@@ -1838,13 +2169,8 @@
   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;
+     return T->getStmtClass() >= firstExplicitCastExprConstant &&
+            T->getStmtClass() <= lastExplicitCastExprConstant;
   }
   static bool classof(const ExplicitCastExpr *) { return true; }
 };
@@ -1855,16 +2181,24 @@
 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,
+                 unsigned PathSize, TypeSourceInfo *writtenTy,
                  SourceLocation l, SourceLocation r)
-    : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, BasePath,
+    : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, PathSize,
                        writtenTy), LPLoc(l), RPLoc(r) {}
 
   /// \brief Construct an empty C-style explicit cast.
-  explicit CStyleCastExpr(EmptyShell Shell)
-    : ExplicitCastExpr(CStyleCastExprClass, Shell) { }
+  explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize)
+    : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }
+
+public:
+  static CStyleCastExpr *Create(ASTContext &Context, QualType T, CastKind K,
+                                Expr *Op, const CXXCastPath *BasePath,
+                                TypeSourceInfo *WrittenTy, SourceLocation L,
+                                SourceLocation R);
+
+  static CStyleCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize);
 
   SourceLocation getLParenLoc() const { return LPLoc; }
   void setLParenLoc(SourceLocation L) { LPLoc = L; }
@@ -1901,33 +2235,14 @@
 /// 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.
-  };
+  typedef BinaryOperatorKind Opcode;
+
 private:
+  unsigned Opc : 6;
+  SourceLocation OpLoc;
+
   enum { LHS, RHS, END_EXPR };
   Stmt* SubExprs[END_EXPR];
-  Opcode Opc;
-  SourceLocation OpLoc;
 public:
 
   BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
@@ -1944,12 +2259,12 @@
 
   /// \brief Construct an empty binary operator.
   explicit BinaryOperator(EmptyShell Empty)
-    : Expr(BinaryOperatorClass, Empty), Opc(Comma) { }
+    : Expr(BinaryOperatorClass, Empty), Opc(BO_Comma) { }
 
   SourceLocation getOperatorLoc() const { return OpLoc; }
   void setOperatorLoc(SourceLocation L) { OpLoc = L; }
 
-  Opcode getOpcode() const { return Opc; }
+  Opcode getOpcode() const { return static_cast<Opcode>(Opc); }
   void setOpcode(Opcode O) { Opc = O; }
 
   Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
@@ -1965,6 +2280,8 @@
   /// corresponds to, e.g. "<<=".
   static const char *getOpcodeStr(Opcode Op);
 
+  const char *getOpcodeStr() const { return getOpcodeStr(getOpcode()); }
+
   /// \brief Retrieve the binary opcode that corresponds to the given
   /// overloaded operator.
   static Opcode getOverloadedOpcode(OverloadedOperatorKind OO);
@@ -1974,33 +2291,38 @@
   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); }
+  bool isMultiplicativeOp() const { return Opc >= BO_Mul && Opc <= BO_Rem; }
+  static bool isAdditiveOp(Opcode Opc) { return Opc == BO_Add || Opc==BO_Sub; }
+  bool isAdditiveOp() const { return isAdditiveOp(getOpcode()); }
+  static bool isShiftOp(Opcode Opc) { return Opc == BO_Shl || Opc == BO_Shr; }
+  bool isShiftOp() const { return isShiftOp(getOpcode()); }
 
-  static bool isBitwiseOp(Opcode Opc) { return Opc >= And && Opc <= Or; }
-  bool isBitwiseOp() const { return isBitwiseOp(Opc); }
+  static bool isBitwiseOp(Opcode Opc) { return Opc >= BO_And && Opc <= BO_Or; }
+  bool isBitwiseOp() const { return isBitwiseOp(getOpcode()); }
 
-  static bool isRelationalOp(Opcode Opc) { return Opc >= LT && Opc <= GE; }
-  bool isRelationalOp() const { return isRelationalOp(Opc); }
+  static bool isRelationalOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_GE; }
+  bool isRelationalOp() const { return isRelationalOp(getOpcode()); }
 
-  static bool isEqualityOp(Opcode Opc) { return Opc == EQ || Opc == NE; }
-  bool isEqualityOp() const { return isEqualityOp(Opc); }
+  static bool isEqualityOp(Opcode Opc) { return Opc == BO_EQ || Opc == BO_NE; }
+  bool isEqualityOp() const { return isEqualityOp(getOpcode()); }
 
-  static bool isComparisonOp(Opcode Opc) { return Opc >= LT && Opc <= NE; }
-  bool isComparisonOp() const { return isComparisonOp(Opc); }
+  static bool isComparisonOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_NE; }
+  bool isComparisonOp() const { return isComparisonOp(getOpcode()); }
 
-  static bool isLogicalOp(Opcode Opc) { return Opc == LAnd || Opc == LOr; }
-  bool isLogicalOp() const { return isLogicalOp(Opc); }
+  static bool isLogicalOp(Opcode Opc) { return Opc == BO_LAnd || Opc==BO_LOr; }
+  bool isLogicalOp() const { return isLogicalOp(getOpcode()); }
 
-  bool isAssignmentOp() const { return Opc >= Assign && Opc <= OrAssign; }
-  bool isCompoundAssignmentOp() const { return Opc > Assign && Opc <= OrAssign;}
-  bool isShiftAssignOp() const { return Opc == ShlAssign || Opc == ShrAssign; }
+  bool isAssignmentOp() const { return Opc >= BO_Assign && Opc <= BO_OrAssign; }
+  bool isCompoundAssignmentOp() const {
+    return Opc > BO_Assign && Opc <= BO_OrAssign;
+  }
+  bool isShiftAssignOp() const {
+    return Opc == BO_ShlAssign || Opc == BO_ShrAssign;
+  }
 
   static bool classof(const Stmt *S) {
-    return S->getStmtClass() == BinaryOperatorClass ||
-           S->getStmtClass() == CompoundAssignOperatorClass;
+    return S->getStmtClass() >= firstBinaryOperatorConstant &&
+           S->getStmtClass() <= lastBinaryOperatorConstant;
   }
   static bool classof(const BinaryOperator *) { return true; }
 
@@ -2020,7 +2342,7 @@
   }
 
   BinaryOperator(StmtClass SC, EmptyShell Empty)
-    : Expr(SC, Empty), Opc(MulAssign) { }
+    : Expr(SC, Empty), Opc(BO_MulAssign) { }
 };
 
 /// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
@@ -2216,23 +2538,27 @@
 /// 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;
+  TypeSourceInfo *TInfo1;
+  TypeSourceInfo *TInfo2;
   SourceLocation BuiltinLoc, RParenLoc;
 public:
   TypesCompatibleExpr(QualType ReturnType, SourceLocation BLoc,
-                      QualType t1, QualType t2, SourceLocation RP) :
+                      TypeSourceInfo *tinfo1, TypeSourceInfo *tinfo2,
+                      SourceLocation RP) :
     Expr(TypesCompatibleExprClass, ReturnType, false, false),
-    Type1(t1), Type2(t2), BuiltinLoc(BLoc), RParenLoc(RP) {}
+    TInfo1(tinfo1), TInfo2(tinfo2), 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; }
+  TypeSourceInfo *getArgTInfo1() const { return TInfo1; }
+  void setArgTInfo1(TypeSourceInfo *TInfo) { TInfo1 = TInfo; }
+  TypeSourceInfo *getArgTInfo2() const { return TInfo2; }
+  void setArgTInfo2(TypeSourceInfo *TInfo) { TInfo2 = TInfo; }
+
+  QualType getArgType1() const { return TInfo1->getType(); }
+  QualType getArgType2() const { return TInfo2->getType(); }
 
   SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
   void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
@@ -2269,9 +2595,6 @@
   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?
@@ -2304,8 +2627,6 @@
   }
   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.
@@ -2432,11 +2753,13 @@
 /// VAArgExpr, used for the builtin function __builtin_va_arg.
 class VAArgExpr : public Expr {
   Stmt *Val;
+  TypeSourceInfo *TInfo;
   SourceLocation BuiltinLoc, RParenLoc;
 public:
-  VAArgExpr(SourceLocation BLoc, Expr* e, QualType t, SourceLocation RPLoc)
+  VAArgExpr(SourceLocation BLoc, Expr* e, TypeSourceInfo *TInfo,
+            SourceLocation RPLoc, QualType t)
     : Expr(VAArgExprClass, t, t->isDependentType(), false),
-      Val(e),
+      Val(e), TInfo(TInfo),
       BuiltinLoc(BLoc),
       RParenLoc(RPLoc) { }
 
@@ -2447,6 +2770,9 @@
   Expr *getSubExpr() { return cast<Expr>(Val); }
   void setSubExpr(Expr *E) { Val = E; }
 
+  TypeSourceInfo *getWrittenTypeInfo() const { return TInfo; }
+  void setWrittenTypeInfo(TypeSourceInfo *TI) { TInfo = TI; }
+
   SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
   void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
 
@@ -2612,12 +2938,18 @@
   virtual child_iterator child_end();
 
   typedef InitExprsTy::iterator iterator;
+  typedef InitExprsTy::const_iterator const_iterator;
   typedef InitExprsTy::reverse_iterator reverse_iterator;
+  typedef InitExprsTy::const_reverse_iterator const_reverse_iterator;
 
   iterator begin() { return InitExprs.begin(); }
+  const_iterator begin() const { return InitExprs.begin(); }
   iterator end() { return InitExprs.end(); }
+  const_iterator end() const { return InitExprs.end(); }
   reverse_iterator rbegin() { return InitExprs.rbegin(); }
+  const_reverse_iterator rbegin() const { return InitExprs.rbegin(); }
   reverse_iterator rend() { return InitExprs.rend(); }
+  const_reverse_iterator rend() const { return InitExprs.rend(); }
 };
 
 /// @brief Represents a C99 designated initializer expression.
@@ -2677,11 +3009,6 @@
     : 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 {
@@ -2949,17 +3276,12 @@
   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) { }
+  explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
 
   unsigned getNumExprs() const { return NumExprs; }
 
@@ -2989,6 +3311,9 @@
   // Iterators
   virtual child_iterator child_begin();
   virtual child_iterator child_end();
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
 };
 
 
@@ -3111,12 +3436,15 @@
   SourceLocation Loc;
   bool IsByRef : 1;
   bool ConstQualAdded : 1;
+  Stmt *CopyConstructorVal;
 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) {}
+                   bool constAdded = false,
+                   Stmt *copyConstructorVal = 0)
+  : Expr(BlockDeclRefExprClass, t, (!t.isNull() && t->isDependentType()),false), 
+    D(d), Loc(l), IsByRef(ByRef),
+    ConstQualAdded(constAdded),  CopyConstructorVal(copyConstructorVal) {}
 
   // \brief Build an empty reference to a declared variable in a
   // block.
@@ -3137,6 +3465,12 @@
 
   bool isConstQualAdded() const { return ConstQualAdded; }
   void setConstQualAdded(bool C) { ConstQualAdded = C; }
+  
+  const Expr *getCopyConstructorExpr() const 
+    { return cast_or_null<Expr>(CopyConstructorVal); }
+  Expr *getCopyConstructorExpr() 
+    { return cast_or_null<Expr>(CopyConstructorVal); }
+  void setCopyConstructorExpr(Expr *E) { CopyConstructorVal = E; }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == BlockDeclRefExprClass;
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index d66642c..450348b 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -88,10 +88,13 @@
 /// the object argument).
 class CXXMemberCallExpr : public CallExpr {
 public:
-  CXXMemberCallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs,
+  CXXMemberCallExpr(ASTContext &C, Expr *fn, Expr **args, unsigned numargs,
                     QualType t, SourceLocation rparenloc)
     : CallExpr(C, CXXMemberCallExprClass, fn, args, numargs, t, rparenloc) {}
 
+  CXXMemberCallExpr(ASTContext &C, EmptyShell Empty)
+    : CallExpr(C, CXXMemberCallExprClass, Empty) { }
+
   /// getImplicitObjectArgument - Retrieves the implicit object
   /// argument for the member call. For example, in "x.f(5)", this
   /// operation would return "x".
@@ -118,12 +121,12 @@
 
 protected:
   CXXNamedCastExpr(StmtClass SC, QualType ty, CastKind kind, Expr *op,
-                   CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+                   unsigned PathSize, TypeSourceInfo *writtenTy,
                    SourceLocation l)
-    : ExplicitCastExpr(SC, ty, kind, op, BasePath, writtenTy), Loc(l) {}
+    : ExplicitCastExpr(SC, ty, kind, op, PathSize, writtenTy), Loc(l) {}
 
-  explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell)
-    : ExplicitCastExpr(SC, Shell) { }
+  explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
+    : ExplicitCastExpr(SC, Shell, PathSize) { }
 
 public:
   const char *getCastName() const;
@@ -155,14 +158,22 @@
 /// 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,
+                    unsigned pathSize, TypeSourceInfo *writtenTy,
                     SourceLocation l)
-    : CXXNamedCastExpr(CXXStaticCastExprClass, ty, kind, op, BasePath, writtenTy, l) {}
+    : CXXNamedCastExpr(CXXStaticCastExprClass, ty, kind, op, pathSize,
+                       writtenTy, l) {}
 
-  explicit CXXStaticCastExpr(EmptyShell Empty)
-    : CXXNamedCastExpr(CXXStaticCastExprClass, Empty) { }
+  explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
+    : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) { }
+
+public:
+  static CXXStaticCastExpr *Create(ASTContext &Context, QualType T,
+                                   CastKind K, Expr *Op,
+                                   const CXXCastPath *Path,
+                                   TypeSourceInfo *Written, SourceLocation L);
+  static CXXStaticCastExpr *CreateEmpty(ASTContext &Context,
+                                        unsigned PathSize);
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXStaticCastExprClass;
@@ -177,15 +188,23 @@
 /// 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,
+                     unsigned pathSize, TypeSourceInfo *writtenTy,
                      SourceLocation l)
-    : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, kind, op, BasePath,
+    : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, kind, op, pathSize,
                        writtenTy, l) {}
 
-  explicit CXXDynamicCastExpr(EmptyShell Empty)
-    : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty) { }
+  explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
+    : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) { }
+
+public:
+  static CXXDynamicCastExpr *Create(ASTContext &Context, QualType T,
+                                    CastKind Kind, Expr *Op,
+                                    const CXXCastPath *Path,
+                                    TypeSourceInfo *Written, SourceLocation L);
+  
+  static CXXDynamicCastExpr *CreateEmpty(ASTContext &Context,
+                                         unsigned pathSize);
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXDynamicCastExprClass;
@@ -200,15 +219,22 @@
 /// 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,
+                         unsigned pathSize,
                          TypeSourceInfo *writtenTy, SourceLocation l)
-    : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op, BasePath,
+    : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op, pathSize,
                        writtenTy, l) {}
 
-  explicit CXXReinterpretCastExpr(EmptyShell Empty)
-    : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty) { }
+  CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
+    : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { }
+
+public:
+  static CXXReinterpretCastExpr *Create(ASTContext &Context, QualType T,
+                                        CastKind Kind, Expr *Op,
+                                        const CXXCastPath *Path,
+                                 TypeSourceInfo *WrittenTy, SourceLocation L);
+  static CXXReinterpretCastExpr *CreateEmpty(ASTContext &Context,
+                                             unsigned pathSize);
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXReinterpretCastExprClass;
@@ -222,14 +248,18 @@
 /// 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) {}
+                       0, writtenTy, l) {}
 
   explicit CXXConstCastExpr(EmptyShell Empty)
-    : CXXNamedCastExpr(CXXConstCastExprClass, Empty) { }
+    : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { }
+
+public:
+  static CXXConstCastExpr *Create(ASTContext &Context, QualType T, Expr *Op,
+                                  TypeSourceInfo *WrittenTy, SourceLocation L);
+  static CXXConstCastExpr *CreateEmpty(ASTContext &Context);
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXConstCastExprClass;
@@ -318,6 +348,14 @@
         Operand->isTypeDependent() || Operand->isValueDependent()),
       Operand(Operand), Range(R) { }
 
+  CXXTypeidExpr(EmptyShell Empty, bool isExpr)
+    : Expr(CXXTypeidExprClass, Empty) {
+    if (isExpr)
+      Operand = (Expr*)0;
+    else
+      Operand = (TypeSourceInfo*)0;
+  }
+  
   bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
   
   /// \brief Retrieves the type operand of this typeid() expression after
@@ -329,15 +367,25 @@
     assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
     return Operand.get<TypeSourceInfo *>();
   }
+
+  void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
+    assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
+    Operand = TSI;
+  }
   
-  Expr* getExprOperand() const {
+  Expr *getExprOperand() const {
     assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
     return static_cast<Expr*>(Operand.get<Stmt *>());
   }
-
-  virtual SourceRange getSourceRange() const {
-    return Range;
+  
+  void setExprOperand(Expr *E) {
+    assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
+    Operand = E;
   }
+  
+  virtual SourceRange getSourceRange() const { return Range; }
+  void setSourceRange(SourceRange R) { Range = R; }
+  
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXTypeidExprClass;
   }
@@ -371,6 +419,11 @@
            Type->isDependentType(), Type->isDependentType()),
       Loc(L), Implicit(isImplicit) { }
 
+  CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
   virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
 
   bool isImplicit() const { return Implicit; }
@@ -399,6 +452,8 @@
   // 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) {}
+  CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
+
   const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); }
   Expr *getSubExpr() { return cast_or_null<Expr>(Op); }
   void setSubExpr(Expr *E) { Op = E; }
@@ -437,7 +492,6 @@
   /// \brief The location where the default argument expression was used.
   SourceLocation Loc;
   
-protected:
   CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param)
     : Expr(SC, 
            param->hasUnparsedDefaultArg()
@@ -448,15 +502,14 @@
 
   CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param, 
                     Expr *SubExpr)
-    : Expr(SC, SubExpr->getType(), false, false), Param(param, true), Loc(Loc)
-  {
+    : Expr(SC, SubExpr->getType(), false, false), Param(param, true), Loc(Loc) {
     *reinterpret_cast<Expr **>(this + 1) = SubExpr;
   }
   
-protected:
-  virtual void DoDestroy(ASTContext &C);
-  
 public:
+  CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}
+
+  
   // Param is the parameter whose default argument is used by this
   // expression.
   static CXXDefaultArgExpr *Create(ASTContext &C, SourceLocation Loc,
@@ -474,7 +527,7 @@
   // 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())
@@ -505,6 +558,9 @@
   // Iterators
   virtual child_iterator child_begin();
   virtual child_iterator child_end();
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
 };
 
 /// CXXTemporary - Represents a C++ temporary.
@@ -514,19 +570,28 @@
 
   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.
+/// \brief Represents binding an expression to a temporary.
+///
+/// This ensures the destructor is called for the temporary. It should only be
+/// needed for non-POD, non-trivially destructable class types. For example:
+///
+/// \code
+///   struct S {
+///     S() { }  // User defined constructor makes S non-POD.
+///     ~S() { } // User defined destructor makes it non-trivial.
+///   };
+///   void test() {
+///     const S &s_ref = S(); // Requires a CXXBindTemporaryExpr.
+///   }
+/// \endcode
 class CXXBindTemporaryExpr : public Expr {
   CXXTemporary *Temp;
 
@@ -535,17 +600,17 @@
   CXXBindTemporaryExpr(CXXTemporary *temp, Expr* subexpr)
    : Expr(CXXBindTemporaryExprClass, subexpr->getType(), false, false),
      Temp(temp), SubExpr(subexpr) { }
-  ~CXXBindTemporaryExpr() { }
-
-protected:
-  virtual void DoDestroy(ASTContext &C);
 
 public:
+  CXXBindTemporaryExpr(EmptyShell Empty)
+    : Expr(CXXBindTemporaryExprClass, Empty), Temp(0), SubExpr(0) {}
+  
   static CXXBindTemporaryExpr *Create(ASTContext &C, CXXTemporary *Temp,
                                       Expr* SubExpr);
 
   CXXTemporary *getTemporary() { return Temp; }
   const CXXTemporary *getTemporary() const { return Temp; }
+  void setTemporary(CXXTemporary *T) { Temp = T; }
 
   const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
   Expr *getSubExpr() { return cast<Expr>(SubExpr); }
@@ -572,8 +637,8 @@
 /// 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).
+/// a reference, and that a temporary needs to be created to hold the
+/// value.
 class CXXBindReferenceExpr : public Expr {
   // SubExpr - The expression being bound.
   Stmt *SubExpr;
@@ -591,15 +656,14 @@
   : 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);
+  
+  explicit CXXBindReferenceExpr(EmptyShell Empty)
+    : Expr(CXXBindReferenceExprClass, Empty) { }
 
   const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
   Expr *getSubExpr() { return cast<Expr>(SubExpr); }
@@ -615,7 +679,7 @@
 
   // extendsLifetime - Whether binding this reference extends the lifetime of
   // the expression being bound. FIXME: Add C++ reference.
-  bool extendsLifetime() { return ExtendsLifetime; }
+  bool extendsLifetime() const { return ExtendsLifetime; }
     
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Stmt *T) {
@@ -626,16 +690,26 @@
   // Iterators
   virtual child_iterator child_begin();
   virtual child_iterator child_end();
+  
+  friend class ASTStmtReader;
 };
 
 /// CXXConstructExpr - Represents a call to a C++ constructor.
 class CXXConstructExpr : public Expr {
+public:
+  enum ConstructionKind {
+    CK_Complete,
+    CK_NonVirtualBase,
+    CK_VirtualBase
+  };
+    
+private:
   CXXConstructorDecl *Constructor;
 
   SourceLocation Loc;
   bool Elidable : 1;
   bool ZeroInitialization : 1;
-  bool BaseInitialization : 1;
+  unsigned ConstructKind : 2;
   Stmt **Args;
   unsigned NumArgs;
 
@@ -645,22 +719,26 @@
                    CXXConstructorDecl *d, bool elidable,
                    Expr **args, unsigned numargs,
                    bool ZeroInitialization = false,
-                   bool BaseInitialization = false);
-  ~CXXConstructExpr() { }
+                   ConstructionKind ConstructKind = CK_Complete);
 
-  virtual void DoDestroy(ASTContext &C);
+  /// \brief Construct an empty C++ construction expression.
+  CXXConstructExpr(StmtClass SC, EmptyShell Empty)
+    : Expr(SC, Empty), Constructor(0), Elidable(0), ZeroInitialization(0),
+      ConstructKind(0), Args(0), NumArgs(0) { }
 
 public:
-  /// \brief Construct an empty C++ construction expression that will store
-  /// \p numargs arguments.
-  CXXConstructExpr(EmptyShell Empty, ASTContext &C, unsigned numargs);
-  
+  /// \brief Construct an empty C++ construction expression.
+  explicit CXXConstructExpr(EmptyShell Empty)
+    : Expr(CXXConstructExprClass, Empty), Constructor(0),
+      Elidable(0), ZeroInitialization(0),
+      ConstructKind(0), Args(0), NumArgs(0) { }
+
   static CXXConstructExpr *Create(ASTContext &C, QualType T,
                                   SourceLocation Loc,
                                   CXXConstructorDecl *D, bool Elidable,
                                   Expr **Args, unsigned NumArgs,
                                   bool ZeroInitialization = false,
-                                  bool BaseInitialization = false);
+                                  ConstructionKind ConstructKind = CK_Complete);
 
 
   CXXConstructorDecl* getConstructor() const { return Constructor; }
@@ -682,8 +760,12 @@
   
   /// \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; }
+  ConstructionKind getConstructionKind() const {
+    return (ConstructionKind)ConstructKind;
+  }
+  void setConstructionKind(ConstructionKind CK) { 
+    ConstructKind = CK;
+  }
   
   typedef ExprIterator arg_iterator;
   typedef ConstExprIterator const_arg_iterator;
@@ -723,6 +805,8 @@
   // Iterators
   virtual child_iterator child_begin();
   virtual child_iterator child_end();
+
+  friend class ASTStmtReader;
 };
 
 /// CXXFunctionalCastExpr - Represents an explicit C++ type conversion
@@ -731,17 +815,27 @@
 class CXXFunctionalCastExpr : public ExplicitCastExpr {
   SourceLocation TyBeginLoc;
   SourceLocation RParenLoc;
-public:
+
   CXXFunctionalCastExpr(QualType ty, TypeSourceInfo *writtenTy,
                         SourceLocation tyBeginLoc, CastKind kind,
-                        Expr *castExpr, CXXBaseSpecifierArray BasePath,
+                        Expr *castExpr, unsigned pathSize,
                         SourceLocation rParenLoc) 
     : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, kind, castExpr, 
-                       BasePath, writtenTy),
+                       pathSize, writtenTy),
       TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
 
-  explicit CXXFunctionalCastExpr(EmptyShell Shell)
-    : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell) { }
+  explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
+    : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { }
+
+public:
+  static CXXFunctionalCastExpr *Create(ASTContext &Context, QualType T,
+                                       TypeSourceInfo *Written,
+                                       SourceLocation TyBeginLoc,
+                                       CastKind Kind, Expr *Op,
+                                       const CXXCastPath *Path,
+                                       SourceLocation RPLoc);
+  static CXXFunctionalCastExpr *CreateEmpty(ASTContext &Context,
+                                            unsigned PathSize);
 
   SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
   void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
@@ -762,12 +856,8 @@
 ///
 /// 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.
+/// constructor to build a temporary object. With N == 1 arguments the 
+/// functional cast expression will be represented by CXXFunctionalCastExpr.
 /// Example:
 /// @code
 /// struct X { X(int, float); }
@@ -784,9 +874,10 @@
   CXXTemporaryObjectExpr(ASTContext &C, CXXConstructorDecl *Cons,
                          QualType writtenTy, SourceLocation tyBeginLoc,
                          Expr **Args,unsigned NumArgs,
-                         SourceLocation rParenLoc);
-
-  ~CXXTemporaryObjectExpr() { }
+                         SourceLocation rParenLoc,
+                         bool ZeroInitialization = false);
+  explicit CXXTemporaryObjectExpr(EmptyShell Empty)
+    : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty) { }
 
   SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -798,26 +889,32 @@
     return T->getStmtClass() == CXXTemporaryObjectExprClass;
   }
   static bool classof(const CXXTemporaryObjectExpr *) { return true; }
+
+  friend class ASTStmtReader;
 };
 
-/// CXXZeroInitValueExpr - [C++ 5.2.3p2]
+/// CXXScalarValueInitExpr - [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.
+/// T, which is a non-class type.
 ///
-class CXXZeroInitValueExpr : public Expr {
+class CXXScalarValueInitExpr : public Expr {
   SourceLocation TyBeginLoc;
   SourceLocation RParenLoc;
 
 public:
-  CXXZeroInitValueExpr(QualType ty, SourceLocation tyBeginLoc,
+  CXXScalarValueInitExpr(QualType ty, SourceLocation tyBeginLoc,
                        SourceLocation rParenLoc ) :
-    Expr(CXXZeroInitValueExprClass, ty, false, false),
+    Expr(CXXScalarValueInitExprClass, ty, false, false),
     TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
+  explicit CXXScalarValueInitExpr(EmptyShell Shell)
+    : Expr(CXXScalarValueInitExprClass, Shell) { }
 
   SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
 
+  void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+  
   /// @brief Whether this initialization expression was
   /// implicitly-generated.
   bool isImplicit() const {
@@ -829,9 +926,9 @@
   }
 
   static bool classof(const Stmt *T) {
-    return T->getStmtClass() == CXXZeroInitValueExprClass;
+    return T->getStmtClass() == CXXScalarValueInitExprClass;
   }
-  static bool classof(const CXXZeroInitValueExpr *) { return true; }
+  static bool classof(const CXXScalarValueInitExpr *) { return true; }
 
   // Iterators
   virtual child_iterator child_begin();
@@ -843,15 +940,13 @@
 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;
+  unsigned NumPlacementArgs : 15;
   // The number of constructor arguments. This may be 1 even for non-class
   // types; use the pseudo copy constructor.
   unsigned NumConstructorArgs : 14;
@@ -868,27 +963,39 @@
   // Must be null for all other types.
   CXXConstructorDecl *Constructor;
 
+  /// \brief If the allocated type was expressed as a parenthesized type-id, 
+  /// the source range covering the parenthesized type-id.
+  SourceRange TypeIdParens;
+  
   SourceLocation StartLoc;
   SourceLocation EndLoc;
 
+  friend class ASTStmtReader;
 public:
   CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
-             Expr **placementArgs, unsigned numPlaceArgs, bool ParenTypeId,
+             Expr **placementArgs, unsigned numPlaceArgs,
+             SourceRange TypeIdParens,
              Expr *arraySize, CXXConstructorDecl *constructor, bool initializer,
              Expr **constructorArgs, unsigned numConsArgs,
              FunctionDecl *operatorDelete, QualType ty,
              SourceLocation startLoc, SourceLocation endLoc);
-  
-  virtual void DoDestroy(ASTContext &C);
+  explicit CXXNewExpr(EmptyShell Shell)
+    : Expr(CXXNewExprClass, Shell), SubExprs(0) { }
 
+  void AllocateArgsArray(ASTContext &C, bool isArray, unsigned numPlaceArgs,
+                         unsigned numConsArgs);
+  
   QualType getAllocatedType() const {
     assert(getType()->isPointerType());
     return getType()->getAs<PointerType>()->getPointeeType();
   }
 
   FunctionDecl *getOperatorNew() const { return OperatorNew; }
+  void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
   FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+  void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
   CXXConstructorDecl *getConstructor() const { return Constructor; }
+  void setConstructor(CXXConstructorDecl *D) { Constructor = D; }
 
   bool isArray() const { return Array; }
   Expr *getArraySize() {
@@ -908,9 +1015,13 @@
     return cast<Expr>(SubExprs[Array + i]);
   }
 
+  bool isParenTypeId() const { return TypeIdParens.isValid(); }
+  SourceRange getTypeIdParens() const { return TypeIdParens; }
+
   bool isGlobalNew() const { return GlobalNew; }
-  bool isParenTypeId() const { return ParenTypeId; }
+  void setGlobalNew(bool V) { GlobalNew = V; }
   bool hasInitializer() const { return Initializer; }
+  void setHasInitializer(bool V) { Initializer = V; }
 
   unsigned getNumConstructorArgs() const { return NumConstructorArgs; }
   Expr *getConstructorArg(unsigned i) {
@@ -950,7 +1061,21 @@
   const_arg_iterator constructor_arg_end() const {
     return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
   }
+  
+  typedef Stmt **raw_arg_iterator;
+  raw_arg_iterator raw_arg_begin() { return SubExprs; }
+  raw_arg_iterator raw_arg_end() {
+    return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
+  }
+  const_arg_iterator raw_arg_begin() const { return SubExprs; }
+  const_arg_iterator raw_arg_end() const { return constructor_arg_end(); }
 
+  
+  SourceLocation getStartLoc() const { return StartLoc; }
+  void setStartLoc(SourceLocation L) { StartLoc = L; }
+  SourceLocation getEndLoc() const { return EndLoc; }
+  void setEndLoc(SourceLocation L) { EndLoc = L; }
+  
   virtual SourceRange getSourceRange() const {
     return SourceRange(StartLoc, EndLoc);
   }
@@ -984,18 +1109,26 @@
     : Expr(CXXDeleteExprClass, ty, false, false), GlobalDelete(globalDelete),
       ArrayForm(arrayForm), OperatorDelete(operatorDelete), Argument(arg),
       Loc(loc) { }
+  explicit CXXDeleteExpr(EmptyShell Shell)
+    : Expr(CXXDeleteExprClass, Shell), OperatorDelete(0), Argument(0) { }
 
   bool isGlobalDelete() const { return GlobalDelete; }
   bool isArrayForm() const { return ArrayForm; }
+  
+  void setGlobalDelete(bool V) { GlobalDelete = V; }
+  void setArrayForm(bool V) { ArrayForm = V; }
 
   FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+  void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
 
   Expr *getArgument() { return cast<Expr>(Argument); }
   const Expr *getArgument() const { return cast<Expr>(Argument); }
+  void setArgument(Expr *E) { Argument = E; }
 
   virtual SourceRange getSourceRange() const {
     return SourceRange(Loc, Argument->getLocEnd());
   }
+  void setStartLoc(SourceLocation L) { Loc = L; } 
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXDeleteExprClass;
@@ -1117,6 +1250,10 @@
       ScopeType(ScopeType), ColonColonLoc(ColonColonLoc), TildeLoc(TildeLoc),
       DestroyedType(DestroyedType) { }
 
+  explicit CXXPseudoDestructorExpr(EmptyShell Shell)
+    : Expr(CXXPseudoDestructorExprClass, Shell),
+      Base(0), IsArrow(false), Qualifier(0), ScopeType(0) { }
+
   void setBase(Expr *E) { Base = E; }
   Expr *getBase() const { return cast<Expr>(Base); }
 
@@ -1129,11 +1266,13 @@
   /// the nested-name-specifier that precedes the member name. Otherwise,
   /// returns an empty source range.
   SourceRange getQualifierRange() const { return QualifierRange; }
+  void setQualifierRange(SourceRange R) { QualifierRange = R; }
 
   /// \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; }
+  void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
 
   /// \brief Determine whether this pseudo-destructor expression was written
   /// using an '->' (otherwise, it used a '.').
@@ -1142,6 +1281,7 @@
 
   /// \brief Retrieve the location of the '.' or '->' operator.
   SourceLocation getOperatorLoc() const { return OperatorLoc; }
+  void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
 
   /// \brief Retrieve the scope type in a qualified pseudo-destructor 
   /// expression.
@@ -1153,13 +1293,16 @@
   /// nested-name-specifier. It is stored as the "scope type" of the pseudo-
   /// destructor expression.
   TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; }
+  void setScopeTypeInfo(TypeSourceInfo *Info) { ScopeType = Info; }
   
   /// \brief Retrieve the location of the '::' in a qualified pseudo-destructor
   /// expression.
   SourceLocation getColonColonLoc() const { return ColonColonLoc; }
+  void setColonColonLoc(SourceLocation L) { ColonColonLoc = L; }
   
   /// \brief Retrieve the location of the '~'.
   SourceLocation getTildeLoc() const { return TildeLoc; }
+  void setTildeLoc(SourceLocation L) { TildeLoc = L; }
   
   /// \brief Retrieve the source location information for the type
   /// being destroyed.
@@ -1187,6 +1330,17 @@
     return DestroyedType.getLocation(); 
   }
 
+  /// \brief Set the name of destroyed type for a dependent pseudo-destructor
+  /// expression.
+  void setDestroyedType(IdentifierInfo *II, SourceLocation Loc) {
+    DestroyedType = PseudoDestructorTypeStorage(II, Loc);
+  }
+
+  /// \brief Set the destroyed type.
+  void setDestroyedType(TypeSourceInfo *Info) {
+    DestroyedType = PseudoDestructorTypeStorage(Info);
+  }
+
   virtual SourceRange getSourceRange() const;
 
   static bool classof(const Stmt *T) {
@@ -1223,6 +1377,9 @@
     : Expr(UnaryTypeTraitExprClass, ty, false, queried->isDependentType()),
       UTT(utt), Loc(loc), RParen(rparen), QueriedType(queried) { }
 
+  explicit UnaryTypeTraitExpr(EmptyShell Empty)
+    : Expr(UnaryTypeTraitExprClass, Empty), UTT((UnaryTypeTrait)0) { }
+
   virtual SourceRange getSourceRange() const { return SourceRange(Loc, RParen);}
 
   UnaryTypeTrait getTrait() const { return UTT; }
@@ -1239,6 +1396,8 @@
   // Iterators
   virtual child_iterator child_begin();
   virtual child_iterator child_end();
+
+  friend class ASTStmtReader;
 };
 
 /// \brief A reference to an overloaded function set, either an
@@ -1247,10 +1406,12 @@
   /// The results.  These are undesugared, which is to say, they may
   /// include UsingShadowDecls.  Access is relative to the naming
   /// class.
-  UnresolvedSet<4> Results;
+  // FIXME: Allocate this data after the OverloadExpr subclass.
+  DeclAccessPair *Results;
+  unsigned NumResults;
 
   /// The common name of these declarations.
-  DeclarationName Name;
+  DeclarationNameInfo NameInfo;
 
   /// The scope specifier, if any.
   NestedNameSpecifier *Qualifier;
@@ -1258,21 +1419,19 @@
   /// The source range of the scope specifier.
   SourceRange QualifierRange;
 
-  /// The location of the name.
-  SourceLocation NameLoc;
-
+protected:
   /// True if the name was a template-id.
   bool HasExplicitTemplateArgs;
 
-protected:
-  OverloadExpr(StmtClass K, QualType T, bool Dependent,
+  OverloadExpr(StmtClass K, ASTContext &C, 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)
-  {}
+               const DeclarationNameInfo &NameInfo,
+               bool HasTemplateArgs,
+               UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+
+  OverloadExpr(StmtClass K, EmptyShell Empty)
+    : Expr(K, Empty), Results(0), NumResults(0),
+      Qualifier(0), HasExplicitTemplateArgs(false) { }
 
 public:
   /// Computes whether an unresolved lookup on the given declarations
@@ -1281,51 +1440,74 @@
                                 UnresolvedSetIterator End,
                                 const TemplateArgumentListInfo *Args);
 
+  struct FindResult {
+    OverloadExpr *Expression;
+    bool IsAddressOfOperand;
+    bool HasFormOfMemberPointer;
+  };
+
   /// 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) {
+  /// \return the expression (which must be there) and true if it has
+  /// the particular form of a member pointer expression
+  static FindResult 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);
-  }
+    FindResult Result;
 
-  void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
-    Results.append(Begin, End);
+    E = E->IgnoreParens();
+    if (isa<UnaryOperator>(E)) {
+      assert(cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf);
+      E = cast<UnaryOperator>(E)->getSubExpr();
+      OverloadExpr *Ovl = cast<OverloadExpr>(E->IgnoreParens());
+
+      Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier());
+      Result.IsAddressOfOperand = true;
+      Result.Expression = Ovl;
+    } else {
+      Result.HasFormOfMemberPointer = false;
+      Result.IsAddressOfOperand = false;
+      Result.Expression = cast<OverloadExpr>(E);
+    }
+
+    return Result;
   }
 
   /// 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; }
+  decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); }
+  decls_iterator decls_end() const { 
+    return UnresolvedSetIterator(Results + NumResults);
+  }
+  
+  void initializeResults(ASTContext &C,
+                         UnresolvedSetIterator Begin,UnresolvedSetIterator End);
 
   /// Gets the number of declarations in the unresolved set.
-  unsigned getNumDecls() const { return Results.size(); }
+  unsigned getNumDecls() const { return NumResults; }
+
+  /// Gets the full name info.
+  const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
+  void setNameInfo(const DeclarationNameInfo &N) { NameInfo = N; }
 
   /// Gets the name looked up.
-  DeclarationName getName() const { return Name; }
-  void setName(DeclarationName N) { Name = N; }
+  DeclarationName getName() const { return NameInfo.getName(); }
+  void setName(DeclarationName N) { NameInfo.setName(N); }
 
   /// Gets the location of the name.
-  SourceLocation getNameLoc() const { return NameLoc; }
-  void setNameLoc(SourceLocation Loc) { NameLoc = Loc; }
+  SourceLocation getNameLoc() const { return NameInfo.getLoc(); }
+  void setNameLoc(SourceLocation Loc) { NameInfo.setLoc(Loc); }
 
   /// Fetches the nested-name qualifier, if one was given.
   NestedNameSpecifier *getQualifier() const { return Qualifier; }
+  void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
 
   /// Fetches the range of the nested-name qualifier.
   SourceRange getQualifierRange() const { return QualifierRange; }
+  void setQualifierRange(SourceRange R) { QualifierRange = R; }
 
   /// \brief Determines whether this expression had an explicit
   /// template argument list, e.g. f<int>.
@@ -1337,10 +1519,12 @@
     return const_cast<OverloadExpr*>(this)->getExplicitTemplateArgs();
   }
 
-  ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
-    if (hasExplicitTemplateArgs())
-      return &getExplicitTemplateArgs();
-    return 0;
+  /// \brief Retrieves the optional explicit template arguments.
+  /// This points to the same data as getExplicitTemplateArgs(), but
+  /// returns null if there are no explicit template arguments.
+  const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+    if (!hasExplicitTemplateArgs()) return 0;
+    return &getExplicitTemplateArgs();
   }
 
   static bool classof(const Stmt *T) {
@@ -1377,28 +1561,38 @@
   /// against the qualified-lookup bits.
   CXXRecordDecl *NamingClass;
 
-  UnresolvedLookupExpr(QualType T, bool Dependent, CXXRecordDecl *NamingClass,
+  UnresolvedLookupExpr(ASTContext &C, 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),
+                       const DeclarationNameInfo &NameInfo,
+                       bool RequiresADL, bool Overloaded, bool HasTemplateArgs,
+                       UnresolvedSetIterator Begin, UnresolvedSetIterator End)
+    : OverloadExpr(UnresolvedLookupExprClass, C, T, Dependent, Qualifier, 
+                   QRange, NameInfo, HasTemplateArgs, Begin, End),
       RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass)
   {}
 
+  UnresolvedLookupExpr(EmptyShell Empty)
+    : OverloadExpr(UnresolvedLookupExprClass, Empty),
+      RequiresADL(false), Overloaded(false), NamingClass(0)
+  {}
+
 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,
+                                      const DeclarationNameInfo &NameInfo,
+                                      bool ADL, bool Overloaded,
+                                      UnresolvedSetIterator Begin, 
+                                      UnresolvedSetIterator End) {
+    return new(C) UnresolvedLookupExpr(C,
+                                       Dependent ? C.DependentTy : C.OverloadTy,
                                        Dependent, NamingClass,
-                                       Qualifier, QualifierRange,
-                                       Name, NameLoc, ADL, Overloaded, false);
+                                       Qualifier, QualifierRange, NameInfo,
+                                       ADL, Overloaded, false,
+                                       Begin, End);
   }
 
   static UnresolvedLookupExpr *Create(ASTContext &C,
@@ -1406,22 +1600,29 @@
                                       CXXRecordDecl *NamingClass,
                                       NestedNameSpecifier *Qualifier,
                                       SourceRange QualifierRange,
-                                      DeclarationName Name,
-                                      SourceLocation NameLoc,
+                                      const DeclarationNameInfo &NameInfo,
                                       bool ADL,
-                                      const TemplateArgumentListInfo &Args);
+                                      const TemplateArgumentListInfo &Args,
+                                      UnresolvedSetIterator Begin, 
+                                      UnresolvedSetIterator End);
+
+  static UnresolvedLookupExpr *CreateEmpty(ASTContext &C,
+                                           unsigned NumTemplateArgs);
 
   /// True if this declaration should be extended by
   /// argument-dependent lookup.
   bool requiresADL() const { return RequiresADL; }
+  void setRequiresADL(bool V) { RequiresADL = V; }
 
   /// True if this lookup is overloaded.
   bool isOverloaded() const { return Overloaded; }
+  void setOverloaded(bool V) { Overloaded = V; }
 
   /// 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; }
+  void setNamingClass(CXXRecordDecl *D) { NamingClass = D; }
 
   // Note that, inconsistently with the explicit-template-argument AST
   // nodes, users are *forbidden* from calling these methods on objects
@@ -1438,6 +1639,14 @@
     return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1);
   }
 
+  /// \brief Retrieves the optional explicit template arguments.
+  /// This points to the same data as getExplicitTemplateArgs(), but
+  /// returns null if there are no explicit template arguments.
+  const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+    if (!hasExplicitTemplateArgs()) return 0;
+    return &getExplicitTemplateArgs();
+  }
+
   /// \brief Copies the template arguments (if present) into the given
   /// structure.
   void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
@@ -1461,7 +1670,7 @@
   }
 
   virtual SourceRange getSourceRange() const {
-    SourceRange Range(getNameLoc());
+    SourceRange Range(getNameInfo().getSourceRange());
     if (getQualifier()) Range.setBegin(getQualifierRange().getBegin());
     if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc());
     return Range;
@@ -1492,10 +1701,7 @@
 /// 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;
+  DeclarationNameInfo NameInfo;
 
   /// QualifierRange - The source range that covers the
   /// nested-name-specifier.
@@ -1511,12 +1717,10 @@
   DependentScopeDeclRefExpr(QualType T,
                             NestedNameSpecifier *Qualifier,
                             SourceRange QualifierRange,
-                            DeclarationName Name,
-                            SourceLocation NameLoc,
+                            const DeclarationNameInfo &NameInfo,
                             bool HasExplicitTemplateArgs)
     : Expr(DependentScopeDeclRefExprClass, T, true, true),
-      Name(Name), Loc(NameLoc),
-      QualifierRange(QualifierRange), Qualifier(Qualifier),
+      NameInfo(NameInfo), QualifierRange(QualifierRange), Qualifier(Qualifier),
       HasExplicitTemplateArgs(HasExplicitTemplateArgs)
   {}
 
@@ -1524,22 +1728,32 @@
   static DependentScopeDeclRefExpr *Create(ASTContext &C,
                                            NestedNameSpecifier *Qualifier,
                                            SourceRange QualifierRange,
-                                           DeclarationName Name,
-                                           SourceLocation NameLoc,
+                                           const DeclarationNameInfo &NameInfo,
                               const TemplateArgumentListInfo *TemplateArgs = 0);
 
+  static DependentScopeDeclRefExpr *CreateEmpty(ASTContext &C,
+                                                unsigned NumTemplateArgs);
+
   /// \brief Retrieve the name that this expression refers to.
-  DeclarationName getDeclName() const { return Name; }
+  const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
+  void setNameInfo(const DeclarationNameInfo &N) { NameInfo =  N; }
+
+  /// \brief Retrieve the name that this expression refers to.
+  DeclarationName getDeclName() const { return NameInfo.getName(); }
+  void setDeclName(DeclarationName N) { NameInfo.setName(N); }
 
   /// \brief Retrieve the location of the name within the expression.
-  SourceLocation getLocation() const { return Loc; }
+  SourceLocation getLocation() const { return NameInfo.getLoc(); }
+  void setLocation(SourceLocation L) { NameInfo.setLoc(L); }
 
   /// \brief Retrieve the source range of the nested-name-specifier.
   SourceRange getQualifierRange() const { return QualifierRange; }
+  void setQualifierRange(SourceRange R) { QualifierRange = R; }
 
   /// \brief Retrieve the nested-name-specifier that qualifies this
   /// declaration.
   NestedNameSpecifier *getQualifier() const { return Qualifier; }
+  void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
 
   /// Determines whether this lookup had explicit template arguments.
   bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
@@ -1548,12 +1762,25 @@
   // 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 Retrieves the optional explicit template arguments.
+  /// This points to the same data as getExplicitTemplateArgs(), but
+  /// returns null if there are no explicit template arguments.
+  const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+    if (!hasExplicitTemplateArgs()) return 0;
+    return &getExplicitTemplateArgs();
+  }
+
   /// \brief Copies the template arguments (if present) into the given
   /// structure.
   void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
@@ -1598,19 +1825,21 @@
   CXXTemporary **Temps;
   unsigned NumTemps;
 
-  CXXExprWithTemporaries(Expr *SubExpr, CXXTemporary **Temps,
+  CXXExprWithTemporaries(ASTContext &C, Expr *SubExpr, CXXTemporary **Temps,
                          unsigned NumTemps);
-  ~CXXExprWithTemporaries();
-
-protected:
-  virtual void DoDestroy(ASTContext &C);
 
 public:
+  CXXExprWithTemporaries(EmptyShell Empty)
+    : Expr(CXXExprWithTemporariesClass, Empty),
+      SubExpr(0), Temps(0), NumTemps(0) {}
+                         
   static CXXExprWithTemporaries *Create(ASTContext &C, Expr *SubExpr,
                                         CXXTemporary **Temps, 
                                         unsigned NumTemps);
 
   unsigned getNumTemporaries() const { return NumTemps; }
+  void setNumTemporaries(ASTContext &C, unsigned N);
+    
   CXXTemporary *getTemporary(unsigned i) {
     assert(i < NumTemps && "Index out of range");
     return Temps[i];
@@ -1618,6 +1847,10 @@
   const CXXTemporary *getTemporary(unsigned i) const {
     return const_cast<CXXExprWithTemporaries*>(this)->getTemporary(i);
   }
+  void setTemporary(unsigned i, CXXTemporary *T) {
+    assert(i < NumTemps && "Index out of range");
+    Temps[i] = T;
+  }
 
   Expr *getSubExpr() { return cast<Expr>(SubExpr); }
   const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
@@ -1682,6 +1915,9 @@
                              unsigned NumArgs,
                              SourceLocation RParenLoc);
 
+  CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
+    : Expr(CXXUnresolvedConstructExprClass, Empty), NumArgs(NumArgs) { }
+
 public:
   static CXXUnresolvedConstructExpr *Create(ASTContext &C,
                                             SourceLocation TyBegin,
@@ -1691,6 +1927,9 @@
                                             unsigned NumArgs,
                                             SourceLocation RParenLoc);
 
+  static CXXUnresolvedConstructExpr *CreateEmpty(ASTContext &C,
+                                                 unsigned NumArgs);
+
   /// \brief Retrieve the source location where the type begins.
   SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
   void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
@@ -1735,6 +1974,11 @@
     return *(arg_begin() + I);
   }
 
+  void setArg(unsigned I, Expr *E) {
+    assert(I < NumArgs && "Argument index out-of-range");
+    *(arg_begin() + I) = E;
+  }
+
   virtual SourceRange getSourceRange() const {
     return SourceRange(TyBeginLoc, RParenLoc);
   }
@@ -1793,24 +2037,7 @@
   /// \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();
-  }
+  DeclarationNameInfo MemberNameInfo;
 
   CXXDependentScopeMemberExpr(ASTContext &C,
                           Expr *Base, QualType BaseType, bool IsArrow,
@@ -1818,8 +2045,7 @@
                           NestedNameSpecifier *Qualifier,
                           SourceRange QualifierRange,
                           NamedDecl *FirstQualifierFoundInScope,
-                          DeclarationName Member,
-                          SourceLocation MemberLoc,
+                          DeclarationNameInfo MemberNameInfo,
                           const TemplateArgumentListInfo *TemplateArgs);
 
 public:
@@ -1830,14 +2056,13 @@
                           NestedNameSpecifier *Qualifier,
                           SourceRange QualifierRange,
                           NamedDecl *FirstQualifierFoundInScope,
-                          DeclarationName Member,
-                          SourceLocation MemberLoc)
+                          DeclarationNameInfo MemberNameInfo)
   : 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) { }
+    MemberNameInfo(MemberNameInfo) { }
 
   static CXXDependentScopeMemberExpr *
   Create(ASTContext &C,
@@ -1846,10 +2071,12 @@
          NestedNameSpecifier *Qualifier,
          SourceRange QualifierRange,
          NamedDecl *FirstQualifierFoundInScope,
-         DeclarationName Member,
-         SourceLocation MemberLoc,
+         DeclarationNameInfo MemberNameInfo,
          const TemplateArgumentListInfo *TemplateArgs);
 
+  static CXXDependentScopeMemberExpr *
+  CreateEmpty(ASTContext &C, unsigned NumTemplateArgs);
+
   /// \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.
@@ -1864,6 +2091,7 @@
   void setBase(Expr *E) { Base = E; }
 
   QualType getBaseType() const { return BaseType; }
+  void setBaseType(QualType T) { BaseType = T; }
 
   /// \brief Determine whether this member expression used the '->'
   /// operator; otherwise, it used the '.' operator.
@@ -1877,10 +2105,12 @@
   /// \brief Retrieve the nested-name-specifier that qualifies the member
   /// name.
   NestedNameSpecifier *getQualifier() const { return Qualifier; }
+  void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
 
   /// \brief Retrieve the source range covering the nested-name-specifier
   /// that qualifies the member name.
   SourceRange getQualifierRange() const { return QualifierRange; }
+  void setQualifierRange(SourceRange R) { QualifierRange = R; }
 
   /// \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
@@ -1896,16 +2126,26 @@
   NamedDecl *getFirstQualifierFoundInScope() const {
     return FirstQualifierFoundInScope;
   }
+  void setFirstQualifierFoundInScope(NamedDecl *D) {
+    FirstQualifierFoundInScope = D;
+  }
 
   /// \brief Retrieve the name of the member that this expression
   /// refers to.
-  DeclarationName getMember() const { return Member; }
-  void setMember(DeclarationName N) { Member = N; }
+  const DeclarationNameInfo &getMemberNameInfo() const {
+    return MemberNameInfo;
+  }
+  void setMemberNameInfo(const DeclarationNameInfo &N) { MemberNameInfo = N; }
+
+  /// \brief Retrieve the name of the member that this expression
+  /// refers to.
+  DeclarationName getMember() const { return MemberNameInfo.getName(); }
+  void setMember(DeclarationName N) { MemberNameInfo.setName(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; }
+  SourceLocation getMemberLoc() const { return MemberNameInfo.getLoc(); }
+  void setMemberLoc(SourceLocation L) { MemberNameInfo.setLoc(L); }
 
   /// \brief Determines whether this member expression actually had a C++
   /// template argument list explicitly specified, e.g., x.f<int>.
@@ -1913,39 +2153,61 @@
     return HasExplicitTemplateArgs;
   }
 
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name, if any.
+  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 {
+    return const_cast<CXXDependentScopeMemberExpr *>(this)
+             ->getExplicitTemplateArgs();
+  }
+
+  /// \brief Retrieves the optional explicit template arguments.
+  /// This points to the same data as getExplicitTemplateArgs(), but
+  /// returns null if there are no explicit template arguments.
+  const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+    if (!hasExplicitTemplateArgs()) return 0;
+    return &getExplicitTemplateArgs();
+  }
+
   /// \brief Copies the template arguments (if present) into the given
   /// structure.
   void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
-    assert(HasExplicitTemplateArgs);
-    getExplicitTemplateArgumentList()->copyInto(List);
+    getExplicitTemplateArgs().copyInto(List);
+  }
+
+  /// \brief Initializes the template arguments using the given structure.
+  void initializeTemplateArgumentsFrom(const TemplateArgumentListInfo &List) {
+    getExplicitTemplateArgs().initializeFrom(List);
   }
 
   /// \brief Retrieve the location of the left angle bracket following the
   /// member name ('<'), if any.
   SourceLocation getLAngleLoc() const {
-    assert(HasExplicitTemplateArgs);
-    return getExplicitTemplateArgumentList()->LAngleLoc;
+    return getExplicitTemplateArgs().LAngleLoc;
   }
 
   /// \brief Retrieve the template arguments provided as part of this
   /// template-id.
   const TemplateArgumentLoc *getTemplateArgs() const {
-    assert(HasExplicitTemplateArgs);
-    return getExplicitTemplateArgumentList()->getTemplateArgs();
+    return getExplicitTemplateArgs().getTemplateArgs();
   }
 
   /// \brief Retrieve the number of template arguments provided as part of this
   /// template-id.
   unsigned getNumTemplateArgs() const {
-    assert(HasExplicitTemplateArgs);
-    return getExplicitTemplateArgumentList()->NumTemplateArgs;
+    return getExplicitTemplateArgs().NumTemplateArgs;
   }
 
   /// \brief Retrieve the location of the right angle bracket following the
   /// template arguments ('>').
   SourceLocation getRAngleLoc() const {
-    assert(HasExplicitTemplateArgs);
-    return getExplicitTemplateArgumentList()->RAngleLoc;
+    return getExplicitTemplateArgs().RAngleLoc;
   }
 
   virtual SourceRange getSourceRange() const {
@@ -1955,12 +2217,12 @@
     else if (getQualifier())
       Range.setBegin(getQualifierRange().getBegin());
     else
-      Range.setBegin(MemberLoc);
+      Range.setBegin(MemberNameInfo.getBeginLoc());
 
     if (hasExplicitTemplateArgs())
       Range.setEnd(getRAngleLoc());
     else
-      Range.setEnd(MemberLoc);
+      Range.setEnd(MemberNameInfo.getEndLoc());
     return Range;
   }
 
@@ -2007,15 +2269,19 @@
   /// \brief The location of the '->' or '.' operator.
   SourceLocation OperatorLoc;
 
-  UnresolvedMemberExpr(QualType T, bool Dependent,
+  UnresolvedMemberExpr(ASTContext &C, 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);
+                       const DeclarationNameInfo &MemberNameInfo,
+                       const TemplateArgumentListInfo *TemplateArgs,
+                       UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+  
+  UnresolvedMemberExpr(EmptyShell Empty)
+    : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
+      HasUnresolvedUsing(false), Base(0) { }
 
 public:
   static UnresolvedMemberExpr *
@@ -2024,9 +2290,12 @@
          SourceLocation OperatorLoc,
          NestedNameSpecifier *Qualifier,
          SourceRange QualifierRange,
-         DeclarationName Member,
-         SourceLocation MemberLoc,
-         const TemplateArgumentListInfo *TemplateArgs);
+         const DeclarationNameInfo &MemberNameInfo,
+         const TemplateArgumentListInfo *TemplateArgs,
+         UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+
+  static UnresolvedMemberExpr *
+  CreateEmpty(ASTContext &C, unsigned NumTemplateArgs);
 
   /// \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
@@ -2046,6 +2315,12 @@
   void setBase(Expr *E) { Base = E; }
 
   QualType getBaseType() const { return BaseType; }
+  void setBaseType(QualType T) { BaseType = T; }
+
+  /// \brief Determine whether the lookup results contain an unresolved using
+  /// declaration.
+  bool hasUnresolvedUsing() const { return HasUnresolvedUsing; }
+  void setHasUnresolvedUsing(bool V) { HasUnresolvedUsing = V; }
 
   /// \brief Determine whether this member expression used the '->'
   /// operator; otherwise, it used the '.' operator.
@@ -2059,6 +2334,11 @@
   /// \brief Retrieves the naming class of this lookup.
   CXXRecordDecl *getNamingClass() const;
 
+  /// \brief Retrieve the full name info for the member that this expression
+  /// refers to.
+  const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); }
+  void setMemberNameInfo(const DeclarationNameInfo &N) { setNameInfo(N); }
+
   /// \brief Retrieve the name of the member that this expression
   /// refers to.
   DeclarationName getMemberName() const { return getName(); }
@@ -2083,6 +2363,14 @@
     return *reinterpret_cast<const ExplicitTemplateArgumentList *>(this + 1);
   }
 
+  /// \brief Retrieves the optional explicit template arguments.
+  /// This points to the same data as getExplicitTemplateArgs(), but
+  /// returns null if there are no explicit template arguments.
+  const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+    if (!hasExplicitTemplateArgs()) return 0;
+    return &getExplicitTemplateArgs();
+  }
+
   /// \brief Copies the template arguments into the given structure.
   void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
     getExplicitTemplateArgs().copyInto(List);
@@ -2113,18 +2401,14 @@
   }
 
   virtual SourceRange getSourceRange() const {
-    SourceRange Range;
+    SourceRange Range = getMemberNameInfo().getSourceRange();
     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;
   }
 
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index 79e4451..a8ef005 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -14,31 +14,25 @@
 #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 llvm {
+template <class T> class SmallVectorImpl;
+}
+
 namespace clang {
 
 class ASTConsumer;
 class Decl;
 class DeclContext;
+class DeclContextLookupResult;
+class DeclarationName;
 class ExternalSemaSource; // layering violation required for downcasting
+class NamedDecl;
+class Selector;
 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
@@ -58,67 +52,108 @@
 
   virtual ~ExternalASTSource();
 
-  /// \brief Resolve a type ID into a type, potentially building a new
-  /// type.
-  virtual QualType GetType(uint32_t ID) = 0;
+  /// \brief RAII class for safely pairing a StartedDeserializing call
+  /// with FinishedDeserializing.
+  class Deserializing {
+    ExternalASTSource *Source;
+  public:
+    explicit Deserializing(ExternalASTSource *source) : Source(source) {
+      assert(Source);
+      Source->StartedDeserializing();
+    }
+    ~Deserializing() {
+      Source->FinishedDeserializing();
+    }
+  };
 
   /// \brief Resolve a declaration ID into a declaration, potentially
   /// building a new declaration.
-  virtual Decl *GetDecl(uint32_t ID) = 0;
+  ///
+  /// This method only needs to be implemented if the AST source ever
+  /// passes back decl sets as VisibleDeclaration objects.
+  virtual Decl *GetExternalDecl(uint32_t ID) = 0;
 
   /// \brief Resolve a selector ID into a selector.
-  virtual Selector GetSelector(uint32_t ID) = 0;
+  ///
+  /// This operation only needs to be implemented if the AST source
+  /// returns non-zero for GetNumKnownSelectors().
+  virtual Selector GetExternalSelector(uint32_t ID) = 0;
 
   /// \brief Returns the number of selectors known to the external AST
   /// source.
-  virtual uint32_t GetNumKnownSelectors() = 0;
+  virtual uint32_t GetNumExternalSelectors() = 0;
 
-  /// \brief Resolve the offset of a statement in the decl stream into a
-  /// statement.
+  /// \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;
+  /// This operation is meant to be used via a LazyOffsetPtr.  It only
+  /// needs to be implemented if the AST source uses methods like
+  /// FunctionDecl::setLazyBody when building decls.
+  virtual Stmt *GetExternalDeclStmt(uint64_t Offset) = 0;
 
-  /// \brief Read all of the declarations lexically stored in a
-  /// declaration context.
+  /// \brief Finds all declarations with the given name in the
+  /// given 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;
+  /// Generally the final step of this method is either to call
+  /// SetExternalVisibleDeclsForName or to recursively call lookup on
+  /// the DeclContext after calling SetExternalVisibleDecls.
+  virtual DeclContextLookupResult
+  FindExternalVisibleDeclsByName(const DeclContext *DC,
+                                 DeclarationName Name) = 0;
 
-  /// \brief Read all of the declarations visible from a declaration
-  /// context.
+  /// \brief Deserialize all the visible declarations from external storage.
   ///
-  /// \param DC The declaration context whose visible declarations
-  /// will be read.
+  /// Name lookup deserializes visible declarations lazily, thus a DeclContext
+  /// may not have a complete name lookup table. This function deserializes
+  /// the rest of visible declarations from the external storage and completes
+  /// the name lookup table of the DeclContext.
+  virtual void MaterializeVisibleDecls(const DeclContext *DC) = 0;
+
+  /// \brief Finds all declarations lexically contained within the given
+  /// DeclContext.
   ///
-  /// \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.
+  /// \return true if an error occurred
+  virtual bool FindExternalLexicalDecls(const DeclContext *DC,
+                                llvm::SmallVectorImpl<Decl*> &Result) = 0;
+
+  /// \brief Notify ExternalASTSource that we started deserialization of
+  /// a decl or type so until FinishedDeserializing is called there may be
+  /// decls that are initializing. Must be paired with FinishedDeserializing.
   ///
-  /// \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;
+  /// The default implementation of this method is a no-op.
+  virtual void StartedDeserializing() { }
+
+  /// \brief Notify ExternalASTSource that we finished the deserialization of
+  /// a decl or type. Must be paired with StartedDeserializing.
+  ///
+  /// The default implementation of this method is a no-op.
+  virtual void FinishedDeserializing() { }
 
   /// \brief Function that will be invoked when we begin parsing a new
   /// translation unit involving this external AST source.
+  ///
+  /// The default implementation of this method is a no-op.
   virtual void StartTranslationUnit(ASTConsumer *Consumer) { }
 
   /// \brief Print any statistics that have been gathered regarding
   /// the external AST source.
+  ///
+  /// The default implementation of this method is a no-op.
   virtual void PrintStats();
+
+protected:
+  static DeclContextLookupResult
+  SetExternalVisibleDeclsForName(const DeclContext *DC,
+                                 DeclarationName Name,
+                                 llvm::SmallVectorImpl<NamedDecl*> &Decls);
+
+  static DeclContextLookupResult
+  SetNoExternalVisibleDeclsForName(const DeclContext *DC,
+                                   DeclarationName Name);
+
+  void MaterializeVisibleDeclsForName(const DeclContext *DC,
+                                      DeclarationName Name,
+                                 llvm::SmallVectorImpl<NamedDecl*> &Decls);
 };
 
 /// \brief A lazy pointer to an AST node (of base type T) that resides
@@ -127,7 +162,7 @@
 /// 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)>
+template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT 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.
@@ -185,7 +220,12 @@
 };
 
 /// \brief A lazy pointer to a statement.
-typedef LazyOffsetPtr<Stmt, &ExternalASTSource::GetDeclStmt> LazyDeclStmtPtr;
+typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>
+  LazyDeclStmtPtr;
+
+/// \brief A lazy pointer to a declaration.
+typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
+  LazyDeclPtr;
 
 } // end namespace clang
 
diff --git a/include/clang/AST/FullExpr.h b/include/clang/AST/FullExpr.h
index bb81bf0..6ceefed 100644
--- a/include/clang/AST/FullExpr.h
+++ b/include/clang/AST/FullExpr.h
@@ -47,7 +47,6 @@
 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 *>())
diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile
new file mode 100644
index 0000000..6ba6e89
--- /dev/null
+++ b/include/clang/AST/Makefile
@@ -0,0 +1,29 @@
+CLANG_LEVEL := ../../..
+TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
+BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc
+
+TABLEGEN_INC_FILES_COMMON = 1
+
+include $(CLANG_LEVEL)/Makefile
+
+$(ObjDir)/Attrs.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \
+                              $(ObjDir)/.dir
+	$(Echo) "Building Clang attribute classes with tblgen"
+	$(Verb) $(TableGen) -gen-clang-attr-classes -o $(call SYSPATH, $@) \
+		-I $(PROJ_SRC_DIR)/../../ $<
+
+$(ObjDir)/AttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \
+                              $(ObjDir)/.dir
+	$(Echo) "Building Clang attribute implementations with tblgen"
+	$(Verb) $(TableGen) -gen-clang-attr-impl -o $(call SYSPATH, $@) \
+		-I $(PROJ_SRC_DIR)/../../ $<
+
+$(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(TBLGEN) \
+                              $(ObjDir)/.dir
+	$(Echo) "Building Clang statement node tables with tblgen"
+	$(Verb) $(TableGen) -gen-clang-stmt-nodes -o $(call SYSPATH, $@) $<
+
+$(ObjDir)/DeclNodes.inc.tmp : $(TD_SRC_DIR)/DeclNodes.td $(TBLGEN) \
+                              $(ObjDir)/.dir
+	$(Echo) "Building Clang declaration node tables with tblgen"
+	$(Verb) $(TableGen) -gen-clang-decl-nodes -o $(call SYSPATH, $@) $<
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index 1594b09..3b25f3b 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -181,8 +181,6 @@
     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);
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
new file mode 100644
index 0000000..8045311
--- /dev/null
+++ b/include/clang/AST/OperationKinds.h
@@ -0,0 +1,158 @@
+//===- OperationKinds.h - Operation enums -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates the different kinds of operations that can be
+// performed by various expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_OPERATION_KINDS_H
+#define LLVM_CLANG_AST_OPERATION_KINDS_H
+
+namespace clang {
+  
+/// 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_LValueBitCast - Used for reinterpret_cast of expressions to
+  /// a reference type.
+  CK_LValueBitCast,
+    
+  /// 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,
+
+  /// \brief Converting between two Objective-C object types, which
+  /// can occur when performing reference binding to an Objective-C
+  /// object.
+  CK_ObjCObjectLValueCast
+};
+
+
+enum BinaryOperatorKind {
+  // Operators listed in order of precedence.
+  // Note that additions to this should also update the StmtVisitor class.
+  BO_PtrMemD, BO_PtrMemI,       // [C++ 5.5] Pointer-to-member operators.
+  BO_Mul, BO_Div, BO_Rem,       // [C99 6.5.5] Multiplicative operators.
+  BO_Add, BO_Sub,               // [C99 6.5.6] Additive operators.
+  BO_Shl, BO_Shr,               // [C99 6.5.7] Bitwise shift operators.
+  BO_LT, BO_GT, BO_LE, BO_GE,   // [C99 6.5.8] Relational operators.
+  BO_EQ, BO_NE,                 // [C99 6.5.9] Equality operators.
+  BO_And,                       // [C99 6.5.10] Bitwise AND operator.
+  BO_Xor,                       // [C99 6.5.11] Bitwise XOR operator.
+  BO_Or,                        // [C99 6.5.12] Bitwise OR operator.
+  BO_LAnd,                      // [C99 6.5.13] Logical AND operator.
+  BO_LOr,                       // [C99 6.5.14] Logical OR operator.
+  BO_Assign, BO_MulAssign,      // [C99 6.5.16] Assignment operators.
+  BO_DivAssign, BO_RemAssign,
+  BO_AddAssign, BO_SubAssign,
+  BO_ShlAssign, BO_ShrAssign,
+  BO_AndAssign, BO_XorAssign,
+  BO_OrAssign,
+  BO_Comma                      // [C99 6.5.17] Comma operator.
+};
+
+enum UnaryOperatorKind {
+  // Note that additions to this should also update the StmtVisitor class.
+  UO_PostInc, UO_PostDec, // [C99 6.5.2.4] Postfix increment and decrement
+  UO_PreInc, UO_PreDec,   // [C99 6.5.3.1] Prefix increment and decrement
+  UO_AddrOf, UO_Deref,    // [C99 6.5.3.2] Address and indirection
+  UO_Plus, UO_Minus,      // [C99 6.5.3.3] Unary arithmetic
+  UO_Not, UO_LNot,        // [C99 6.5.3.3] Unary arithmetic
+  UO_Real, UO_Imag,       // "__real expr"/"__imag expr" Extension.
+  UO_Extension            // __extension__ marker.
+};
+
+}
+
+#endif
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index e78476e..2b3229e 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -109,6 +109,11 @@
     /// which is the alignment of the object without virtual bases.
     uint64_t NonVirtualAlign;
 
+    /// SizeOfLargestEmptySubobject - The size of the largest empty subobject
+    /// (either a base or a member). Will be zero if the class doesn't contain
+    /// any empty subobjects.
+    uint64_t SizeOfLargestEmptySubobject;
+    
     /// PrimaryBase - The primary base info for this record.
     PrimaryBaseInfo PrimaryBase;
     
@@ -127,7 +132,6 @@
   CXXRecordLayoutInfo *CXXInfo;
 
   friend class ASTContext;
-  friend class ASTRecordLayoutBuilder;
 
   ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment,
                   unsigned datasize, const uint64_t *fieldoffsets,
@@ -139,7 +143,9 @@
                   uint64_t size, unsigned alignment, uint64_t datasize,
                   const uint64_t *fieldoffsets, unsigned fieldcount,
                   uint64_t nonvirtualsize, unsigned nonvirtualalign,
-                  const PrimaryBaseInfo &PrimaryBase,
+                  uint64_t SizeOfLargestEmptySubobject,
+                  const CXXRecordDecl *PrimaryBase,
+                  bool PrimaryBaseIsVirtual,
                   const BaseOffsetsMapTy& BaseOffsets,
                   const BaseOffsetsMapTy& VBaseOffsets);
 
@@ -222,6 +228,11 @@
     return CXXInfo->VBaseOffsets[VBase];
   }
   
+  uint64_t getSizeOfLargestEmptySubobject() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    return CXXInfo->SizeOfLargestEmptySubobject;
+  }
+
   primary_base_info_iterator primary_base_begin() const {
     assert(CXXInfo && "Record layout does not have C++ specific info!");
   
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
new file mode 100644
index 0000000..79ac072
--- /dev/null
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -0,0 +1,1737 @@
+//===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- 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 RecursiveASTVisitor interface, which recursively
+//  traverses the entire AST.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
+#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.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/NestedNameSpecifier.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+
+// The following three macros are used for meta programming.  The code
+// using them is responsible for defining macro OPERATOR().
+
+// All unary operators.
+#define UNARYOP_LIST()                          \
+  OPERATOR(PostInc)   OPERATOR(PostDec)         \
+  OPERATOR(PreInc)    OPERATOR(PreDec)          \
+  OPERATOR(AddrOf)    OPERATOR(Deref)           \
+  OPERATOR(Plus)      OPERATOR(Minus)           \
+  OPERATOR(Not)       OPERATOR(LNot)            \
+  OPERATOR(Real)      OPERATOR(Imag)            \
+  OPERATOR(Extension)
+
+// All binary operators (excluding compound assign operators).
+#define BINOP_LIST() \
+  OPERATOR(PtrMemD)              OPERATOR(PtrMemI)    \
+  OPERATOR(Mul)   OPERATOR(Div)  OPERATOR(Rem)        \
+  OPERATOR(Add)   OPERATOR(Sub)  OPERATOR(Shl)        \
+  OPERATOR(Shr)                                       \
+                                                      \
+  OPERATOR(LT)    OPERATOR(GT)   OPERATOR(LE)         \
+  OPERATOR(GE)    OPERATOR(EQ)   OPERATOR(NE)         \
+  OPERATOR(And)   OPERATOR(Xor)  OPERATOR(Or)         \
+  OPERATOR(LAnd)  OPERATOR(LOr)                       \
+                                                      \
+  OPERATOR(Assign)                                    \
+  OPERATOR(Comma)
+
+// All compound assign operators.
+#define CAO_LIST()                                                      \
+  OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
+  OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or)  OPERATOR(Xor)
+
+namespace clang {
+
+// A helper macro to implement short-circuiting when recursing.  It
+// invokes CALL_EXPR, which must be a method call, on the derived
+// object (s.t. a user of RecursiveASTVisitor can override the method
+// in CALL_EXPR).
+#define TRY_TO(CALL_EXPR) \
+  do { if (!getDerived().CALL_EXPR) return false; } while (0)
+
+/// \brief A class that does preorder depth-first traversal on the
+/// entire Clang AST and visits each node.
+///
+/// This class performs three distinct tasks:
+///   1. traverse the AST (i.e. go to each node);
+///   2. at a given node, walk up the class hierarchy, starting from
+///      the node's dynamic type, until the top-most class (e.g. Stmt,
+///      Decl, or Type) is reached.
+///   3. given a (node, class) combination, where 'class' is some base
+///      class of the dynamic type of 'node', call a user-overridable
+///      function to actually visit the node.
+///
+/// These tasks are done by three groups of methods, respectively:
+///   1. TraverseDecl(Decl *x) does task #1.  It is the entry point
+///      for traversing an AST rooted at x.  This method simply
+///      dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
+///      is the dynamic type of *x, which calls WalkUpFromFoo(x) and
+///      then recursively visits the child nodes of x.
+///      TraverseStmt(Stmt *x) and TraverseType(QualType x) work
+///      similarly.
+///   2. WalkUpFromFoo(Foo *x) does task #2.  It does not try to visit
+///      any child node of x.  Instead, it first calls WalkUpFromBar(x)
+///      where Bar is the direct parent class of Foo (unless Foo has
+///      no parent), and then calls VisitFoo(x) (see the next list item).
+///   3. VisitFoo(Foo *x) does task #3.
+///
+/// These three method groups are tiered (Traverse* > WalkUpFrom* >
+/// Visit*).  A method (e.g. Traverse*) may call methods from the same
+/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
+/// It may not call methods from a higher tier.
+///
+/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
+/// is Foo's super class) before calling VisitFoo(), the result is
+/// that the Visit*() methods for a given node are called in the
+/// top-down order (e.g. for a node of type NamedDecl, the order will
+/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
+///
+/// This scheme guarantees that all Visit*() calls for the same AST
+/// node are grouped together.  In other words, Visit*() methods for
+/// different nodes are never interleaved.
+///
+/// Clients of this visitor should subclass the visitor (providing
+/// themselves as the template argument, using the curiously recurring
+/// template pattern) and override any of the Traverse*, WalkUpFrom*,
+/// and Visit* methods for declarations, types, statements,
+/// expressions, or other AST nodes where the visitor should customize
+/// behavior.  Most users only need to override Visit*.  Advanced
+/// users may override Traverse* and WalkUpFrom* to implement custom
+/// traversal strategies.  Returning false from one of these overridden
+/// functions will abort the entire traversal.
+template<typename Derived>
+class RecursiveASTVisitor {
+public:
+  /// \brief Return a reference to the derived class.
+  Derived &getDerived() { return *static_cast<Derived*>(this); }
+
+  /// \brief Recursively visit a statement or expression, by
+  /// dispatching to Traverse*() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is NULL).
+  bool TraverseStmt(Stmt *S);
+
+  /// \brief Recursively visit a type, by dispatching to
+  /// Traverse*Type() based on the argument's getTypeClass() property.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type).
+  bool TraverseType(QualType T);
+
+  /// \brief Recursively visit a type with location, by dispatching to
+  /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type location).
+  bool TraverseTypeLoc(TypeLoc TL);
+
+  /// \brief Recursively visit a declaration, by dispatching to
+  /// Traverse*Decl() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is NULL).
+  bool TraverseDecl(Decl *D);
+
+  /// \brief Recursively visit a C++ nested-name-specifier.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
+
+  /// \brief Recursively visit a template name and dispatch to the
+  /// appropriate method.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseTemplateName(TemplateName Template);
+
+  /// \brief Recursively visit a template argument and dispatch to the
+  /// appropriate method for the argument type.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  // FIXME: migrate callers to TemplateArgumentLoc instead.
+  bool TraverseTemplateArgument(const TemplateArgument &Arg);
+
+  /// \brief Recursively visit a template argument location and dispatch to the
+  /// appropriate method for the argument type.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
+
+  /// \brief Recursively visit a set of template arguments.
+  /// This can be overridden by a subclass, but it's not expected that
+  /// will be needed -- this visitor always dispatches to another.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
+  bool TraverseTemplateArguments(const TemplateArgument *Args,
+                                 unsigned NumArgs);
+
+  /// \brief Recursively visit a constructor initializer.  This
+  /// automatically dispatches to another visitor for the initializer
+  /// expression, but not for the name of the initializer, so may
+  /// be overridden for clients that need access to the name.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseConstructorInitializer(CXXBaseOrMemberInitializer *Init);
+
+  // ---- Methods on Stmts ----
+
+  // Declare Traverse*() for all concrete Stmt classes.
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT)                                     \
+  bool Traverse##CLASS(CLASS *S);
+#include "clang/AST/StmtNodes.inc"
+  // The above header #undefs ABSTRACT_STMT and STMT upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
+  bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
+  bool VisitStmt(Stmt *S) { return true; }
+#define STMT(CLASS, PARENT)                                     \
+  bool WalkUpFrom##CLASS(CLASS *S) {                            \
+    TRY_TO(WalkUpFrom##PARENT(S));                              \
+    TRY_TO(Visit##CLASS(S));                                    \
+    return true;                                                \
+  }                                                             \
+  bool Visit##CLASS(CLASS *S) { return true; }
+#include "clang/AST/StmtNodes.inc"
+
+  // Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
+  // operator methods.  Unary operators are not classes in themselves
+  // (they're all opcodes in UnaryOperator) but do have visitors.
+#define OPERATOR(NAME)                                           \
+  bool TraverseUnary##NAME(UnaryOperator *S) {                  \
+    TRY_TO(WalkUpFromUnary##NAME(S));                           \
+    TRY_TO(TraverseStmt(S->getSubExpr()));                      \
+    return true;                                                \
+  }                                                             \
+  bool WalkUpFromUnary##NAME(UnaryOperator *S) {                \
+    TRY_TO(WalkUpFromUnaryOperator(S));                         \
+    TRY_TO(VisitUnary##NAME(S));                                \
+    return true;                                                \
+  }                                                             \
+  bool VisitUnary##NAME(UnaryOperator *S) { return true; }
+
+  UNARYOP_LIST()
+#undef OPERATOR
+
+  // Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
+  // operator methods.  Binary operators are not classes in themselves
+  // (they're all opcodes in BinaryOperator) but do have visitors.
+#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE)                \
+  bool TraverseBin##NAME(BINOP_TYPE *S) {                       \
+    TRY_TO(WalkUpFromBin##NAME(S));                             \
+    TRY_TO(TraverseStmt(S->getLHS()));                          \
+    TRY_TO(TraverseStmt(S->getRHS()));                          \
+    return true;                                                \
+  }                                                             \
+  bool WalkUpFromBin##NAME(BINOP_TYPE *S) {                     \
+    TRY_TO(WalkUpFrom##BINOP_TYPE(S));                          \
+    TRY_TO(VisitBin##NAME(S));                                  \
+    return true;                                                \
+  }                                                             \
+  bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
+
+#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
+  BINOP_LIST()
+#undef OPERATOR
+
+  // Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
+  // assignment methods.  Compound assignment operators are not
+  // classes in themselves (they're all opcodes in
+  // CompoundAssignOperator) but do have visitors.
+#define OPERATOR(NAME) \
+  GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
+
+  CAO_LIST()
+#undef OPERATOR
+#undef GENERAL_BINOP_FALLBACK
+
+  // ---- Methods on Types ----
+  // FIXME: revamp to take TypeLoc's rather than Types.
+
+  // Declare Traverse*() for all concrete Type classes.
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE) \
+  bool Traverse##CLASS##Type(CLASS##Type *T);
+#include "clang/AST/TypeNodes.def"
+  // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all Type classes.
+  bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
+  bool VisitType(Type *T) { return true; }
+#define TYPE(CLASS, BASE)                                       \
+  bool WalkUpFrom##CLASS##Type(CLASS##Type *T) {                \
+    TRY_TO(WalkUpFrom##BASE(T));                                \
+    TRY_TO(Visit##CLASS##Type(T));                              \
+    return true;                                                \
+  }                                                             \
+  bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
+#include "clang/AST/TypeNodes.def"
+
+  // ---- Methods on TypeLocs ----
+  // FIXME: this currently just calls the matching Type methods
+
+  // Declare Traverse*() for all concrete Type classes.
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE) \
+  bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
+#include "clang/AST/TypeLocNodes.def"
+  // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
+  bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
+  bool VisitTypeLoc(TypeLoc TL) { return true; }
+
+  // QualifiedTypeLoc and UnqualTypeLoc are not declared in
+  // TypeNodes.def and thus need to be handled specially.
+  bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
+    return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
+  }
+  bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
+  bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) {
+    return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
+  }
+  bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
+
+  // Note that BASE includes trailing 'Type' which CLASS doesn't.
+#define TYPE(CLASS, BASE)                                       \
+  bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) {          \
+    TRY_TO(WalkUpFrom##BASE##Loc(TL));                          \
+    TRY_TO(Visit##CLASS##TypeLoc(TL));                          \
+    return true;                                                \
+  }                                                             \
+  bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
+#include "clang/AST/TypeNodes.def"
+
+  // ---- Methods on Decls ----
+
+  // Declare Traverse*() for all concrete Decl classes.
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE) \
+  bool Traverse##CLASS##Decl(CLASS##Decl *D);
+#include "clang/AST/DeclNodes.inc"
+  // The above header #undefs ABSTRACT_DECL and DECL upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
+  bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
+  bool VisitDecl(Decl *D) { return true; }
+#define DECL(CLASS, BASE)                                       \
+  bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) {                \
+    TRY_TO(WalkUpFrom##BASE(D));                                \
+    TRY_TO(Visit##CLASS##Decl(D));                              \
+    return true;                                                \
+  }                                                             \
+  bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
+#include "clang/AST/DeclNodes.inc"
+
+private:
+  // These are helper methods used by more than one Traverse* method.
+  bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
+  bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
+                                          unsigned Count);
+  bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
+  bool TraverseRecordHelper(RecordDecl *D);
+  bool TraverseCXXRecordHelper(CXXRecordDecl *D);
+  bool TraverseDeclaratorHelper(DeclaratorDecl *D);
+  bool TraverseDeclContextHelper(DeclContext *DC);
+  bool TraverseFunctionHelper(FunctionDecl *D);
+  bool TraverseVarHelper(VarDecl *D);
+};
+
+#define DISPATCH(NAME, CLASS, VAR) \
+  return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR))
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
+  if (!S)
+    return true;
+
+  // 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()) {
+#define OPERATOR(NAME) \
+    case BO_##NAME: DISPATCH(Bin##PtrMemD, BinaryOperator, S);
+
+    BINOP_LIST()
+#undef OPERATOR
+#undef BINOP_LIST
+
+#define OPERATOR(NAME)                                          \
+    case BO_##NAME##Assign:                          \
+      DISPATCH(Bin##NAME##Assign, CompoundAssignOperator, S);
+
+    CAO_LIST()
+#undef OPERATOR
+#undef CAO_LIST
+    }
+  } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
+    switch (UnOp->getOpcode()) {
+#define OPERATOR(NAME)                                                  \
+    case UO_##NAME: DISPATCH(Unary##NAME, UnaryOperator, S);
+
+    UNARYOP_LIST()
+#undef OPERATOR
+#undef UNARYOP_LIST
+    }
+  }
+
+  // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
+  switch (S->getStmtClass()) {
+  case Stmt::NoStmtClass: break;
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT) \
+  case Stmt::CLASS##Class: DISPATCH(CLASS, CLASS, S);
+#include "clang/AST/StmtNodes.inc"
+  }
+
+  return true;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
+  if (T.isNull())
+    return true;
+
+  switch (T->getTypeClass()) {
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE) \
+  case Type::CLASS: DISPATCH(CLASS##Type, CLASS##Type, T.getTypePtr());
+#include "clang/AST/TypeNodes.def"
+  }
+
+  return true;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
+  if (TL.isNull())
+    return true;
+
+  switch (TL.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE) \
+  case TypeLoc::CLASS: \
+    return getDerived().Traverse##CLASS##TypeLoc(*cast<CLASS##TypeLoc>(&TL));
+#include "clang/AST/TypeLocNodes.def"
+  }
+
+  return true;
+}
+
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
+  if (!D)
+    return true;
+
+  // As a syntax visitor, we want to ignore declarations for
+  // implicitly-defined declarations (ones not typed explicitly by the
+  // user).
+  if (D->isImplicit())
+    return true;
+
+  switch (D->getKind()) {
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE) \
+  case Decl::CLASS: DISPATCH(CLASS##Decl, CLASS##Decl, D);
+#include "clang/AST/DeclNodes.inc"
+ }
+
+  return true;
+}
+
+#undef DISPATCH
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
+                                                    NestedNameSpecifier *NNS) {
+  if (!NNS)
+    return true;
+
+  if (NNS->getPrefix())
+    TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
+
+  switch (NNS->getKind()) {
+  case NestedNameSpecifier::Identifier:
+  case NestedNameSpecifier::Namespace:
+  case NestedNameSpecifier::Global:
+    return true;
+
+  case NestedNameSpecifier::TypeSpec:
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+    TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
+  }
+
+  return true;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
+  if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
+    TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
+  else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
+    TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
+
+  return true;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
+                                                const TemplateArgument &Arg) {
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Integral:
+    return true;
+
+  case TemplateArgument::Type:
+    return getDerived().TraverseType(Arg.getAsType());
+
+  case TemplateArgument::Template:
+    return getDerived().TraverseTemplateName(Arg.getAsTemplate());
+
+  case TemplateArgument::Expression:
+    return getDerived().TraverseStmt(Arg.getAsExpr());
+
+  case TemplateArgument::Pack:
+    return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
+                                                  Arg.pack_size());
+  }
+
+  return true;
+}
+
+// FIXME: no template name location?
+// FIXME: no source locations for a template argument pack?
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
+                                           const TemplateArgumentLoc &ArgLoc) {
+  const TemplateArgument &Arg = ArgLoc.getArgument();
+
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Integral:
+    return true;
+
+  case TemplateArgument::Type: {
+    TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo();
+    return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
+  }
+
+  case TemplateArgument::Template:
+    return getDerived().TraverseTemplateName(Arg.getAsTemplate());
+
+  case TemplateArgument::Expression:
+    return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
+
+  case TemplateArgument::Pack:
+    return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
+                                                  Arg.pack_size());
+  }
+
+  return true;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
+                                                  const TemplateArgument *Args,
+                                                            unsigned NumArgs) {
+  for (unsigned I = 0; I != NumArgs; ++I) {
+    TRY_TO(TraverseTemplateArgument(Args[I]));
+  }
+
+  return true;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
+                                            CXXBaseOrMemberInitializer *Init) {
+  // FIXME: recurse on TypeLoc of the base initializer if isBaseInitializer()?
+  if (Init->isWritten())
+    TRY_TO(TraverseStmt(Init->getInit()));
+  return true;
+}
+
+
+// ----------------- Type traversal -----------------
+
+// This macro makes available a variable T, the passed-in type.
+#define DEF_TRAVERSE_TYPE(TYPE, CODE)                     \
+  template<typename Derived>                                           \
+  bool RecursiveASTVisitor<Derived>::Traverse##TYPE (TYPE *T) {        \
+    TRY_TO(WalkUpFrom##TYPE (T));                                      \
+    { CODE; }                                                          \
+    return true;                                                       \
+  }
+
+DEF_TRAVERSE_TYPE(BuiltinType, { })
+
+DEF_TRAVERSE_TYPE(ComplexType, {
+    TRY_TO(TraverseType(T->getElementType()));
+  })
+
+DEF_TRAVERSE_TYPE(PointerType, {
+    TRY_TO(TraverseType(T->getPointeeType()));
+  })
+
+DEF_TRAVERSE_TYPE(BlockPointerType, {
+    TRY_TO(TraverseType(T->getPointeeType()));
+  })
+
+DEF_TRAVERSE_TYPE(LValueReferenceType, {
+    TRY_TO(TraverseType(T->getPointeeType()));
+  })
+
+DEF_TRAVERSE_TYPE(RValueReferenceType, {
+    TRY_TO(TraverseType(T->getPointeeType()));
+  })
+
+DEF_TRAVERSE_TYPE(MemberPointerType, {
+    TRY_TO(TraverseType(QualType(T->getClass(), 0)));
+    TRY_TO(TraverseType(T->getPointeeType()));
+  })
+
+DEF_TRAVERSE_TYPE(ConstantArrayType, {
+    TRY_TO(TraverseType(T->getElementType()));
+  })
+
+DEF_TRAVERSE_TYPE(IncompleteArrayType, {
+    TRY_TO(TraverseType(T->getElementType()));
+  })
+
+DEF_TRAVERSE_TYPE(VariableArrayType, {
+    TRY_TO(TraverseType(T->getElementType()));
+    TRY_TO(TraverseStmt(T->getSizeExpr()));
+  })
+
+DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
+    TRY_TO(TraverseType(T->getElementType()));
+    if (T->getSizeExpr())
+      TRY_TO(TraverseStmt(T->getSizeExpr()));
+  })
+
+DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
+    if (T->getSizeExpr())
+      TRY_TO(TraverseStmt(T->getSizeExpr()));
+    TRY_TO(TraverseType(T->getElementType()));
+  })
+
+DEF_TRAVERSE_TYPE(VectorType, {
+    TRY_TO(TraverseType(T->getElementType()));
+  })
+
+DEF_TRAVERSE_TYPE(ExtVectorType, {
+    TRY_TO(TraverseType(T->getElementType()));
+  })
+
+DEF_TRAVERSE_TYPE(FunctionNoProtoType, {
+    TRY_TO(TraverseType(T->getResultType()));
+  })
+
+DEF_TRAVERSE_TYPE(FunctionProtoType, {
+    TRY_TO(TraverseType(T->getResultType()));
+
+    for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
+                                           AEnd = T->arg_type_end();
+         A != AEnd; ++A) {
+      TRY_TO(TraverseType(*A));
+    }
+
+    for (FunctionProtoType::exception_iterator E = T->exception_begin(),
+                                            EEnd = T->exception_end();
+         E != EEnd; ++E) {
+      TRY_TO(TraverseType(*E));
+    }
+  })
+
+DEF_TRAVERSE_TYPE(UnresolvedUsingType, { })
+DEF_TRAVERSE_TYPE(TypedefType, { })
+
+DEF_TRAVERSE_TYPE(TypeOfExprType, {
+    TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
+  })
+
+DEF_TRAVERSE_TYPE(TypeOfType, {
+    TRY_TO(TraverseType(T->getUnderlyingType()));
+  })
+
+DEF_TRAVERSE_TYPE(DecltypeType, {
+    TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
+  })
+
+DEF_TRAVERSE_TYPE(RecordType, { })
+DEF_TRAVERSE_TYPE(EnumType, { })
+DEF_TRAVERSE_TYPE(TemplateTypeParmType, { })
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, { })
+
+DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
+    TRY_TO(TraverseTemplateName(T->getTemplateName()));
+    TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+  })
+
+DEF_TRAVERSE_TYPE(InjectedClassNameType, { })
+
+DEF_TRAVERSE_TYPE(ElaboratedType, {
+    if (T->getQualifier()) {
+      TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+    }
+    TRY_TO(TraverseType(T->getNamedType()));
+  })
+
+DEF_TRAVERSE_TYPE(DependentNameType, {
+    TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+  })
+
+DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
+    TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+    TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+  })
+
+DEF_TRAVERSE_TYPE(ObjCInterfaceType, { })
+
+DEF_TRAVERSE_TYPE(ObjCObjectType, {
+    // We have to watch out here because an ObjCInterfaceType's base
+    // type is itself.
+    if (T->getBaseType().getTypePtr() != T)
+      TRY_TO(TraverseType(T->getBaseType()));
+  })
+
+DEF_TRAVERSE_TYPE(ObjCObjectPointerType, {
+    TRY_TO(TraverseType(T->getPointeeType()));
+  })
+
+#undef DEF_TRAVERSE_TYPE
+
+// ----------------- TypeLoc traversal -----------------
+
+// This macro makes available a variable TL, the passed-in TypeLoc.
+// It calls WalkUpFrom* for the Type in the given TypeLoc, in addition
+// to WalkUpFrom* for the TypeLoc itself, such that existing clients
+// that override the WalkUpFrom*Type() and/or Visit*Type() methods
+// continue to work.
+#define DEF_TRAVERSE_TYPELOC(TYPE, CODE)                                \
+  template<typename Derived>                                            \
+  bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
+    TRY_TO(WalkUpFrom##TYPE(TL.getTypePtr()));                          \
+    TRY_TO(WalkUpFrom##TYPE##Loc(TL));                                  \
+    { CODE; }                                                           \
+    return true;                                                        \
+  }
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(
+    QualifiedTypeLoc TL) {
+  // Move this over to the 'main' typeloc tree.  Note that this is a
+  // move -- we pretend that we were really looking at the unqualified
+  // typeloc all along -- rather than a recursion, so we don't follow
+  // the normal CRTP plan of going through
+  // getDerived().TraverseTypeLoc.  If we did, we'd be traversing
+  // twice for the same type (once as a QualifiedTypeLoc version of
+  // the type, once as an UnqualifiedTypeLoc version of the type),
+  // which in effect means we'd call VisitTypeLoc twice with the
+  // 'same' type.  This solves that problem, at the cost of never
+  // seeing the qualified version of the type (unless the client
+  // subclasses TraverseQualifiedTypeLoc themselves).  It's not a
+  // perfect solution.  A perfect solution probably requires making
+  // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
+  // wrapper around Type* -- rather than being its own class in the
+  // type hierarchy.
+  return TraverseTypeLoc(TL.getUnqualifiedLoc());
+}
+
+DEF_TRAVERSE_TYPELOC(BuiltinType, { })
+
+// FIXME: ComplexTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(ComplexType, {
+    TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+  })
+
+DEF_TRAVERSE_TYPELOC(PointerType, {
+    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+  })
+
+DEF_TRAVERSE_TYPELOC(BlockPointerType, {
+    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+  })
+
+DEF_TRAVERSE_TYPELOC(LValueReferenceType, {
+    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+  })
+
+DEF_TRAVERSE_TYPELOC(RValueReferenceType, {
+    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+  })
+
+// FIXME: location of base class?
+// We traverse this in the type case as well, but how is it not reached through
+// the pointee type?
+DEF_TRAVERSE_TYPELOC(MemberPointerType, {
+    TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
+    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+  })
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
+  // This isn't available for ArrayType, but is for the ArrayTypeLoc.
+  TRY_TO(TraverseStmt(TL.getSizeExpr()));
+  return true;
+}
+
+DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
+    TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+    return TraverseArrayTypeLocHelper(TL);
+  })
+
+DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
+    TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+    return TraverseArrayTypeLocHelper(TL);
+  })
+
+DEF_TRAVERSE_TYPELOC(VariableArrayType, {
+    TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+    return TraverseArrayTypeLocHelper(TL);
+  })
+
+DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
+    TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+    return TraverseArrayTypeLocHelper(TL);
+  })
+
+// FIXME: order? why not size expr first?
+// FIXME: base VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
+    if (TL.getTypePtr()->getSizeExpr())
+      TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+    TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+  })
+
+// FIXME: VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(VectorType, {
+    TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+  })
+
+// FIXME: size and attributes
+// FIXME: base VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(ExtVectorType, {
+    TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+  })
+
+DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, {
+    TRY_TO(TraverseTypeLoc(TL.getResultLoc()));
+  })
+
+// FIXME: location of arguments, exception specifications (attributes?)
+// Note that we have the ParmVarDecl's here. Do we want to use them?
+DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
+    TRY_TO(TraverseTypeLoc(TL.getResultLoc()));
+
+    FunctionProtoType *T = TL.getTypePtr();
+/*
+    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+      TRY_TO(TraverseDecl(TL.getArg(I)));
+    }
+*/
+    for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
+                                           AEnd = T->arg_type_end();
+         A != AEnd; ++A) {
+      TRY_TO(TraverseType(*A));
+    }
+    for (FunctionProtoType::exception_iterator E = T->exception_begin(),
+                                            EEnd = T->exception_end();
+         E != EEnd; ++E) {
+      TRY_TO(TraverseType(*E));
+    }
+  })
+
+DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, { })
+DEF_TRAVERSE_TYPELOC(TypedefType, { })
+
+DEF_TRAVERSE_TYPELOC(TypeOfExprType, {
+    TRY_TO(TraverseStmt(TL.getUnderlyingExpr()));
+  })
+
+DEF_TRAVERSE_TYPELOC(TypeOfType, {
+    TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+  })
+
+// FIXME: location of underlying expr
+DEF_TRAVERSE_TYPELOC(DecltypeType, {
+    TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
+  })
+
+DEF_TRAVERSE_TYPELOC(RecordType, { })
+DEF_TRAVERSE_TYPELOC(EnumType, { })
+DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, { })
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, { })
+
+// FIXME: use the loc for the template name?
+DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
+    TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
+    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+      TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+    }
+  })
+
+DEF_TRAVERSE_TYPELOC(InjectedClassNameType, { })
+
+// FIXME: use the sourceloc on qualifier?
+DEF_TRAVERSE_TYPELOC(ElaboratedType, {
+    if (TL.getTypePtr()->getQualifier()) {
+      TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
+    }
+    TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
+  })
+
+// FIXME: use the sourceloc on qualifier?
+DEF_TRAVERSE_TYPELOC(DependentNameType, {
+    TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
+  })
+
+DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
+    TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
+    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+      TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+    }
+  })
+
+DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, { })
+
+DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
+    // We have to watch out here because an ObjCInterfaceType's base
+    // type is itself.
+    if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
+      TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
+  })
+
+DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, {
+    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+  })
+
+#undef DEF_TRAVERSE_TYPELOC
+
+// ----------------- Decl traversal -----------------
+//
+// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
+// the children that come from the DeclContext associated with it.
+// Therefore each Traverse* only needs to worry about children other
+// than those.
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
+  if (!DC)
+    return true;
+
+  for (DeclContext::decl_iterator Child = DC->decls_begin(),
+           ChildEnd = DC->decls_end();
+       Child != ChildEnd; ++Child) {
+    TRY_TO(TraverseDecl(*Child));
+  }
+
+  return true;
+}
+
+// This macro makes available a variable D, the passed-in decl.
+#define DEF_TRAVERSE_DECL(DECL, CODE)                           \
+template<typename Derived>                                      \
+bool RecursiveASTVisitor<Derived>::Traverse##DECL (DECL *D) {   \
+  TRY_TO(WalkUpFrom##DECL (D));                                 \
+  { CODE; }                                                     \
+  TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D)));  \
+  return true;                                                  \
+}
+
+DEF_TRAVERSE_DECL(AccessSpecDecl, { })
+
+DEF_TRAVERSE_DECL(BlockDecl, {
+    // We don't traverse nodes in param_begin()/param_end(), as they
+    // appear in decls_begin()/decls_end() and thus are handled by the
+    // DEF_TRAVERSE_DECL macro already.
+    TRY_TO(TraverseStmt(D->getBody()));
+  })
+
+DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
+    TRY_TO(TraverseStmt(D->getAsmString()));
+  })
+
+DEF_TRAVERSE_DECL(FriendDecl, {
+    TRY_TO(TraverseDecl(D->getFriendDecl()));
+  })
+
+DEF_TRAVERSE_DECL(FriendTemplateDecl, {
+    TRY_TO(TraverseDecl(D->getFriendDecl()));
+    for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
+      TemplateParameterList *TPL = D->getTemplateParameterList(I);
+      for (TemplateParameterList::iterator ITPL = TPL->begin(),
+                                           ETPL = TPL->end();
+           ITPL != ETPL; ++ITPL) {
+        TRY_TO(TraverseDecl(*ITPL));
+      }
+    }
+  })
+
+DEF_TRAVERSE_DECL(LinkageSpecDecl, { })
+
+DEF_TRAVERSE_DECL(ObjCClassDecl, {
+    // FIXME: implement this
+  })
+
+DEF_TRAVERSE_DECL(ObjCForwardProtocolDecl, {
+    // FIXME: implement this
+  })
+
+DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {
+    // FIXME: implement this
+  })
+
+DEF_TRAVERSE_DECL(StaticAssertDecl, {
+    TRY_TO(TraverseStmt(D->getAssertExpr()));
+    TRY_TO(TraverseStmt(D->getMessage()));
+  })
+
+DEF_TRAVERSE_DECL(TranslationUnitDecl, {
+    // Code in an unnamed namespace shows up automatically in
+    // decls_begin()/decls_end().  Thus we don't need to recurse on
+    // D->getAnonymousNamespace().
+  })
+
+DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
+    // We shouldn't traverse an aliased namespace, since it will be
+    // defined (and, therefore, traversed) somewhere else.
+    //
+    // This return statement makes sure the traversal of nodes in
+    // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+    // is skipped - don't remove it.
+    return true;
+  })
+
+DEF_TRAVERSE_DECL(NamespaceDecl, {
+    // Code in an unnamed namespace shows up automatically in
+    // decls_begin()/decls_end().  Thus we don't need to recurse on
+    // D->getAnonymousNamespace().
+  })
+
+DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {
+    // FIXME: implement
+  })
+
+DEF_TRAVERSE_DECL(ObjCCategoryDecl, {
+    // FIXME: implement
+  })
+
+DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {
+    // FIXME: implement
+  })
+
+DEF_TRAVERSE_DECL(ObjCImplementationDecl, {
+    // FIXME: implement
+  })
+
+DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {
+    // FIXME: implement
+  })
+
+DEF_TRAVERSE_DECL(ObjCProtocolDecl, {
+    // FIXME: implement
+  })
+
+DEF_TRAVERSE_DECL(ObjCMethodDecl, {
+    // FIXME: implement
+  })
+
+DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
+    // FIXME: implement
+  })
+
+DEF_TRAVERSE_DECL(UsingDecl, {
+    TRY_TO(TraverseNestedNameSpecifier(D->getTargetNestedNameDecl()));
+  })
+
+DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
+    TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
+  })
+
+DEF_TRAVERSE_DECL(UsingShadowDecl, { })
+
+// A helper method for TemplateDecl's children.
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
+    TemplateParameterList *TPL) {
+  if (TPL) {
+    for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+         I != E; ++I) {
+      TRY_TO(TraverseDecl(*I));
+    }
+  }
+  return true;
+}
+
+DEF_TRAVERSE_DECL(ClassTemplateDecl, {
+    TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+    // We should not traverse the specializations/partial
+    // specializations.  Those will show up in other contexts.
+    // getInstantiatedFromMemberTemplate() is just a link from a
+    // template instantiation back to the template from which it was
+    // instantiated, and thus should not be traversed either.
+  })
+
+DEF_TRAVERSE_DECL(FunctionTemplateDecl, {
+    TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+  })
+
+DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
+    // D is the "T" in something like
+    //   template <template <typename> class T> class container { };
+    TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+    if (D->hasDefaultArgument()) {
+      TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
+    }
+    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+  })
+
+DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
+    // D is the "T" in something like "template<typename T> class vector;"
+    if (D->getTypeForDecl())
+      TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+    if (D->hasDefaultArgument())
+      TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
+  })
+
+DEF_TRAVERSE_DECL(TypedefDecl, {
+    TRY_TO(TraverseType(D->getUnderlyingType()));
+    // We shouldn't traverse D->getTypeForDecl(); it's a result of
+    // declaring the typedef, not something that was written in the
+    // source.
+  })
+
+DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
+    // A dependent using declaration which was marked with 'typename'.
+    //   template<class T> class A : public B<T> { using typename B<T>::foo; };
+    TRY_TO(TraverseNestedNameSpecifier(D->getTargetNestedNameSpecifier()));
+    // We shouldn't traverse D->getTypeForDecl(); it's a result of
+    // declaring the type, not something that was written in the
+    // source.
+  })
+
+DEF_TRAVERSE_DECL(EnumDecl, {
+    if (D->getTypeForDecl())
+      TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+
+    TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
+    // The enumerators are already traversed by
+    // decls_begin()/decls_end().
+  })
+
+
+// Helper methods for RecordDecl and its children.
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(
+    RecordDecl *D) {
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the type, not something that was written in the source.
+  //
+  // The anonymous struct or union object is the variable or field
+  // whose type is the anonymous struct or union.  We shouldn't
+  // traverse D->getAnonymousStructOrUnionObject(), as it's not
+  // something that is explicitly written in the source.
+  TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
+  return true;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(
+    CXXRecordDecl *D) {
+  if (!TraverseRecordHelper(D))
+    return false;
+  if (D->hasDefinition()) {
+    for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
+                                            E = D->bases_end();
+         I != E; ++I) {
+      TRY_TO(TraverseTypeLoc(I->getTypeSourceInfo()->getTypeLoc()));
+    }
+    // We don't traverse the friends or the conversions, as they are
+    // already in decls_begin()/decls_end().
+  }
+  return true;
+}
+
+DEF_TRAVERSE_DECL(RecordDecl, {
+    TRY_TO(TraverseRecordHelper(D));
+  })
+
+DEF_TRAVERSE_DECL(CXXRecordDecl, {
+    TRY_TO(TraverseCXXRecordHelper(D));
+  })
+
+DEF_TRAVERSE_DECL(ClassTemplateSpecializationDecl, {
+    // For implicit instantiations ("set<int> x;"), we don't want to
+    // recurse at all, since the instatiated class isn't written in
+    // the source code anywhere.  (Note the instatiated *type* --
+    // set<int> -- is written, and will still get a callback of
+    // TemplateSpecializationType).  For explicit instantiations
+    // ("template set<int>;"), we do need a callback, since this
+    // is the only callback that's made for this instantiation.
+    // We use getTypeAsWritten() to distinguish.
+    // FIXME: see how we want to handle template specializations.
+    if (TypeSourceInfo *TSI = D->getTypeAsWritten())
+      TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
+    return true;
+  })
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
+    const TemplateArgumentLoc *TAL, unsigned Count) {
+  for (unsigned I = 0; I < Count; ++I) {
+    TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
+  }
+  return true;
+}
+
+DEF_TRAVERSE_DECL(ClassTemplatePartialSpecializationDecl, {
+    // The partial specialization.
+    if (TemplateParameterList *TPL = D->getTemplateParameters()) {
+      for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+           I != E; ++I) {
+        TRY_TO(TraverseDecl(*I));
+      }
+    }
+    // The args that remains unspecialized.
+    TRY_TO(TraverseTemplateArgumentLocsHelper(
+        D->getTemplateArgsAsWritten(), D->getNumTemplateArgsAsWritten()));
+
+    // Don't need the ClassTemplatePartialSpecializationHelper, even
+    // though that's our parent class -- we already visit all the
+    // template args here.
+    TRY_TO(TraverseCXXRecordHelper(D));
+  })
+
+DEF_TRAVERSE_DECL(EnumConstantDecl, {
+    TRY_TO(TraverseStmt(D->getInitExpr()));
+  })
+
+DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
+    // Like UnresolvedUsingTypenameDecl, but without the 'typename':
+    //    template <class T> Class A : public Base<T> { using Base<T>::foo; };
+    TRY_TO(TraverseNestedNameSpecifier(D->getTargetNestedNameSpecifier()));
+  })
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
+  TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
+  if (D->getTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  return true;
+}
+
+DEF_TRAVERSE_DECL(FieldDecl, {
+    TRY_TO(TraverseDeclaratorHelper(D));
+    if (D->isBitField())
+      TRY_TO(TraverseStmt(D->getBitWidth()));
+  })
+
+DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
+    TRY_TO(TraverseDeclaratorHelper(D));
+    if (D->isBitField())
+      TRY_TO(TraverseStmt(D->getBitWidth()));
+    // FIXME: implement the rest.
+  })
+
+DEF_TRAVERSE_DECL(ObjCIvarDecl, {
+    TRY_TO(TraverseDeclaratorHelper(D));
+    if (D->isBitField())
+      TRY_TO(TraverseStmt(D->getBitWidth()));
+    // FIXME: implement the rest.
+  })
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
+  TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
+
+  // Visit the function type itself, which can be either
+  // FunctionNoProtoType or FunctionProtoType, or a typedef.  If it's
+  // not a Function*ProtoType, then it can't have a body or arguments,
+  // so we have to do less work.
+  Type *FuncType = D->getType().getTypePtr();
+  if (FunctionProtoType *FuncProto = dyn_cast<FunctionProtoType>(FuncType)) {
+    if (D->isThisDeclarationADefinition()) {
+      // Don't call Traverse*, or the result type and parameter types
+      // will be double counted.
+      TRY_TO(WalkUpFromFunctionProtoType(FuncProto));
+    } else {
+      // This works around a bug in Clang that does not add the parameters
+      // to decls_begin/end for function declarations (as opposed to
+      // definitions):
+      //    http://llvm.org/PR7442
+      // We work around this here by traversing the function type.
+      // This isn't perfect because we don't traverse the default
+      // values, if any.  It also may not interact great with
+      // templates.  But it's the best we can do until the bug is
+      // fixed.
+      // FIXME: replace the entire 'if' statement with
+      //   TRY_TO(WalkUpFromFunctionProtoType(FuncProto));
+      // when the bug is fixed.
+      TRY_TO(TraverseFunctionProtoType(FuncProto));
+      return true;
+    }
+  } else if (FunctionNoProtoType *FuncNoProto =
+      dyn_cast<FunctionNoProtoType>(FuncType)) {
+    // Don't call Traverse*, or the result type will be double
+    // counted.
+    TRY_TO(WalkUpFromFunctionNoProtoType(FuncNoProto));
+  } else {   // a typedef type, or who knows what
+    assert(!D->isThisDeclarationADefinition() && "Unexpected function type");
+    TRY_TO(TraverseType(D->getType()));
+    return true;
+  }
+
+  TRY_TO(TraverseType(D->getResultType()));
+
+  // If we're an explicit template specialization, iterate over the
+  // template args that were explicitly specified.
+  if (const FunctionTemplateSpecializationInfo *FTSI =
+      D->getTemplateSpecializationInfo()) {
+    if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
+        FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
+      // A specialization might not have explicit template arguments if it has
+      // a templated return type and concrete arguments.
+      if (const TemplateArgumentListInfo *TALI =
+          FTSI->TemplateArgumentsAsWritten) {
+        TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getArgumentArray(),
+                                                  TALI->size()));
+      }
+    }
+  }
+
+  for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end();
+       I != E; ++I) {
+    TRY_TO(TraverseDecl(*I));
+  }
+
+  if (FunctionProtoType *FuncProto = dyn_cast<FunctionProtoType>(FuncType)) {
+    if (D->isThisDeclarationADefinition()) {
+      // This would be visited if we called TraverseType(D->getType())
+      // above, but we don't (at least, not in the
+      // declaration-is-a-definition case), in order to avoid duplicate
+      // visiting for parameters.  (We need to check parameters here,
+      // rather than letting D->getType() do it, so we visit default
+      // parameter values).  So we need to re-do some of the work the
+      // type would do.
+      for (FunctionProtoType::exception_iterator
+               E = FuncProto->exception_begin(),
+               EEnd = FuncProto->exception_end();
+           E != EEnd; ++E) {
+        TRY_TO(TraverseType(*E));
+      }
+    }
+  }
+
+  if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
+    // Constructor initializers.
+    for (CXXConstructorDecl::init_iterator I = Ctor->init_begin(),
+                                           E = Ctor->init_end();
+         I != E; ++I) {
+      TRY_TO(TraverseConstructorInitializer(*I));
+    }
+  }
+
+  if (D->isThisDeclarationADefinition()) {
+    TRY_TO(TraverseStmt(D->getBody()));  // Function body.
+  }
+  return true;
+}
+
+DEF_TRAVERSE_DECL(FunctionDecl, {
+    // We skip decls_begin/decls_end, which are already covered by
+    // TraverseFunctionHelper().
+    return TraverseFunctionHelper(D);
+  })
+
+DEF_TRAVERSE_DECL(CXXMethodDecl, {
+    // We skip decls_begin/decls_end, which are already covered by
+    // TraverseFunctionHelper().
+    return TraverseFunctionHelper(D);
+  })
+
+DEF_TRAVERSE_DECL(CXXConstructorDecl, {
+    // We skip decls_begin/decls_end, which are already covered by
+    // TraverseFunctionHelper().
+    return TraverseFunctionHelper(D);
+  })
+
+// CXXConversionDecl is the declaration of a type conversion operator.
+// It's not a cast expression.
+DEF_TRAVERSE_DECL(CXXConversionDecl, {
+    // We skip decls_begin/decls_end, which are already covered by
+    // TraverseFunctionHelper().
+    return TraverseFunctionHelper(D);
+  })
+
+DEF_TRAVERSE_DECL(CXXDestructorDecl, {
+    // We skip decls_begin/decls_end, which are already covered by
+    // TraverseFunctionHelper().
+    return TraverseFunctionHelper(D);
+  })
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
+  TRY_TO(TraverseDeclaratorHelper(D));
+  TRY_TO(TraverseStmt(D->getInit()));
+  return true;
+}
+
+DEF_TRAVERSE_DECL(VarDecl, {
+    TRY_TO(TraverseVarHelper(D));
+  })
+
+DEF_TRAVERSE_DECL(ImplicitParamDecl, {
+    TRY_TO(TraverseVarHelper(D));
+  })
+
+DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
+    // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
+    TRY_TO(TraverseVarHelper(D));
+    TRY_TO(TraverseStmt(D->getDefaultArgument()));
+  })
+
+DEF_TRAVERSE_DECL(ParmVarDecl, {
+    TRY_TO(TraverseVarHelper(D));
+
+    if (D->hasDefaultArg() &&
+        D->hasUninstantiatedDefaultArg() &&
+        !D->hasUnparsedDefaultArg())
+      TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
+
+    if (D->hasDefaultArg() &&
+        !D->hasUninstantiatedDefaultArg() &&
+        !D->hasUnparsedDefaultArg())
+      TRY_TO(TraverseStmt(D->getDefaultArg()));
+  })
+
+#undef DEF_TRAVERSE_DECL
+
+// ----------------- Stmt traversal -----------------
+//
+// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
+// over the children defined in child_begin/child_end (every stmt
+// defines these, though sometimes the range is empty).  Each
+// individual Traverse* method only needs to worry about children
+// other than those.  To see what child_begin()/end() does for a given
+// class, see, e.g.,
+// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
+
+// This macro makes available a variable S, the passed-in stmt.
+#define DEF_TRAVERSE_STMT(STMT, CODE)                                   \
+template<typename Derived>                                              \
+bool RecursiveASTVisitor<Derived>::Traverse##STMT (STMT *S) {           \
+  TRY_TO(WalkUpFrom##STMT(S));                                          \
+  { CODE; }                                                             \
+  for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end(); \
+       C != CEnd; ++C) {                                                \
+    TRY_TO(TraverseStmt(*C));                                           \
+  }                                                                     \
+  return true;                                                          \
+}
+
+DEF_TRAVERSE_STMT(AsmStmt, {
+    TRY_TO(TraverseStmt(S->getAsmString()));
+    for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
+      TRY_TO(TraverseStmt(S->getInputConstraintLiteral(I)));
+    }
+    for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
+      TRY_TO(TraverseStmt(S->getOutputConstraintLiteral(I)));
+    }
+    for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
+      TRY_TO(TraverseStmt(S->getClobber(I)));
+    }
+    // child_begin()/end() iterates over inputExpr and outputExpr.
+  })
+
+DEF_TRAVERSE_STMT(CXXCatchStmt, {
+    TRY_TO(TraverseDecl(S->getExceptionDecl()));
+    // child_begin()/end() iterates over the handler block.
+  })
+
+DEF_TRAVERSE_STMT(DeclStmt, {
+    for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();
+         I != E; ++I) {
+      TRY_TO(TraverseDecl(*I));
+    }
+    // Suppress the default iteration over child_begin/end by
+    // returning.  Here's why: A DeclStmt looks like 'type var [=
+    // initializer]'.  The decls above already traverse over the
+    // initializers, so we don't have to do it again (which
+    // child_begin/end would do).
+    return true;
+  })
+
+
+// These non-expr stmts (most of them), do not need any action except
+// iterating over the children.
+DEF_TRAVERSE_STMT(BreakStmt, { })
+DEF_TRAVERSE_STMT(CXXTryStmt, { })
+DEF_TRAVERSE_STMT(CaseStmt, { })
+DEF_TRAVERSE_STMT(CompoundStmt, { })
+DEF_TRAVERSE_STMT(ContinueStmt, { })
+DEF_TRAVERSE_STMT(DefaultStmt, { })
+DEF_TRAVERSE_STMT(DoStmt, { })
+DEF_TRAVERSE_STMT(ForStmt, { })
+DEF_TRAVERSE_STMT(GotoStmt, { })
+DEF_TRAVERSE_STMT(IfStmt, { })
+DEF_TRAVERSE_STMT(IndirectGotoStmt, { })
+DEF_TRAVERSE_STMT(LabelStmt, { })
+DEF_TRAVERSE_STMT(NullStmt, { })
+DEF_TRAVERSE_STMT(ObjCAtCatchStmt, { })
+DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, { })
+DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, { })
+DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { })
+DEF_TRAVERSE_STMT(ObjCAtTryStmt, { })
+DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { })
+DEF_TRAVERSE_STMT(ReturnStmt, { })
+DEF_TRAVERSE_STMT(SwitchCase, { })
+DEF_TRAVERSE_STMT(SwitchStmt, { })
+DEF_TRAVERSE_STMT(WhileStmt, { })
+
+
+DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
+    if (S->hasExplicitTemplateArgs()) {
+      TRY_TO(TraverseTemplateArgumentLocsHelper(
+          S->getTemplateArgs(), S->getNumTemplateArgs()));
+    }
+    TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
+  })
+
+DEF_TRAVERSE_STMT(DeclRefExpr, {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(
+        S->getTemplateArgs(), S->getNumTemplateArgs()));
+    // FIXME: Should we be recursing on the qualifier?
+    TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
+  })
+
+DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
+    // FIXME: Should we be recursing on these two things?
+    if (S->hasExplicitTemplateArgs()) {
+      TRY_TO(TraverseTemplateArgumentLocsHelper(
+          S->getExplicitTemplateArgs().getTemplateArgs(),
+          S->getNumTemplateArgs()));
+    }
+    TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
+  })
+
+DEF_TRAVERSE_STMT(MemberExpr, {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(
+        S->getTemplateArgs(), S->getNumTemplateArgs()));
+    // FIXME: Should we be recursing on the qualifier?
+    TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
+  })
+
+DEF_TRAVERSE_STMT(ImplicitCastExpr, {
+    // We don't traverse the cast type, as it's not written in the
+    // source code.
+  })
+
+DEF_TRAVERSE_STMT(CStyleCastExpr, {
+    TRY_TO(TraverseType(S->getTypeAsWritten()));
+  })
+
+DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
+    TRY_TO(TraverseType(S->getTypeAsWritten()));
+  })
+
+DEF_TRAVERSE_STMT(CXXConstCastExpr, {
+    TRY_TO(TraverseType(S->getTypeAsWritten()));
+  })
+
+DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
+    TRY_TO(TraverseType(S->getTypeAsWritten()));
+  })
+
+DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
+    TRY_TO(TraverseType(S->getTypeAsWritten()));
+  })
+
+DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
+    TRY_TO(TraverseType(S->getTypeAsWritten()));
+  })
+
+// InitListExpr is a tricky one, because we want to do all our work on
+// the syntactic form of the listexpr, but this method takes the
+// semantic form by default.  We can't use the macro helper because it
+// calls WalkUp*() on the semantic form, before our code can convert
+// to the syntactic form.
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
+  if (InitListExpr *Syn = S->getSyntacticForm())
+    S = Syn;
+  TRY_TO(WalkUpFromInitListExpr(S));
+  // All we need are the default actions.  FIXME: use a helper function.
+  for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end();
+       C != CEnd; ++C) {
+    TRY_TO(TraverseStmt(*C));
+  }
+  return true;
+}
+
+DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
+    // This is called for code like 'return T()' where T is a built-in
+    // (i.e. non-class) type.
+    if (!S->isImplicit())
+      TRY_TO(TraverseType(S->getType()));
+  })
+
+DEF_TRAVERSE_STMT(CXXNewExpr, {
+    TRY_TO(TraverseType(S->getAllocatedType()));
+  })
+
+DEF_TRAVERSE_STMT(OffsetOfExpr, {
+    // The child-iterator will pick up the expression representing
+    // the field.
+    // FIMXE: for code like offsetof(Foo, a.b.c), should we get
+    // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
+    TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+  })
+
+DEF_TRAVERSE_STMT(SizeOfAlignOfExpr, {
+    // The child-iterator will pick up the arg if it's an expression,
+    // but not if it's a type.
+    if (S->isArgumentType())
+      TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
+  })
+
+DEF_TRAVERSE_STMT(CXXTypeidExpr, {
+    // The child-iterator will pick up the arg if it's an expression,
+    // but not if it's a type.
+    if (S->isTypeOperand())
+      TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+  })
+
+DEF_TRAVERSE_STMT(TypesCompatibleExpr, {
+    TRY_TO(TraverseTypeLoc(S->getArgTInfo1()->getTypeLoc()));
+    TRY_TO(TraverseTypeLoc(S->getArgTInfo2()->getTypeLoc()));
+  })
+
+DEF_TRAVERSE_STMT(UnaryTypeTraitExpr, {
+    TRY_TO(TraverseType(S->getQueriedType()));
+  })
+
+// These exprs (most of them), do not need any action except iterating
+// over the children.
+DEF_TRAVERSE_STMT(AddrLabelExpr, { })
+DEF_TRAVERSE_STMT(ArraySubscriptExpr, { })
+DEF_TRAVERSE_STMT(BlockDeclRefExpr, { })
+DEF_TRAVERSE_STMT(BlockExpr, { })
+DEF_TRAVERSE_STMT(ChooseExpr, { })
+DEF_TRAVERSE_STMT(CompoundLiteralExpr, { })
+DEF_TRAVERSE_STMT(CXXBindReferenceExpr, { })
+DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { })
+DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { })
+DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { })
+DEF_TRAVERSE_STMT(CXXDeleteExpr, { })
+DEF_TRAVERSE_STMT(CXXExprWithTemporaries, { })
+DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })
+DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, { })
+DEF_TRAVERSE_STMT(CXXThisExpr, { })
+DEF_TRAVERSE_STMT(CXXThrowExpr, { })
+DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, { })
+DEF_TRAVERSE_STMT(DesignatedInitExpr, { })
+DEF_TRAVERSE_STMT(ExtVectorElementExpr, { })
+DEF_TRAVERSE_STMT(GNUNullExpr, { })
+DEF_TRAVERSE_STMT(ImplicitValueInitExpr, { })
+DEF_TRAVERSE_STMT(ObjCEncodeExpr, { })
+DEF_TRAVERSE_STMT(ObjCImplicitSetterGetterRefExpr, { })
+DEF_TRAVERSE_STMT(ObjCIsaExpr, { })
+DEF_TRAVERSE_STMT(ObjCIvarRefExpr, { })
+DEF_TRAVERSE_STMT(ObjCMessageExpr, { })
+DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { })
+DEF_TRAVERSE_STMT(ObjCProtocolExpr, { })
+DEF_TRAVERSE_STMT(ObjCSelectorExpr, { })
+DEF_TRAVERSE_STMT(ObjCSuperExpr, { })
+DEF_TRAVERSE_STMT(ParenExpr, { })
+DEF_TRAVERSE_STMT(ParenListExpr, { })
+DEF_TRAVERSE_STMT(PredefinedExpr, { })
+DEF_TRAVERSE_STMT(ShuffleVectorExpr, { })
+DEF_TRAVERSE_STMT(StmtExpr, { })
+DEF_TRAVERSE_STMT(UnresolvedLookupExpr, { })
+DEF_TRAVERSE_STMT(UnresolvedMemberExpr, { })
+DEF_TRAVERSE_STMT(VAArgExpr, {
+    // The child-iterator will pick up the expression argument.
+    TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
+  })
+DEF_TRAVERSE_STMT(CXXConstructExpr, { })
+
+DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
+    // This is called for code like 'return T()' where T is a class type.
+    TRY_TO(TraverseType(S->getType()));
+  })
+
+DEF_TRAVERSE_STMT(CallExpr, { })
+DEF_TRAVERSE_STMT(CXXMemberCallExpr, { })
+DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { })
+
+// These operators (all of them) do not need any action except
+// iterating over the children.
+DEF_TRAVERSE_STMT(ConditionalOperator, { })
+DEF_TRAVERSE_STMT(UnaryOperator, { })
+DEF_TRAVERSE_STMT(BinaryOperator, { })
+DEF_TRAVERSE_STMT(CompoundAssignOperator, { })
+
+// These literals (all of them) do not need any action.
+DEF_TRAVERSE_STMT(IntegerLiteral, { })
+DEF_TRAVERSE_STMT(CharacterLiteral, { })
+DEF_TRAVERSE_STMT(FloatingLiteral, { })
+DEF_TRAVERSE_STMT(ImaginaryLiteral, { })
+DEF_TRAVERSE_STMT(StringLiteral, { })
+DEF_TRAVERSE_STMT(ObjCStringLiteral, { })
+
+// FIXME: look at the following tricky-seeming exprs to see if we
+// need to recurse on anything.  These are ones that have methods
+// returning decls or qualtypes or nestednamespecifier -- though I'm
+// not sure if they own them -- or just seemed very complicated, or
+// had lots of sub-types to explore.
+//
+// VisitOverloadExpr and its children: recurse on template args? etc?
+
+// FIXME: go through all the stmts and exprs again, and see which of them
+// create new types, and recurse on the types (TypeLocs?) of those.
+// Candidates:
+//
+//    http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
+//    http://clang.llvm.org/doxygen/classclang_1_1SizeOfAlignOfExpr.html
+//    http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
+//    http://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html
+//    Every class that has getQualifier.
+
+#undef DEF_TRAVERSE_STMT
+
+#undef TRY_TO
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index 01f4b29..ba77829 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -92,6 +92,11 @@
     return D;
   }
 
+  /// \brief Returns true if this is the first declaration.
+  bool isFirstDeclaration() const {
+    return RedeclLink.NextIsLatest();
+  }
+
   /// \brief Returns the most recent (re)declaration of this declaration.
   decl_type *getMostRecentDeclaration() {
     return getFirstDeclaration()->RedeclLink.getNext();
@@ -172,6 +177,9 @@
                                           static_cast<const decl_type*>(this)));
   }
   redecl_iterator redecls_end() const { return redecl_iterator(); }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
 };
 
 }
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 0b68a40..62a6b64 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -98,12 +98,12 @@
   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"
+#define STMT_RANGE(BASE, FIRST, LAST) \
+        first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class,
+#define LAST_STMT_RANGE(BASE, FIRST, LAST) \
+        first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class
+#define ABSTRACT_STMT(STMT)
+#include "clang/AST/StmtNodes.inc"
 };
 private:
   /// \brief The statement class.
@@ -151,22 +151,11 @@
   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);
@@ -181,13 +170,6 @@
   }
 #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
@@ -221,6 +203,7 @@
   /// This is useful in a debugger.
   void dump() const;
   void dump(SourceManager &SM) const;
+  void dump(llvm::raw_ostream &OS, SourceManager &SM) const;
 
   /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
   void dumpAll() const;
@@ -295,9 +278,6 @@
   DeclGroupRef DG;
   SourceLocation StartLoc, EndLoc;
 
-protected:
-  virtual void DoDestroy(ASTContext &Ctx);
-
 public:
   DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
            SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
@@ -615,24 +595,16 @@
 /// IfStmt - This represents an if/then/else.
 ///
 class IfStmt : public Stmt {
-  enum { COND, THEN, ELSE, END_EXPR };
+  enum { VAR, 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;
-  }
-
+  IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, 
+         Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = 0);
+  
   /// \brief Build an empty if/then/else statement
   explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
 
@@ -644,8 +616,8 @@
   ///   printf("x is %d", x);
   /// }
   /// \endcode
-  VarDecl *getConditionVariable() const { return Var; }
-  void setConditionVariable(VarDecl *V) { Var = V; }
+  VarDecl *getConditionVariable() const;
+  void setConditionVariable(ASTContext &C, VarDecl *V);
   
   const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
   void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
@@ -679,31 +651,19 @@
   // 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 };
+  enum { VAR, 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;
-  }
+  SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond);
 
   /// \brief Build a empty switch statement.
   explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
@@ -717,8 +677,8 @@
   ///   // ...
   /// }
   /// \endcode
-  VarDecl *getConditionVariable() const { return Var; }
-  void setConditionVariable(VarDecl *V) { Var = V; }
+  VarDecl *getConditionVariable() const;
+  void setConditionVariable(ASTContext &C, VarDecl *V);
 
   const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
   const Stmt *getBody() const { return SubExprs[BODY]; }
@@ -766,18 +726,12 @@
 /// WhileStmt - This represents a 'while' stmt.
 ///
 class WhileStmt : public Stmt {
-  enum { COND, BODY, END_EXPR };
-  VarDecl *Var;
+  enum { VAR, COND, BODY, END_EXPR };
   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;
-  }
+  WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, 
+            SourceLocation WL);
 
   /// \brief Build an empty while statement.
   explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
@@ -790,8 +744,8 @@
   ///   // ...
   /// }
   /// \endcode
-  VarDecl *getConditionVariable() const { return Var; }
-  void setConditionVariable(VarDecl *V) { Var = V; }
+  VarDecl *getConditionVariable() const;
+  void setConditionVariable(ASTContext &C, VarDecl *V);
 
   Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
   const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
@@ -814,9 +768,6 @@
   // Iterators
   virtual child_iterator child_begin();
   virtual child_iterator child_end();
-  
-protected:
-  virtual void DoDestroy(ASTContext &Ctx);
 };
 
 /// DoStmt - This represents a 'do/while' stmt.
@@ -873,23 +824,14 @@
 /// specified in the source.
 ///
 class ForStmt : public Stmt {
-  enum { INIT, COND, INC, BODY, END_EXPR };
+  enum { INIT, CONDVAR, 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;
-  }
+  ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, 
+          Stmt *Body, SourceLocation FL, SourceLocation LP, SourceLocation RP);
 
   /// \brief Build an empty for statement.
   explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { }
@@ -904,8 +846,8 @@
   ///   // ...
   /// }
   /// \endcode
-  VarDecl *getConditionVariable() const { return CondVar; }
-  void setConditionVariable(VarDecl *V) { CondVar = V; }
+  VarDecl *getConditionVariable() const;
+  void setConditionVariable(ASTContext &C, VarDecl *V);
   
   Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
   Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
@@ -939,9 +881,6 @@
   // Iterators
   virtual child_iterator child_begin();
   virtual child_iterator child_end();
-  
-protected:
-  virtual void DoDestroy(ASTContext &Ctx);
 };
 
 /// GotoStmt - This represents a direct goto.
@@ -1083,9 +1022,15 @@
 class ReturnStmt : public Stmt {
   Stmt *RetExpr;
   SourceLocation RetLoc;
+  const VarDecl *NRVOCandidate;
+  
 public:
-  ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
-    RetExpr((Stmt*) E), RetLoc(RL) {}
+  ReturnStmt(SourceLocation RL)
+    : Stmt(ReturnStmtClass), RetExpr(0), RetLoc(RL), NRVOCandidate(0) { }
+
+  ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
+    : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL),
+      NRVOCandidate(NRVOCandidate) {}
 
   /// \brief Build an empty return expression.
   explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }
@@ -1097,6 +1042,14 @@
   SourceLocation getReturnLoc() const { return RetLoc; }
   void setReturnLoc(SourceLocation L) { RetLoc = L; }
 
+  /// \brief Retrieve the variable that might be used for the named return
+  /// value optimization.
+  ///
+  /// The optimization itself can only be performed if the variable is
+  /// also marked as an NRVO object.
+  const VarDecl *getNRVOCandidate() const { return NRVOCandidate; }
+  void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; }
+  
   virtual SourceRange getSourceRange() const;
 
   static bool classof(const Stmt *T) {
@@ -1128,9 +1081,6 @@
   StringLiteral **Constraints;
   Stmt **Exprs;
   StringLiteral **Clobbers;
-
-protected:
-  virtual void DoDestroy(ASTContext &Ctx);
   
 public:
   AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, 
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index 4e87c27..0508f35 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -29,14 +29,14 @@
   /// 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) {}
 
+  CXXCatchStmt(EmptyShell Empty)
+  : Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {}
+
   virtual SourceRange getSourceRange() const {
     return SourceRange(CatchLoc, HandlerBlock->getLocEnd());
   }
@@ -53,6 +53,8 @@
 
   virtual child_iterator child_begin();
   virtual child_iterator child_end();
+
+  friend class ASTStmtReader;
 };
 
 /// CXXTryStmt - A C++ try block, including all handlers.
@@ -64,38 +66,46 @@
   CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers,
              unsigned numHandlers);
 
+  CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
+    : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
+
+  Stmt const * const *getStmts() const {
+    return reinterpret_cast<Stmt const * const*>(this + 1);
+  }
+  Stmt **getStmts() {
+    return reinterpret_cast<Stmt **>(this + 1);
+  }
+
 public:
   static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc,
                             Stmt *tryBlock, Stmt **handlers,
                             unsigned numHandlers);
 
+  static CXXTryStmt *Create(ASTContext &C, EmptyShell Empty,
+                            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();
+    return getStmts()[NumHandlers]->getLocEnd();
   }
 
   CompoundStmt *getTryBlock() {
-    Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
-    return llvm::cast<CompoundStmt>(Stmts[0]);
+    return llvm::cast<CompoundStmt>(getStmts()[0]);
   }
   const CompoundStmt *getTryBlock() const {
-    Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
-    return llvm::cast<CompoundStmt>(Stmts[0]);
+    return llvm::cast<CompoundStmt>(getStmts()[0]);
   }
 
   unsigned getNumHandlers() const { return NumHandlers; }
   CXXCatchStmt *getHandler(unsigned i) {
-    Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
-    return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
+    return llvm::cast<CXXCatchStmt>(getStmts()[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]);
+    return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]);
   }
 
   static bool classof(const Stmt *T) {
@@ -105,6 +115,8 @@
 
   virtual child_iterator child_begin();
   virtual child_iterator child_end();
+
+  friend class ASTStmtReader;
 };
 
 
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
index a48f4e6..4da2e34 100644
--- a/include/clang/AST/StmtIterator.h
+++ b/include/clang/AST/StmtIterator.h
@@ -16,6 +16,7 @@
 
 #include "llvm/System/DataTypes.h"
 #include <cassert>
+#include <cstddef>
 #include <iterator>
 
 namespace clang {
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
deleted file mode 100644
index 4e80ecb..0000000
--- a/include/clang/AST/StmtNodes.def
+++ /dev/null
@@ -1,164 +0,0 @@
-//===-- 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/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
index 4986f08..b8c141d 100644
--- a/include/clang/AST/StmtVisitor.h
+++ b/include/clang/AST/StmtVisitor.h
@@ -37,78 +37,67 @@
     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 BO_PtrMemD:   DISPATCH(BinPtrMemD,   BinaryOperator);
+      case BO_PtrMemI:   DISPATCH(BinPtrMemI,   BinaryOperator);
+      case BO_Mul:       DISPATCH(BinMul,       BinaryOperator);
+      case BO_Div:       DISPATCH(BinDiv,       BinaryOperator);
+      case BO_Rem:       DISPATCH(BinRem,       BinaryOperator);
+      case BO_Add:       DISPATCH(BinAdd,       BinaryOperator);
+      case BO_Sub:       DISPATCH(BinSub,       BinaryOperator);
+      case BO_Shl:       DISPATCH(BinShl,       BinaryOperator);
+      case BO_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 BO_LT:        DISPATCH(BinLT,        BinaryOperator);
+      case BO_GT:        DISPATCH(BinGT,        BinaryOperator);
+      case BO_LE:        DISPATCH(BinLE,        BinaryOperator);
+      case BO_GE:        DISPATCH(BinGE,        BinaryOperator);
+      case BO_EQ:        DISPATCH(BinEQ,        BinaryOperator);
+      case BO_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);
+      case BO_And:       DISPATCH(BinAnd,       BinaryOperator);
+      case BO_Xor:       DISPATCH(BinXor,       BinaryOperator);
+      case BO_Or :       DISPATCH(BinOr,        BinaryOperator);
+      case BO_LAnd:      DISPATCH(BinLAnd,      BinaryOperator);
+      case BO_LOr :      DISPATCH(BinLOr,       BinaryOperator);
+      case BO_Assign:    DISPATCH(BinAssign,    BinaryOperator);
+      case BO_MulAssign: DISPATCH(BinMulAssign, CompoundAssignOperator);
+      case BO_DivAssign: DISPATCH(BinDivAssign, CompoundAssignOperator);
+      case BO_RemAssign: DISPATCH(BinRemAssign, CompoundAssignOperator);
+      case BO_AddAssign: DISPATCH(BinAddAssign, CompoundAssignOperator);
+      case BO_SubAssign: DISPATCH(BinSubAssign, CompoundAssignOperator);
+      case BO_ShlAssign: DISPATCH(BinShlAssign, CompoundAssignOperator);
+      case BO_ShrAssign: DISPATCH(BinShrAssign, CompoundAssignOperator);
+      case BO_AndAssign: DISPATCH(BinAndAssign, CompoundAssignOperator);
+      case BO_OrAssign:  DISPATCH(BinOrAssign,  CompoundAssignOperator);
+      case BO_XorAssign: DISPATCH(BinXorAssign, CompoundAssignOperator);
+      case BO_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);
+      case UO_PostInc:   DISPATCH(UnaryPostInc,   UnaryOperator);
+      case UO_PostDec:   DISPATCH(UnaryPostDec,   UnaryOperator);
+      case UO_PreInc:    DISPATCH(UnaryPreInc,    UnaryOperator);
+      case UO_PreDec:    DISPATCH(UnaryPreDec,    UnaryOperator);
+      case UO_AddrOf:    DISPATCH(UnaryAddrOf,    UnaryOperator);
+      case UO_Deref:     DISPATCH(UnaryDeref,     UnaryOperator);
+      case UO_Plus:      DISPATCH(UnaryPlus,      UnaryOperator);
+      case UO_Minus:     DISPATCH(UnaryMinus,     UnaryOperator);
+      case UO_Not:       DISPATCH(UnaryNot,       UnaryOperator);
+      case UO_LNot:      DISPATCH(UnaryLNot,      UnaryOperator);
+      case UO_Real:      DISPATCH(UnaryReal,      UnaryOperator);
+      case UO_Imag:      DISPATCH(UnaryImag,      UnaryOperator);
+      case UO_Extension: DISPATCH(UnaryExtension, 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 ABSTRACT_STMT(STMT)
 #define STMT(CLASS, PARENT)                              \
     case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS);
-#include "clang/AST/StmtNodes.def"
+#include "clang/AST/StmtNodes.inc"
     }
   }
 
@@ -116,7 +105,7 @@
   // 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"
+#include "clang/AST/StmtNodes.inc"
 
   // If the implementation doesn't implement binary operator methods, fall back
   // on VisitBinaryOperator.
@@ -163,7 +152,7 @@
   UNARYOP_FALLBACK(Plus)      UNARYOP_FALLBACK(Minus)
   UNARYOP_FALLBACK(Not)       UNARYOP_FALLBACK(LNot)
   UNARYOP_FALLBACK(Real)      UNARYOP_FALLBACK(Imag)
-  UNARYOP_FALLBACK(Extension) UNARYOP_FALLBACK(OffsetOf)
+  UNARYOP_FALLBACK(Extension)
 #undef UNARYOP_FALLBACK
 
   // Base case, ignore it. :)
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 50a100c..7d5123f 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -28,6 +28,7 @@
 namespace clang {
 
 class Decl;
+class DiagnosticBuilder;
 class Expr;
 class TypeSourceInfo;
 
@@ -255,6 +256,10 @@
     return Args.NumArgs;
   }
 
+  /// Determines whether two template arguments are superficially the
+  /// same.
+  bool structurallyEquals(const TemplateArgument &Other) const;
+
   /// \brief Construct a template argument pack.
   void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
 
@@ -473,6 +478,31 @@
   }
 };
 
+const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                    const TemplateArgument &Arg);
+
+inline TemplateSpecializationType::iterator
+    TemplateSpecializationType::end() const {
+  return getArgs() + getNumArgs();
 }
 
+inline DependentTemplateSpecializationType::iterator
+    DependentTemplateSpecializationType::end() const {
+  return getArgs() + getNumArgs();
+}
+
+inline const TemplateArgument &
+    TemplateSpecializationType::getArg(unsigned Idx) const {
+  assert(Idx < getNumArgs() && "Template argument out of range");
+  return getArgs()[Idx];
+}
+
+inline const TemplateArgument &
+    DependentTemplateSpecializationType::getArg(unsigned Idx) const {
+  assert(Idx < getNumArgs() && "Template argument out of range");
+  return getArgs()[Idx];
+}
+  
+} // end namespace clang
+
 #endif
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index f3de9fa..ddfac71 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -101,6 +101,14 @@
   }
 
 public:
+  // \brief Kind of name that is actually stored.
+  enum NameKind {
+    Template,
+    OverloadedTemplate,
+    QualifiedTemplate,
+    DependentTemplate
+  };
+
   TemplateName() : Storage() { }
   explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
   explicit TemplateName(OverloadedTemplateStorage *Storage)
@@ -110,6 +118,9 @@
 
   /// \brief Determine whether this template name is NULL.
   bool isNull() const { return Storage.isNull(); }
+  
+  // \brief Get the kind of name that is actually stored.
+  NameKind getKind() const;
 
   /// \brief Retrieve the the underlying template declaration that
   /// this template name refers to, if known.
@@ -188,7 +199,7 @@
 /// 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,
+/// manner, it is to TemplateName what ElaboratedType 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.
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 822f490..b7d0510 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -92,7 +92,7 @@
   class TemplateArgumentLoc;
   class TemplateArgumentListInfo;
   class Type;
-  class QualifiedNameType;
+  class ElaboratedType;
   struct PrintingPolicy;
 
   template <typename> class CanQual;  
@@ -271,6 +271,8 @@
     }
   }
 
+  bool isSupersetOf(Qualifiers Other) const;
+
   bool operator==(Qualifiers Other) const { return Mask == Other.Mask; }
   bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; }
 
@@ -287,7 +289,18 @@
     L += R;
     return L;
   }
+  
+  Qualifiers &operator-=(Qualifiers R) {
+    Mask = Mask & ~(R.Mask);
+    return *this;
+  }
 
+  /// \brief Compute the difference between two qualifier sets.
+  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;
@@ -396,7 +409,8 @@
   CC_Default,
   CC_C,           // __attribute__((cdecl))
   CC_X86StdCall,  // __attribute__((stdcall))
-  CC_X86FastCall  // __attribute__((fastcall))
+  CC_X86FastCall, // __attribute__((fastcall))
+  CC_X86ThisCall  // __attribute__((thiscall))
 };
 
 
@@ -626,6 +640,16 @@
   bool isAtLeastAsQualifiedAs(QualType Other) const;
   QualType getNonReferenceType() const;
 
+  /// \brief Determine the type of a (typically non-lvalue) expression with the
+  /// specified result type.
+  ///                       
+  /// This routine should be used for expressions for which the return type is
+  /// explicitly specified (e.g., in a cast or call) and isn't necessarily
+  /// an lvalue. It removes a top-level reference (since there are no 
+  /// expressions of reference type) and deletes top-level cvr-qualifiers
+  /// from non-class types (in C++) or all types (in C).
+  QualType getNonLValueExprType(ASTContext &Context) 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
@@ -755,6 +779,9 @@
   };
 
 private:
+  Type(const Type&);           // DO NOT IMPLEMENT.
+  void operator=(const Type&); // DO NOT IMPLEMENT.
+
   QualType CanonicalType;
 
   /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
@@ -764,22 +791,42 @@
   /// 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;
+  
+  /// \brief Whether the linkage of this type is already known.
+  mutable bool LinkageKnown : 1;
+  
+  /// \brief Linkage of this type.
+  mutable unsigned CachedLinkage : 2;
 
-  Type(const Type&);           // DO NOT IMPLEMENT.
-  void operator=(const Type&); // DO NOT IMPLEMENT.
+  /// \brief FromAST - Whether this type comes from an AST file.
+  mutable bool FromAST : 1;
+
+  /// \brief Set whether this type comes from an AST file.
+  void setFromAST(bool V = true) const { 
+    FromAST = V;
+  }
+
 protected:
+  /// \brief Compute the linkage of this type.
+  virtual Linkage getLinkageImpl() const;
+  
+  enum { BitsRemainingInType = 19 };
+
   // 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);
+      TC(tc), Dependent(dependent), LinkageKnown(false), 
+      CachedLinkage(NoLinkage), FromAST(false) {}
+  virtual ~Type();
   friend class ASTContext;
 
 public:
   TypeClass getTypeClass() const { return static_cast<TypeClass>(TC); }
 
+  /// \brief Whether this type comes from an AST file.
+  bool isFromAST() const { return FromAST; }
+
   bool isCanonicalUnqualified() const {
     return CanonicalType.getTypePtr() == this;
   }
@@ -787,14 +834,6 @@
   /// 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
@@ -821,6 +860,9 @@
   /// Helper methods to distinguish type categories. All type predicates
   /// operate on the canonical type, ignoring typedefs and qualifiers.
 
+  /// isBuiltinType - returns true if the type is a builtin type.
+  bool isBuiltinType() const;
+
   /// isSpecificBuiltinType - Test for a particular builtin type.
   bool isSpecificBuiltinType(unsigned K) const;
 
@@ -832,8 +874,11 @@
   bool isCharType() const;
   bool isWideCharType() const;
   bool isAnyCharacterType() const;
-  bool isIntegralType() const;
+  bool isIntegralType(ASTContext &Ctx) const;
   
+  /// \brief Determine whether this type is an integral or enumeration type.
+  bool isIntegralOrEnumerationType() const;
+                                   
   /// Floating point categories.
   bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
   /// isComplexType() does *not* include complex integers (a GCC extension).
@@ -863,6 +908,7 @@
   bool isFunctionPointerType() const;
   bool isMemberPointerType() const;
   bool isMemberFunctionPointerType() const;
+  bool isMemberDataPointerType() const;
   bool isArrayType() const;
   bool isConstantArrayType() const;
   bool isIncompleteArrayType() const;
@@ -879,10 +925,11 @@
   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 isObjCObjectType() const;                // NSString or typeof(*(id)0)
   bool isObjCQualifiedInterfaceType() const;    // NSString<foo>
   bool isObjCQualifiedIdType() const;           // id<foo>
   bool isObjCQualifiedClassType() const;        // Class<foo>
+  bool isObjCObjectOrInterfaceType() const;
   bool isObjCIdType() const;                    // id
   bool isObjCClassType() const;                 // Class
   bool isObjCSelType() const;                 // Class
@@ -909,6 +956,22 @@
   /// an objective pointer type for the purpose of GC'ability
   bool hasObjCPointerRepresentation() const;
 
+  /// \brief Determine whether this type has an integer representation
+  /// of some sort, e.g., it is an integer type or a vector.
+  bool hasIntegerRepresentation() const;
+
+  /// \brief Determine whether this type has an signed integer representation
+  /// of some sort, e.g., it is an signed integer type or a vector.
+  bool hasSignedIntegerRepresentation() const;
+
+  /// \brief Determine whether this type has an unsigned integer representation
+  /// of some sort, e.g., it is an unsigned integer type or a vector.
+  bool hasUnsignedIntegerRepresentation() const;
+
+  /// \brief Determine whether this type has a floating-point representation
+  /// of some sort, e.g., it is a floating-point type or a vector thereof.
+  bool hasFloatingRepresentation() 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.
@@ -920,20 +983,22 @@
   // for object declared using an interface.
   const ObjCObjectPointerType *getAsObjCInterfacePointerType() const;
   const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
-  const ObjCInterfaceType *getAsObjCQualifiedInterfaceType() const;
+  const ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
   const CXXRecordDecl *getCXXRecordDeclForPointerType() const;
 
-  // Member-template getAs<specific type>'.  This scheme will eventually
+  /// \brief Retrieves the CXXRecordDecl that this type refers to, either
+  /// because the type is a RecordType or because it is the injected-class-name 
+  /// type of a class template or class template partial specialization.
+  CXXRecordDecl *getAsCXXRecordDecl() const;
+  
+  // Member-template getAs<specific type>'.  Look through sugar for
+  // an instance of <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.
@@ -972,10 +1037,13 @@
   /// set of type specifiers.
   bool isSpecifierType() const;
 
-  const char *getTypeClassName() const;
-
   /// \brief Determine the linkage of this type.
-  virtual Linkage getLinkage() const;
+  Linkage getLinkage() const;
+  
+  /// \brief Note that the linkage is no longer known.
+  void ClearLinkageCache();
+  
+  const char *getTypeClassName() const;
 
   QualType getCanonicalTypeInternal() const {
     return CanonicalType;
@@ -983,6 +1051,9 @@
   CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
   void dump() const;
   static bool classof(const Type *) { return true; }
+
+  friend class ASTReader;
+  friend class ASTWriter;
 };
 
 template <> inline const TypedefType *Type::getAs() const {
@@ -1035,12 +1106,25 @@
 
     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.
+
+    /// The primitive Objective C 'id' type.  The type pointed to by the
+    /// user-visible 'id' type.  Only ever shows up in an AST as the base
+    /// type of an ObjCObjectType.
+    ObjCId,
+
+    /// The primitive Objective C 'Class' type.  The type pointed to by the
+    /// user-visible 'Class' type.  Only ever shows up in an AST as the
+    /// base type of an ObjCObjectType.
+    ObjCClass,
+
     ObjCSel    // This represents the ObjC 'SEL' type.
   };
 private:
   Kind TypeKind;
+  
+protected:
+  virtual Linkage getLinkageImpl() const;
+  
 public:
   BuiltinType(Kind K)
     : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent)),
@@ -1068,8 +1152,6 @@
     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; }
 };
@@ -1084,6 +1166,10 @@
     ElementType(Element) {
   }
   friend class ASTContext;  // ASTContext creates these.
+
+protected:
+  virtual Linkage getLinkageImpl() const;
+  
 public:
   QualType getElementType() const { return ElementType; }
 
@@ -1097,8 +1183,6 @@
     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; }
 };
@@ -1112,6 +1196,10 @@
     Type(Pointer, CanonicalPtr, Pointee->isDependentType()), PointeeType(Pointee) {
   }
   friend class ASTContext;  // ASTContext creates these.
+
+protected:
+  virtual Linkage getLinkageImpl() const;
+  
 public:
 
   QualType getPointeeType() const { return PointeeType; }
@@ -1126,8 +1214,6 @@
     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; }
 };
@@ -1143,6 +1229,10 @@
     PointeeType(Pointee) {
   }
   friend class ASTContext;  // ASTContext creates these.
+  
+protected:
+  virtual Linkage getLinkageImpl() const;
+  
 public:
 
   // Get the pointee type. Pointee is required to always be a function type.
@@ -1158,8 +1248,6 @@
       ID.AddPointer(Pointee.getAsOpaquePtr());
   }
 
-  virtual Linkage getLinkage() const;
-
   static bool classof(const Type *T) {
     return T->getTypeClass() == BlockPointer;
   }
@@ -1195,6 +1283,9 @@
     PointeeType(Referencee), SpelledAsLValue(SpelledAsLValue),
     InnerRef(Referencee->isReferenceType()) {
   }
+  
+  virtual Linkage getLinkageImpl() const;
+  
 public:
   bool isSpelledAsLValue() const { return SpelledAsLValue; }
   bool isInnerRef() const { return InnerRef; }
@@ -1218,8 +1309,6 @@
     ID.AddBoolean(SpelledAsLValue);
   }
 
-  virtual Linkage getLinkage() const;
-
   static bool classof(const Type *T) {
     return T->getTypeClass() == LValueReference ||
            T->getTypeClass() == RValueReference;
@@ -1276,10 +1365,25 @@
     PointeeType(Pointee), Class(Cls) {
   }
   friend class ASTContext; // ASTContext creates these.
+  
+protected:
+  virtual Linkage getLinkageImpl() const;
+  
 public:
-
   QualType getPointeeType() const { return PointeeType; }
 
+  /// Returns true if the member type (i.e. the pointee type) is a
+  /// function type rather than a data-member type.
+  bool isMemberFunctionPointer() const {
+    return PointeeType->isFunctionProtoType();
+  }
+
+  /// Returns true if the member type (i.e. the pointee type) is a
+  /// data type rather than a function type.
+  bool isMemberDataPointer() const {
+    return !PointeeType->isFunctionProtoType();
+  }
+
   const Type *getClass() const { return Class; }
 
   bool isSugared() const { return false; }
@@ -1294,8 +1398,6 @@
     ID.AddPointer(Class);
   }
 
-  virtual Linkage getLinkage() const;
-
   static bool classof(const Type *T) {
     return T->getTypeClass() == MemberPointer;
   }
@@ -1337,6 +1439,9 @@
       ElementType(et), SizeModifier(sm), IndexTypeQuals(tq) {}
 
   friend class ASTContext;  // ASTContext creates these.
+
+  virtual Linkage getLinkageImpl() const;
+  
 public:
   QualType getElementType() const { return ElementType; }
   ArraySizeModifier getSizeModifier() const {
@@ -1347,8 +1452,6 @@
   }
   unsigned getIndexTypeCVRQualifiers() const { return IndexTypeQuals; }
 
-  virtual Linkage getLinkage() const;
-
   static bool classof(const Type *T) {
     return T->getTypeClass() == ConstantArray ||
            T->getTypeClass() == VariableArray ||
@@ -1379,6 +1482,17 @@
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
+  
+  /// \brief Determine the number of bits required to address a member of
+  // an array with the given element type and number of elements.
+  static unsigned getNumAddressingBits(ASTContext &Context,
+                                       QualType ElementType,
+                                       const llvm::APInt &NumElements);
+  
+  /// \brief Determine the maximum number of active bits that an array's size
+  /// can require, which limits the maximum size of the array.
+  static unsigned getMaxSizeBits(ASTContext &Context);
+  
   void Profile(llvm::FoldingSetNodeID &ID) {
     Profile(ID, getElementType(), getSize(),
             getSizeModifier(), getIndexTypeCVRQualifiers());
@@ -1458,7 +1572,6 @@
     : 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 {
@@ -1517,7 +1630,6 @@
     : 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 {
@@ -1571,7 +1683,6 @@
       Context(Context), SizeExpr(SizeExpr), ElementType(ElementType),
       loc(loc) {}
   friend class ASTContext;
-  virtual void Destroy(ASTContext& C);
 
 public:
   Expr *getSizeExpr() const { return SizeExpr; }
@@ -1601,6 +1712,13 @@
 /// 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 {
+public:
+  enum AltiVecSpecific {
+    NotAltiVec,  // is not AltiVec vector
+    AltiVec,     // is AltiVec vector
+    Pixel,       // is AltiVec 'vector Pixel'
+    Bool         // is AltiVec 'vector bool ...'
+  };
 protected:
   /// ElementType - The element type of the vector.
   QualType ElementType;
@@ -1608,22 +1726,20 @@
   /// 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;
+  AltiVecSpecific AltiVecSpec;
 
   VectorType(QualType vecType, unsigned nElements, QualType canonType,
-      bool isAltiVec, bool isPixel) :
+      AltiVecSpecific altiVecSpec) :
     Type(Vector, canonType, vecType->isDependentType()),
-    ElementType(vecType), NumElements(nElements),
-    AltiVec(isAltiVec), Pixel(isPixel) {}
+    ElementType(vecType), NumElements(nElements), AltiVecSpec(altiVecSpec) {}
   VectorType(TypeClass tc, QualType vecType, unsigned nElements,
-             QualType canonType, bool isAltiVec, bool isPixel)
+             QualType canonType, AltiVecSpecific altiVecSpec)
     : Type(tc, canonType, vecType->isDependentType()), ElementType(vecType),
-      NumElements(nElements), AltiVec(isAltiVec), Pixel(isPixel) {}
+      NumElements(nElements), AltiVecSpec(altiVecSpec) {}
   friend class ASTContext;  // ASTContext creates these.
+  
+  virtual Linkage getLinkageImpl() const;
+  
 public:
 
   QualType getElementType() const { return ElementType; }
@@ -1632,26 +1748,20 @@
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
-  bool isAltiVec() const { return AltiVec; }
-  
-  bool isPixel() const { return Pixel; }
-  
+  AltiVecSpecific getAltiVecSpecific() const { return AltiVecSpec; }
+
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, getElementType(), getNumElements(), getTypeClass(),
-      AltiVec, Pixel);
+    Profile(ID, getElementType(), getNumElements(), getTypeClass(), AltiVecSpec);
   }
   static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
                       unsigned NumElements, TypeClass TypeClass,
-                      bool isAltiVec, bool isPixel) {
+                      unsigned AltiVecSpec) {
     ID.AddPointer(ElementType.getAsOpaquePtr());
     ID.AddInteger(NumElements);
     ID.AddInteger(TypeClass);
-    ID.AddBoolean(isAltiVec);
-    ID.AddBoolean(isPixel);
+    ID.AddInteger(AltiVecSpec);
   }
 
-  virtual Linkage getLinkage() const;
-
   static bool classof(const Type *T) {
     return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
   }
@@ -1665,7 +1775,7 @@
 /// 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) {}
+    VectorType(ExtVector, vecType, nElements, canonType, NotAltiVec) {}
   friend class ASTContext;  // ASTContext creates these.
 public:
   static int getPointAccessorIdx(char c) {
@@ -1728,6 +1838,8 @@
 /// class of FunctionNoProtoType and FunctionProtoType.
 ///
 class FunctionType : public Type {
+  virtual void ANCHOR(); // Key function for FunctionType.
+  
   /// SubClassData - This field is owned by the subclass, put here to pack
   /// tightly with the ivars in Type.
   bool SubClassData : 1;
@@ -1748,7 +1860,7 @@
   unsigned RegParm : 3;
 
   /// CallConv - The calling convention used by the function.
-  unsigned CallConv : 2;
+  unsigned CallConv : 3;
 
   // The type returned by the function.
   QualType ResultType;
@@ -1768,13 +1880,13 @@
   // * FunctionNoProtoType::Profile
   // * FunctionProtoType::Profile
   // * TypePrinter::PrintFunctionProto
-  // * PCH read and write
+  // * AST 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).
+    // have all the elements (when reading an AST file for example).
     ExtInfo(bool noReturn, unsigned regParm, CallingConv cc) :
         NoReturn(noReturn), RegParm(regParm), CC(cc) {}
 
@@ -1816,7 +1928,7 @@
     // The value passed to __attribute__((regparm(x)))
     unsigned RegParm;
     // The calling convention as specified via
-    // __attribute__((cdecl|stdcall||fastcall))
+    // __attribute__((cdecl|stdcall|fastcall|thiscall))
     CallingConv CC;
   };
 
@@ -1833,6 +1945,7 @@
 public:
 
   QualType getResultType() const { return ResultType; }
+  
   unsigned getRegParmType() const { return RegParm; }
   bool getNoReturnAttr() const { return NoReturn; }
   CallingConv getCallConv() const { return (CallingConv)CallConv; }
@@ -1840,6 +1953,12 @@
     return ExtInfo(NoReturn, RegParm, (CallingConv)CallConv);
   }
 
+  /// \brief Determine the type of an expression that calls a function of
+  /// this type.
+  QualType getCallResultType(ASTContext &Context) const { 
+    return getResultType().getNonLValueExprType(Context);
+  }
+
   static llvm::StringRef getNameForCallConv(CallingConv CC);
 
   static bool classof(const Type *T) {
@@ -1857,6 +1976,10 @@
     : FunctionType(FunctionNoProto, Result, false, 0, Canonical,
                    /*Dependent=*/false, Info) {}
   friend class ASTContext;  // ASTContext creates these.
+  
+protected:
+  virtual Linkage getLinkageImpl() const;
+  
 public:
   // No additional state past what FunctionType provides.
 
@@ -1874,8 +1997,6 @@
     ID.AddPointer(ResultType.getAsOpaquePtr());
   }
 
-  virtual Linkage getLinkage() const;
-
   static bool classof(const Type *T) {
     return T->getTypeClass() == FunctionNoProto;
   }
@@ -1939,6 +2060,9 @@
 
   friend class ASTContext;  // ASTContext creates these.
 
+protected:
+  virtual Linkage getLinkageImpl() const;
+  
 public:
   unsigned getNumArgs() const { return NumArgs; }
   QualType getArgType(unsigned i) const {
@@ -1979,8 +2103,6 @@
   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;
   }
@@ -2173,27 +2295,21 @@
 };
 
 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;
+  /// Stores the TagDecl associated with this type. The decl may point to any
+  /// TagDecl that declares the entity.
+  TagDecl * decl;
 
 protected:
   TagType(TypeClass TC, const TagDecl *D, QualType can);
 
+  virtual Linkage getLinkageImpl() const;
+  
 public:
-  TagDecl *getDecl() const { return decl.getPointer(); }
+  TagDecl *getDecl() const;
 
   /// @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;
+  bool isBeingDefined() const;
 
   static bool classof(const Type *T) {
     return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
@@ -2259,68 +2375,6 @@
   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;
@@ -2433,28 +2487,17 @@
 /// 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.
+  /// \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,
+  TemplateSpecializationType(TemplateName T,
                              const TemplateArgument *Args,
                              unsigned NumArgs, QualType Canon);
 
-  virtual void Destroy(ASTContext& C);
-
   friend class ASTContext;  // ASTContext creates these
 
 public:
@@ -2484,13 +2527,13 @@
   /// True if this template specialization type matches a current
   /// instantiation in the context in which it is found.
   bool isCurrentInstantiation() const {
-    return ContextAndCurrentInstantiation.getInt();
+    return isa<InjectedClassNameType>(getCanonicalTypeInternal());
   }
 
   typedef const TemplateArgument * iterator;
 
   iterator begin() const { return getArgs(); }
-  iterator end() const;
+  iterator end() const; // defined inline in TemplateBase.h
 
   /// \brief Retrieve the name of the template that we are specializing.
   TemplateName getTemplateName() const { return Template; }
@@ -2505,20 +2548,18 @@
 
   /// \brief Retrieve a specific template argument as a type.
   /// \precondition @c isArgType(Arg)
-  const TemplateArgument &getArg(unsigned Idx) const;
+  const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
 
   bool isSugared() const {
     return !isDependentType() || isCurrentInstantiation();
   }
   QualType desugar() const { return getCanonicalTypeInternal(); }
 
-  void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, Template, isCurrentInstantiation(), getArgs(), NumArgs,
-            *ContextAndCurrentInstantiation.getPointer());
+  void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Ctx) {
+    Profile(ID, Template, getArgs(), NumArgs, Ctx);
   }
 
   static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
-                      bool IsCurrentInstantiation,
                       const TemplateArgument *Args,
                       unsigned NumArgs,
                       ASTContext &Context);
@@ -2561,6 +2602,9 @@
   QualType InjectedType;
 
   friend class ASTContext; // ASTContext creates these.
+  friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not
+                          // currently suitable for AST reading, too much
+                          // interdependencies.
   InjectedClassNameType(CXXRecordDecl *D, QualType TST)
     : Type(InjectedClassName, QualType(), true),
       Decl(D), InjectedType(TST) {
@@ -2575,7 +2619,7 @@
     return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
   }
 
-  CXXRecordDecl *getDecl() const { return Decl; }
+  CXXRecordDecl *getDecl() const;
 
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
@@ -2586,46 +2630,117 @@
   static bool classof(const InjectedClassNameType *T) { return true; }
 };
 
+/// \brief The kind of a tag type.
+enum TagTypeKind {
+  /// \brief The "struct" keyword.
+  TTK_Struct,
+  /// \brief The "union" keyword.
+  TTK_Union,
+  /// \brief The "class" keyword.
+  TTK_Class,
+  /// \brief The "enum" keyword.
+  TTK_Enum
+};
+
 /// \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 "class" keyword introduces the elaborated-type-specifier.
+  ETK_Class,
   /// \brief The "enum" keyword introduces the elaborated-type-specifier.
-  ETK_Enum
+  ETK_Enum,
+  /// \brief The "typename" keyword precedes the qualified type name, e.g.,
+  /// \c typename T::type.
+  ETK_Typename,
+  /// \brief No keyword precedes the qualified type name.
+  ETK_None
 };
-  
-/// \brief Represents a type that was referred to via a qualified
-/// name, e.g., N::M::type.
+
+/// A helper class for Type nodes having an ElaboratedTypeKeyword.
+/// The keyword in stored in the free bits of the base class.
+/// Also provides a few static helpers for converting and printing
+/// elaborated type keyword and tag type kind enumerations.
+class TypeWithKeyword : public Type {
+  /// Keyword - Encodes an ElaboratedTypeKeyword enumeration constant.
+  unsigned Keyword : 3;
+
+protected:
+  TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
+                  QualType Canonical, bool dependent)
+    : Type(tc, Canonical, dependent), Keyword(Keyword) {}
+
+public:
+  virtual ~TypeWithKeyword(); // pin vtable to Type.cpp
+
+  ElaboratedTypeKeyword getKeyword() const {
+    return static_cast<ElaboratedTypeKeyword>(Keyword);
+  }
+
+  /// getKeywordForTypeSpec - Converts a type specifier (DeclSpec::TST)
+  /// into an elaborated type keyword.
+  static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
+
+  /// getTagTypeKindForTypeSpec - Converts a type specifier (DeclSpec::TST)
+  /// into a tag type kind.  It is an error to provide a type specifier
+  /// which *isn't* a tag kind here.
+  static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
+
+  /// getKeywordForTagDeclKind - Converts a TagTypeKind into an
+  /// elaborated type keyword.
+  static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);
+
+  /// getTagTypeKindForKeyword - Converts an elaborated type keyword into
+  // a TagTypeKind. It is an error to provide an elaborated type keyword
+  /// which *isn't* a tag kind here.
+  static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword);
+
+  static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword);
+
+  static const char *getKeywordName(ElaboratedTypeKeyword Keyword);
+
+  static const char *getTagTypeKindName(TagTypeKind Kind) {
+    return getKeywordName(getKeywordForTagTypeKind(Kind));
+  }
+
+  class CannotCastToThisType {};
+  static CannotCastToThisType classof(const Type *);
+};
+
+/// \brief Represents a type that was referred to using an elaborated type
+/// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type,
+/// or both.
 ///
 /// 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 {
+/// source code, including tag keywords and 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 ElaboratedType : public TypeWithKeyword, 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) { }
+  ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
+                 QualType NamedType, QualType CanonType)
+    : TypeWithKeyword(Keyword, Elaborated, CanonType,
+                      NamedType->isDependentType()),
+      NNS(NNS), NamedType(NamedType) {
+    assert(!(Keyword == ETK_None && NNS == 0) &&
+           "ElaboratedType cannot have elaborated type keyword "
+           "and name qualifier both null.");
+  }
 
   friend class ASTContext;  // ASTContext creates these
 
 public:
+  ~ElaboratedType();
+
   /// \brief Retrieve the qualification on this type.
   NestedNameSpecifier *getQualifier() const { return NNS; }
 
@@ -2639,19 +2754,20 @@
   bool isSugared() const { return true; }
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, NNS, NamedType);
+    Profile(ID, getKeyword(), NNS, NamedType);
   }
 
-  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
-                      QualType NamedType) {
+  static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
+                      NestedNameSpecifier *NNS, QualType NamedType) {
+    ID.AddInteger(Keyword);
     ID.AddPointer(NNS);
     NamedType.Profile(ID);
   }
 
   static bool classof(const Type *T) {
-    return T->getTypeClass() == QualifiedName;
+    return T->getTypeClass() == Elaborated;
   }
-  static bool classof(const QualifiedNameType *T) { return true; }
+  static bool classof(const ElaboratedType *T) { return true; }
 };
 
 /// \brief Represents a qualified type name for which the type name is
@@ -2663,31 +2779,18 @@
 /// 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;
-  
+class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
+
   /// \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;
+  const IdentifierInfo *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) {
+    : TypeWithKeyword(Keyword, DependentName, CanonType, true),
+      NNS(NNS), Name(Name) {
     assert(NNS->isDependent() &&
            "DependentNameType requires a dependent nested-name-specifier");
   }
@@ -2695,9 +2798,8 @@
   friend class ASTContext;  // ASTContext creates these
 
 public:
-  /// \brief Retrieve the keyword used to elaborate this type.
-  ElaboratedTypeKeyword getKeyword() const { return Keyword; }
-  
+  virtual ~DependentNameType();
+
   /// \brief Retrieve the qualification on this type.
   NestedNameSpecifier *getQualifier() const { return NNS; }
 
@@ -2708,27 +2810,21 @@
   /// 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 *>();
+    return Name;
   }
 
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, Keyword, NNS, Name);
+    Profile(ID, getKeyword(), NNS, Name);
   }
 
   static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
-                      NestedNameSpecifier *NNS, NameType Name) {
+                      NestedNameSpecifier *NNS, const IdentifierInfo *Name) {
     ID.AddInteger(Keyword);
     ID.AddPointer(NNS);
-    ID.AddPointer(Name.getOpaqueValue());
+    ID.AddPointer(Name);
   }
 
   static bool classof(const Type *T) {
@@ -2737,153 +2833,402 @@
   static bool classof(const DependentNameType *T) { return true; }
 };
 
+/// DependentTemplateSpecializationType - Represents a template
+/// specialization type whose template cannot be resolved, e.g.
+///   A<T>::template B<T>
+class DependentTemplateSpecializationType :
+  public TypeWithKeyword, public llvm::FoldingSetNode {
+
+  /// \brief The nested name specifier containing the qualifier.
+  NestedNameSpecifier *NNS;
+
+  /// \brief The identifier of the template.
+  const IdentifierInfo *Name;
+
+  /// \brief - The number of template arguments named in this class
+  /// template specialization.
+  unsigned NumArgs;
+
+  const TemplateArgument *getArgBuffer() const {
+    return reinterpret_cast<const TemplateArgument*>(this+1);
+  }
+  TemplateArgument *getArgBuffer() {
+    return reinterpret_cast<TemplateArgument*>(this+1);
+  }
+
+  DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+                                      NestedNameSpecifier *NNS,
+                                      const IdentifierInfo *Name,
+                                      unsigned NumArgs,
+                                      const TemplateArgument *Args,
+                                      QualType Canon);
+
+  friend class ASTContext;  // ASTContext creates these
+
+public:
+  virtual ~DependentTemplateSpecializationType();
+
+  NestedNameSpecifier *getQualifier() const { return NNS; }
+  const IdentifierInfo *getIdentifier() const { return Name; }
+
+  /// \brief Retrieve the template arguments.
+  const TemplateArgument *getArgs() const {
+    return getArgBuffer();
+  }
+
+  /// \brief Retrieve the number of template arguments.
+  unsigned getNumArgs() const { return NumArgs; }
+
+  const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
+
+  typedef const TemplateArgument * iterator;
+  iterator begin() const { return getArgs(); }
+  iterator end() const; // inline in TemplateBase.h
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) {
+    Profile(ID, Context, getKeyword(), NNS, Name, NumArgs, getArgs());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      ASTContext &Context,
+                      ElaboratedTypeKeyword Keyword,
+                      NestedNameSpecifier *Qualifier,
+                      const IdentifierInfo *Name,
+                      unsigned NumArgs,
+                      const TemplateArgument *Args);
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == DependentTemplateSpecialization;
+  }
+  static bool classof(const DependentTemplateSpecializationType *T) {
+    return true;
+  }  
+};
+
+/// ObjCObjectType - Represents a class type in Objective C.
+/// Every Objective C type is a combination of a base type and a
+/// list of protocols.
+///
+/// Given the following declarations:
+///   @class C;
+///   @protocol P;
+///
+/// 'C' is an ObjCInterfaceType C.  It is sugar for an ObjCObjectType
+/// with base C and no protocols.
+///
+/// 'C<P>' is an ObjCObjectType with base C and protocol list [P].
+///
+/// 'id' is a TypedefType which is sugar for an ObjCPointerType whose
+/// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType
+/// and no protocols.
+///
+/// 'id<P>' is an ObjCPointerType whose pointee is an ObjCObjecType
+/// with base BuiltinType::ObjCIdType and protocol list [P].  Eventually
+/// this should get its own sugar class to better represent the source.
+class ObjCObjectType : public Type {
+  // Pad the bit count up so that NumProtocols is 2-byte aligned
+  unsigned : BitsRemainingInType - 16;
+
+  /// \brief The number of protocols stored after the
+  /// ObjCObjectPointerType node.
+  ///
+  /// These protocols are those written directly on the type.  If
+  /// protocol qualifiers ever become additive, the iterators will
+  /// get kindof complicated.
+  ///
+  /// In the canonical object type, these are sorted alphabetically
+  /// and uniqued.
+  unsigned NumProtocols : 16;
+
+  /// Either a BuiltinType or an InterfaceType or sugar for either.
+  QualType BaseType;
+
+  ObjCProtocolDecl * const *getProtocolStorage() const {
+    return const_cast<ObjCObjectType*>(this)->getProtocolStorage();
+  }
+
+  ObjCProtocolDecl **getProtocolStorage();
+
+protected:
+  ObjCObjectType(QualType Canonical, QualType Base, 
+                 ObjCProtocolDecl * const *Protocols, unsigned NumProtocols);
+
+  enum Nonce_ObjCInterface { Nonce_ObjCInterface };
+  ObjCObjectType(enum Nonce_ObjCInterface)
+    : Type(ObjCInterface, QualType(), false),
+      NumProtocols(0),
+      BaseType(QualType(this_(), 0)) {}
+
+protected:
+  Linkage getLinkageImpl() const; // key function
+  
+public:
+  /// getBaseType - Gets the base type of this object type.  This is
+  /// always (possibly sugar for) one of:
+  ///  - the 'id' builtin type (as opposed to the 'id' type visible to the
+  ///    user, which is a typedef for an ObjCPointerType)
+  ///  - the 'Class' builtin type (same caveat)
+  ///  - an ObjCObjectType (currently always an ObjCInterfaceType)
+  QualType getBaseType() const { return BaseType; }
+
+  bool isObjCId() const {
+    return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId);
+  }
+  bool isObjCClass() const {
+    return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass);
+  }
+  bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); }
+  bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); }
+  bool isObjCUnqualifiedIdOrClass() const {
+    if (!qual_empty()) return false;
+    if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>())
+      return T->getKind() == BuiltinType::ObjCId ||
+             T->getKind() == BuiltinType::ObjCClass;
+    return false;
+  }
+  bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); }
+  bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); }
+
+  /// Gets the interface declaration for this object type, if the base type
+  /// really is an interface.
+  ObjCInterfaceDecl *getInterface() const;
+
+  typedef ObjCProtocolDecl * const *qual_iterator;
+
+  qual_iterator qual_begin() const { return getProtocolStorage(); }
+  qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
+
+  bool qual_empty() const { return getNumProtocols() == 0; }
+
+  /// getNumProtocols - Return the number of qualifying protocols in this
+  /// interface type, or 0 if there are none.
+  unsigned getNumProtocols() const { return NumProtocols; }
+
+  /// \brief Fetch a protocol by index.
+  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); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ObjCObject ||
+           T->getTypeClass() == ObjCInterface;
+  }
+  static bool classof(const ObjCObjectType *) { return true; }
+};
+
+/// ObjCObjectTypeImpl - A class providing a concrete implementation
+/// of ObjCObjectType, so as to not increase the footprint of
+/// ObjCInterfaceType.  Code outside of ASTContext and the core type
+/// system should not reference this type.
+class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode {
+  friend class ASTContext;
+
+  // If anyone adds fields here, ObjCObjectType::getProtocolStorage()
+  // will need to be modified.
+
+  ObjCObjectTypeImpl(QualType Canonical, QualType Base, 
+                     ObjCProtocolDecl * const *Protocols,
+                     unsigned NumProtocols)
+    : ObjCObjectType(Canonical, Base, Protocols, NumProtocols) {}
+
+public:
+  void Profile(llvm::FoldingSetNodeID &ID);
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      QualType Base,
+                      ObjCProtocolDecl *const *protocols, 
+                      unsigned NumProtocols);  
+};
+
+inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() {
+  return reinterpret_cast<ObjCProtocolDecl**>(
+            static_cast<ObjCObjectTypeImpl*>(this) + 1);
+}
+
 /// 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 {
+///
+/// ObjCInterfaceType guarantees the following properties when considered
+/// as a subtype of its superclass, ObjCObjectType:
+///   - There are no protocol qualifiers.  To reinforce this, code which
+///     tries to invoke the protocol methods via an ObjCInterfaceType will
+///     fail to compile.
+///   - It is its own base type.  That is, if T is an ObjCInterfaceType*,
+///     T->getBaseType() == QualType(T, 0).
+class ObjCInterfaceType : public ObjCObjectType {
   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);
+  ObjCInterfaceType(const ObjCInterfaceDecl *D)
+    : ObjCObjectType(Nonce_ObjCInterface),
+      Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
   friend class ASTContext;  // ASTContext creates these.
 public:
-  void Destroy(ASTContext& C);
-
+  /// getDecl - Get the declaration of this interface.
   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; }
+
+  // Nonsense to "hide" certain members of ObjCObjectType within this
+  // class.  People asking for protocols on an ObjCInterfaceType are
+  // not going to get what they want: ObjCInterfaceTypes are
+  // guaranteed to have no protocols.
+  enum {
+    qual_iterator,
+    qual_begin,
+    qual_end,
+    getNumProtocols,
+    getProtocol
+  };
 };
 
-/// ObjCObjectPointerType - Used to represent 'id', 'Interface *', 'id <p>',
-/// and 'Interface <p> *'.
+inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const {
+  if (const ObjCInterfaceType *T =
+        getBaseType()->getAs<ObjCInterfaceType>())
+    return T->getDecl();
+  return 0;
+}
+
+/// ObjCObjectPointerType - Used to represent a pointer to an
+/// Objective C object.  These are constructed from pointer
+/// declarators when the pointee type is an ObjCObjectType (or sugar
+/// for one).  In addition, the 'id' and 'Class' types are typedefs
+/// for these, and the protocol-qualified types 'id<P>' and 'Class<P>'
+/// are translated into these.
 ///
-/// Duplicate protocols are removed and protocol list is canonicalized to be in
-/// alphabetical order.
+/// Pointers to pointers to Objective C objects are still PointerTypes;
+/// only the first level of pointer gets it own type implementation.
 class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
-  QualType PointeeType; // A builtin or interface type.
+  QualType PointeeType;
 
-  /// \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);
+  ObjCObjectPointerType(QualType Canonical, QualType Pointee)
+    : Type(ObjCObjectPointer, Canonical, false),
+      PointeeType(Pointee) {}
   friend class ASTContext;  // ASTContext creates these.
 
+protected:
+  virtual Linkage getLinkageImpl() const;
+  
 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;
+  /// getPointeeType - Gets the type pointed to by this ObjC pointer.
+  /// The result will always be an ObjCObjectType or sugar thereof.
   QualType getPointeeType() const { return PointeeType; }
 
+  /// getObjCObjectType - Gets the type pointed to by this ObjC
+  /// pointer.  This method always returns non-null.
+  ///
+  /// This method is equivalent to getPointeeType() except that
+  /// it discards any typedefs (or other sugar) between this
+  /// type and the "outermost" object type.  So for:
+  ///   @class A; @protocol P; @protocol Q;
+  ///   typedef A<P> AP;
+  ///   typedef A A1;
+  ///   typedef A1<P> A1P;
+  ///   typedef A1P<Q> A1PQ;
+  /// For 'A*', getObjectType() will return 'A'.
+  /// For 'A<P>*', getObjectType() will return 'A<P>'.
+  /// For 'AP*', getObjectType() will return 'A<P>'.
+  /// For 'A1*', getObjectType() will return 'A'.
+  /// For 'A1<P>*', getObjectType() will return 'A1<P>'.
+  /// For 'A1P*', getObjectType() will return 'A1<P>'.
+  /// For 'A1PQ*', getObjectType() will return 'A1<Q>', because
+  ///   adding protocols to a protocol-qualified base discards the
+  ///   old qualifiers (for now).  But if it didn't, getObjectType()
+  ///   would return 'A1P<Q>' (and we'd have to make iterating over
+  ///   qualifiers more complicated).
+  const ObjCObjectType *getObjectType() const {
+    return PointeeType->getAs<ObjCObjectType>();
+  }
+
+  /// getInterfaceType - If this pointer points to an Objective C
+  /// @interface type, gets the type for that interface.  Any protocol
+  /// qualifiers on the interface are ignored.
+  ///
+  /// \return null if the base type for this pointer is 'id' or 'Class'
   const ObjCInterfaceType *getInterfaceType() const {
-    return PointeeType->getAs<ObjCInterfaceType>();
+    return getObjectType()->getBaseType()->getAs<ObjCInterfaceType>();
   }
-  /// getInterfaceDecl - returns an interface decl for user-defined types.
+
+  /// getInterfaceDecl - If this pointer points to an Objective @interface
+  /// type, gets the declaration for that interface.
+  ///
+  /// \return null if the base type for this pointer is 'id' or 'Class'
   ObjCInterfaceDecl *getInterfaceDecl() const {
-    return getInterfaceType() ? getInterfaceType()->getDecl() : 0;
+    return getObjectType()->getInterface();
   }
-  /// isObjCIdType - true for "id".
+
+  /// isObjCIdType - True if this is equivalent to the 'id' type, i.e. if
+  /// its object type is the primitive 'id' type with no protocols.
   bool isObjCIdType() const {
-    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
-           !NumProtocols;
+    return getObjectType()->isObjCUnqualifiedId();
   }
-  /// isObjCClassType - true for "Class".
+
+  /// isObjCClassType - True if this is equivalent to the 'Class' type,
+  /// i.e. if its object tive is the primitive 'Class' type with no protocols.
   bool isObjCClassType() const {
-    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
-           !NumProtocols;
+    return getObjectType()->isObjCUnqualifiedClass();
   }
   
-  /// isObjCQualifiedIdType - true for "id <p>".
+  /// isObjCQualifiedIdType - True if this is equivalent to 'id<P>' for some
+  /// non-empty set of protocols.
   bool isObjCQualifiedIdType() const {
-    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
-           NumProtocols;
+    return getObjectType()->isObjCQualifiedId();
   }
-  /// isObjCQualifiedClassType - true for "Class <p>".
+
+  /// isObjCQualifiedClassType - True if this is equivalent to 'Class<P>' for
+  /// some non-empty set of protocols.
   bool isObjCQualifiedClassType() const {
-    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
-           NumProtocols;
+    return getObjectType()->isObjCQualifiedClass();
   }
-  /// qual_iterator and friends: this provides access to the (potentially empty)
-  /// list of protocols qualifying this interface.
-  typedef ObjCProtocolDecl*  const * qual_iterator;
+
+  /// An iterator over the qualifiers on the object type.  Provided
+  /// for convenience.  This will always iterate over the full set of
+  /// protocols on a type, not just those provided directly.
+  typedef ObjCObjectType::qual_iterator qual_iterator;
 
   qual_iterator qual_begin() const {
-    return reinterpret_cast<qual_iterator> (this + 1);
+    return getObjectType()->qual_begin();
   }
-  qual_iterator qual_end() const   {
-    return qual_begin() + NumProtocols;
+  qual_iterator qual_end() const {
+    return getObjectType()->qual_end();
   }
-  bool qual_empty() const { return NumProtocols == 0; }
+  bool qual_empty() const { return getObjectType()->qual_empty(); }
 
-  /// getNumProtocols - Return the number of qualifying protocols in this
-  /// interface type, or 0 if there are none.
-  unsigned getNumProtocols() const { return NumProtocols; }
+  /// getNumProtocols - Return the number of qualifying protocols on
+  /// the object type.
+  unsigned getNumProtocols() const {
+    return getObjectType()->getNumProtocols();
+  }
 
-  /// \brief Retrieve the Ith protocol.
+  /// \brief Retrieve a qualifying protocol by index on the object
+  /// type.
   ObjCProtocolDecl *getProtocol(unsigned I) const {
-    assert(I < getNumProtocols() && "Out-of-range protocol access");
-    return qual_begin()[I];
+    return getObjectType()->getProtocol(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);
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getPointeeType());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
+    ID.AddPointer(T.getAsOpaquePtr());
+  }
   static bool classof(const Type *T) {
     return T->getTypeClass() == ObjCObjectPointer;
   }
@@ -3079,6 +3424,12 @@
   return getFunctionExtInfo(*t);
 }
 
+/// \brief Determine whether this set of qualifiers is a superset of the given 
+/// set of qualifiers.
+inline bool Qualifiers::isSupersetOf(Qualifiers Other) const {
+  return Mask != Other.Mask && (Mask | Other.Mask) == Mask;
+}
+
 /// 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
@@ -3122,12 +3473,6 @@
     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);
 }
@@ -3160,7 +3505,13 @@
 }
 inline bool Type::isMemberFunctionPointerType() const {
   if (const MemberPointerType* T = getAs<MemberPointerType>())
-    return T->getPointeeType()->isFunctionType();
+    return T->isMemberFunctionPointer();
+  else
+    return false;
+}
+inline bool Type::isMemberDataPointerType() const {
+  if (const MemberPointerType* T = getAs<MemberPointerType>())
+    return T->isMemberDataPointer();
   else
     return false;
 }
@@ -3194,9 +3545,14 @@
 inline bool Type::isObjCObjectPointerType() const {
   return isa<ObjCObjectPointerType>(CanonicalType);
 }
-inline bool Type::isObjCInterfaceType() const {
-  return isa<ObjCInterfaceType>(CanonicalType);
+inline bool Type::isObjCObjectType() const {
+  return isa<ObjCObjectType>(CanonicalType);
 }
+inline bool Type::isObjCObjectOrInterfaceType() const {
+  return isa<ObjCInterfaceType>(CanonicalType) || 
+    isa<ObjCObjectType>(CanonicalType);
+}
+
 inline bool Type::isObjCQualifiedIdType() const {
   if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
     return OPT->isObjCQualifiedIdType();
@@ -3229,6 +3585,10 @@
   return isa<TemplateTypeParmType>(CanonicalType);
 }
 
+inline bool Type::isBuiltinType() const {
+  return getAs<BuiltinType>();
+}
+
 inline bool Type::isSpecificBuiltinType(unsigned K) const {
   if (const BuiltinType *BT = getAs<BuiltinType>())
     if (BT->getKind() == (BuiltinType::Kind) K)
@@ -3244,13 +3604,11 @@
 
 inline bool Type::hasPointerRepresentation() const {
   return (isPointerType() || isReferenceType() || isBlockPointerType() ||
-          isObjCInterfaceType() || isObjCObjectPointerType() ||
-          isObjCQualifiedInterfaceType() || isNullPtrType());
+          isObjCObjectPointerType() || isNullPtrType());
 }
 
 inline bool Type::hasObjCPointerRepresentation() const {
-  return (isObjCInterfaceType() || isObjCObjectPointerType() ||
-          isObjCQualifiedInterfaceType());
+  return isObjCObjectPointerType();
 }
 
 /// Insertion operator for diagnostics.  This allows sending QualType's into a
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index a51da74..f1c64bd 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_AST_TYPELOC_H
 
 #include "clang/AST/Type.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/TemplateBase.h"
 #include "clang/Basic/Specifiers.h"
 
@@ -84,21 +85,20 @@
     return Data;
   }
 
+  /// \brief Get the begin source location.
+  SourceLocation getBeginLoc() const;
+
+  /// \brief Get the end source location.
+  SourceLocation getEndLoc() const;
+
   /// \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);
+  SourceRange getSourceRange() const {
+    return SourceRange(getBeginLoc(), getEndLoc());
   }
 
   /// \brief Get the local source range.
-  SourceRange getSourceRange() const {
-    return getSourceRangeImpl(*this);
+  SourceRange getLocalSourceRange() const {
+    return getLocalSourceRangeImpl(*this);
   }
 
   /// \brief Returns the size of the type source info data block.
@@ -137,9 +137,14 @@
 private:
   static void initializeImpl(TypeLoc TL, SourceLocation Loc);
   static TypeLoc getNextTypeLocImpl(TypeLoc TL);
-  static SourceRange getSourceRangeImpl(TypeLoc TL);
+  static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
 };
 
+/// \brief Return the TypeLoc for a type source info.
+inline TypeLoc TypeSourceInfo::getTypeLoc() const {
+  return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
+}
+
 /// \brief Wrapper of type source information for a type with
 /// no direct quqlaifiers.
 class UnqualTypeLoc : public TypeLoc {
@@ -168,7 +173,7 @@
 /// type qualifiers.
 class QualifiedTypeLoc : public TypeLoc {
 public:
-  SourceRange getSourceRange() const {
+  SourceRange getLocalSourceRange() const {
     return SourceRange();
   }
 
@@ -263,6 +268,16 @@
     return TypeClass::classof(Ty);
   }
 
+  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;
+  }
+
   TypeLoc getNextTypeLoc() const {
     return getNextTypeLoc(asDerived()->getInnerType());
   }
@@ -326,6 +341,10 @@
 template <class Base, class Derived, class TypeClass>
 class InheritingConcreteTypeLoc : public Base {
 public:
+  static bool classofType(const Type *Ty) {
+    return TypeClass::classof(Ty);
+  }
+
   static bool classof(const TypeLoc *TL) {
     return Derived::classofType(TL->getTypePtr());
   }
@@ -361,7 +380,7 @@
   void setNameLoc(SourceLocation Loc) {
     this->getLocalData()->NameLoc = Loc;
   }
-  SourceRange getSourceRange() const {
+  SourceRange getLocalSourceRange() const {
     return SourceRange(getNameLoc(), getNameLoc());
   }
   void initializeLocal(SourceLocation Loc) {
@@ -413,7 +432,7 @@
     return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
   }
 
-  SourceRange getSourceRange() const {
+  SourceRange getLocalSourceRange() const {
     return SourceRange(getBuiltinLoc(), getBuiltinLoc());
   }
 
@@ -553,6 +572,7 @@
 struct ObjCProtocolListLocInfo {
   SourceLocation LAngleLoc;
   SourceLocation RAngleLoc;
+  bool HasBaseTypeAsWritten;
 };
 
 // A helper class for defining ObjC TypeLocs that can qualified with
@@ -560,24 +580,15 @@
 //
 // TypeClass basically has to be either ObjCInterfaceType or
 // ObjCObjectPointerType.
-template <class Derived, class TypeClass, class LocalData>
-class ObjCProtocolListTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
-                                                       Derived,
-                                                       TypeClass,
-                                                       LocalData> {
+class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                                 ObjCObjectTypeLoc,
+                                                 ObjCObjectType,
+                                                 ObjCProtocolListLocInfo> {
   // 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;
@@ -611,29 +622,49 @@
     return *(this->getTypePtr()->qual_begin() + i);
   }
   
-  SourceRange getSourceRange() const {
+  bool hasBaseTypeAsWritten() const {
+    return getLocalData()->HasBaseTypeAsWritten;
+  }
+
+  void setHasBaseTypeAsWritten(bool HasBaseType) {
+    getLocalData()->HasBaseTypeAsWritten = HasBaseType;
+  }
+
+  TypeLoc getBaseLoc() const {
+    return getInnerTypeLoc();
+  }
+
+  SourceRange getLocalSourceRange() const {
     return SourceRange(getLAngleLoc(), getRAngleLoc());
   }
 
   void initializeLocal(SourceLocation Loc) {
-    initializeLocalBase(Loc);
+    setHasBaseTypeAsWritten(true);
+    setLAngleLoc(Loc);
+    setRAngleLoc(Loc);
+    for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
+      setProtocolLoc(i, Loc);
   }
 
   unsigned getExtraLocalDataSize() const {
     return this->getNumProtocols() * sizeof(SourceLocation);
   }
+
+  QualType getInnerType() const {
+    return getTypePtr()->getBaseType();
+  }
 };
 
 
-struct ObjCInterfaceLocInfo : ObjCProtocolListLocInfo {
+struct ObjCInterfaceLocInfo {
   SourceLocation NameLoc;
 };
 
 /// \brief Wrapper for source info for ObjC interfaces.
-class ObjCInterfaceTypeLoc :
-    public ObjCProtocolListTypeLoc<ObjCInterfaceTypeLoc,
-                                   ObjCInterfaceType,
-                                   ObjCInterfaceLocInfo> {
+class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
+                                                    ObjCInterfaceTypeLoc,
+                                                    ObjCInterfaceType,
+                                                    ObjCInterfaceLocInfo> {
 public:
   ObjCInterfaceDecl *getIFaceDecl() const {
     return getTypePtr()->getDecl();
@@ -647,85 +678,16 @@
     getLocalData()->NameLoc = Loc;
   }
 
-  SourceRange getSourceRange() const {
-    if (getNumProtocols()) 
-      return SourceRange(getNameLoc(), getRAngleLoc());
-    else
-      return SourceRange(getNameLoc(), getNameLoc());
+  SourceRange getLocalSourceRange() const {
+    return SourceRange(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;
 };
@@ -746,7 +708,7 @@
     return this->getInnerTypeLoc();
   }
 
-  SourceRange getSourceRange() const {
+  SourceRange getLocalSourceRange() const {
     return SourceRange(getSigilLoc(), getSigilLoc());
   }
 
@@ -798,6 +760,20 @@
   }
 };
 
+/// Wraps an ObjCPointerType with source location information.
+class ObjCObjectPointerTypeLoc :
+    public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
+                              ObjCObjectPointerType> {
+public:
+  SourceLocation getStarLoc() const {
+    return getSigilLoc();
+  }
+
+  void setStarLoc(SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+};
+
 
 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
                                                    ReferenceType> {
@@ -871,13 +847,11 @@
   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 {
+  SourceRange getLocalSourceRange() const {
     return SourceRange(getLParenLoc(), getRParenLoc());
   }
 
@@ -950,7 +924,7 @@
     return getInnerTypeLoc();
   }
 
-  SourceRange getSourceRange() const {
+  SourceRange getLocalSourceRange() const {
     return SourceRange(getLBracketLoc(), getRBracketLoc());
   }
 
@@ -1055,7 +1029,7 @@
     memcpy(Data, Loc.Data, size);
   }
 
-  SourceRange getSourceRange() const {
+  SourceRange getLocalSourceRange() const {
     return SourceRange(getTemplateNameLoc(), getRAngleLoc());
   }
 
@@ -1063,13 +1037,20 @@
     setLAngleLoc(Loc);
     setRAngleLoc(Loc);
     setTemplateNameLoc(Loc);
+    initializeArgLocs(getNumArgs(), getTypePtr()->getArgs(),
+                      getArgInfos(), Loc);
+  }
 
-    for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
+  static void initializeArgLocs(unsigned NumArgs,
+                                const TemplateArgument *Args,
+                                TemplateArgumentLocInfo *ArgInfos,
+                                SourceLocation Loc) {
+    for (unsigned i = 0, e = NumArgs; 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()) {
+      switch (Args[i].getKind()) {
       case TemplateArgument::Expression:
       case TemplateArgument::Declaration:
         Info = TemplateArgumentLocInfo((Expr*) 0);
@@ -1080,7 +1061,7 @@
         break;
 
       case TemplateArgument::Template:
-        Info = TemplateArgumentLocInfo(SourceRange(), SourceLocation());
+        Info = TemplateArgumentLocInfo(SourceRange(Loc), Loc);
         break;
           
       case TemplateArgument::Integral:
@@ -1090,7 +1071,7 @@
         break;
       }
 #endif
-      getArgInfos()[i] = Info;
+      ArgInfos[i] = Info;
     }
   }
 
@@ -1183,7 +1164,7 @@
       setRParenLoc(range.getEnd());
   }
 
-  SourceRange getSourceRange() const {
+  SourceRange getLocalSourceRange() const {
     return SourceRange(getTypeofLoc(), getRParenLoc());
   }
 
@@ -1204,7 +1185,7 @@
   // Reimplemented to account for GNU/C++ extension
   //     typeof unary-expression
   // where there are no parentheses.
-  SourceRange getSourceRange() const;
+  SourceRange getLocalSourceRange() const;
 };
 
 class TypeOfTypeLoc
@@ -1227,24 +1208,211 @@
                                                          DecltypeType> {
 };
 
-// FIXME: location of the tag keyword.
-class ElaboratedTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
-                                                           ElaboratedTypeLoc,
-                                                           ElaboratedType> {
+struct ElaboratedLocInfo {
+  SourceLocation KeywordLoc;
+  SourceRange QualifierRange;
 };
 
-// FIXME: locations for the nested name specifier;  at the very least,
-// a SourceRange.
-class QualifiedNameTypeLoc :
-    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
-                                     QualifiedNameTypeLoc,
-                                     QualifiedNameType> {
+class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                                 ElaboratedTypeLoc,
+                                                 ElaboratedType,
+                                                 ElaboratedLocInfo> {
+public:
+  SourceLocation getKeywordLoc() const {
+    return this->getLocalData()->KeywordLoc;
+  }
+  void setKeywordLoc(SourceLocation Loc) {
+    this->getLocalData()->KeywordLoc = Loc;
+  }
+
+  SourceRange getQualifierRange() const {
+    return this->getLocalData()->QualifierRange;
+  }
+  void setQualifierRange(SourceRange Range) {
+    this->getLocalData()->QualifierRange = Range;
+  }
+
+  SourceRange getLocalSourceRange() const {
+    if (getKeywordLoc().isValid())
+      if (getQualifierRange().getEnd().isValid())
+        return SourceRange(getKeywordLoc(), getQualifierRange().getEnd());
+      else
+        return SourceRange(getKeywordLoc());
+    else
+      return getQualifierRange();
+  }
+
+  void initializeLocal(SourceLocation Loc) {
+    setKeywordLoc(Loc);
+    setQualifierRange(SourceRange(Loc));
+  }
+
+  TypeLoc getNamedTypeLoc() const {
+    return getInnerTypeLoc();
+  }
+
+  QualType getInnerType() const {
+    return getTypePtr()->getNamedType();
+  }
+
+  void copy(ElaboratedTypeLoc Loc) {
+    unsigned size = getFullDataSize();
+    assert(size == Loc.getFullDataSize());
+    memcpy(Data, Loc.Data, size);
+  }
 };
 
-// FIXME: locations for the typename keyword and nested name specifier.
-class DependentNameTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
-                                                         DependentNameTypeLoc,
-                                                         DependentNameType> {
+// This is exactly the structure of an ElaboratedTypeLoc whose inner
+// type is some sort of TypeDeclTypeLoc.
+struct DependentNameLocInfo : ElaboratedLocInfo {
+  SourceLocation NameLoc;
+};
+
+class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                                    DependentNameTypeLoc,
+                                                    DependentNameType,
+                                                    DependentNameLocInfo> {
+public:
+  SourceLocation getKeywordLoc() const {
+    return this->getLocalData()->KeywordLoc;
+  }
+  void setKeywordLoc(SourceLocation Loc) {
+    this->getLocalData()->KeywordLoc = Loc;
+  }
+
+  SourceRange getQualifierRange() const {
+    return this->getLocalData()->QualifierRange;
+  }
+  void setQualifierRange(SourceRange Range) {
+    this->getLocalData()->QualifierRange = Range;
+  }
+
+  SourceLocation getNameLoc() const {
+    return this->getLocalData()->NameLoc;
+  }
+  void setNameLoc(SourceLocation Loc) {
+    this->getLocalData()->NameLoc = Loc;
+  }
+
+  SourceRange getLocalSourceRange() const {
+    if (getKeywordLoc().isValid())
+      return SourceRange(getKeywordLoc(), getNameLoc());
+    else
+      return SourceRange(getQualifierRange().getBegin(), getNameLoc());
+  }
+
+  void copy(DependentNameTypeLoc Loc) {
+    unsigned size = getFullDataSize();
+    assert(size == Loc.getFullDataSize());
+    memcpy(Data, Loc.Data, size);
+  }
+
+  void initializeLocal(SourceLocation Loc) {
+    setKeywordLoc(Loc);
+    setQualifierRange(SourceRange(Loc));
+    setNameLoc(Loc);
+  }
+};
+
+// This is exactly the structure of an ElaboratedTypeLoc whose inner
+// type is some sort of TemplateSpecializationTypeLoc.
+struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
+  SourceLocation LAngleLoc;
+  SourceLocation RAngleLoc;
+  // followed by a TemplateArgumentLocInfo[]
+};
+
+class DependentTemplateSpecializationTypeLoc :
+    public ConcreteTypeLoc<UnqualTypeLoc,
+                           DependentTemplateSpecializationTypeLoc,
+                           DependentTemplateSpecializationType,
+                           DependentTemplateSpecializationLocInfo> {
+public:
+  SourceLocation getKeywordLoc() const {
+    return this->getLocalData()->KeywordLoc;
+  }
+  void setKeywordLoc(SourceLocation Loc) {
+    this->getLocalData()->KeywordLoc = Loc;
+  }
+
+  SourceRange getQualifierRange() const {
+    return this->getLocalData()->QualifierRange;
+  }
+  void setQualifierRange(SourceRange Range) {
+    this->getLocalData()->QualifierRange = Range;
+  }
+
+  SourceLocation getNameLoc() const {
+    return this->getLocalData()->NameLoc;
+  }
+  void setNameLoc(SourceLocation Loc) {
+    this->getLocalData()->NameLoc = Loc;
+  }
+
+  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 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));
+  }
+
+  SourceRange getLocalSourceRange() const {
+    if (getKeywordLoc().isValid())
+      return SourceRange(getKeywordLoc(), getRAngleLoc());
+    else
+      return SourceRange(getQualifierRange().getBegin(), getRAngleLoc());
+  }
+
+  void copy(DependentTemplateSpecializationTypeLoc Loc) {
+    unsigned size = getFullDataSize();
+    assert(size == Loc.getFullDataSize());
+    memcpy(Data, Loc.Data, size);
+  }
+
+  void initializeLocal(SourceLocation Loc) {
+    setKeywordLoc(Loc);
+    setQualifierRange(SourceRange(Loc));
+    setNameLoc(Loc);
+    setLAngleLoc(Loc);
+    setRAngleLoc(Loc);
+    TemplateSpecializationTypeLoc::initializeArgLocs(getNumArgs(),
+                                                     getTypePtr()->getArgs(),
+                                                     getArgInfos(), Loc);
+  }
+
+  unsigned getExtraLocalDataSize() const {
+    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
+  }
+
+private:
+  TemplateArgumentLocInfo *getArgInfos() const {
+    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
+  }
 };
 
 }
diff --git a/include/clang/AST/TypeLocBuilder.h b/include/clang/AST/TypeLocBuilder.h
index c3b1c68..880af26 100644
--- a/include/clang/AST/TypeLocBuilder.h
+++ b/include/clang/AST/TypeLocBuilder.h
@@ -59,13 +59,34 @@
       grow(Requested);
   }
 
+  /// Pushes a copy of the given TypeLoc onto this builder.  The builder
+  /// must be empty for this to work.
+  void pushFullCopy(TypeLoc L) {
+#ifndef NDEBUG
+    assert(LastTy.isNull() && "pushing copy on non-empty TypeLocBuilder");
+    LastTy = L.getNextTypeLoc().getType();
+#endif
+    assert(Index == Capacity && "pushing copy on non-empty TypeLocBuilder");
+
+    unsigned Size = L.getFullDataSize();
+    TypeLoc Copy = pushImpl(L.getType(), Size);
+    memcpy(Copy.getOpaqueData(), L.getOpaqueData(), Size);
+  }
+
   /// 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));
   }
-  
+
+  /// Resets this builder to the newly-initialized state.
+  void clear() {
+#ifndef NDEBUG
+    LastTy = QualType();
+#endif
+    Index = Capacity;
+  }  
 
   /// Pushes space for a new TypeLoc of the given type.  Invalidates
   /// any TypeLocs previously retrieved from this builder.
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index c665073..9cb5686 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -90,10 +90,11 @@
 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)
+DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
+TYPE(ObjCObject, Type)
+TYPE(ObjCInterface, ObjCObjectType)
 TYPE(ObjCObjectPointer, Type)
 
 #ifdef LAST_TYPE
diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h
index 1a050d2..7cf0d5e 100644
--- a/include/clang/AST/TypeOrdering.h
+++ b/include/clang/AST/TypeOrdering.h
@@ -17,6 +17,7 @@
 #define LLVM_CLANG_TYPE_ORDERING_H
 
 #include "clang/AST/Type.h"
+#include "clang/AST/CanonicalType.h"
 #include <functional>
 
 namespace clang {
@@ -51,6 +52,26 @@
       return LHS == RHS;
     }
   };
+
+  template<> struct DenseMapInfo<clang::CanQualType> {
+    static inline clang::CanQualType getEmptyKey() { 
+      return clang::CanQualType(); 
+    }
+    
+    static inline clang::CanQualType getTombstoneKey() {
+      using clang::CanQualType;
+      return CanQualType::getFromOpaquePtr(reinterpret_cast<clang::Type *>(-1));
+    }
+    
+    static unsigned getHashValue(clang::CanQualType Val) {
+      return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^
+      ((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9));
+    }
+    
+    static bool isEqual(clang::CanQualType LHS, clang::CanQualType RHS) {
+      return LHS == RHS;
+    }
+  };
 }
 
 #endif
diff --git a/include/clang/AST/TypeVisitor.h b/include/clang/AST/TypeVisitor.h
index 19f7f42..5c9c528 100644
--- a/include/clang/AST/TypeVisitor.h
+++ b/include/clang/AST/TypeVisitor.h
@@ -1,4 +1,4 @@
-//===--- TypeVisitor.h - Visitor for Stmt subclasses ------------*- C++ -*-===//
+//===--- TypeVisitor.h - Visitor for Type subclasses ------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -25,7 +25,7 @@
 class TypeVisitor {
 public:
   RetTy Visit(Type *T) {
-    // Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
+    // Top switch stmt: dispatch to VisitFooType for each FooType.
     switch (T->getTypeClass()) {
     default: assert(0 && "Unknown type class!");
 #define ABSTRACT_TYPE(CLASS, PARENT)
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index cad7e61..a548b0b 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -31,9 +31,13 @@
   IteratorTy ir;
 
   friend class UnresolvedSetImpl;
+  friend class OverloadExpr;
   explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {}
   explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) :
     ir(const_cast<DeclsTy::iterator>(ir)) {}
+  
+  IteratorTy getIterator() const { return ir; }
+  
 public:
   UnresolvedSetIterator() {}
 
@@ -45,6 +49,7 @@
 
   NamedDecl *getDecl() const { return ir->getDecl(); }
   AccessSpecifier getAccess() const { return ir->getAccess(); }
+  void setAccess(AccessSpecifier AS) { ir->setAccess(AS); }
   DeclAccessPair getPair() const { return *ir; }
 
   NamedDecl *operator*() const { return getDecl(); }
@@ -80,9 +85,7 @@
   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.
+/// UnresolvedSet - A set of unresolved declarations.
 class UnresolvedSetImpl {
   typedef UnresolvedSetIterator::DeclsTy DeclsTy;
 
diff --git a/include/clang/AST/UsuallyTinyPtrVector.h b/include/clang/AST/UsuallyTinyPtrVector.h
index 5ee40e0..534d4d4 100644
--- a/include/clang/AST/UsuallyTinyPtrVector.h
+++ b/include/clang/AST/UsuallyTinyPtrVector.h
@@ -41,6 +41,7 @@
   typedef const T **iterator;
   iterator begin() const;
   iterator end() const;
+  size_t size() const;
 
   void push_back(T *Method);
   void Destroy();
@@ -56,7 +57,6 @@
   return &Vec->front();
 }
 
-
 template<typename T>
 typename UsuallyTinyPtrVector<T>::iterator 
 UsuallyTinyPtrVector<T>::end() const {
@@ -72,6 +72,15 @@
 }
 
 template<typename T>
+size_t UsuallyTinyPtrVector<T>::size() const {
+  if ((Storage & 0x01) == 0)
+    return (Storage == 0) ? 0 : 1;
+
+  vector_type *Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
+  return Vec->size();
+}
+
+template<typename T>
 void UsuallyTinyPtrVector<T>::push_back(T *Element) {
   if (Storage == 0) {
     // 0 -> 1 element.
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h
new file mode 100644
index 0000000..280b126
--- /dev/null
+++ b/include/clang/Analysis/Analyses/FormatString.h
@@ -0,0 +1,595 @@
+//= FormatString.h - Analysis of printf/fprintf format strings --*- 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 APIs for analyzing the format strings of printf, fscanf,
+// and friends.
+//
+// The structure of format strings for fprintf are described in C99 7.19.6.1.
+//
+// The structure of format strings for fscanf are described in C99 7.19.6.2.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FORMAT_H
+#define LLVM_CLANG_FORMAT_H
+
+#include "clang/AST/CanonicalType.h"
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+/// Common components of both fprintf and fscanf format strings.
+namespace analyze_format_string {
+
+/// Class representing optional flags with location and representation
+/// information.
+class OptionalFlag {
+public:
+  OptionalFlag(const char *Representation)
+      : representation(Representation), flag(false) {}
+  bool isSet() { return flag; }
+  void set() { flag = true; }
+  void clear() { flag = false; }
+  void setPosition(const char *position) {
+    assert(position);
+    this->position = position;
+  }
+  const char *getPosition() const {
+    assert(position);
+    return position;
+  }
+  const char *toString() const { return representation; }
+
+  // Overloaded operators for bool like qualities
+  operator bool() const { return flag; }
+  OptionalFlag& operator=(const bool &rhs) {
+    flag = rhs;
+    return *this;  // Return a reference to myself.
+  }
+private:
+  const char *representation;
+  const char *position;
+  bool flag;
+};
+
+/// Represents the length modifier in a format string in scanf/printf.
+class LengthModifier {
+public:
+  enum Kind {
+    None,
+    AsChar,       // 'hh'
+    AsShort,      // 'h'
+    AsLong,       // 'l'
+    AsLongLong,   // 'll', 'q' (BSD, deprecated)
+    AsIntMax,     // 'j'
+    AsSizeT,      // 'z'
+    AsPtrDiff,    // 't'
+    AsLongDouble, // 'L'
+    AsWideChar = AsLong // for '%ls', only makes sense for printf
+  };
+
+  LengthModifier()
+    : Position(0), kind(None) {}
+  LengthModifier(const char *pos, Kind k)
+    : Position(pos), kind(k) {}
+
+  const char *getStart() const {
+    return Position;
+  }
+
+  unsigned getLength() const {
+    switch (kind) {
+      default:
+        return 1;
+      case AsLongLong:
+      case AsChar:
+        return 2;
+      case None:
+        return 0;
+    }
+  }
+
+  Kind getKind() const { return kind; }
+  void setKind(Kind k) { kind = k; }
+
+  const char *toString() const;
+
+private:
+  const char *Position;
+  Kind kind;
+};
+  
+class ConversionSpecifier {
+public:
+  enum Kind {
+    InvalidSpecifier = 0,
+      // C99 conversion specifiers.
+    cArg,
+    dArg,
+    iArg,
+    IntArgBeg = cArg, IntArgEnd = iArg,    
+    
+    oArg,
+    uArg,
+    xArg,
+    XArg,
+    UIntArgBeg = oArg, UIntArgEnd = XArg,
+    
+    fArg,
+    FArg,
+    eArg,
+    EArg,
+    gArg,
+    GArg,
+    aArg,
+    AArg,
+    DoubleArgBeg = fArg, DoubleArgEnd = AArg,
+    
+    sArg,
+    pArg,
+    nArg,
+    PercentArg,
+    CArg,
+    SArg,
+    
+    // ** Printf-specific **
+  
+    // Objective-C specific specifiers.
+    ObjCObjArg,  // '@'
+    ObjCBeg = ObjCObjArg, ObjCEnd = ObjCObjArg,
+    
+    // GlibC specific specifiers.
+    PrintErrno,   // 'm'
+    
+    PrintfConvBeg = ObjCObjArg, PrintfConvEnd = PrintErrno,
+    
+    // ** Scanf-specific **    
+    ScanListArg, // '['
+    ScanfConvBeg = ScanListArg, ScanfConvEnd = ScanListArg
+  };
+  
+  ConversionSpecifier(bool isPrintf)
+    : IsPrintf(isPrintf), Position(0), EndScanList(0), kind(InvalidSpecifier) {}
+  
+  ConversionSpecifier(bool isPrintf, const char *pos, Kind k)
+    : IsPrintf(isPrintf), Position(pos), EndScanList(0), kind(k) {}
+  
+  const char *getStart() const {
+    return Position;
+  }
+  
+  llvm::StringRef getCharacters() const {
+    return llvm::StringRef(getStart(), getLength());
+  }
+  
+  bool consumesDataArgument() const {
+    switch (kind) {
+      case PrintErrno:
+        assert(IsPrintf);
+      case PercentArg:
+        return false;
+      default:
+        return true;
+    }
+  }
+  
+  Kind getKind() const { return kind; }
+  void setKind(Kind k) { kind = k; }
+  unsigned getLength() const {
+    return EndScanList ? EndScanList - Position : 1;
+  }
+  
+  const char *toString() const;
+  
+  bool isPrintfKind() const { return IsPrintf; }
+
+protected:
+  bool IsPrintf;
+  const char *Position;
+  const char *EndScanList;
+  Kind kind;
+};
+
+class ArgTypeResult {
+public:
+  enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CPointerTy,
+    CStrTy, WCStrTy, WIntTy };
+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 OptionalAmount {
+public:
+  enum HowSpecified { NotSpecified, Constant, Arg, Invalid };
+
+  OptionalAmount(HowSpecified howSpecified,
+                 unsigned amount,
+                 const char *amountStart,
+                 unsigned amountLength,
+                 bool usesPositionalArg)
+  : start(amountStart), length(amountLength), hs(howSpecified), amt(amount),
+  UsesPositionalArg(usesPositionalArg), UsesDotPrefix(0) {}
+
+  OptionalAmount(bool valid = true)
+  : start(0),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
+  UsesPositionalArg(0), UsesDotPrefix(0) {}
+
+  bool isInvalid() const {
+    return hs == Invalid;
+  }
+
+  HowSpecified getHowSpecified() const { return hs; }
+  void setHowSpecified(HowSpecified h) { hs = h; }
+
+  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 {
+      // We include the . character if it is given.
+    return start - UsesDotPrefix;
+  }
+
+  unsigned getConstantLength() const {
+    assert(hs == Constant);
+    return length + UsesDotPrefix;
+  }
+
+  ArgTypeResult getArgType(ASTContext &Ctx) const;
+
+  void toString(llvm::raw_ostream &os) const;
+
+  bool usesPositionalArg() const { return (bool) UsesPositionalArg; }
+  unsigned getPositionalArgIndex() const {
+    assert(hasDataArgument());
+    return amt + 1;
+  }
+
+  bool usesDotPrefix() const { return UsesDotPrefix; }
+  void setUsesDotPrefix() { UsesDotPrefix = true; }
+
+private:
+  const char *start;
+  unsigned length;
+  HowSpecified hs;
+  unsigned amt;
+  bool UsesPositionalArg : 1;
+  bool UsesDotPrefix;
+};
+
+
+class FormatSpecifier {
+protected:
+  LengthModifier LM;
+  OptionalAmount FieldWidth;
+  ConversionSpecifier CS;
+    /// Positional arguments, an IEEE extension:
+    ///  IEEE Std 1003.1, 2004 Edition
+    ///  http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
+  bool UsesPositionalArg;
+  unsigned argIndex;
+public:
+  FormatSpecifier(bool isPrintf)
+    : CS(isPrintf), UsesPositionalArg(false), argIndex(0) {}
+
+  void setLengthModifier(LengthModifier lm) {
+    LM = lm;
+  }
+
+  void setUsesPositionalArg() { UsesPositionalArg = true; }
+
+  void setArgIndex(unsigned i) {
+    argIndex = i;
+  }
+
+  unsigned getArgIndex() const {
+    return argIndex;
+  }
+
+  unsigned getPositionalArgIndex() const {
+    return argIndex + 1;
+  }
+
+  const LengthModifier &getLengthModifier() const {
+    return LM;
+  }
+
+  const OptionalAmount &getFieldWidth() const {
+    return FieldWidth;
+  }
+
+  void setFieldWidth(const OptionalAmount &Amt) {
+    FieldWidth = Amt;
+  }
+
+  bool usesPositionalArg() const { return UsesPositionalArg; }
+  
+  bool hasValidLengthModifier() const;
+};
+
+} // end analyze_format_string namespace
+
+//===----------------------------------------------------------------------===//
+/// Pieces specific to fprintf format strings.
+
+namespace analyze_printf {
+
+class PrintfConversionSpecifier : 
+  public analyze_format_string::ConversionSpecifier  {
+public:
+  PrintfConversionSpecifier()
+    : ConversionSpecifier(true, 0, InvalidSpecifier) {}
+
+  PrintfConversionSpecifier(const char *pos, Kind k)
+    : ConversionSpecifier(true, pos, k) {}
+
+  bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
+  bool isIntArg() const { return kind >= IntArgBeg && kind <= IntArgEnd; }
+  bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; }
+  bool isDoubleArg() const { return kind >= DoubleArgBeg && 
+                                    kind <= DoubleArgBeg; }
+  unsigned getLength() const {
+      // Conversion specifiers currently only are represented by
+      // single characters, but we be flexible.
+    return 1;
+  }
+
+  static bool classof(const analyze_format_string::ConversionSpecifier *CS) {
+    return CS->isPrintfKind();
+  }
+};
+
+using analyze_format_string::ArgTypeResult;
+using analyze_format_string::LengthModifier;
+using analyze_format_string::OptionalAmount;
+using analyze_format_string::OptionalFlag;
+
+class PrintfSpecifier : public analyze_format_string::FormatSpecifier {
+  OptionalFlag IsLeftJustified; // '-'
+  OptionalFlag HasPlusPrefix; // '+'
+  OptionalFlag HasSpacePrefix; // ' '
+  OptionalFlag HasAlternativeForm; // '#'
+  OptionalFlag HasLeadingZeroes; // '0'
+  OptionalAmount Precision;
+public:
+  PrintfSpecifier() :
+    FormatSpecifier(/* isPrintf = */ true),
+    IsLeftJustified("-"), HasPlusPrefix("+"), HasSpacePrefix(" "),
+    HasAlternativeForm("#"), HasLeadingZeroes("0") {}
+
+  static PrintfSpecifier Parse(const char *beg, const char *end);
+
+    // Methods for incrementally constructing the PrintfSpecifier.
+  void setConversionSpecifier(const PrintfConversionSpecifier &cs) {
+    CS = cs;
+  }
+  void setIsLeftJustified(const char *position) {
+    IsLeftJustified = true;
+    IsLeftJustified.setPosition(position);
+  }
+  void setHasPlusPrefix(const char *position) {
+    HasPlusPrefix = true;
+    HasPlusPrefix.setPosition(position);
+  }
+  void setHasSpacePrefix(const char *position) {
+    HasSpacePrefix = true;
+    HasSpacePrefix.setPosition(position);
+  }
+  void setHasAlternativeForm(const char *position) {
+    HasAlternativeForm = true;
+    HasAlternativeForm.setPosition(position);
+  }
+  void setHasLeadingZeros(const char *position) {
+    HasLeadingZeroes = true;
+    HasLeadingZeroes.setPosition(position);
+  }
+  void setUsesPositionalArg() { UsesPositionalArg = true; }
+
+    // Methods for querying the format specifier.
+
+  const PrintfConversionSpecifier &getConversionSpecifier() const {
+    return cast<PrintfConversionSpecifier>(CS);
+  }
+
+  void setPrecision(const OptionalAmount &Amt) {
+    Precision = Amt;
+    Precision.setUsesDotPrefix();
+  }
+
+  const OptionalAmount &getPrecision() const {
+    return Precision;
+  }
+  
+  bool consumesDataArgument() const {
+    return getConversionSpecifier().consumesDataArgument();
+  }
+
+  /// \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;
+
+  const OptionalFlag &isLeftJustified() const { return IsLeftJustified; }
+  const OptionalFlag &hasPlusPrefix() const { return HasPlusPrefix; }
+  const OptionalFlag &hasAlternativeForm() const { return HasAlternativeForm; }
+  const OptionalFlag &hasLeadingZeros() const { return HasLeadingZeroes; }
+  const OptionalFlag &hasSpacePrefix() const { return HasSpacePrefix; }
+  bool usesPositionalArg() const { return UsesPositionalArg; }
+
+    /// Changes the specifier and length according to a QualType, retaining any
+    /// flags or options. Returns true on success, or false when a conversion
+    /// was not successful.
+  bool fixType(QualType QT);
+
+  void toString(llvm::raw_ostream &os) const;
+
+    // Validation methods - to check if any element results in undefined behavior
+  bool hasValidPlusPrefix() const;
+  bool hasValidAlternativeForm() const;
+  bool hasValidLeadingZeros() const;
+  bool hasValidSpacePrefix() const;
+  bool hasValidLeftJustified() const;
+
+  bool hasValidPrecision() const;
+  bool hasValidFieldWidth() const;
+};
+}  // end analyze_printf namespace
+
+//===----------------------------------------------------------------------===//
+/// Pieces specific to fscanf format strings.
+
+namespace analyze_scanf {
+
+class ScanfConversionSpecifier :
+    public analyze_format_string::ConversionSpecifier  {
+public:
+  ScanfConversionSpecifier()
+    : ConversionSpecifier(false, 0, InvalidSpecifier) {}
+
+  ScanfConversionSpecifier(const char *pos, Kind k)
+    : ConversionSpecifier(false, pos, k) {}
+
+  void setEndScanList(const char *pos) { EndScanList = pos; }
+      
+  static bool classof(const analyze_format_string::ConversionSpecifier *CS) {
+    return !CS->isPrintfKind();
+  }      
+};
+
+using analyze_format_string::LengthModifier;
+using analyze_format_string::OptionalAmount;
+using analyze_format_string::OptionalFlag;
+
+class ScanfSpecifier : public analyze_format_string::FormatSpecifier {
+  OptionalFlag SuppressAssignment; // '*'
+public:
+  ScanfSpecifier() :
+    FormatSpecifier(/* isPrintf = */ false),
+    SuppressAssignment("*") {}
+
+  void setSuppressAssignment(const char *position) {
+    SuppressAssignment = true;
+    SuppressAssignment.setPosition(position);
+  }
+
+  const OptionalFlag &getSuppressAssignment() const {
+    return SuppressAssignment;
+  }
+
+  void setConversionSpecifier(const ScanfConversionSpecifier &cs) {
+    CS = cs;
+  }
+
+  const ScanfConversionSpecifier &getConversionSpecifier() const {
+    return cast<ScanfConversionSpecifier>(CS);
+  }
+  
+  bool consumesDataArgument() const {
+    return CS.consumesDataArgument() && !SuppressAssignment;
+  }
+
+  static ScanfSpecifier Parse(const char *beg, const char *end);
+};
+
+} // end analyze_scanf namespace
+
+//===----------------------------------------------------------------------===//
+// Parsing and processing of format strings (both fprintf and fscanf).
+
+namespace analyze_format_string {
+
+enum PositionContext { FieldWidthPos = 0, PrecisionPos = 1 };
+
+class FormatStringHandler {
+public:
+  FormatStringHandler() {}
+  virtual ~FormatStringHandler();
+
+  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 void HandleIncompleteSpecifier(const char *startSpecifier,
+                                         unsigned specifierLen) {}
+
+  // Printf-specific handlers.
+
+  virtual bool HandleInvalidPrintfConversionSpecifier(
+                                      const analyze_printf::PrintfSpecifier &FS,
+                                      const char *startSpecifier,
+                                      unsigned specifierLen) {
+    return true;
+  }
+
+  virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,
+                                     const char *startSpecifier,
+                                     unsigned specifierLen) {
+    return true;
+  }
+
+    // Scanf-specific handlers.
+
+  virtual bool HandleInvalidScanfConversionSpecifier(
+                                        const analyze_scanf::ScanfSpecifier &FS,
+                                        const char *startSpecifier,
+                                        unsigned specifierLen) {
+    return true;
+  }
+
+  virtual bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS,
+                                    const char *startSpecifier,
+                                    unsigned specifierLen) {
+    return true;
+  }
+
+  virtual void HandleIncompleteScanList(const char *start, const char *end) {}
+};
+
+bool ParsePrintfString(FormatStringHandler &H,
+                       const char *beg, const char *end);
+
+bool ParseScanfString(FormatStringHandler &H,
+                       const char *beg, const char *end);
+
+} // end analyze_format_string namespace
+} // end clang namespace
+#endif
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index 44ab080..237fe14 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -41,8 +41,9 @@
     ObserverTy* Observer;
     ValTy AlwaysLive;
     AnalysisContext *AC;
+    bool killAtAssign;
 
-    AnalysisDataTy() : Observer(NULL), AC(NULL) {}
+    AnalysisDataTy() : Observer(NULL), AC(NULL), killAtAssign(true) {}
   };
 
   //===-----------------------------------------------------===//
@@ -68,7 +69,7 @@
 public:
   typedef LiveVariables_ValueTypes::ObserverTy ObserverTy;
 
-  LiveVariables(AnalysisContext &AC);
+  LiveVariables(AnalysisContext &AC, bool killAtAssign = true);
 
   /// IsLive - Return true if a variable is live at the end of a
   /// specified block.
diff --git a/include/clang/Analysis/Analyses/PrintfFormatString.h b/include/clang/Analysis/Analyses/PrintfFormatString.h
deleted file mode 100644
index e4f7c57..0000000
--- a/include/clang/Analysis/Analyses/PrintfFormatString.h
+++ /dev/null
@@ -1,313 +0,0 @@
-//==- 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/PseudoConstantAnalysis.h b/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h
new file mode 100644
index 0000000..cb73850
--- /dev/null
+++ b/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h
@@ -0,0 +1,45 @@
+//== PseudoConstantAnalysis.h - Find Pseudo-constants in the AST -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tracks the usage of variables in a Decl body to see if they are
+// never written to, implying that they constant. This is useful in static
+// analysis to see if a developer might have intended a variable to be const.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_PSEUDOCONSTANTANALYSIS
+#define LLVM_CLANG_ANALYSIS_PSEUDOCONSTANTANALYSIS
+
+#include "clang/AST/Stmt.h"
+
+namespace clang {
+
+class PseudoConstantAnalysis {
+public:
+  PseudoConstantAnalysis(const Stmt *DeclBody);
+  ~PseudoConstantAnalysis();
+
+  bool isPseudoConstant(const VarDecl *VD);
+  bool wasReferenced(const VarDecl *VD);
+
+private:
+  void RunAnalysis();
+  inline static const Decl *getDecl(const Expr *E);
+
+  // for storing the result of analyzed ValueDecls
+  void *NonConstantsImpl;
+  void *UsedVarsImpl;
+
+  const Stmt *DeclBody;
+  bool Analyzed;
+};
+
+}
+
+#endif
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index 9ebd93b..7d4d25f 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -30,41 +30,67 @@
 class CFGBlock;
 class LiveVariables;
 class ParentMap;
+class PseudoConstantAnalysis;
 class ImplicitParamDecl;
 class LocationContextManager;
 class StackFrameContext;
 
+namespace idx { class TranslationUnit; }
+
 /// AnalysisContext contains the context data for the function or method under
 /// analysis.
 class AnalysisContext {
   const Decl *D;
 
+  // TranslationUnit is NULL if we don't have multiple translation units.
+  idx::TranslationUnit *TU;
+
   // AnalysisContext owns the following data.
-  CFG *cfg;
-  bool builtCFG;
+  CFG *cfg, *completeCFG;
+  bool builtCFG, builtCompleteCFG;
   LiveVariables *liveness;
+  LiveVariables *relaxedLiveness;
   ParentMap *PM;
+  PseudoConstantAnalysis *PCA;
   llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
   llvm::BumpPtrAllocator A;
+  bool UseUnoptimizedCFG;  
   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(const Decl *d, idx::TranslationUnit *tu,
+                  bool useUnoptimizedCFG = false,
+                  bool addehedges = false)
+    : D(d), TU(tu), cfg(0), completeCFG(0),
+      builtCFG(false), builtCompleteCFG(false),
+      liveness(0), relaxedLiveness(0), PM(0), PCA(0),
+      ReferencedBlockVars(0), UseUnoptimizedCFG(useUnoptimizedCFG),
+      AddEHEdges(addehedges) {}
 
   ~AnalysisContext();
 
   ASTContext &getASTContext() { return D->getASTContext(); }
-  const Decl *getDecl() { return D; }
+  const Decl *getDecl() const { return D; }
+
+  idx::TranslationUnit *getTranslationUnit() const { return TU; }
+
   /// 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; }
+  
+  bool getUseUnoptimizedCFG() const { return UseUnoptimizedCFG; }
+
   Stmt *getBody();
   CFG *getCFG();
+  
+  /// Return a version of the CFG without any edges pruned.
+  CFG *getUnoptimizedCFG();
+
   ParentMap &getParentMap();
+  PseudoConstantAnalysis *getPseudoConstantAnalysis();
   LiveVariables *getLiveVariables();
+  LiveVariables *getRelaxedLiveVariables();
 
   typedef const VarDecl * const * referenced_decls_iterator;
 
@@ -79,10 +105,16 @@
 class AnalysisContextManager {
   typedef llvm::DenseMap<const Decl*, AnalysisContext*> ContextMap;
   ContextMap Contexts;
+  bool UseUnoptimizedCFG;
 public:
+  AnalysisContextManager(bool useUnoptimizedCFG = false)
+    : UseUnoptimizedCFG(useUnoptimizedCFG) {}
+  
   ~AnalysisContextManager();
 
-  AnalysisContext *getContext(const Decl *D);
+  AnalysisContext *getContext(const Decl *D, idx::TranslationUnit *TU = 0);
+
+  bool getUseUnoptimizedCFG() const { return UseUnoptimizedCFG; }
 
   // Discard all previously created AnalysisContexts.
   void clear();
@@ -94,7 +126,10 @@
 
 private:
   ContextKind Kind;
+
+  // AnalysisContext can't be const since some methods may modify its member.
   AnalysisContext *Ctx;
+
   const LocationContext *Parent;
 
 protected:
@@ -109,6 +144,10 @@
 
   AnalysisContext *getAnalysisContext() const { return Ctx; }
 
+  idx::TranslationUnit *getTranslationUnit() const { 
+    return Ctx->getTranslationUnit(); 
+  }
+
   const LocationContext *getParent() const { return Parent; }
 
   bool isParentOf(const LocationContext *LC) const;
diff --git a/include/clang/Analysis/AnalysisDiagnostic.h b/include/clang/Analysis/AnalysisDiagnostic.h
index 114ae74..e98a3df 100644
--- a/include/clang/Analysis/AnalysisDiagnostic.h
+++ b/include/clang/Analysis/AnalysisDiagnostic.h
@@ -15,7 +15,7 @@
 namespace clang {
   namespace diag {
     enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
 #define ANALYSISSTART
 #include "clang/Basic/DiagnosticAnalysisKinds.inc"
 #undef DIAG
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index b7256c9..b7a8e11 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -35,22 +35,6 @@
   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;
@@ -59,7 +43,6 @@
   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; }
@@ -67,7 +50,6 @@
   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.
@@ -285,6 +267,7 @@
   /// 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 pruneTriviallyFalseEdges = true,
                        bool AddEHEdges = false,
                        bool AddScopes = false /* NOT FULLY IMPLEMENTED.
                                                  NOT READY FOR GENERAL USE. */);
diff --git a/include/clang/Analysis/CFGStmtMap.h b/include/clang/Analysis/CFGStmtMap.h
new file mode 100644
index 0000000..6e8e140
--- /dev/null
+++ b/include/clang/Analysis/CFGStmtMap.h
@@ -0,0 +1,52 @@
+//===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- 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 CFGStmtMap class, which defines a mapping from
+//  Stmt* to CFGBlock*
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CFGSTMTMAP_H
+#define LLVM_CLANG_CFGSTMTMAP_H
+
+#include "clang/Analysis/CFG.h"
+
+namespace clang {
+
+class CFG;
+class CFGBlock;
+class ParentMap;
+class Stmt;
+
+class CFGStmtMap {
+  ParentMap *PM;
+  void *M;
+  
+  CFGStmtMap(ParentMap *pm, void *m) : PM(pm), M(m) {}
+  
+public:
+  ~CFGStmtMap();
+  
+  /// Returns a new CFGMap for the given CFG.  It is the caller's
+  /// responsibility to 'delete' this object when done using it.
+  static CFGStmtMap *Build(CFG* C, ParentMap *PM);
+
+  /// Returns the CFGBlock the specified Stmt* appears in.  For Stmt* that
+  /// are terminators, the CFGBlock is the block they appear as a terminator,
+  /// and not the block they appear as a block-level expression (e.g, '&&').
+  /// CaseStmts and LabelStmts map to the CFGBlock they label.
+  CFGBlock *getBlock(Stmt * S);
+
+  const CFGBlock *getBlock(const Stmt * S) const {
+    return const_cast<CFGStmtMap*>(this)->getBlock(const_cast<Stmt*>(S));
+  }
+};
+
+} // end clang namespace
+#endif
diff --git a/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
index 3c76201..9375db0 100644
--- a/include/clang/Analysis/FlowSensitive/DataflowSolver.h
+++ b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
@@ -231,7 +231,7 @@
 
     EdgeDataMapTy& M = D.getEdgeDataMap();
     bool firstMerge = true;
-
+    bool noEdges = true;
     for (PrevBItr I=ItrTraits::PrevBegin(B),E=ItrTraits::PrevEnd(B); I!=E; ++I){
 
       CFGBlock *PrevBlk = *I;
@@ -243,6 +243,7 @@
         M.find(ItrTraits::PrevEdge(B, PrevBlk));
 
       if (EI != M.end()) {
+        noEdges = false;
         if (firstMerge) {
           firstMerge = false;
           V.copyValues(EI->second);
@@ -252,8 +253,20 @@
       }
     }
 
+    bool isInitialized = true;
+    typename BlockDataMapTy::iterator BI = D.getBlockDataMap().find(B);
+    if(BI == D.getBlockDataMap().end()) {
+      isInitialized = false;
+      BI = D.getBlockDataMap().insert( std::make_pair(B,ValTy()) ).first;
+    }
+    // If no edges have been found, it means this is the first time the solver 
+    // has been called on block B, we copy the initialization values (if any)
+    // as current value for V (which will be used as edge data)
+    if(noEdges && isInitialized) 
+      Merge(V, BI->second);
+
     // Set the data for the block.
-    D.getBlockDataMap()[B].copyValues(V);
+    BI->second.copyValues(V);
   }
 
   /// ProcessBlock - Process the transfer functions for a given block.
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index fb8d4d5..c71c305 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT
 #define LLVM_CLANG_ANALYSIS_PROGRAM_POINT
 
+#include "clang/Analysis/AnalysisContext.h"
 #include "clang/Analysis/CFG.h"
 #include "llvm/System/DataTypes.h"
 #include "llvm/ADT/DenseMap.h"
@@ -26,6 +27,7 @@
 namespace clang {
 
 class LocationContext;
+class AnalysisContext;
 class FunctionDecl;
 
 class ProgramPoint {
@@ -59,7 +61,7 @@
 protected:
   ProgramPoint(const void* P, Kind k, const LocationContext *l,
                const void *tag = 0)
-    : Data(P, NULL), K(k), L(l), Tag(tag) {}
+    : Data(P, static_cast<const void*>(NULL)), K(k), L(l), Tag(tag) {}
 
   ProgramPoint(const void* P1, const void* P2, Kind k, const LocationContext *l,
                const void *tag = 0)
@@ -107,16 +109,16 @@
                 const void *tag = 0)
     : ProgramPoint(B, BlockEntranceKind, L, tag) {}
 
-  CFGBlock* getBlock() const {
-    return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
+  const CFGBlock* getBlock() const {
+    return reinterpret_cast<const CFGBlock*>(getData1());
   }
 
-  CFGElement getFirstElement() const {
+  const CFGElement getFirstElement() const {
     const CFGBlock* B = getBlock();
     return B->empty() ? CFGElement() : B->front();
   }
   
-  Stmt *getFirstStmt() const {
+  const Stmt *getFirstStmt() const {
     return getFirstElement().getStmt();
   }
 
@@ -130,16 +132,16 @@
   BlockExit(const CFGBlock* B, const LocationContext *L)
     : ProgramPoint(B, BlockExitKind, L) {}
 
-  CFGBlock* getBlock() const {
-    return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
+  const CFGBlock* getBlock() const {
+    return reinterpret_cast<const CFGBlock*>(getData1());
   }
 
-  Stmt* getLastStmt() const {
+  const Stmt* getLastStmt() const {
     const CFGBlock* B = getBlock();
     return B->empty() ? CFGElement() : B->back();
   }
 
-  Stmt* getTerminator() const {
+  const Stmt* getTerminator() const {
     return getBlock()->getTerminator();
   }
 
@@ -298,12 +300,12 @@
   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()));
+  const CFGBlock* getSrc() const {
+    return static_cast<const CFGBlock*>(getData1());
   }
 
-  CFGBlock* getDst() const {
-    return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData2()));
+  const CFGBlock* getDst() const {
+    return static_cast<const CFGBlock*>(getData2());
   }
 
   static bool classof(const ProgramPoint* Location) {
@@ -313,16 +315,17 @@
 
 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) {}
+  // L is caller's location context. AC is callee's AnalysisContext.
+  CallEnter(const Stmt *S, const AnalysisContext *AC, const LocationContext *L)
+    : StmtPoint(S, AC, CallEnterKind, L, 0) {}
 
   const Stmt *getCallExpr() const {
     return static_cast<const Stmt *>(getData1());
   }
 
-  const FunctionDecl *getCallee() const {
-    return static_cast<const FunctionDecl *>(getData2());
+  AnalysisContext *getCalleeContext() const {
+    return const_cast<AnalysisContext *>(
+                              static_cast<const AnalysisContext *>(getData2()));
   }
 
   static bool classof(const ProgramPoint *Location) {
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
index c6c9eed..7cd4812 100644
--- a/include/clang/Analysis/Support/BumpVector.h
+++ b/include/clang/Analysis/Support/BumpVector.h
@@ -24,6 +24,7 @@
 #include "llvm/ADT/PointerIntPair.h"
 #include <algorithm>
 #include <cstring>
+#include <memory>
 
 namespace clang {
   
diff --git a/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h b/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
index d627b88..f20a49a 100644
--- a/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
+++ b/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
@@ -22,13 +22,14 @@
 #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));\
+#define DISPATCH_CASE(CLASS)                                  \
+case Decl::CLASS:                                             \
+static_cast<ImplClass*>(this)->Visit##CLASS##Decl(            \
+                               static_cast<CLASS##Decl*>(D)); \
 break;
 
-#define DEFAULT_DISPATCH(CLASS) void Visit##CLASS(CLASS* D) {}
-#define DEFAULT_DISPATCH_VARDECL(CLASS) void Visit##CLASS(CLASS* D)\
+#define DEFAULT_DISPATCH(CLASS) void Visit##CLASS##Decl(CLASS##Decl* D) {}
+#define DEFAULT_DISPATCH_VARDECL(CLASS) void Visit##CLASS##Decl(CLASS##Decl* D)\
   { static_cast<ImplClass*>(this)->VisitVarDecl(D); }
 
 
@@ -55,34 +56,39 @@
 
   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)
+        DISPATCH_CASE(Function)
+        DISPATCH_CASE(CXXMethod)
+        DISPATCH_CASE(Var)
+        DISPATCH_CASE(ParmVar)       // FIXME: (same)
+        DISPATCH_CASE(ImplicitParam)
+        DISPATCH_CASE(EnumConstant)
+        DISPATCH_CASE(Typedef)
+        DISPATCH_CASE(Record)    // FIXME: Refine.  VisitStructDecl?
+        DISPATCH_CASE(CXXRecord)
+        DISPATCH_CASE(Enum)
       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)
+  DEFAULT_DISPATCH(Var)
+  DEFAULT_DISPATCH(Function)
+  DEFAULT_DISPATCH(CXXMethod)
+  DEFAULT_DISPATCH_VARDECL(ParmVar)
+  DEFAULT_DISPATCH(ImplicitParam)
+  DEFAULT_DISPATCH(EnumConstant)
+  DEFAULT_DISPATCH(Typedef)
+  DEFAULT_DISPATCH(Record)
+  DEFAULT_DISPATCH(Enum)
+  DEFAULT_DISPATCH(ObjCInterface)
+  DEFAULT_DISPATCH(ObjCClass)
+  DEFAULT_DISPATCH(ObjCMethod)
+  DEFAULT_DISPATCH(ObjCProtocol)
+  DEFAULT_DISPATCH(ObjCCategory)
+
+  void VisitCXXRecordDecl(CXXRecordDecl *D) {
+    static_cast<ImplClass*>(this)->VisitRecordDecl(D);
+  }
 };
 
 } // end namespace clang
diff --git a/include/clang/Analysis/Visitors/CFGStmtVisitor.h b/include/clang/Analysis/Visitors/CFGStmtVisitor.h
index 8a85ec1..6421f18 100644
--- a/include/clang/Analysis/Visitors/CFGStmtVisitor.h
+++ b/include/clang/Analysis/Visitors/CFGStmtVisitor.h
@@ -86,7 +86,7 @@
         BinaryOperator* B = cast<BinaryOperator>(S);
         if (B->isLogicalOp())
           return static_cast<ImplClass*>(this)->BlockStmt_VisitLogicalOp(B);
-        else if (B->getOpcode() == BinaryOperator::Comma)
+        else if (B->getOpcode() == BO_Comma)
           return static_cast<ImplClass*>(this)->BlockStmt_VisitComma(B);
         // Fall through.
       }
@@ -149,7 +149,7 @@
 
       case Stmt::BinaryOperatorClass: {
         BinaryOperator* B = cast<BinaryOperator>(S);
-        if (B->getOpcode() != BinaryOperator::Comma) break;
+        if (B->getOpcode() != BO_Comma) break;
         static_cast<ImplClass*>(this)->Visit(B->getRHS());
         return;
       }
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
new file mode 100644
index 0000000..688d368
--- /dev/null
+++ b/include/clang/Basic/Attr.td
@@ -0,0 +1,408 @@
+////////////////////////////////////////////////////////////////////////////////
+// Note: This file is a work in progress. Please do not apply non-trivial
+// updates unless you have talked to Sean Hunt <rideau3@gmail.com> prior.
+// Merely adding a new attribute is a trivial update.
+////////////////////////////////////////////////////////////////////////////////
+
+// An attribute's subject is whatever it appertains to. In this file, it is
+// more accurately a list of things that an attribute can appertain to. All
+// Decls and Stmts are possibly AttrSubjects (even though the syntax may not
+// allow attributes on a given Decl or Stmt).
+class AttrSubject;
+
+include "DeclNodes.td"
+include "StmtNodes.td"
+
+// A subset-subject is an AttrSubject constrained to operate only on some subset
+// of that subject.
+//
+// The description is used in output messages to specify what the subject
+// represents. FIXME: Deal with translation issues.
+//
+// The code fragment is a boolean expression that will confirm that the subject
+// meets the requirements; the subject will have the name S, and will have the
+// type specified by the base. It should be a simple boolean expression.
+class SubsetSubject<AttrSubject base, string description, code check>
+    : AttrSubject {
+  AttrSubject Base = base;
+  string Description = description;
+  code CheckCode = check;
+}
+
+// This is the type of a variable which C++0x defines [[aligned()]] as being
+// a possible subject.
+def NormalVar : SubsetSubject<Var, "non-register, non-parameter variable",
+                              [{S->getStorageClass() != VarDecl::Register &&
+                                S->getKind() != Decl::ImplicitParam &&
+                                S->getKind() != Decl::ParmVar &&
+                                S->getKind() != Decl::NonTypeTemplateParm}]>;
+def CXXVirtualMethod : SubsetSubject<CXXRecord, "virtual member function",
+                                     [{S->isVirtual()}]>;
+def NonBitField : SubsetSubject<Field, "non-bit field",
+                                [{!S->isBitField()}]>;
+
+// A single argument to an attribute
+class Argument<string name> {
+  string Name = name;
+}
+
+class IdentifierArgument<string name> : Argument<name>;
+class IntArgument<string name> : Argument<name>;
+class StringArgument<string name> : Argument<name>;
+class ExprArgument<string name> : Argument<name>;
+class FunctionArgument<string name> : Argument<name>;
+class TypeArgument<string name> : Argument<name>;
+class UnsignedArgument<string name> : Argument<name>;
+class VariadicUnsignedArgument<string name> : Argument<name>;
+
+// This one's a doozy, so it gets its own special type
+// It can be an unsigned integer, or a type. Either can
+// be dependent.
+class AlignedArgument<string name> : Argument<name>;
+
+// An integer argument with a default value
+class DefaultIntArgument<string name, int default> : IntArgument<name> {
+  int Default = default;
+}
+
+// This argument is more complex, it includes the enumerator type name,
+// a list of strings to accept, and a list of enumerators to map them to.
+class EnumArgument<string name, string type, list<string> values,
+                         list<string> enums> : Argument<name> {
+  string Type = type;
+  list<string> Values = values;
+  list<string> Enums = enums;
+}
+
+class Attr {
+  // The various ways in which an attribute can be spelled in source
+  list<string> Spellings;
+  // The things to which an attribute can appertain
+  list<AttrSubject> Subjects;
+  // The arguments allowed on an attribute
+  list<Argument> Args = [];
+  // The namespaces in which the attribute appears in C++0x attributes.
+  // The attribute will not be permitted in C++0x attribute-specifiers if
+  // this is empty; the empty string can be used as a namespace.
+  list<string> Namespaces = [];
+  // Any additional text that should be included verbatim in the class.
+  code AdditionalMembers = [{}];
+}
+
+//
+// Attributes begin here
+//
+
+def Alias : Attr {
+  let Spellings = ["alias"];
+  let Args = [StringArgument<"Aliasee">];
+}
+
+def Aligned : Attr {
+  let Spellings = ["align", "aligned"];
+  let Subjects = [NonBitField, NormalVar, Tag];
+  let Args = [AlignedArgument<"Alignment">];
+  let Namespaces = ["", "std"];
+}
+
+def AlignMac68k : Attr {
+  let Spellings = [];
+}
+
+def AlwaysInline : Attr {
+  let Spellings = ["always_inline"];
+}
+
+def AnalyzerNoReturn : Attr {
+  let Spellings = ["analyzer_noreturn"];
+}
+
+def Annotate : Attr {
+  let Spellings = ["annotate"];
+  let Args = [StringArgument<"Annotation">];
+}
+
+def AsmLabel : Attr {
+  let Spellings = [];
+  let Args = [StringArgument<"Label">];
+}
+
+def BaseCheck : Attr {
+  let Spellings = ["base_check"];
+  let Subjects = [CXXRecord];
+  let Namespaces = ["", "std"];
+}
+
+def Blocks : Attr {
+  let Spellings = ["blocks"];
+  let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
+}
+
+def CarriesDependency : Attr {
+  let Spellings = ["carries_dependency"];
+  let Subjects = [ParmVar, Function];
+  let Namespaces = ["", "std"];
+}
+
+def CDecl : Attr {
+  let Spellings = ["cdecl", "__cdecl"];
+}
+
+def CFReturnsRetained : Attr {
+  let Spellings = ["cf_returns_retained"];
+}
+
+def CFReturnsNotRetained : Attr {
+  let Spellings = ["cf_returns_not_retained"];
+}
+
+def Cleanup : Attr {
+  let Spellings = ["cleanup"];
+  let Args = [FunctionArgument<"FunctionDecl">];
+}
+
+def Const : Attr {
+  let Spellings = ["const"];
+}
+
+def Constructor : Attr {
+  let Spellings = ["constructor"];
+  let Args = [IntArgument<"Priority">];
+}
+
+def Deprecated : Attr {
+  let Spellings = ["deprecated"];
+}
+
+def Destructor : Attr {
+  let Spellings = ["destructor"];
+  let Args = [IntArgument<"Priority">];
+}
+
+def DLLExport : Attr {
+  let Spellings = ["dllexport"];
+}
+
+def DLLImport : Attr {
+  let Spellings = ["dllimport"];
+}
+
+def FastCall : Attr {
+  let Spellings = ["fastcall", "__fastcall"];
+}
+
+def Final : Attr {
+  let Spellings = ["final"];
+  let Subjects = [CXXRecord, CXXVirtualMethod];
+  let Namespaces = ["", "std"];
+}
+
+def Format : Attr {
+  let Spellings = ["format"];
+  let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">,
+              IntArgument<"FirstArg">];
+}
+
+def FormatArg : Attr {
+  let Spellings = ["format_arg"];
+  let Args = [IntArgument<"FormatIdx">];
+}
+
+def GNUInline : Attr {
+  let Spellings = ["gnu_inline"];
+}
+
+def Hiding : Attr {
+  let Spellings = ["hiding"];
+  let Subjects = [Field, CXXMethod];
+  let Namespaces = ["", "std"];
+}
+
+def IBAction : Attr {
+  let Spellings = ["ibaction"];
+}
+
+def IBOutlet : Attr {
+  let Spellings = ["iboutlet"];
+}
+
+def IBOutletCollection : Attr {
+  let Spellings = ["iboutletcollection"];
+  let Args = [TypeArgument<"Interface">];
+}
+
+def Malloc : Attr {
+  let Spellings = ["malloc"];
+}
+
+def MaxFieldAlignment : Attr {
+  let Spellings = [];
+  let Args = [UnsignedArgument<"Alignment">];
+}
+
+def MSP430Interrupt : Attr {
+  let Spellings = [];
+  let Args = [UnsignedArgument<"Number">];
+}
+
+def NoDebug : Attr {
+  let Spellings = ["nodebug"];
+}
+
+def NoInline : Attr {
+  let Spellings = ["noinline"];
+}
+
+def NonNull : Attr {
+  let Spellings = ["nonnull"];
+  let Args = [VariadicUnsignedArgument<"Args">];
+  let AdditionalMembers =
+[{bool isNonNull(unsigned idx) const {
+    for (args_iterator i = args_begin(), e = args_end();
+         i != e; ++i)
+      if (*i == idx)
+        return true;
+    return false;
+  } }];
+}
+
+def NoReturn : Attr {
+  let Spellings = ["noreturn"];
+  // FIXME: Does GCC allow this on the function instead?
+  let Subjects = [Function];
+  let Namespaces = ["", "std"];
+}
+
+def NoInstrumentFunction : Attr {
+  let Spellings = ["no_instrument_function"];
+  let Subjects = [Function];
+}
+
+def NoThrow : Attr {
+  let Spellings = ["nothrow"];
+}
+
+def NSReturnsRetained : Attr {
+  let Spellings = ["ns_returns_retained"];
+}
+
+def NSReturnsNotRetained : Attr {
+  let Spellings = ["ns_returns_not_retained"];
+}
+
+def ObjCException : Attr {
+  let Spellings = ["objc_exception"];
+}
+
+def ObjCNSObject : Attr {
+  let Spellings = ["NSOjbect"];
+}
+
+def Override : Attr {
+  let Spellings = ["override"];
+  let Subjects = [CXXVirtualMethod];
+  let Namespaces = ["", "std"];
+}
+
+def Overloadable : Attr {
+  let Spellings = ["overloadable"];
+}
+
+def Ownership : Attr {
+  let Spellings = ["ownership_holds", "ownership_returns", "ownership_takes"];
+  let Args = [EnumArgument<"OwnKind", "OwnershipKind",
+                    ["ownership_holds", "ownership_returns", "ownership_takes"],
+                    ["Holds", "Returns", "Takes"]>,
+              StringArgument<"Module">, VariadicUnsignedArgument<"Args">];
+}
+
+def Packed : Attr {
+  let Spellings = ["packed"];
+}
+
+def Pure : Attr {
+  let Spellings = ["pure"];
+}
+
+def Regparm : Attr {
+  let Spellings = ["regparm"];
+  let Args = [UnsignedArgument<"NumParams">];
+}
+
+def ReqdWorkGroupSize : Attr {
+  let Spellings = ["reqd_work_group_size"];
+  let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">,
+              UnsignedArgument<"ZDim">];
+}
+
+def InitPriority : Attr {
+  let Spellings = ["init_priority"];
+  let Args = [UnsignedArgument<"Priority">];
+}
+
+def Section : Attr {
+  let Spellings = ["section"];
+  let Args = [StringArgument<"Name">];
+}
+
+def Sentinel : Attr {
+  let Spellings = ["sentinel"];
+  let Args = [DefaultIntArgument<"Sentinel", 0>,
+              DefaultIntArgument<"NullPos", 0>];
+}
+
+def StdCall : Attr {
+  let Spellings = ["stdcall", "__stdcall"];
+}
+
+def ThisCall : Attr {
+  let Spellings = ["thiscall", "__thiscall"];
+}
+
+def TransparentUnion : Attr {
+  let Spellings = ["transparent_union"];
+}
+
+def Unavailable : Attr {
+  let Spellings = ["unavailable"];
+}
+
+def Unused : Attr {
+  let Spellings = ["unused"];
+}
+
+def Used : Attr {
+  let Spellings = ["used"];
+}
+
+def Visibility : Attr {
+  let Spellings = ["visibility"];
+  let Args = [EnumArgument<"Visibility", "VisibilityType",
+                           ["default", "hidden", "internal", "protected"],
+                           ["Default", "Hidden", "Hidden", "Protected"]>];
+}
+
+def VecReturn : Attr {
+  let Spellings = ["vecreturn"];
+  let Subjects = [CXXRecord];
+}
+
+def WarnUnusedResult : Attr {
+  let Spellings = ["warn_unused_result"];
+}
+
+def Weak : Attr {
+  let Spellings = ["weak"];
+}
+
+def WeakImport : Attr {
+  let Spellings = ["weak_import"];
+}
+
+def WeakRef : Attr {
+  let Spellings = ["weakref"];
+}
+
+def X86ForceAlignArgPointer : Attr {
+  let Spellings = [];
+}
diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h
new file mode 100644
index 0000000..822573b
--- /dev/null
+++ b/include/clang/Basic/AttrKinds.h
@@ -0,0 +1,31 @@
+//===----- Attr.h - Enum values for C Attribute 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 attr::Kind enum
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ATTRKINDS_H
+#define LLVM_CLANG_ATTRKINDS_H
+
+namespace clang {
+
+namespace attr {
+
+// Kind - This is a list of all the recognized kinds of attributes.
+enum Kind {
+#define ATTR(X) X,
+#include "clang/Basic/AttrList.inc"
+  NUM_ATTRS
+};
+
+} // end namespace attr
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index b306954..0da8938 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -66,6 +66,11 @@
 //  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
+//  s:N: -> this is a scanf-like function whose Nth argument is the format
+//          string.
+//  S:N: -> similar to the s:N: attribute, but the function is like vscanf
+//          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
 
@@ -193,9 +198,9 @@
 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_conj, "XdXd", "Fnc")
+BUILTIN(__builtin_conjf, "XfXf", "Fnc")
+BUILTIN(__builtin_conjl, "XLdXLd", "Fnc")
 BUILTIN(__builtin_clog, "XdXd", "Fnc")
 BUILTIN(__builtin_clogf, "XfXf", "Fnc")
 BUILTIN(__builtin_clogl, "XLdXLd", "Fnc")
@@ -281,12 +286,14 @@
 BUILTIN(__builtin_bcmp, "iv*v*z", "n")
 BUILTIN(__builtin_bcopy, "vv*v*z", "n")
 BUILTIN(__builtin_bzero, "vv*z", "nF")
+BUILTIN(__builtin_fprintf, "iP*cC*.", "Fp:1:")
 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_printf, "icC*.", "Fp:0:")
 BUILTIN(__builtin_stpcpy, "c*c*cC*", "nF")
 BUILTIN(__builtin_stpncpy, "c*c*cC*z", "nF")
 BUILTIN(__builtin_strcasecmp, "icC*cC*", "nF")
@@ -314,11 +321,12 @@
 BUILTIN(__builtin_longjmp, "vv**i", "r")
 BUILTIN(__builtin_unwind_init, "v", "")
 BUILTIN(__builtin_eh_return_data_regno, "ii", "nc")
+BUILTIN(__builtin_snprintf, "ic*zcC*.", "nFp:2:")
 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_eh_return, "vzv*", "r") // 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")
@@ -362,75 +370,75 @@
 // 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_add_1, "ccD*c.", "n")
+BUILTIN(__sync_fetch_and_add_2, "ssD*s.", "n")
+BUILTIN(__sync_fetch_and_add_4, "iiD*i.", "n")
+BUILTIN(__sync_fetch_and_add_8, "LLiLLiD*LLi.", "n")
+BUILTIN(__sync_fetch_and_add_16, "LLLiLLLiD*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_sub_1, "ccD*c.", "n")
+BUILTIN(__sync_fetch_and_sub_2, "ssD*s.", "n")
+BUILTIN(__sync_fetch_and_sub_4, "iiD*i.", "n")
+BUILTIN(__sync_fetch_and_sub_8, "LLiLLiD*LLi.", "n")
+BUILTIN(__sync_fetch_and_sub_16, "LLLiLLLiD*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_or_1, "ccD*c.", "n")
+BUILTIN(__sync_fetch_and_or_2, "ssD*s.", "n")
+BUILTIN(__sync_fetch_and_or_4, "iiD*i.", "n")
+BUILTIN(__sync_fetch_and_or_8, "LLiLLiD*LLi.", "n")
+BUILTIN(__sync_fetch_and_or_16, "LLLiLLLiD*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_and_1, "ccD*c.", "n")
+BUILTIN(__sync_fetch_and_and_2, "ssD*s.", "n")
+BUILTIN(__sync_fetch_and_and_4, "iiD*i.", "n")
+BUILTIN(__sync_fetch_and_and_8, "LLiLLiD*LLi.", "n")
+BUILTIN(__sync_fetch_and_and_16, "LLLiLLLiD*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_fetch_and_xor_1, "ccD*c.", "n")
+BUILTIN(__sync_fetch_and_xor_2, "ssD*s.", "n")
+BUILTIN(__sync_fetch_and_xor_4, "iiD*i.", "n")
+BUILTIN(__sync_fetch_and_xor_8, "LLiLLiD*LLi.", "n")
+BUILTIN(__sync_fetch_and_xor_16, "LLLiLLLiD*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_add_and_fetch_1, "ccD*c.", "n")
+BUILTIN(__sync_add_and_fetch_2, "ssD*s.", "n")
+BUILTIN(__sync_add_and_fetch_4, "iiD*i.", "n")
+BUILTIN(__sync_add_and_fetch_8, "LLiLLiD*LLi.", "n")
+BUILTIN(__sync_add_and_fetch_16, "LLLiLLLiD*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_sub_and_fetch_1, "ccD*c.", "n")
+BUILTIN(__sync_sub_and_fetch_2, "ssD*s.", "n")
+BUILTIN(__sync_sub_and_fetch_4, "iiD*i.", "n")
+BUILTIN(__sync_sub_and_fetch_8, "LLiLLiD*LLi.", "n")
+BUILTIN(__sync_sub_and_fetch_16, "LLLiLLLiD*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_or_and_fetch_1, "ccD*c.", "n")
+BUILTIN(__sync_or_and_fetch_2, "ssD*s.", "n")
+BUILTIN(__sync_or_and_fetch_4, "iiD*i.", "n")
+BUILTIN(__sync_or_and_fetch_8, "LLiLLiD*LLi.", "n")
+BUILTIN(__sync_or_and_fetch_16, "LLLiLLLiD*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_and_and_fetch_1, "ccD*c.", "n")
+BUILTIN(__sync_and_and_fetch_2, "ssD*s.", "n")
+BUILTIN(__sync_and_and_fetch_4, "iiD*i.", "n")
+BUILTIN(__sync_and_and_fetch_8, "LLiLLiD*LLi.", "n")
+BUILTIN(__sync_and_and_fetch_16, "LLLiLLLiD*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_xor_and_fetch_1, "ccD*c.", "n")
+BUILTIN(__sync_xor_and_fetch_2, "ssD*s.", "n")
+BUILTIN(__sync_xor_and_fetch_4, "iiD*i.", "n")
+BUILTIN(__sync_xor_and_fetch_8, "LLiLLiD*LLi.", "n")
+BUILTIN(__sync_xor_and_fetch_16, "LLLiLLLiD*LLLi.", "n")
 
 BUILTIN(__sync_bool_compare_and_swap, "v.", "")
 BUILTIN(__sync_bool_compare_and_swap_1, "bcD*cc.", "n")
@@ -447,18 +455,18 @@
 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_test_and_set_1, "ccD*c.", "n")
+BUILTIN(__sync_lock_test_and_set_2, "ssD*s.", "n")
+BUILTIN(__sync_lock_test_and_set_4, "iiD*i.", "n")
+BUILTIN(__sync_lock_test_and_set_8, "LLiLLiD*LLi.", "n")
+BUILTIN(__sync_lock_test_and_set_16, "LLLiLLLiD*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")
+BUILTIN(__sync_lock_release_1, "vcD*.", "n")
+BUILTIN(__sync_lock_release_2, "vsD*.", "n")
+BUILTIN(__sync_lock_release_4, "viD*.", "n")
+BUILTIN(__sync_lock_release_8, "vLLiD*.", "n")
+BUILTIN(__sync_lock_release_16, "vLLLiD*.", "n")
 
 
 
@@ -467,10 +475,10 @@
 // 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")
+BUILTIN(__sync_fetch_and_min, "iiD*i", "n")
+BUILTIN(__sync_fetch_and_max, "iiD*i", "n")
+BUILTIN(__sync_fetch_and_umin, "UiUiD*Ui", "n")
+BUILTIN(__sync_fetch_and_umax, "UiUiD*Ui", "n")
 
 // Random libc builtins.
 BUILTIN(__builtin_abort, "v", "Fnr")
@@ -515,6 +523,7 @@
 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")
+LIBBUILTIN(scanf, "icC*.",       "fs:0:", "stdio.h")
 // C99
 LIBBUILTIN(longjmp, "vJi",        "fr",    "setjmp.h")
 
@@ -540,6 +549,7 @@
 //   id objc_msgSend(id, SEL)
 // but we need new type letters for that.
 LIBBUILTIN(objc_msgSend, "v*.",   "f",     "objc/message.h")
+BUILTIN(__builtin_objc_memmove_collectable, "v*v*vC*z", "nF")
 
 // Builtin math library functions
 LIBBUILTIN(pow, "ddd", "fe", "math.h")
@@ -558,5 +568,10 @@
 LIBBUILTIN(cosl, "LdLd", "fe", "math.h")
 LIBBUILTIN(cosf, "ff", "fe", "math.h")
 
+// Blocks runtime Builtin math library functions
+LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h")
+LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h")
+// FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock.
+
 #undef BUILTIN
 #undef LIBBUILTIN
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
index 07f091a..94d5e69 100644
--- a/include/clang/Basic/Builtins.h
+++ b/include/clang/Basic/Builtins.h
@@ -119,6 +119,11 @@
   /// argument and whether this function as a va_list argument.
   bool isPrintfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg);
 
+  /// \brief Determine whether this builtin is like scanf 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 isScanfLike(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 {
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
index 4973076..080d17f 100644
--- a/include/clang/Basic/BuiltinsARM.def
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -14,7 +14,25 @@
 
 // The format of this database matches clang/Basic/Builtins.def.
 
-// FIXME: This is just a placeholder. NEON intrinsics should be listed here.
+// In libgcc
+BUILTIN(__clear_cache, "v.", "")
 BUILTIN(__builtin_thread_pointer, "v*", "")
 
+// Saturating arithmetic
+BUILTIN(__builtin_arm_qadd, "iii", "nc")
+BUILTIN(__builtin_arm_qsub, "iii", "nc")
+BUILTIN(__builtin_arm_ssat, "iiUi", "nc")
+BUILTIN(__builtin_arm_usat, "UiUiUi", "nc")
+
+// VFP
+BUILTIN(__builtin_arm_get_fpscr, "Ui", "nc")
+BUILTIN(__builtin_arm_set_fpscr, "vUi", "nc")
+BUILTIN(__builtin_arm_vcvtr_f, "ffi", "nc")
+BUILTIN(__builtin_arm_vcvtr_d, "fdi", "nc")
+
+// NEON
+#define GET_NEON_BUILTINS
+#include "clang/Basic/arm_neon.inc"
+#undef GET_NEON_BUILTINS
+
 #undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def
index 287bba9..e0518dc 100644
--- a/include/clang/Basic/BuiltinsPPC.def
+++ b/include/clang/Basic/BuiltinsPPC.def
@@ -18,14 +18,6 @@
 // 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", "")
@@ -49,6 +41,67 @@
 BUILTIN(__builtin_altivec_vavgsw, "V4SiV4SiV4Si", "")
 BUILTIN(__builtin_altivec_vavguw, "V4UiV4UiV4Ui", "")
 
+BUILTIN(__builtin_altivec_vrfip, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcfsx, "V4fV4ii", "")
+BUILTIN(__builtin_altivec_vcfux, "V4fV4ii", "")
+BUILTIN(__builtin_altivec_vctsxs, "V4SiV4fi", "")
+BUILTIN(__builtin_altivec_vctuxs, "V4UiV4fi", "")
+
+BUILTIN(__builtin_altivec_dss, "vUi", "")
+BUILTIN(__builtin_altivec_dssall, "v", "")
+BUILTIN(__builtin_altivec_dst, "vv*iUi", "") 
+BUILTIN(__builtin_altivec_dstt, "vv*iUi", "")
+BUILTIN(__builtin_altivec_dstst, "vv*iUi", "")
+BUILTIN(__builtin_altivec_dststt, "vv*iUi", "")
+
+BUILTIN(__builtin_altivec_vexptefp, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vrfim, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_lvx, "V4iiv*", "")
+BUILTIN(__builtin_altivec_lvxl, "V4iiv*", "")
+BUILTIN(__builtin_altivec_lvebx, "V16civ*", "")
+BUILTIN(__builtin_altivec_lvehx, "V8siv*", "")
+BUILTIN(__builtin_altivec_lvewx, "V4iiv*", "")
+
+BUILTIN(__builtin_altivec_vlogefp, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_lvsl, "V16cUcv*", "")
+BUILTIN(__builtin_altivec_lvsr, "V16cUcv*", "")
+
+BUILTIN(__builtin_altivec_vmaddfp, "V4fV4fV4fV4f", "")
+BUILTIN(__builtin_altivec_vmhaddshs, "V8sV8sV8sV8s", "")
+BUILTIN(__builtin_altivec_vmhraddshs, "V8sV8sV8sV8s", "")
+
+BUILTIN(__builtin_altivec_vmsumubm, "V4UiV16UcV16UcV4Ui", "")
+BUILTIN(__builtin_altivec_vmsummbm, "V4SiV16ScV16UcV4Si", "")
+BUILTIN(__builtin_altivec_vmsumuhm, "V4UiV8UsV8UsV4Ui", "")
+BUILTIN(__builtin_altivec_vmsumshm, "V4SiV8SsV8SsV4Si", "")
+BUILTIN(__builtin_altivec_vmsumuhs, "V4UiV8UsV8UsV4Ui", "")
+BUILTIN(__builtin_altivec_vmsumshs, "V4SiV8SsV8SsV4Si", "")
+
+BUILTIN(__builtin_altivec_vmuleub, "V8UsV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vmulesb, "V8SsV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vmuleuh, "V4UiV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vmulesh, "V4SiV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vmuloub, "V8UsV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vmulosb, "V8SsV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vmulouh, "V4UiV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vmulosh, "V4SiV8SsV8Ss", "")
+
+BUILTIN(__builtin_altivec_vnmsubfp, "V4fV4fV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vpkpx, "V8sV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vpkuhus, "V16UcV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vpkshss, "V16ScV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vpkuwus, "V8UsV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vpkswss, "V8SsV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vpkshus, "V16UcV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vpkswus, "V8UsV4SiV4Si", "")
+
+BUILTIN(__builtin_altivec_vperm_4si, "V4iV4iV4iV16Uc", "")
+
 BUILTIN(__builtin_altivec_stvx, "vV4iiv*", "")
 BUILTIN(__builtin_altivec_stvxl, "vV4iiv*", "")
 BUILTIN(__builtin_altivec_stvebx, "vV16civ*", "")
@@ -92,6 +145,48 @@
 
 BUILTIN(__builtin_altivec_mtvscr, "vV4i", "")
 
+BUILTIN(__builtin_altivec_vrefp, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vrlb, "V16cV16cV16Uc", "")
+BUILTIN(__builtin_altivec_vrlh, "V8sV8sV8Us", "")
+BUILTIN(__builtin_altivec_vrlw, "V4iV4iV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsel_4si, "V4iV4iV4iV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsl, "V4iV4iV4i", "")
+BUILTIN(__builtin_altivec_vslo, "V4iV4iV4i", "")
+
+BUILTIN(__builtin_altivec_vsrab, "V16cV16cV16Uc", "")
+BUILTIN(__builtin_altivec_vsrah, "V8sV8sV8Us", "")
+BUILTIN(__builtin_altivec_vsraw, "V4iV4iV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsr, "V4iV4iV4i", "")
+BUILTIN(__builtin_altivec_vsro, "V4iV4iV4i", "")
+
+BUILTIN(__builtin_altivec_vrfin, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vrsqrtefp, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vsubcuw, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsum4sbs, "V4SiV16ScV4Si", "")
+BUILTIN(__builtin_altivec_vsum4ubs, "V4UiV16UcV4Ui", "")
+BUILTIN(__builtin_altivec_vsum4shs, "V4SiV8SsV4Si", "")
+
+BUILTIN(__builtin_altivec_vsum2sws, "V4SiV4SiV4Si", "")
+
+BUILTIN(__builtin_altivec_vsumsws, "V4SiV4SiV4Si", "")
+
+BUILTIN(__builtin_altivec_vrfiz, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vupkhsb, "V8sV16c", "")
+BUILTIN(__builtin_altivec_vupkhpx, "V4UiV8s", "")
+BUILTIN(__builtin_altivec_vupkhsh, "V4iV8s", "")
+
+BUILTIN(__builtin_altivec_vupklsb, "V8sV16c", "")
+BUILTIN(__builtin_altivec_vupklpx, "V4UiV8s", "")
+BUILTIN(__builtin_altivec_vupklsh, "V4iV8s", "")
+
 BUILTIN(__builtin_altivec_vcmpbfp_p, "iiV4fV4f", "")
 
 BUILTIN(__builtin_altivec_vcmpgefp_p, "iiV4fV4f", "")
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index a878dd1..8586d2c 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -324,5 +324,98 @@
 BUILTIN(__builtin_ia32_aesdec128, "V2LLiV2LLiV2LLi", "")
 BUILTIN(__builtin_ia32_aesdeclast128, "V2LLiV2LLiV2LLi", "")
 BUILTIN(__builtin_ia32_aesimc128, "V2LLiV2LLi", "")
-BUILTIN(__builtin_ia32_aeskeygenassist128, "V2LLiV2LLii", "")
+BUILTIN(__builtin_ia32_aeskeygenassist128, "V2LLiV2LLic", "")
+
+// AVX
+BUILTIN(__builtin_ia32_addsubpd256, "V4dV4dV4d", "")
+BUILTIN(__builtin_ia32_addsubps256, "V8fV8fV8f", "")
+BUILTIN(__builtin_ia32_haddpd256, "V4dV4dV4d", "")
+BUILTIN(__builtin_ia32_hsubps256, "V8fV8fV8f", "")
+BUILTIN(__builtin_ia32_hsubpd256, "V4dV4dV4d", "")
+BUILTIN(__builtin_ia32_haddps256, "V8fV8fV8f", "")
+BUILTIN(__builtin_ia32_maxpd256, "V4dV4dV4d", "")
+BUILTIN(__builtin_ia32_maxps256, "V8fV8fV8f", "")
+BUILTIN(__builtin_ia32_minpd256, "V4dV4dV4d", "")
+BUILTIN(__builtin_ia32_minps256, "V8fV8fV8f", "")
+BUILTIN(__builtin_ia32_vpermilvarpd, "V2dV2dV2LLi", "")
+BUILTIN(__builtin_ia32_vpermilvarps, "V4fV4fV4i", "")
+BUILTIN(__builtin_ia32_vpermilvarpd256, "V4dV4dV4LLi", "")
+BUILTIN(__builtin_ia32_vpermilvarps256, "V8fV8fV8i", "")
+BUILTIN(__builtin_ia32_blendpd256, "V4dV4dV4di", "")
+BUILTIN(__builtin_ia32_blendps256, "V8fV8fV8fi", "")
+BUILTIN(__builtin_ia32_blendvpd256, "V4dV4dV4dV4d", "")
+BUILTIN(__builtin_ia32_blendvps256, "V8fV8fV8fV8f", "")
+BUILTIN(__builtin_ia32_dpps256, "V8fV8fV8fi", "")
+BUILTIN(__builtin_ia32_cmppd256, "V4dV4dV4dc", "")
+BUILTIN(__builtin_ia32_cmpps256, "V8fV8fV8fc", "")
+BUILTIN(__builtin_ia32_vextractf128_pd256, "V2dV4dc", "")
+BUILTIN(__builtin_ia32_vextractf128_ps256, "V4fV8fc", "")
+BUILTIN(__builtin_ia32_vextractf128_si256, "V4iV8ic", "")
+BUILTIN(__builtin_ia32_cvtdq2pd256, "V4dV4i", "")
+BUILTIN(__builtin_ia32_cvtdq2ps256, "V8fV8i", "")
+BUILTIN(__builtin_ia32_cvtpd2ps256, "V4fV4d", "")
+BUILTIN(__builtin_ia32_cvtps2dq256, "V8iV8f", "")
+BUILTIN(__builtin_ia32_cvtps2pd256, "V4dV4f", "")
+BUILTIN(__builtin_ia32_cvttpd2dq256, "V4iV4d", "")
+BUILTIN(__builtin_ia32_cvtpd2dq256, "V4iV4d", "")
+BUILTIN(__builtin_ia32_cvttps2dq256, "V8iV8f", "")
+BUILTIN(__builtin_ia32_vperm2f128_pd256, "V4dV4dV4dc", "")
+BUILTIN(__builtin_ia32_vperm2f128_ps256, "V8fV8fV8fc", "")
+BUILTIN(__builtin_ia32_vperm2f128_si256, "V8iV8iV8ic", "")
+BUILTIN(__builtin_ia32_vpermilpd, "V2dV2dc", "")
+BUILTIN(__builtin_ia32_vpermilps, "V4fV4fc", "")
+BUILTIN(__builtin_ia32_vpermilpd256, "V4dV4dc", "")
+BUILTIN(__builtin_ia32_vpermilps256, "V8fV8fc", "")
+BUILTIN(__builtin_ia32_vinsertf128_pd256, "V4dV4dV2dc", "")
+BUILTIN(__builtin_ia32_vinsertf128_ps256, "V8fV8fV4fc", "")
+BUILTIN(__builtin_ia32_vinsertf128_si256, "V8iV8iV4ic", "")
+BUILTIN(__builtin_ia32_sqrtpd256, "V4dV4d", "")
+BUILTIN(__builtin_ia32_sqrtps256, "V8fV8f", "")
+BUILTIN(__builtin_ia32_rsqrtps256, "V8fV8f", "")
+BUILTIN(__builtin_ia32_rcpps256, "V8fV8f", "")
+BUILTIN(__builtin_ia32_roundpd256, "V4dV4di", "")
+BUILTIN(__builtin_ia32_roundps256, "V8fV8fi", "")
+BUILTIN(__builtin_ia32_vtestzpd, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_vtestcpd, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_vtestnzcpd, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_vtestzps, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_vtestcps, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_vtestnzcps, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_vtestzpd256, "iV4dV4d", "")
+BUILTIN(__builtin_ia32_vtestcpd256, "iV4dV4d", "")
+BUILTIN(__builtin_ia32_vtestnzcpd256, "iV4dV4d", "")
+BUILTIN(__builtin_ia32_vtestzps256, "iV8fV8f", "")
+BUILTIN(__builtin_ia32_vtestcps256, "iV8fV8f", "")
+BUILTIN(__builtin_ia32_vtestnzcps256, "iV8fV8f", "")
+BUILTIN(__builtin_ia32_ptestz256, "iV4LLiV4LLi", "")
+BUILTIN(__builtin_ia32_ptestc256, "iV4LLiV4LLi", "")
+BUILTIN(__builtin_ia32_ptestnzc256, "iV4LLiV4LLi", "")
+BUILTIN(__builtin_ia32_movmskpd256, "iV4d", "")
+BUILTIN(__builtin_ia32_movmskps256, "iV8f", "")
+BUILTIN(__builtin_ia32_vzeroall, "v", "")
+BUILTIN(__builtin_ia32_vzeroupper, "v", "")
+BUILTIN(__builtin_ia32_vbroadcastss, "V4ffC*", "")
+BUILTIN(__builtin_ia32_vbroadcastsd256, "V4ddC*", "")
+BUILTIN(__builtin_ia32_vbroadcastss256, "V8ffC*", "")
+BUILTIN(__builtin_ia32_vbroadcastf128_pd256, "V4dV2dC*", "")
+BUILTIN(__builtin_ia32_vbroadcastf128_ps256, "V8fV4fC*", "")
+BUILTIN(__builtin_ia32_loadupd256, "V4ddC*", "")
+BUILTIN(__builtin_ia32_loadups256, "V8ffC*", "")
+BUILTIN(__builtin_ia32_storeupd256, "vd*V4d", "")
+BUILTIN(__builtin_ia32_storeups256, "vf*V8f", "")
+BUILTIN(__builtin_ia32_loaddqu256, "V32ccC*", "")
+BUILTIN(__builtin_ia32_storedqu256, "vc*V32c", "")
+BUILTIN(__builtin_ia32_lddqu256, "V32ccC*", "")
+BUILTIN(__builtin_ia32_movntdq256, "vV4LLi*V4LLi", "")
+BUILTIN(__builtin_ia32_movntpd256, "vd*V4d", "")
+BUILTIN(__builtin_ia32_movntps256, "vf*V8f", "")
+BUILTIN(__builtin_ia32_maskloadpd, "V2dV2dC*V2d", "")
+BUILTIN(__builtin_ia32_maskloadps, "V4fV4fC*V4f", "")
+BUILTIN(__builtin_ia32_maskloadpd256, "V4dV4dC*V4d", "")
+BUILTIN(__builtin_ia32_maskloadps256, "V8fV8fC*V8f", "")
+BUILTIN(__builtin_ia32_maskstorepd, "vV2d*V2dV2d", "")
+BUILTIN(__builtin_ia32_maskstoreps, "vV4f*V4fV4f", "")
+BUILTIN(__builtin_ia32_maskstorepd256, "vV4d*V4dV4d", "")
+BUILTIN(__builtin_ia32_maskstoreps256, "vV8f*V8fV8f", "")
+
 #undef BUILTIN
diff --git a/include/clang/Basic/CMakeLists.txt b/include/clang/Basic/CMakeLists.txt
index c2a4e13..c595236 100644
--- a/include/clang/Basic/CMakeLists.txt
+++ b/include/clang/Basic/CMakeLists.txt
@@ -18,3 +18,15 @@
          -gen-clang-diag-groups)
 add_custom_target(ClangDiagnosticGroups
   DEPENDS DiagnosticGroups.inc)
+
+set(LLVM_TARGET_DEFINITIONS Attr.td)
+tablegen(AttrList.inc
+         -gen-clang-attr-list
+         -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrList
+  DEPENDS AttrList.inc)
+
+# ARM NEON
+set(LLVM_TARGET_DEFINITIONS arm_neon.td)
+tablegen(arm_neon.inc -gen-arm-neon-sema)
+add_custom_target(ClangARMNeon DEPENDS arm_neon.inc)
diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td
new file mode 100644
index 0000000..e2f93e0
--- /dev/null
+++ b/include/clang/Basic/DeclNodes.td
@@ -0,0 +1,71 @@
+class AttrSubject;
+
+class Decl<bit abstract = 0> : AttrSubject {
+  bit Abstract = abstract;
+}
+
+class DDecl<Decl base, bit abstract = 0> : Decl<abstract> {
+  Decl Base = base;
+}
+
+class DeclContext { }
+
+def TranslationUnit : Decl, DeclContext;
+def Named : Decl<1>;
+  def Namespace : DDecl<Named>, DeclContext;
+  def UsingDirective : DDecl<Named>;
+  def NamespaceAlias : DDecl<Named>;
+  def Type : DDecl<Named, 1>;
+    def Typedef : DDecl<Type>;
+    def UnresolvedUsingTypename : DDecl<Type>;
+    def Tag : DDecl<Type, 1>, DeclContext;
+      def Enum : DDecl<Tag>;
+      def Record : DDecl<Tag>;
+        def CXXRecord : DDecl<Record>;
+          def ClassTemplateSpecialization : DDecl<CXXRecord>;
+            def ClassTemplatePartialSpecialization
+              : DDecl<ClassTemplateSpecialization>;
+    def TemplateTypeParm : DDecl<Type>;
+  def Value : DDecl<Named, 1>;
+    def EnumConstant : DDecl<Value>;
+    def UnresolvedUsingValue : DDecl<Value>;
+    def Declarator : DDecl<Value, 1>;
+      def Function : DDecl<Declarator>, DeclContext;
+        def CXXMethod : DDecl<Function>;
+          def CXXConstructor : DDecl<CXXMethod>;
+          def CXXDestructor : DDecl<CXXMethod>;
+          def CXXConversion : DDecl<CXXMethod>;
+      def Field : DDecl<Declarator>;
+        def ObjCIvar : DDecl<Field>;
+        def ObjCAtDefsField : DDecl<Field>;
+      def Var : DDecl<Declarator>;
+        def ImplicitParam : DDecl<Var>;
+        def ParmVar : DDecl<Var>;
+        def NonTypeTemplateParm : DDecl<Var>;
+  def Template : DDecl<Named, 1>;
+    def RedeclarableTemplate : DDecl<Template, 1>;
+      def FunctionTemplate : DDecl<RedeclarableTemplate>;
+      def ClassTemplate : DDecl<RedeclarableTemplate>;
+    def TemplateTemplateParm : DDecl<Template>;
+  def Using : DDecl<Named>;
+  def UsingShadow : DDecl<Named>;
+  def ObjCMethod : DDecl<Named>, DeclContext;
+  def ObjCContainer : DDecl<Named, 1>, DeclContext;
+    def ObjCCategory : DDecl<ObjCContainer>;
+    def ObjCProtocol : DDecl<ObjCContainer>;
+    def ObjCInterface : DDecl<ObjCContainer>;
+    def ObjCImpl : DDecl<ObjCContainer, 1>;
+      def ObjCCategoryImpl : DDecl<ObjCImpl>;
+      def ObjCImplementation : DDecl<ObjCImpl>;
+  def ObjCProperty : DDecl<Named>;
+  def ObjCCompatibleAlias : DDecl<Named>;
+def LinkageSpec : Decl, DeclContext;
+def ObjCPropertyImpl : Decl;
+def ObjCForwardProtocol : Decl;
+def ObjCClass : Decl;
+def FileScopeAsm : Decl;
+def AccessSpec : Decl;
+def Friend : Decl;
+def FriendTemplate : Decl;
+def StaticAssert : Decl;
+def Block : Decl, DeclContext;
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index bf94af6..37d2694 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -16,6 +16,7 @@
 
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/type_traits.h"
 #include <string>
@@ -24,7 +25,6 @@
 
 namespace llvm {
   template <typename T> class SmallVectorImpl;
-  class raw_ostream;
 }
 
 namespace clang {
@@ -36,8 +36,6 @@
   class LangOptions;
   class PartialDiagnostic;
   class Preprocessor;
-  class SourceManager;
-  class SourceRange;
 
   // Import the diagnostic enums themselves.
   namespace diag {
@@ -60,7 +58,7 @@
 
     // Get typedefs for common diagnostics.
     enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
 #include "clang/Basic/DiagnosticCommonKinds.inc"
       NUM_BUILTIN_COMMON_DIAGNOSTICS
 #undef DIAG
@@ -98,12 +96,9 @@
 /// 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 Code that should be replaced to correct the error. Empty for an
+  /// insertion hint.
+  CharSourceRange RemoveRange;
 
   /// \brief The actual code to insert at the insertion location, as a
   /// string.
@@ -111,10 +106,10 @@
 
   /// \brief Empty code modification hint, indicating that no code
   /// modification is known.
-  FixItHint() : RemoveRange(), InsertionLoc() { }
+  FixItHint() : RemoveRange() { }
 
   bool isNull() const {
-    return !RemoveRange.isValid() && !InsertionLoc.isValid();
+    return !RemoveRange.isValid();
   }
   
   /// \brief Create a code modification hint that inserts the given
@@ -122,29 +117,37 @@
   static FixItHint CreateInsertion(SourceLocation InsertionLoc,
                                    llvm::StringRef Code) {
     FixItHint Hint;
-    Hint.InsertionLoc = InsertionLoc;
+    Hint.RemoveRange =
+      CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false);
     Hint.CodeToInsert = Code;
     return Hint;
   }
 
   /// \brief Create a code modification hint that removes the given
   /// source range.
-  static FixItHint CreateRemoval(SourceRange RemoveRange) {
+  static FixItHint CreateRemoval(CharSourceRange RemoveRange) {
     FixItHint Hint;
     Hint.RemoveRange = RemoveRange;
     return Hint;
   }
-
+  static FixItHint CreateRemoval(SourceRange RemoveRange) {
+    return CreateRemoval(CharSourceRange::getTokenRange(RemoveRange));
+  }
+  
   /// \brief Create a code modification hint that replaces the given
   /// source range with the given code string.
-  static FixItHint CreateReplacement(SourceRange RemoveRange,
+  static FixItHint CreateReplacement(CharSourceRange RemoveRange,
                                      llvm::StringRef Code) {
     FixItHint Hint;
     Hint.RemoveRange = RemoveRange;
-    Hint.InsertionLoc = RemoveRange.getBegin();
     Hint.CodeToInsert = Code;
     return Hint;
   }
+  
+  static FixItHint CreateReplacement(SourceRange RemoveRange,
+                                     llvm::StringRef Code) {
+    return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), Code);
+  }
 };
 
 /// Diagnostic - This concrete class is used by the front-end to report
@@ -176,7 +179,14 @@
     ak_nestednamespec,  // NestedNameSpecifier *
     ak_declcontext      // DeclContext *
   };
-  
+
+  /// Specifies which overload candidates to display when overload resolution
+  /// fails.
+  enum OverloadsShown {
+    Ovl_All,  ///< Show all overloads.
+    Ovl_Best  ///< Show just the "best" overload candidates.
+  };
+
   /// ArgumentValue - This typedef represents on argument value, which is a
   /// union discriminated by ArgumentKind, with a value.
   typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
@@ -188,20 +198,37 @@
   bool ErrorsAsFatal;            // Treat errors like fatal errors.
   bool SuppressSystemWarnings;   // Suppress warnings in system headers.
   bool SuppressAllDiagnostics;   // Suppress all diagnostics.
+  OverloadsShown ShowOverloads;  // Which overload candidates to show.
   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;
-
+  llvm::OwningPtr<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.
+  class DiagMappings {
+    unsigned char Values[diag::DIAG_UPPER_LIMIT/2];
 
-  typedef std::vector<unsigned char> DiagMappings;
+  public:
+    DiagMappings() {
+      memset(Values, 0, diag::DIAG_UPPER_LIMIT/2);
+    }
+
+    void setMapping(diag::kind Diag, unsigned Map) {
+      size_t Shift = (Diag & 1)*4;
+      Values[Diag/2] = (Values[Diag/2] & ~(15 << Shift)) | (Map << Shift);
+    }
+
+    diag::Mapping getMapping(diag::kind Diag) const {
+      return (diag::Mapping)((Values[Diag/2] >> (Diag & 1)*4) & 15);
+    }
+  };
+
   mutable std::vector<DiagMappings> DiagMappingsStack;
 
   /// ErrorOccurred / FatalErrorOccurred - This is set to true when an error or
@@ -259,8 +286,12 @@
   //  Diagnostic characterization methods, used by a client to customize how
   //
 
-  DiagnosticClient *getClient() { return Client; }
-  const DiagnosticClient *getClient() const { return Client; }
+  DiagnosticClient *getClient() { return Client.get(); }
+  const DiagnosticClient *getClient() const { return Client.get(); }
+  
+  /// \brief Return the current diagnostic client along with ownership of that
+  /// client.
+  DiagnosticClient *takeClient() { return Client.take(); }
 
   /// pushMappings - Copies the current DiagMappings and pushes the new copy
   /// onto the top of the stack.
@@ -272,7 +303,10 @@
   /// stack.
   bool popMappings();
 
-  void setClient(DiagnosticClient* client) { Client = client; }
+  /// \brief Set the diagnostic client associated with this diagnostic object.
+  ///
+  /// The diagnostic object takes ownership of \c client.
+  void setClient(DiagnosticClient* client) { Client.reset(client); }
 
   /// setErrorLimit - Specify a limit for the number of errors we should
   /// emit before giving up.  Zero disables the limit.
@@ -283,13 +317,13 @@
   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; }
@@ -318,6 +352,13 @@
   }
   bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
   
+  /// \brief Specify which overload candidates to show when overload resolution
+  /// fails.  By default, we show all candidates.
+  void setShowOverloads(OverloadsShown Val) {
+    ShowOverloads = Val;
+  }
+  OverloadsShown getShowOverloads() const { return ShowOverloads; }
+  
   /// \brief Pretend that the last diagnostic issued was ignored. This can
   /// be used by clients who suppress diagnostics themselves.
   void setLastDiagnosticIgnored() {
@@ -362,6 +403,10 @@
   unsigned getNumErrorsSuppressed() const { return NumErrorsSuppressed; }
   unsigned getNumWarnings() const { return NumWarnings; }
 
+  void setNumWarnings(unsigned NumWarnings) {
+    this->NumWarnings = 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.
@@ -384,6 +429,10 @@
     ArgToStringCookie = Cookie;
   }
 
+  /// \brief Reset the state of the diagnostic object to its initial 
+  /// configuration.
+  void Reset();
+  
   //===--------------------------------------------------------------------===//
   // Diagnostic classification and reporting interfaces.
   //
@@ -423,6 +472,14 @@
   /// the diagnostic, this returns null.
   static const char *getWarningOptionForDiag(unsigned DiagID);
 
+  /// getWarningOptionForDiag - Return the category number that a specified
+  /// DiagID belongs to, or 0 if no category.
+  static unsigned getCategoryNumberForDiag(unsigned DiagID);
+
+  /// getCategoryNameFromID - Given a category ID, return the name of the
+  /// category.
+  static const char *getCategoryNameFromID(unsigned CategoryID);
+  
   /// \brief Enumeration describing how the the emission of a diagnostic should
   /// be treated when it occurs during C++ template argument deduction.
   enum SFINAEResponse {
@@ -507,17 +564,13 @@
   /// 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);
+    return DiagMappingsStack.back().getMapping(Diag);
   }
 
   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;
+    DiagMappingsStack.back().setMapping((diag::kind)DiagId, Map);
   }
 
   /// getDiagnosticLevel - This is an internal implementation helper used when
@@ -574,7 +627,7 @@
 
   /// DiagRanges - The list of ranges added to this diagnostic.  It currently
   /// only support 10 ranges, could easily be extended if needed.
-  SourceRange DiagRanges[10];
+  CharSourceRange DiagRanges[10];
 
   enum { MaxFixItHints = 3 };
 
@@ -673,7 +726,7 @@
     }
   }
 
-  void AddSourceRange(const SourceRange &R) const {
+  void AddSourceRange(const CharSourceRange &R) const {
     assert(NumRanges <
            sizeof(DiagObj->DiagRanges)/sizeof(DiagObj->DiagRanges[0]) &&
            "Too many arguments to diagnostic!");
@@ -744,11 +797,17 @@
   
 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
                                            const SourceRange &R) {
-  DB.AddSourceRange(R);
+  DB.AddSourceRange(CharSourceRange::getTokenRange(R));
   return DB;
 }
 
 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const CharSourceRange &R) {
+  DB.AddSourceRange(R);
+  return DB;
+}
+  
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
                                            const FixItHint &Hint) {
   DB.AddFixItHint(Hint);
   return DB;
@@ -841,7 +900,7 @@
     return DiagObj->NumDiagRanges;
   }
 
-  SourceRange getRange(unsigned Idx) const {
+  const CharSourceRange &getRange(unsigned Idx) const {
     assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
     return DiagObj->DiagRanges[Idx];
   }
@@ -878,7 +937,7 @@
   Diagnostic::Level Level;
   FullSourceLoc Loc;
   std::string Message;
-  std::vector<SourceRange> Ranges;
+  std::vector<CharSourceRange> Ranges;
   std::vector<FixItHint> FixIts;
 
 public:
@@ -893,8 +952,10 @@
   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;
+
+  void setLocation(FullSourceLoc Loc) { this->Loc = Loc; }
+
+  typedef std::vector<CharSourceRange>::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(); }
diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td
index 6aa3b43..fabf9eb 100644
--- a/include/clang/Basic/Diagnostic.td
+++ b/include/clang/Basic/Diagnostic.td
@@ -26,16 +26,26 @@
 def CLASS_EXTENSION : DiagClass;
 def CLASS_ERROR     : DiagClass;
 
+// Diagnostic Categories.  These can be applied to groups or individual
+// diagnostics to specify a category.
+class DiagCategory<string Name> {
+  string CategoryName = Name;
+}
+
 // Diagnostic Groups.
 class DiagGroup<string Name, list<DiagGroup> subgroups = []> {
   string GroupName = Name;
   list<DiagGroup> SubGroups = subgroups;
+  string CategoryName = "";
 }
 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.
+// This defines all of the named diagnostic categories.
+include "DiagnosticCategories.td"
+
+// This defines all of the named diagnostic groups.
 include "DiagnosticGroups.td"
 
 
@@ -48,6 +58,7 @@
   bit         SFINAE = 1;
   DiagMapping DefaultMapping = defaultmapping;
   DiagGroup   Group;
+  string      CategoryName = "";
 }
 
 class Error<string str>     : Diagnostic<str, CLASS_ERROR, MAP_ERROR>;
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index cc89c7c..d755d99 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -14,17 +14,20 @@
 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">;
+let CategoryName = "Inline Assembly Issue" in {
+  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">;
+  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<
diff --git a/include/clang/Basic/DiagnosticCategories.td b/include/clang/Basic/DiagnosticCategories.td
new file mode 100644
index 0000000..a02fbdf
--- /dev/null
+++ b/include/clang/Basic/DiagnosticCategories.td
@@ -0,0 +1,10 @@
+//==--- DiagnosticCategories.td - Diagnostic Category Definitions ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+class CatInlineAsm : DiagCategory<"Inline Assembly Issue">;
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index 88e7dc1..98ea9d4 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -41,7 +41,8 @@
   "must end with ':'">;
 
 // Parse && Sema
-def ext_no_declarators : ExtWarn<"declaration does not declare anything">;
+def ext_no_declarators : ExtWarn<"declaration does not declare anything">,
+  InGroup<MissingDeclarations>;
 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">;
@@ -66,6 +67,7 @@
   "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_unknown_cxxabi : Error<"unknown C++ ABI '%0'">;
 def err_target_invalid_feature : Error<"invalid target feature '%0'">;
 
 // Source manager
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 3b7272e5..34cd600 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -49,6 +49,8 @@
   "'%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_clang_unsupported_opt_cxx_darwin_i386 : Error<
+  "the clang compiler does not support '%0' for C++ on Darwin/i386">;
 def err_drv_command_failed : Error<
   "%0 command failed with exit code %1 (use -v to see invocation)">;
 def err_drv_command_signalled : Error<
@@ -66,6 +68,8 @@
     "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 err_drv_preamble_format : Error<
+    "incorrect format for -preamble-bytes=N,END">;
 
 def warn_drv_input_file_unused : Warning<
   "%0: '%1' input unused when '%2' is present">;
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 5289a84..7c74bf4 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -16,8 +16,12 @@
 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">;
+// Error generated by the backend.
+def err_fe_inline_asm : Error<"%0">, CatInlineAsm;
+def note_fe_inline_asm_here : Note<"instantated into assembly 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">,
@@ -72,12 +76,12 @@
 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">;
+    "cannot find start ('{{') of expected %0">;
 def err_verify_missing_end : Error<
-    "cannot find end ('}}') of expected string">;
+    "cannot find end ('}}') of expected %0">;
+def err_verify_invalid_content : Error<
+    "invalid expected %0: %1">;
 def err_verify_inconsistent_diags : Error<
     "'%0' diagnostics %select{expected|seen}1 but not %select{seen|expected}1: %2">;
 
@@ -95,7 +99,7 @@
 def err_fe_invoking : Error<"error invoking%0: %1">, DefaultFatal;
 
 // PCH reader
-def err_relocatable_without_without_isysroot : Error<
+def err_relocatable_without_isysroot : Error<
     "must specify system root with -isysroot when building a relocatable "
     "PCH file">;
 def warn_pch_target_triple : Error<
@@ -185,9 +189,6 @@
     "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">;
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 1b2abfe..f6fb79d 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -15,24 +15,29 @@
     ImplicitFunctionDeclare,
     ImplicitInt
 ]>;
-    
-
 
 // Empty DiagGroups are recognized by clang but ignored.
+def : DiagGroup<"abi">;
 def : DiagGroup<"address">;
 def AddressOfTemporary : DiagGroup<"address-of-temporary">;
 def : DiagGroup<"aggregate-return">;
+def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">;
 def : DiagGroup<"attributes">;
 def : DiagGroup<"bad-function-cast">;
-def : DiagGroup<"c++-compat">;
-def : DiagGroup<"cast-align">;
+def BoolConversions : DiagGroup<"bool-conversions">;
+def CXXCompat: DiagGroup<"c++-compat">;
+def CastAlign : 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 DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
+def Deprecated : DiagGroup<"deprecated", [ DeprecatedDeclarations] >,
+                 DiagCategory<"Deprecations">;
+
 def : DiagGroup<"disabled-optimization">;
 def : DiagGroup<"discard-qual">;
 def : DiagGroup<"div-by-zero">;
@@ -42,16 +47,23 @@
 def FormatExtraArgs : DiagGroup<"format-extra-args">;
 def FormatZeroLength : DiagGroup<"format-zero-length">;
 
+def CXXHexFloats : DiagGroup<"c++-hex-floats">;
+
+def : DiagGroup<"c++0x-compat", [CXXHexFloats]>;
+def : DiagGroup<"effc++">;
 def FourByteMultiChar : DiagGroup<"four-char-constants">;
+def GlobalConstructors : DiagGroup<"global-constructors">;
 def : DiagGroup<"idiomatic-parentheses">;
+def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">;
 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 : DiagGroup<"main">;
 def MissingBraces : DiagGroup<"missing-braces">;
-def : DiagGroup<"missing-declarations">;
+def MissingDeclarations: DiagGroup<"missing-declarations">;
 def : DiagGroup<"missing-format-attribute">;
 def : DiagGroup<"missing-include-dirs">;
 def : DiagGroup<"missing-noreturn">;
@@ -61,22 +73,32 @@
 def LongLong : DiagGroup<"long-long">;
 def MismatchedTags : DiagGroup<"mismatched-tags">;
 def MissingFieldInitializers : DiagGroup<"missing-field-initializers">;
+def InitializerOverrides : DiagGroup<"initializer-overrides">;
 def NonNull : DiagGroup<"nonnull">;
 def : DiagGroup<"nonportable-cfstrings">;
 def : DiagGroup<"non-virtual-dtor">;
+def : DiagGroup<"old-style-cast">;
 def : DiagGroup<"old-style-definition">;
+def OutOfLineDeclaration : DiagGroup<"out-of-line-declaration">;
 def : DiagGroup<"overflow">;
+def OverlengthStrings : DiagGroup<"overlength-strings">;
 def : DiagGroup<"overloaded-virtual">;
 def : DiagGroup<"packed">;
 def PointerArith : DiagGroup<"pointer-arith">;
+def PoundWarning : DiagGroup<"#warnings">,
+                   DiagCategory<"#warning Directive">;
 def : DiagGroup<"pointer-to-int-cast">;
 def : DiagGroup<"redundant-decls">;
 def ReturnType : DiagGroup<"return-type">;
+def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy">;
 def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
 def : DiagGroup<"sequence-point">;
 def Shadow : DiagGroup<"shadow">;
 def : DiagGroup<"shorten-64-to-32">;
+def : DiagGroup<"sign-promo">;
 def SignCompare : DiagGroup<"sign-compare">;
+def : DiagGroup<"stack-protector">;
+def : DiagGroup<"switch-default">;
 def : DiagGroup<"synth">;
 
 // Preprocessor warnings.
@@ -99,16 +121,19 @@
 
 def InvalidOffsetof : DiagGroup<"invalid-offsetof">;
 def : DiagGroup<"strict-prototypes">;
-def : DiagGroup<"strict-selector-match">;
+def StrictSelector : DiagGroup<"strict-selector-match">;
 def SwitchEnum     : DiagGroup<"switch-enum">;
 def Switch         : DiagGroup<"switch", [SwitchEnum]>;
-def Trigraphs : DiagGroup<"trigraphs">;
+def Trigraphs      : DiagGroup<"trigraphs">;
 
 def : DiagGroup<"type-limits">;
 def Uninitialized  : DiagGroup<"uninitialized">;
 def UnknownPragmas : DiagGroup<"unknown-pragmas">;
+def UnknownAttributes : DiagGroup<"unknown-attributes">;
 def UnusedArgument : DiagGroup<"unused-argument">;
+def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">;
 def UnusedFunction : DiagGroup<"unused-function">;
+def UnusedMemberFunction : DiagGroup<"unused-member-function">;
 def UnusedLabel : DiagGroup<"unused-label">;
 def UnusedParameter : DiagGroup<"unused-parameter">;
 def UnusedValue    : DiagGroup<"unused-value">;
@@ -116,11 +141,14 @@
 def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">;
 def Reorder : DiagGroup<"reorder">;
 def UndeclaredSelector : DiagGroup<"undeclared-selector">;
+def Selector : DiagGroup<"selector">;
+def NonfragileAbi2 : DiagGroup<"nonfragile-abi2">;
 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 VLA : DiagGroup<"vla">;
 def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
 def : DiagGroup<"write-strings">;
 def CharSubscript : DiagGroup<"char-subscripts">;
@@ -134,15 +162,19 @@
 // -Wconversion has its own warnings, but we split this one out for
 // legacy reasons.
 def Conversion : DiagGroup<"conversion",
-                           [DiagGroup<"shorten-64-to-32">]>;
+                           [DiagGroup<"shorten-64-to-32">, BoolConversions]>,
+                 DiagCategory<"Value Conversion Issue">;
 
 def Unused : DiagGroup<"unused",
                        [UnusedArgument, UnusedFunction, UnusedLabel,
                         // UnusedParameter, (matches GCC's behavior)
-                        UnusedValue, UnusedVariable]>;
+                        // UnusedMemberFunction, (clean-up llvm before enabling)
+                        UnusedValue, UnusedVariable]>,
+                        DiagCategory<"Unused Entity Issue">;
 
 // Format settings.
-def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull]>;
+def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull]>,
+             DiagCategory<"Format String Issue">;
 def FormatSecurity : DiagGroup<"format-security", [Format]>;
 def FormatNonLiteral : DiagGroup<"format-nonliteral", [FormatSecurity]>;
 def FormatY2K : DiagGroup<"format-y2k", [Format]>;
@@ -151,6 +183,8 @@
 
 def Extra : DiagGroup<"extra", [
     MissingFieldInitializers,
+    IgnoredQualifiers,
+    InitializerOverrides,
     SemiBeforeMethodBody,
     SignCompare,
     UnusedParameter
@@ -189,4 +223,4 @@
     [SignCompare, Conversion, LiteralRange]>;
 
 // A warning group for warnings about GCC extensions.
-def GNU : DiagGroup<"gnu", [GNUDesignator]>;
+def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>;
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 3f765bd..08ba1c4 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -11,7 +11,7 @@
 // Lexer Diagnostics
 //===----------------------------------------------------------------------===//
 
-let Component = "Lex" in {
+let Component = "Lex", CategoryName = "Lexical or Preprocessor Issue" 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">;
@@ -84,9 +84,9 @@
 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<
+def ext_hexconstant_cplusplus : Extension<
   "hexadecimal floating constants are a C99 feature that is incompatible with "
-  "C++0x">;
+  "C++0x">, InGroup<CXXHexFloats>;
 def ext_hexconstant_invalid : Extension<
   "hexadecimal floating constants are a C99 feature">;
 def ext_binary_literal : Extension<
@@ -94,7 +94,10 @@
 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">;
-
+def ext_string_too_long : Extension<"string literal of length %0 exceeds "
+  "maximum length %1 that %select{C90|ISO C99|C++}2 compilers are required to "
+  "support">, InGroup<OverlengthStrings>;
+  
 //===----------------------------------------------------------------------===//
 // PTH Diagnostics
 //===----------------------------------------------------------------------===//
@@ -106,7 +109,7 @@
 //===----------------------------------------------------------------------===//
 // Preprocessor Diagnostics
 //===----------------------------------------------------------------------===//
-def pp_hash_warning : Warning<"#warning%0">, InGroup<DiagGroup<"#warnings">>;
+def pp_hash_warning : Warning<"#warning%0">, InGroup<PoundWarning>;
 def pp_include_next_in_primary : Warning<
   "#include_next in primary source file">;
 def pp_include_macros_out_of_predefines : Error<
@@ -225,6 +228,13 @@
   "_Pragma takes a parenthesized string literal">;
 def err_pragma_comment_malformed : Error<
   "pragma comment requires parenthesized identifier and optional string">;
+def err_pragma_message_malformed : Error<
+  "pragma message requires parenthesized string">;
+def err_pragma_push_pop_macro_malformed : Error<
+   "pragma %0 requires a parenthesized string">;
+def warn_pragma_pop_macro_no_push : Warning<
+   "pragma pop_macro could not pop '%0', no matching push_macro">;
+def warn_pragma_message : Warning<"%0">;
 def warn_pragma_ignored : Warning<"unknown pragma ignored">,
    InGroup<UnknownPragmas>, DefaultIgnore;
 def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">,
@@ -258,6 +268,9 @@
 def warn_pragma_diagnostic_unknown_warning :
    ExtWarn<"unknown warning group '%0', ignored">,
    InGroup<UnknownPragmas>;
+// - #pragma __debug
+def warn_pragma_debug_unexpected_command : Warning<
+  "unexpected debug command '%0'">;
 
 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">;
@@ -274,6 +287,9 @@
   "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_bad_paste_ms : Warning<
+  "pasting formed '%0', an invalid preprocessing token">, DefaultError,
+  InGroup<DiagGroup<"invalid-token-paste">>;
 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<
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 2795851..d9d5014 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -13,15 +13,20 @@
 
 let Component = "Parse" in {
 
-def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">;
+def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">,
+                              CatInlineAsm;
 def warn_file_asm_volatile : Warning<
-  "meaningless 'volatile' on asm outside function">;
+  "meaningless 'volatile' on asm outside function">, CatInlineAsm;
+
+let CategoryName = "Parse Issue" in {
 
 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">;
+  "extra ';' inside a %0">;
+def ext_extra_ivar_semi : Extension<
+  "extra ';' inside instance variable list">;
 
 def ext_duplicate_declspec : Extension<"duplicate '%0' declaration specifier">;
 def ext_plain_complex : ExtWarn<
@@ -30,8 +35,10 @@
   "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 ext_empty_struct_union : Extension<"empty %select{struct|union}0 "
+  "(accepted as an extension) has size 0 in C, size 1 in C++">, 
+  InGroup<CXXCompat>;
+def error_empty_enum : Error<"use of empty enum">;
 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">;
@@ -96,11 +103,13 @@
   "expected member name or ';' after declaration specifiers">;
 def err_function_declared_typedef : Error<
   "function definition declared 'typedef'">;
+def err_iboutletcollection_builtintype : Error<
+  "type argument of iboutletcollection attribute cannot be a builtin type">;
 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">;
+  "expected ';' 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">;
@@ -119,6 +128,9 @@
   "expected ';' after namespace name">;
 def err_unexpected_namespace_attributes_alias : Error<
   "attributes can not be specified on namespace alias">;
+def err_inline_namespace_alias : Error<"namespace alias cannot be inline">;
+def err_namespace_nonnamespace_scope : Error<
+  "namespaces can only be defined in global or namespace scope">;
 def err_expected_semi_after_attribute_list : Error<
   "expected ';' after attribute list">;
 def err_expected_semi_after_static_assert : Error<
@@ -129,7 +141,7 @@
   "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">;
+  "expected string literal or '[' for asm operand">, CatInlineAsm;
 def err_expected_selector_for_method : Error<
   "expected selector for Objective-C method">;
 def err_expected_property_name : Error<"expected property name">;
@@ -163,11 +175,15 @@
 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">;
+  "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'">;
+  "'__pixel' must be preceded by '__vector'.  "
+  "'%0' declaration specifier not allowed here">;
+def err_invalid_vector_decl_spec : Error<
+  "cannot use '%0' with '__vector'">;
+def err_invalid_vector_bool_decl_spec : Error<
+  "cannot use '%0' with '__vector bool'">;
 def warn_vector_long_decl_spec_combination : Warning<
   "Use of 'long' with '__vector' is deprecated">, InGroup<Deprecated>;
 def err_friend_invalid_in_context : Error<
@@ -258,6 +274,8 @@
   "expected a class name after '~' to name a destructor">;
 def err_destructor_template_id : Error<
   "destructor name %0 does not refer to a template">;
+def err_default_arg_unparsed : Error<
+  "unexpected end of default argument expression">;
 
 // C++ derived classes
 def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
@@ -311,6 +329,9 @@
     "'template' keyword">;
 def err_enum_template : Error<"enumeration cannot be a template">;
 
+def err_missing_dependent_template_keyword : Error<
+  "use 'template' keyword to treat '%0' as a dependent template name">;
+
 // Constructor template diagnostics.
 def err_out_of_line_constructor_template_id : Error<
   "out-of-line constructor for %0 cannot have template arguments">;
@@ -355,6 +376,13 @@
   "expected identifier in '#pragma %0' - ignored">;  
 def warn_pragma_extra_tokens_at_eol : Warning<
   "extra tokens at end of '#pragma %0' - ignored">; 
+// - #pragma options
+def warn_pragma_options_expected_align : Warning<
+  "expected 'align' following '#pragma options' - ignored">;
+def warn_pragma_align_expected_equal : Warning<
+  "expected '=' following '#pragma %select{align|options align}0' - ignored">;
+def warn_pragma_align_invalid_option : Warning<
+  "invalid alignment option in '#pragma %select{align|options align}0' - ignored">;
 // - #pragma pack
 def warn_pragma_pack_invalid_action : Warning<
   "unknown action for '#pragma pack' - ignored">;
@@ -368,4 +396,5 @@
 def warn_pragma_unused_expected_punc : Warning<
   "expected ')' or ',' in '#pragma unused'">;
 
+} // end of Parse Issue category.
 } // end of Parser diagnostics
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 94f1df1..32550dc 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 let Component = "Sema" in {
+let CategoryName = "Semantic Issue" in {
 
 // Constant expressions
 def err_expr_not_ice : Error<
@@ -20,12 +21,6 @@
   "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">;
@@ -36,6 +31,28 @@
   "magnitude of floating-point constant too small for type %0; minimum is %1">,
   InGroup<LiteralRange>;
 
+// C99 variable-length arrays
+def ext_vla : Extension<
+  "variable length arrays are a C99 feature, accepted as an extension">,
+  InGroup<VLA>;
+def err_vla_non_pod : Error<"variable length array of non-POD element type %0">;
+def err_vla_in_sfinae : Error<
+  "variable length array cannot be formed during template argument deduction">;
+def err_array_star_in_function_definition : Error<
+  "variable length array must be bound in function definition">;
+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">;
+  
+// C99 variably modified types
+def err_variably_modified_template_arg : Error<
+  "variably modified type %0 cannot be used as a template argument">;
+def err_variably_modified_nontype_template_param : Error<
+  "non-type template parameter of variably modified type %0">;
+
 // C99 Designated Initializers
 def err_array_designator_negative : Error<
   "array designator value '%0' is negative">;
@@ -57,9 +74,10 @@
   "designator in initializer for scalar type %0">;
 def warn_subobject_initializer_overrides : Warning<
   "subobject initialization overrides initialization of other fields "
-  "within its enclosing subobject">;
+  "within its enclosing subobject">, InGroup<InitializerOverrides>;
 def warn_initializer_overrides : Warning<
-  "initializer overrides prior initialization of this subobject">;
+  "initializer overrides prior initialization of this subobject">,
+  InGroup<InitializerOverrides>;
 def note_previous_initializer : Note<
   "previous initialization %select{|with side effects }0is here"
   "%select{| (side effects may not occur at run time)}0">;
@@ -71,11 +89,6 @@
   "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<
@@ -85,12 +98,14 @@
   InGroup<UnusedParameter>, DefaultIgnore;
 def warn_unused_variable : Warning<"unused variable %0">,
   InGroup<UnusedVariable>, DefaultIgnore;
+def warn_unused_exception_param : Warning<"unused exception parameter %0">,
+  InGroup<UnusedExceptionParameter>, 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_unused_member_function : Warning<"unused member function %0">,
+  InGroup<UnusedMemberFunction>, DefaultIgnore;
   
 def warn_implicit_function_decl : Warning<
   "implicit declaration of function %0">,
@@ -107,6 +122,9 @@
   "use of out-of-scope declaration of %0">;
 def err_inline_non_function : Error<
   "'inline' can only appear on functions">;
+def warn_qual_return_type : Warning< 
+  "'%0' type qualifier%s1 on return type %plural{1:has|:have}1 no effect">,
+  InGroup<IgnoredQualifiers>, DefaultIgnore;
 
 def warn_decl_shadow :
   Warning<"declaration shadows a %select{"
@@ -152,6 +170,13 @@
   "access declarations are deprecated; use using declarations instead">,
   InGroup<Deprecated>;
 
+def warn_global_constructor : Warning<
+  "declaration requires a global constructor">,
+  InGroup<GlobalConstructors>, DefaultIgnore;
+def warn_global_destructor : Warning<
+  "declaration requires a global destructor">,
+   InGroup<GlobalConstructors>, DefaultIgnore;
+
 def err_invalid_thread : Error<
   "'__thread' is only allowed on variable declarations">;
 def err_thread_non_global : Error<
@@ -211,13 +236,21 @@
     "platform-specific data}0) must be of type %1">;
 
 /// parser diagnostics
-def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">;
+def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">,
+  InGroup<MissingDeclarations>;
+def err_typedef_not_identifier : Error<"typedef name must be an identifier">;
 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_options_align_unsupported_option : Warning<
+  "unsupported alignment option in '#pragma options align'">;
+def warn_pragma_options_align_reset_failed : Warning<
+  "#pragma options align=reset failed: %0">;
+def err_pragma_options_align_mac68k_target_unsupported : Error<
+  "mac68k alignment pragma is not supported on this target">;
 def warn_pragma_pack_invalid_alignment : Warning<
   "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">;
 // Follow the MSVC implementation.
@@ -291,12 +324,16 @@
 
 def warn_conflicting_param_types : Warning<
   "conflicting parameter types in implementation of %0: %1 vs %2">;
+def warn_conflicting_variadic :Warning<
+  "conflicting variadic declaration of method and its implementation">;
 
 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_strict_multiple_method_decl : Warning<
+  "multiple methods named %0 found">, InGroup<StrictSelector>, DefaultIgnore;
 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">;
@@ -374,6 +411,8 @@
   InGroup<ReadOnlySetterAttrs>, DefaultIgnore;
 def warn_undeclared_selector : Warning<
   "undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore;
+def warn_unimplemented_selector:  Warning<
+  "unimplemented selector %0">, InGroup<Selector>, DefaultIgnore;
 def warn_unimplemented_protocol_method : Warning<
   "method in protocol not implemented">, InGroup<Protocol>;
 
@@ -406,6 +445,7 @@
   "allocation of an object of abstract type %0">;
 def err_throw_abstract_type : Error<
   "cannot throw an object of abstract type %0">;
+def err_array_of_abstract_type : Error<"array of abstract class type %0">;
 
 def err_multiple_final_overriders : Error<
   "virtual function %q0 has more than one final overrider in %1">; 
@@ -431,6 +471,9 @@
   "emitted in every translation unit">,
   InGroup<DiagGroup<"weak-vtables">>, DefaultIgnore;
 
+def ext_using_undefined_std : ExtWarn<
+  "using directive refers to implicitly-defined namespace 'std'">;
+  
 // C++ exception specifications
 def err_exception_spec_in_typedef : Error<
   "exception specifications are not allowed in typedefs">;
@@ -459,6 +502,10 @@
   "%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 ext_rvalue_to_reference_access_ctor : ExtWarn<
+  "C++98 requires an accessible copy constructor for class %2 when binding "
+  "a reference to a temporary; was %select{private|protected}0">,
+  NoSFINAE, InGroup<BindToTemporaryCopy>;
 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|"
@@ -480,6 +527,9 @@
 def err_access_dtor_temp :
     Error<"temporary of type %0 has %select{private|protected}1 destructor">,
     NoSFINAE;
+def err_access_dtor_exception :
+    Error<"exception object 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;
@@ -500,6 +550,10 @@
 def err_access_copy_base :
     Error<"base class %0 has %select{private|protected}1 copy constructor">,
     NoSFINAE;
+def err_access_dtor_ivar :
+    Error<"instance variable of type %0 has %select{private|protected}1 "
+          "destructor">,
+    NoSFINAE;
 def note_previous_access_declaration : Note<
   "previously declared '%1' here">;
 def err_access_outside_class : Error<
@@ -518,6 +572,9 @@
   "parameter">;
 def err_nested_name_member_ref_lookup_ambiguous : Error<
   "lookup of %0 in member access expression is ambiguous">;
+def ext_nested_name_member_ref_lookup_ambiguous : ExtWarn<
+  "lookup of %0 in member access expression is ambiguous; using member of %1">,
+  InGroup<AmbigMemberTemplate>;
 def note_ambig_member_ref_object_type : Note<
   "lookup in the object type %0 refers here">;
 def note_ambig_member_ref_scope : Note<
@@ -578,9 +635,9 @@
   "%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 err_illegal_union_or_anon_struct_member : Error<
+  "%select{anonymous struct|union}0 member %1 has a non-trivial "
+  "%select{constructor|copy constructor|copy assignment operator|destructor}2">;
 def note_nontrivial_has_virtual : Note<
   "because type %0 has a virtual %select{member function|base class}1">;
 def note_nontrivial_has_nontrivial : Note<
@@ -706,12 +763,20 @@
   "uninitialized reference member is here">;
 def warn_field_is_uninit : Warning<"field is uninitialized when used here">,
   InGroup<DiagGroup<"uninitialized">>;
+def err_init_incomplete_type : Error<"initialization of incomplete type %0">;
 
 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 ext_rvalue_to_reference_temp_copy_no_viable : ExtWarn<
+  "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; C++98 requires a copy "
+  "constructor when binding a reference to a temporary">,
+  InGroup<BindToTemporaryCopy>;
 def err_temp_copy_ambiguous : Error<
   "ambiguous constructor call when %select{copying variable|copying "
   "parameter|returning object|throwing object|copying member subobject|copying "
@@ -763,11 +828,22 @@
   "%0 and %1 attributes are not compatible">;
 def err_attribute_wrong_number_arguments : Error<
   "attribute requires %0 argument(s)">;
+def err_iboutletcollection_type : Error<
+  "invalid type %0 as argument of iboutletcollection attribute">;
+def err_iboutletcollection_object_type : Error<
+  "%select{ivar|property}1 with iboutletcollection attribute must "
+  "have object type (invalid %0)">;
 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_invalid_vector_type : Error<"invalid vector element type %0">;
 def err_attribute_argument_not_int : Error<
   "'%0' attribute requires integer constant">;
+def err_attribute_argument_outof_range : Error<
+  "init_priority attribute requires integer constant between "
+  "101 and 65535 inclusive">;
+def err_init_priority_object_attr : Error<
+  "can only use ‘init_priority’ attribute on file-scope definitions "
+  "of objects of class type">;
 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<
@@ -776,8 +852,10 @@
   "'%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<
+def warn_nonnull_pointers_only : Warning<
   "nonnull attribute only applies to pointer arguments">;
+def err_ownership_type : Error<
+  "%0 attribute only applies to %1 arguments">;
 def err_format_strftime_third_parameter : Error<
   "strftime format attribute requires 3rd parameter to be 0">;
 def err_format_attribute_requires_variadic : Error<
@@ -806,7 +884,8 @@
 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">;
+  "illegal implicit conversion 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<
@@ -822,6 +901,8 @@
 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_unknown_attribute_ignored : Warning<
+  "unknown attribute %0 ignored">, InGroup<UnknownAttributes>;
 def warn_attribute_precede_definition : Warning<
   "attribute declaration must precede definition">;
 def warn_attribute_void_function_method : Warning<
@@ -867,26 +948,40 @@
   "function with no prototype cannot use %0 calling convention">;
 def err_cconv_varargs : Error<
   "variadic function cannot use %0 calling convention">;
+def err_regparm_mismatch : Error<"function declared with with regparm(%0) "
+  "attribute was previously declared %plural{0:without the regparm|1:"
+  "with the regparm(1)|2:with the regparm(2)|3:with the regparm(3)|:with the"
+  "regparm}1 attribute">;
 
 def warn_impcast_vector_scalar : Warning<
-  "implicit cast turns vector to scalar: %0 to %1">,
+  "implicit conversion 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">,
+  "implicit conversion 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">,
+  "implicit conversion 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">,
+  "implicit conversion turns floating-point number into integer: %0 to %1">,
+  InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_integer_sign : Warning<
+  "implicit conversion changes signedness: %0 to %1">,
+  InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_integer_sign_conditional : Warning<
+  "operand of ? changes signedness: %0 to %1">,
   InGroup<DiagGroup<"conversion">>, DefaultIgnore;
 def warn_impcast_integer_precision : Warning<
-  "implicit cast loses integer precision: %0 to %1">,
+  "implicit conversion 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">,
+  "implicit conversion loses integer precision: %0 to %1">,
   InGroup<DiagGroup<"shorten-64-to-32">>, DefaultIgnore;
 
+def warn_cast_align : Warning<
+  "cast from %0 to %1 increases required alignment from %2 to %3">,
+  InGroup<CastAlign>, 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<
@@ -899,14 +994,14 @@
   "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">;
+  "first field of a transparent union cannot have %select{floating point|"
+  "vector}0 type %1; 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 warn_attribute_unknown_visibility : Warning<"unknown visibility '%0'">;
 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<
@@ -948,8 +1043,7 @@
 
 // Clang-Specific Attributes
 def err_attribute_iboutlet : Error<
-  "iboutlet attribute can only be applied to instance variables or "
-  "properties">;
+  "%0 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<
@@ -1040,6 +1134,9 @@
   "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_too_many_candidates : Note<
+    "remaining %0 candidate%s0 omitted; "
+    "pass -fshow-overloads=all to show them">;
 def note_ovl_candidate : Note<"candidate "
     "%select{function|function|constructor|"
     "function |function |constructor |"
@@ -1047,19 +1144,40 @@
     "is the implicit copy constructor|"
     "is the implicit copy assignment operator}0%1">;
 
+def warn_init_pointer_from_false : Warning<
+    "initialization of pointer of type %0 from literal 'false'">,
+    InGroup<BoolConversions>;
+
 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">;
-
+def note_ovl_candidate_inconsistent_deduction : Note<
+    "candidate template ignored: deduced conflicting %select{types|values|"
+    "templates}0 for parameter %1 (%2 vs. %3)">;
+def note_ovl_candidate_explicit_arg_mismatch_named : Note<
+    "candidate template ignored: invalid explicitly-specified argument "
+    "for template parameter %0">;
+def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note<
+    "candidate template ignored: invalid explicitly-specified argument "
+    "for %ordinal0 template parameter">;
+def note_ovl_candidate_instantiation_depth : Note<
+    "candidate template ignored: substitution exceeded maximum template "
+    "instantiation depth">;
+def note_ovl_candidate_underqualified : Note<
+    "candidate template ignored: can't deduce a type for %0 which would "
+    "make %2 equal %1">;
+def note_ovl_candidate_substitution_failure : Note<
+    "candidate template ignored: substitution failure %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">;
+    "function (the implicit copy assignment operator)}0 %select{|template }1"
+    "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|"
@@ -1105,7 +1223,7 @@
     "%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|"
+    "%select{const|restrict|const or restrict|volatile|const or volatile|"
     "volatile or restrict|const, volatile, or restrict}3">;
 def note_ovl_candidate_bad_cvr : Note<"candidate "
     "%select{function|function|constructor|"
@@ -1114,9 +1232,20 @@
     "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|"
+    "%select{const|restrict|const and restrict|volatile|const and volatile|"
     "volatile and restrict|const, volatile, and restrict}3 qualifier"
     "%select{||s||s|s|s}3">;
+def note_ovl_candidate_bad_base_to_derived_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: cannot %select{convert from|convert from|bind}2 "
+    "%select{base class pointer|superclass|base class object of type}2 %3 to "
+    "%select{derived class pointer|subclass|derived class reference}2 %4 for "
+    "%ordinal5 argument">;
+
 def note_ambiguous_type_conversion: Note<
     "because of ambiguity in conversion of %0 to %1">;
 def note_ovl_builtin_binary_candidate : Note<
@@ -1157,6 +1286,8 @@
   "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">;
+def err_addr_ovl_no_qualifier : Error<
+  "can't form member pointer of type %0 without '&' and class name">;
   
 // C++ Template Declarations
 def err_template_param_shadow : Error<
@@ -1183,6 +1314,7 @@
   "%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">;
@@ -1454,7 +1586,7 @@
   "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)">;
+  "see all)">;
 
 def err_field_instantiates_to_function : Error<
   "data member instantiated with function type %0">;
@@ -1477,10 +1609,18 @@
     "explicit instantiation of non-templated type %0">;
 def note_nontemplate_decl_here : Note<
     "non-templated declaration is here">;
+def err_explicit_instantiation_in_class : Error<
+  "explicit instantiation of %0 in class scope">;
 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 warn_explicit_instantiation_out_of_scope_0x : Warning<
+  "explicit instantiation of %0 not in a namespace enclosing %1">, 
+  InGroup<DiagGroup<"-Wc++0x-compat"> >;
+def warn_explicit_instantiation_must_be_global_0x : Warning<
+  "explicit instantiation of %0 must occur at global scope">, 
+  InGroup<DiagGroup<"-Wc++0x-compat"> >;
   
 def err_explicit_instantiation_requires_name : Error<
   "explicit instantiation declaration requires a name">;
@@ -1503,12 +1643,14 @@
   "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 ext_explicit_instantiation_without_qualified_id : ExtWarn<
+  "qualifier in explicit instantiation of %q0 requires a template-id "
+  "(a typedef is not permitted)">;
 def err_explicit_instantiation_unqualified_wrong_namespace : Error<
   "explicit instantiation of %q0 must occur in %1">;
+def warn_explicit_instantiation_unqualified_wrong_namespace_0x : Warning<
+  "explicit instantiation of %q0 must occur in %1">, 
+  InGroup<DiagGroup<"c++0x-compat"> >;
 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">;
@@ -1528,6 +1670,8 @@
     "referenced member %0 is declared here">;
 def err_typename_missing : Error<
   "missing 'typename' prior to dependent type name '%0%1'">;
+def ext_typename_outside_of_template : ExtWarn<
+  "'typename' occurs outside of a template">;
 
 def err_template_kw_refers_to_non_template : Error<
     "%0 following the 'template' keyword does not refer to a template">;
@@ -1539,6 +1683,8 @@
     "class template declared here">;
 def err_template_kw_missing : Error<
   "missing 'template' keyword prior to dependent template name '%0%1'">;
+def ext_template_outside_of_template : ExtWarn<
+  "'template' keyword outside of a template">;
 
 // C++0x Variadic Templates
 def err_template_param_pack_default_arg : Error<
@@ -1546,6 +1692,18 @@
 def err_template_param_pack_must_be_last_template_parameter : Error<
   "template parameter pack must be the last template parameter">;
 
+def err_template_parameter_pack_non_pack : Error<
+  "template %select{type|non-type|template}0 parameter%select{| pack}1 "
+  "conflicts with previous template %select{type|non-type|template}0 "
+  "parameter%select{ pack|}1">;
+def note_template_parameter_pack_non_pack : Note<
+  "template %select{type|non-type|template}0 parameter%select{| pack}1 "
+  "does not match template %select{type|non-type|template}0 "
+  "parameter%select{ pack|}1 in template argument">;
+def note_template_parameter_pack_here : Note<
+  "previous template %select{type|non-type|template}0 "
+  "parameter%select{| pack}1 declared here">;
+  
 def err_unexpected_typedef : Error<
   "unexpected type name %0: expected expression">;
 def err_unexpected_namespace : Error<
@@ -1555,9 +1713,8 @@
     "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">>;
+    InGroup<DeprecatedDeclarations>;
+def err_unavailable : Error<"%0 is unavailable">;
 def note_unavailable_here : Note<
   "function has been explicitly marked %select{unavailable|deleted}0 here">;
 def warn_not_enough_argument : Warning<
@@ -1578,6 +1735,8 @@
   "redefinition of typedef %0 is invalid in C">,
   InGroup<DiagGroup<"typedef-redefinition"> >, DefaultError;
 
+def err_inline_declaration_block_scope : Error<
+  "inline declaration of %0 not allowed in block scope">;
 def err_static_non_static : Error<
   "static declaration of %0 follows non-static declaration">;
 def err_non_static_static : Error<
@@ -1614,6 +1773,9 @@
   "ISO C forbids forward references to 'enum' types">;
 def err_forward_ref_enum : Error<
   "ISO C++ forbids forward references to 'enum' types">;
+def ext_forward_ref_enum_def : Extension<
+  "redeclaration of already-defined enum %0 is a GNU extension">, InGroup<GNU>;
+  
 def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">;
 def err_duplicate_member : Error<"duplicate member %0">;
 def err_misplaced_ivar : Error<
@@ -1628,12 +1790,6 @@
   
 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<
@@ -1643,6 +1799,8 @@
   "extension will never be supported">;
 def err_vm_func_decl : Error<
   "function declaration cannot have variably modified type">;
+def err_array_too_large : Error<
+  "array is too large (%0 elements)">;
 
 def err_typecheck_negative_array_size : Error<"array size is negative">;
 def warn_typecheck_function_qualifiers : Warning<
@@ -1684,12 +1842,14 @@
   InGroup<MissingFieldInitializers>, DefaultIgnore;
 def warn_braces_around_scalar_init : Warning<
   "braces around scalar initializer">;
-def err_many_braces_around_scalar_init : Error<
+def warn_many_braces_around_scalar_init : ExtWarn<
   "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_init_objc_class : Error<
+  "cannot initialize Objective-C class type %0">;
 def err_implicit_empty_initializer : Error<
   "initializer for aggregate with no elements requires explicit braces">;
 def err_bitfield_has_negative_width : Error<
@@ -1717,23 +1877,23 @@
 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_goto_into_protected_scope : Error<"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">>;
+  "switch case is in protected scope">;
+def err_indirect_goto_without_addrlabel : Error<
+  "indirect goto in function with no address-of-label expressions">;
+def warn_indirect_goto_in_protected_scope : Warning<
+  "indirect goto might cross protected scopes">,
+  InGroup<DiagGroup<"label-address-scope">>;
+def note_indirect_goto_target : Note<"possible target of indirect goto">;
 def note_protected_by_variable_init : Note<
   "jump bypasses variable initialization">;
+def note_protected_by_cleanup : Note<
+  "jump bypasses initialization of variable with __attribute__((cleanup))">;
 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<
@@ -1749,6 +1909,25 @@
 def note_protected_by___block : Note<
   "jump bypasses setup of __block variable">;
 
+def note_exits_cleanup : Note<
+  "jump exits scope of variable with __attribute__((cleanup))">;
+def note_exits_dtor : Note<
+  "jump exits scope of variable with non-trivial destructor">;
+def note_exits___block : Note<
+  "jump exits scope of __block variable">;
+def note_exits_objc_try : Note<
+  "jump exits @try block">;
+def note_exits_objc_catch : Note<
+  "jump exits @catch block">;
+def note_exits_objc_finally : Note<
+  "jump exits @finally block">;
+def note_exits_objc_synchronized : Note<
+  "jump exits @synchronized block">;
+def note_exits_cxx_try : Note<
+  "jump exits try block">;
+def note_exits_cxx_catch : Note<
+  "jump exits catch block">;
+
 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">;
@@ -1759,6 +1938,8 @@
 
 def err_flexible_array_empty_struct : Error<
   "flexible array %0 not allowed in otherwise empty struct">;
+def err_flexible_array_has_nonpod_type : Error<
+  "flexible array member %0 of non-POD element type %1">;
 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<
@@ -1771,6 +1952,8 @@
   "'%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_message_expr_incomplete_type : Error<
+  "objective-c message has incomplete result 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<
@@ -1801,6 +1984,9 @@
 // Expressions.
 def ext_sizeof_function_type : Extension<
   "invalid application of 'sizeof' to a function type">, InGroup<PointerArith>;
+def err_sizeof_alignof_overloaded_function_type : Error<
+  "invalid application of '%select{sizeof|__alignof}0' to an overloaded "
+  "function">;
 def ext_sizeof_void_type : Extension<
   "invalid application of '%0' to a void type">, InGroup<PointerArith>;
 def err_sizeof_alignof_incomplete_type : Error<
@@ -1816,6 +2002,7 @@
   "using extended field designator is an extension">;
 def warn_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
   InGroup<InvalidOffsetof>;
+def err_offsetof_bitfield : Error<"cannot compute offset of bit-field %0">;
 
 def warn_floatingpoint_eq : Warning<
   "comparing floating point with == or != is unsafe">,
@@ -1833,6 +2020,10 @@
   "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 warn_logical_instead_of_bitwise : Warning<
+  "use of logical %0 with constant operand; switch to bitwise %1 or "
+  "remove constant">, InGroup<DiagGroup<"constant-logical-operand">>;
   
 def err_sizeof_nonfragile_interface : Error<
   "invalid application of '%select{alignof|sizeof}1' to interface %0 in "
@@ -1890,8 +2081,9 @@
   "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 ext_out_of_line_declaration : ExtWarn<
+  "out-of-line declaration of a member must be a definition">,
+  InGroup<OutOfLineDeclaration>, DefaultError;
 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">;
@@ -1935,7 +2127,11 @@
 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">;
+  "must explicitly qualify name of member function when taking its address">;
+def err_invalid_form_pointer_member_function : Error<
+  "cannot create a non-constant pointer to member function">;
+def err_parens_pointer_member_function : Error<
+  "cannot parenthesize the name of a method when forming a member pointer">;
 def err_typecheck_invalid_lvalue_addrof : Error<
   "address expression must be an lvalue or a function designator">;
 def ext_typecheck_addrof_class_temporary : ExtWarn<
@@ -1947,8 +2143,13 @@
   "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 warn_indirection_through_null : Warning<
+  "indirection of non-volatile null pointer will be deleted, not trap">;
+def note_indirection_through_null : Note<
+  "consider using __builtin_trap() or qualifying pointer with 'volatile'">;
+
+def err_assignment_requires_nonfragile_object : Error<
+  "cannot assign to class object 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<
@@ -1965,8 +2166,12 @@
   "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 err_typecheck_comparison_of_fptr_to_void : Error<
+  "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 err_typecheck_comparison_of_pointer_integer : Error<
+  "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<
@@ -2000,9 +2205,11 @@
   "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_function_pointer : Error<
+  "type qualifier is not allowed on this function %select{pointer|reference}0">;
 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">;
+  "a qualified function type cannot be used to declare a "
+  "%select{static member|nonmember}0 function">;
 
 def err_invalid_non_static_member_use : Error<
   "invalid use of nonstatic data member %0">;
@@ -2014,10 +2221,10 @@
   "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<
+def warn_format_nonliteral_noargs : Warning<
   "format string is not a string literal (potentially insecure)">,
   InGroup<FormatSecurity>;
-def warn_printf_nonliteral : Warning<
+def warn_format_nonliteral : Warning<
   "format string is not a string literal">,
   InGroup<FormatNonLiteral>, DefaultIgnore;
 
@@ -2046,7 +2253,7 @@
 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">;
+  "expression is not assignable">;
 
 def ext_freestanding_complex : Extension<
   "complex numbers are an extension in a freestanding C99 implementation">;
@@ -2094,7 +2301,13 @@
   "'register' storage specifier on @catch parameter will be ignored">;
 def err_qualified_objc_catch_parm : Error<
   "@catch parameter declarator cannot be qualified">;
-
+def err_objc_pointer_cxx_catch_gnu : Error<
+  "can't catch Objective C exceptions in C++ in the GNU runtime">;
+def err_objc_pointer_cxx_catch_fragile : Error<
+  "can't catch Objective C exceptions in C++ in the non-unified "
+  "exception model">;
+def err_objc_object_catch : Error<
+  "can't catch an Objective C object by value">;
 
 def warn_setter_getter_impl_required : Warning<
   "property %0 requires method %1 to be defined - "
@@ -2144,6 +2357,9 @@
   "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_cxx_cast_member_pointer_size : Error<
+  "cannot %select{||reinterpret_cast||C-style cast|}0 from member pointer "
+  "type %1 to member pointer type %2 of different size">;
 def err_bad_static_cast_incomplete : Error<"%0 is an incomplete type">;
 
 // These messages don't adhere to the pattern.
@@ -2177,23 +2393,44 @@
   "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<
+def err_new_array_init_args : Error<
+  "array 'new' cannot have initialization arguments">;
+def ext_new_paren_array_nonconst : ExtWarn<
   "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_array_size_incomplete_type : Error<
+  "array size expression has incomplete class type %0">;
+def err_array_size_explicit_conversion : Error<
+  "array size expression of type %0 requires explicit conversion to type %1">;
+def note_array_size_conversion : Note<
+  "conversion to %select{integral|enumeration}0 type %1 declared here">;
+def err_array_size_ambiguous_conversion : Error<
+  "ambiguous conversion of array size expression of type %0 to an integral or "
+  "enumeration type">;
+def ext_array_size_conversion : Extension<
+  "implicit conversion from array size expression of type %0 to "
+  "%select{integral|enumeration}1 type %2 is a C++0x extension">;
+  
 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 ext_delete_void_ptr_operand : ExtWarn<
+  "cannot delete expression with pointer-to-'void' 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_delete_incomplete_class_type : Warning<
+  "deleting incomplete class type %0; no conversions to pointer type">;
 def err_no_suitable_delete_member_function_found : Error<
   "no suitable member %0 in %1">;
+def err_ambiguous_suitable_delete_member_function_found : Error<
+  "multiple suitable %0 functions in %1">;
 def note_member_declared_here : Note<
   "member %0 declared here">;
 def err_decrement_bool : Error<"cannot decrement expression of type bool">;
@@ -2285,7 +2522,9 @@
   "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 err_incomplete_pointer_to_member_return : Error<
+  "incomplete return type %0 of pointer-to-member constant">;
+
 def warn_condition_is_assignment : Warning<"using the result of an "
   "assignment as a condition without parentheses">,
   InGroup<Parentheses>;
@@ -2298,8 +2537,11 @@
 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">;
+def warn_ivar_variable_conflict : Warning<
+  "when default property synthesis is on, "
+  "%0 lookup will access property ivar instead of global variable">, 
+  InGroup<NonfragileAbi2>;
+def note_global_declared_at : Note<"global variable declared here">;
 
 // assignment related diagnostics (also for argument passing, returning, etc).
 // In most of these diagnostics the %2 is a value from the
@@ -2460,6 +2702,8 @@
   "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 err_typecheck_cast_to_incomplete : Error<
+  "cast to incomplete type %0">;
 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">;
@@ -2502,31 +2746,35 @@
 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 '('">;
-  
+
+} // End of general sema category.
+
 // 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">;
+let CategoryName = "Inline Assembly Issue" in {
+  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 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">;
+}
 
-
+let CategoryName = "Semantic Issue" in {
 
 def err_invalid_conversion_between_vectors : Error<
   "invalid conversion between vector type %0 and %1 of different size">;
@@ -2693,7 +2941,7 @@
 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">;
+  "first parameter of %0 must have type %1">;
 
 // C++ literal operators
 def err_literal_operator_outside_namespace : Error<
@@ -2740,33 +2988,36 @@
   "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<
+def warn_format_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<
+def warn_missing_format_string : Warning<
   "format string missing">, InGroup<Format>;
+def warn_scanf_nonzero_width : Warning<
+  "zero field width in scanf format string is unused">,
+  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<
+def warn_format_zero_positional_specifier : Warning<
   "position arguments in format strings start counting at 1 (not 0)">,
   InGroup<Format>;
-def warn_printf_invalid_positional_specifier : Warning<
+def warn_format_invalid_positional_specifier : Warning<
   "invalid position specified for %select{field width|field precision}0">,
   InGroup<Format>;
-def warn_printf_mix_positional_nonpositional_args : Warning<
+def warn_format_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<
+def warn_empty_format_string : Warning<
   "format string is empty">, InGroup<FormatZeroLength>;
-def warn_printf_format_string_is_wide_literal : Warning<
+def warn_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>;
@@ -2775,11 +3026,20 @@
 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)">,
+def warn_printf_nonsensical_optional_amount: Warning<
+  "%select{field width|precision}0 used with '%1' conversion specifier, resulting in undefined behavior">,
   InGroup<Format>;
 def warn_printf_nonsensical_flag: Warning<
-  "flag '%0' results in undefined behavior in '%1' conversion specifier">,
+  "flag '%0' results in undefined behavior with '%1' conversion specifier">,
+  InGroup<Format>;
+def warn_format_nonsensical_length: Warning<
+  "length modifier '%0' results in undefined behavior or no effect with '%1' conversion specifier">,
+  InGroup<Format>;
+def warn_printf_ignored_flag: Warning<
+  "flag '%0' is ignored when flag '%1' is present">,
+  InGroup<Format>;
+def warn_scanf_scanlist_incomplete : Warning<
+  "no closing ']' for '%%[' in scanf format string">,
   InGroup<Format>;
   
 // CHECK: returning address/reference of stack memory
@@ -2795,8 +3055,11 @@
 
 // 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">;
+// Array comparisons have similar warnings
+def warn_comparison_always : Warning<
+  "%select{self-|array }0comparison always evaluates to %select{false|true|a constant}1">,
+  InGroup<DiagGroup<"tautological-compare">>;
+
 def warn_stringcompare : Warning<
   "result of comparison against %select{a string literal|@encode}0 is "
   "unspecified (use strncmp instead)">;
@@ -2834,9 +3097,11 @@
   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_case_for_condition :
+  Warning<"no case matching constant switch condition '%0'">;
 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">,
+def warn_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)">;
@@ -2863,19 +3128,22 @@
   "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">,
+  "non-void %select{function|method}1 %0 should return a value">, DefaultError,
   InGroup<ReturnType>;
 def ext_return_missing_expr : ExtWarn<
-  "non-void %select{function|method}1 %0 should return a value">,
+  "non-void %select{function|method}1 %0 should return a value">, DefaultError,
   InGroup<ReturnType>;
 def ext_return_has_expr : ExtWarn<
-  "void %select{function|method}1 %0 should not return a value">,
+  "void %select{function|method}1 %0 should not return a value">, DefaultError,
   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_noreturn_function_has_nonvoid_result : Warning<
+  "%select{functions|blocks}0 declared 'noreturn' should have a 'void' result type">,
+  InGroup<DiagGroup<"invalid-noreturn">>;
 def warn_falloff_noreturn_function : Warning<
   "function declared 'noreturn' should not return">,
   InGroup<DiagGroup<"invalid-noreturn">>;
@@ -2900,6 +3168,8 @@
   "%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_invalid_neon_type_code : Error<
+  "incompatible constant for this __builtin_neon function">; 
 def err_argument_invalid_range : Error<
   "argument should be a value from %0 to %1">;
 
@@ -2910,7 +3180,9 @@
   "argument to %0 must be a constant integer">;
 
 def ext_mixed_decls_code : Extension<
-  "ISO C90 forbids mixing declarations and code">;
+  "ISO C90 forbids mixing declarations and code">,
+  InGroup<DiagGroup<"declaration-after-statement">>;
+  
 def err_non_variable_decl_in_for : Error<
   "declaration of non-local variable in 'for' loop">;
 def err_toomany_element_decls : Error<
@@ -2921,6 +3193,8 @@
   "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 warn_collection_expr_type : Warning<
+  "collection expression type %0 may not respond to %1">;
 
 def err_invalid_conversion_between_ext_vectors : Error<
   "invalid conversion between ext-vector type %0 and %1">;
@@ -3001,7 +3275,12 @@
   "cannot find protocol declaration for %0; did you mean %1?">;
 def note_base_class_specified_here : Note<
   "base class %0 specified here">;
+def err_using_directive_suggest : Error<
+  "no namespace named %0; did you mean %1?">;
+def err_using_directive_member_suggest : Error<
+  "no namespace named %0 in %1; did you mean %2?">;
+def note_namespace_defined_here : Note<"namespace %0 defined here">;
 
-}
-
+} // end of sema category
+} // end of sema component.
 
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index d0e0118..e71f51a 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -189,7 +189,7 @@
   /// getDirectory - Lookup, cache, and verify the specified directory.  This
   /// returns null if the directory doesn't exist.
   ///
-  const DirectoryEntry *getDirectory(const llvm::StringRef &Filename) {
+  const DirectoryEntry *getDirectory(llvm::StringRef Filename) {
     return getDirectory(Filename.begin(), Filename.end());
   }
   const DirectoryEntry *getDirectory(const char *FileStart,const char *FileEnd);
@@ -197,7 +197,7 @@
   /// getFile - Lookup, cache, and verify the specified file.  This returns null
   /// if the file doesn't exist.
   ///
-  const FileEntry *getFile(const llvm::StringRef &Filename) {
+  const FileEntry *getFile(llvm::StringRef Filename) {
     return getFile(Filename.begin(), Filename.end());
   }
   const FileEntry *getFile(const char *FilenameStart,
@@ -206,8 +206,8 @@
   /// \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);
+  const FileEntry *getVirtualFile(llvm::StringRef Filename, off_t Size,
+                                  time_t ModificationTime);
   void PrintStats() const;
 };
 
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 582d59c..24fe086 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -59,7 +59,11 @@
   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.
+  bool IsFromAST              : 1; // True if identfier first appeared in an AST
+                                   // file and wasn't modified since.
+  bool RevertedTokenID        : 1; // True if RevertTokenIDToIdentifier was
+                                   // called.
+  // 7 bits left in 32-bit word.
   void *FETokenInfo;               // Managed by the language front-end.
   llvm::StringMapEntry<IdentifierInfo*> *Entry;
 
@@ -89,7 +93,8 @@
     // 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;
+    typedef std::pair<IdentifierInfo, const char*> actualtype;
+    return ((const actualtype*) this)->second;
   }
 
   /// getLength - Efficiently return the length of this identifier info.
@@ -101,7 +106,8 @@
     // 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;
+    typedef std::pair<IdentifierInfo, const char*> actualtype;
+    const char* p = ((const actualtype*) this)->second - 2;
     return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1;
   }
 
@@ -123,13 +129,28 @@
       NeedsHandleIdentifier = 1;
     else
       RecomputeNeedsHandleIdentifier();
+    IsFromAST = false;
   }
 
-  /// get/setTokenID - If this is a source-language token (e.g. 'for'), this API
+  /// getTokenID - 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; }
+
+  /// \brief True if RevertTokenIDToIdentifier() was called.
+  bool hasRevertedTokenIDToIdentifier() const { return RevertedTokenID; }
+
+  /// \brief Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2
+  /// compatibility.
+  ///
+  /// TokenID is normally read-only but there are 2 instances where we revert it
+  /// to tok::identifier for libstdc++ 4.2. Keep track of when this happens
+  /// using this method so we can inform serialization about it.
+  void RevertTokenIDToIdentifier() {
+    assert(TokenID != tok::identifier && "Already at tok::identifier");
+    TokenID = tok::identifier;
+    RevertedTokenID = true;
+  }
 
   /// getPPKeywordID - Return the preprocessor keyword ID for this identifier.
   /// For example, "define" will return tok::pp_define.
@@ -184,6 +205,7 @@
       NeedsHandleIdentifier = 1;
     else
       RecomputeNeedsHandleIdentifier();
+    IsFromAST = false;
   }
 
   /// isPoisoned - Return true if this token has been poisoned.
@@ -211,6 +233,12 @@
   /// know that HandleIdentifier will not affect the token.
   bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; }
 
+  /// isFromAST - Return true if the identifier in its current state was loaded
+  /// from an AST file.
+  bool isFromAST() const { return IsFromAST; }
+
+  void setIsFromAST(bool FromAST = true) { IsFromAST = FromAST; }
+
 private:
   /// RecomputeNeedsHandleIdentifier - The Preprocessor::HandleIdentifier does
   /// several special (but rare) things to identifiers of various sorts.  For
@@ -311,6 +339,12 @@
     return *II;
   }
 
+  IdentifierInfo &get(llvm::StringRef Name, tok::TokenKind TokenCode) {
+    IdentifierInfo &II = get(Name);
+    II.TokenID = TokenCode;
+    return II;
+  }
+
   IdentifierInfo &get(const char *NameStart, const char *NameEnd) {
     return get(llvm::StringRef(NameStart, NameEnd-NameStart));
   }
@@ -319,35 +353,33 @@
     return get(llvm::StringRef(Name, NameLen));
   }
 
-  /// \brief Creates a new IdentifierInfo from the given string.
+  /// \brief Gets an IdentifierInfo for the given name without consulting
+  ///        external sources.
   ///
-  /// 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) {
+  /// This is a version of get() meant for external sources that want to
+  /// introduce or modify an identifier. If they called get(), they would
+  /// likely end up in a recursion.
+  IdentifierInfo &getOwn(const char *NameStart, const char *NameEnd) {
     llvm::StringMapEntry<IdentifierInfo*> &Entry =
       HashTable.GetOrCreateValue(NameStart, NameEnd);
 
     IdentifierInfo *II = Entry.getValue();
-    assert(!II && "IdentifierInfo already exists");
+    if (!II) {
 
-    // Lookups failed, make a new IdentifierInfo.
-    void *Mem = getAllocator().Allocate<IdentifierInfo>();
-    II = new (Mem) IdentifierInfo();
-    Entry.setValue(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;
+      // 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());
+  IdentifierInfo &getOwn(llvm::StringRef Name) {
+    return getOwn(Name.begin(), Name.end());
   }
 
   typedef HashTableTy::const_iterator iterator;
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index f88b0ef..bbcceb7 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -66,9 +66,6 @@
   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.
 
@@ -102,20 +99,21 @@
   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
+  unsigned InlineVisibilityHidden : 1; // Whether inline C++ methods have
+                                       // hidden visibility by default.  
 
+  unsigned SpellChecking : 1; // Whether to perform spell-checking for error
+                              // recovery.
   // 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.
+  // We declare multibit enums as unsigned because MSVC insists on making enums
+  // signed.  Set/Query these values using accessors.
+  unsigned GC : 2;                // Objective-C Garbage Collection modes.
   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.
+  unsigned StackProtector    : 2; // Whether stack protectors are on.
+  unsigned SignedOverflowBehavior : 2; // How to handle signed integer overflow.
 
 public:
   unsigned InstantiationDepth;    // Maximum template instantiation depth.
@@ -129,13 +127,19 @@
     Protected,
     Hidden
   };
+  
+  enum SignedOverflowBehaviorTy {
+    SOB_Undefined,  // Default C standard behavior.
+    SOB_Defined,    // -fwrapv
+    SOB_Trapping    // -ftrapv
+  };
 
   LangOptions() {
     Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0;
     GNUMode = GNUKeywords = ImplicitInt = Digraphs = 0;
     HexFloats = 0;
     GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0;
-    NoConstantCFStrings = 0;
+    NoConstantCFStrings = 0; InlineVisibilityHidden = 0;
     C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
     CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0;
     Exceptions = SjLjExceptions = Freestanding = NoBuiltin = 0;
@@ -146,23 +150,22 @@
     AltiVec = OpenCL = StackProtector = 0;
 
     SymbolVisibility = (unsigned) Default;
-
+      
     ThreadsafeStatics = 1;
     POSIXThreads = 0;
     Blocks = 0;
     EmitAllDecls = 0;
     MathErrno = 1;
-
+    SignedOverflowBehavior = SOB_Undefined;
+    
     AssumeSaneOperatorNew = 1;
-
-    // FIXME: The default should be 1.
-    AccessControl = 0;
+    AccessControl = 1;
     ElideConstructors = 1;
 
-    OverflowChecking = 0;
+    SignedOverflowBehavior = 0;
     ObjCGCBitmapPrint = 0;
 
-    InstantiationDepth = 500;
+    InstantiationDepth = 1024;
 
     Optimize = 0;
     OptimizeSize = 0;
@@ -178,6 +181,7 @@
     CatchUndefined = 0;
     DumpRecordLayouts = 0;
     DumpVTableLayouts = 0;
+    SpellChecking = 1;
     NoBitFieldTypeAlign = 0;
   }
 
@@ -195,6 +199,13 @@
     return (VisibilityMode) SymbolVisibility;
   }
   void setVisibilityMode(VisibilityMode v) { SymbolVisibility = (unsigned) v; }
+  
+  SignedOverflowBehaviorTy getSignedOverflowBehavior() const {
+    return (SignedOverflowBehaviorTy)SignedOverflowBehavior;
+  }
+  void setSignedOverflowBehavior(SignedOverflowBehaviorTy V) {
+    SignedOverflowBehavior = (unsigned)V;
+  }
 };
 
 }  // end namespace clang
diff --git a/include/clang/Basic/Linkage.h b/include/clang/Basic/Linkage.h
index de0de34..01b6c79 100644
--- a/include/clang/Basic/Linkage.h
+++ b/include/clang/Basic/Linkage.h
@@ -41,6 +41,17 @@
   ExternalLinkage
 };
 
+/// \brief A more specific kind of linkage. This is relevant to CodeGen and
+/// AST file reading.
+enum GVALinkage {
+  GVA_Internal,
+  GVA_C99Inline,
+  GVA_CXXInline,
+  GVA_StrongExternal,
+  GVA_TemplateInstantiation,
+  GVA_ExplicitTemplateInstantiation
+};
+
 /// \brief Determine whether the given linkage is semantically
 /// external.
 inline bool isExternalLinkage(Linkage L) {
diff --git a/include/clang/Basic/Makefile b/include/clang/Basic/Makefile
index 48f7f9d..7db3e29 100644
--- a/include/clang/Basic/Makefile
+++ b/include/clang/Basic/Makefile
@@ -1,16 +1,33 @@
-LEVEL = ../../../../..
-BUILT_SOURCES = DiagnosticAnalysisKinds.inc DiagnosticASTKinds.inc \
+CLANG_LEVEL := ../../..
+BUILT_SOURCES = \
+	DiagnosticAnalysisKinds.inc DiagnosticASTKinds.inc \
 	DiagnosticCommonKinds.inc DiagnosticDriverKinds.inc \
 	DiagnosticFrontendKinds.inc DiagnosticLexKinds.inc \
 	DiagnosticParseKinds.inc DiagnosticSemaKinds.inc \
-        DiagnosticGroups.inc
+	DiagnosticGroups.inc AttrList.inc arm_neon.inc \
+	Version.inc
 
 TABLEGEN_INC_FILES_COMMON = 1
 
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
 
 INPUT_TDS = $(wildcard $(PROJ_SRC_DIR)/Diagnostic*.td)
 
+# Compute the Clang version from the LLVM version, unless specified explicitly.
+ifndef CLANG_VERSION
+CLANG_VERSION := $(subst svn,,$(LLVMVersion))
+endif
+
+CLANG_VERSION_COMPONENTS := $(subst ., ,$(CLANG_VERSION))
+CLANG_VERSION_MAJOR := $(word 1,$(CLANG_VERSION_COMPONENTS))
+CLANG_VERSION_MINOR := $(word 2,$(CLANG_VERSION_COMPONENTS))
+CLANG_VERSION_PATCHLEVEL := $(word 3,$(CLANG_VERSION_COMPONENTS))
+ifeq ($(CLANG_VERSION_PATCHLEVEL),)
+CLANG_HAS_VERSION_PATCHLEVEL := 0
+else
+CLANG_HAS_VERSION_PATCHLEVEL := 1
+endif
+
 $(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, $@) $<
@@ -19,4 +36,20 @@
 	$(Echo) "Building Clang diagnostic groups with tblgen"
 	$(Verb) $(TableGen) -gen-clang-diag-groups -o $(call SYSPATH, $@) $<
 
+$(ObjDir)/AttrList.inc.tmp : Attr.td $(TBLGEN) $(ObjDir)/.dir
+	$(Echo) "Building Clang attribute list with tblgen"
+	$(Verb) $(TableGen) -gen-clang-attr-list -o $(call SYSPATH, $@) \
+	  -I $(PROJ_SRC_DIR)/../.. $<
 
+$(ObjDir)/arm_neon.inc.tmp : arm_neon.td $(TBLGEN) $(ObjDir)/.dir
+	$(Echo) "Building Clang arm_neon.inc with tblgen"
+	$(Verb) $(TableGen) -gen-arm-neon-sema -o $(call SYSPATH, $@) $<
+
+$(ObjDir)/Version.inc.tmp : Version.inc.in Makefile $(LLVM_OBJ_ROOT)/Makefile.config $(ObjDir)/.dir
+	$(Echo) "Updating Clang version info."
+	$(Verb)sed -e "s#@CLANG_VERSION@#$(CLANG_VERSION)#g" \
+	           -e "s#@CLANG_VERSION_MAJOR@#$(CLANG_VERSION_MAJOR)#g" \
+	           -e "s#@CLANG_VERSION_MINOR@#$(CLANG_VERSION_MINOR)#g" \
+	           -e "s#@CLANG_VERSION_PATCHLEVEL@#$(CLANG_VERSION_PATCHLEVEL)#g" \
+	           -e "s#@CLANG_HAS_VERSION_PATCHLEVEL@#$(CLANG_HAS_VERSION_PATCHLEVEL)#g" \
+	           $< > $@
diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h
index 2019e27..8909e47 100644
--- a/include/clang/Basic/OnDiskHashTable.h
+++ b/include/clang/Basic/OnDiskHashTable.h
@@ -124,8 +124,9 @@
     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)) {}
+    Item(typename Info::key_type_ref k, typename Info::data_type_ref d,
+         Info &InfoObj)
+    : key(k), data(d), next(0), hash(InfoObj.ComputeHash(k)) {}
   };
 
   class Bucket {
@@ -168,10 +169,17 @@
 
   void insert(typename Info::key_type_ref key,
               typename Info::data_type_ref data) {
+    Info InfoObj;
+    insert(key, data, InfoObj);
+  }
+
+  void insert(typename Info::key_type_ref key,
+              typename Info::data_type_ref data, Info &InfoObj) {
 
     ++NumEntries;
     if (4*NumEntries >= 3*NumBuckets) resize(NumBuckets*2);
-    insert(Buckets, NumBuckets, new (BA.Allocate<Item>()) Item(key, data));
+    insert(Buckets, NumBuckets, new (BA.Allocate<Item>()) Item(key, data,
+                                                               InfoObj));
   }
 
   io::Offset Emit(llvm::raw_ostream &out) {
@@ -278,8 +286,8 @@
       InfoPtr = &InfoObj;
 
     using namespace io;
-    const internal_key_type& iKey = Info::GetInternalKey(eKey);
-    unsigned key_hash = Info::ComputeHash(iKey);
+    const internal_key_type& iKey = InfoObj.GetInternalKey(eKey);
+    unsigned key_hash = InfoObj.ComputeHash(iKey);
 
     // Each bucket is just a 32-bit offset into the hash table file.
     unsigned idx = key_hash & (NumBuckets - 1);
@@ -326,6 +334,71 @@
 
   iterator end() const { return iterator(); }
 
+  /// \brief Iterates over all the entries in the table, returning
+  /// a key/data pair.
+  class item_iterator {
+    const unsigned char* Ptr;
+    unsigned NumItemsInBucketLeft;
+    unsigned NumEntriesLeft;
+    Info *InfoObj;
+  public:
+    typedef std::pair<external_key_type, data_type> value_type;
+
+    item_iterator(const unsigned char* const Ptr, unsigned NumEntries,
+                  Info *InfoObj)
+      : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries),
+        InfoObj(InfoObj) { }
+    item_iterator()
+      : Ptr(0), NumItemsInBucketLeft(0), NumEntriesLeft(0), InfoObj(0) { }
+
+    bool operator==(const item_iterator& X) const {
+      return X.NumEntriesLeft == NumEntriesLeft;
+    }
+    bool operator!=(const item_iterator& X) const {
+      return X.NumEntriesLeft != NumEntriesLeft;
+    }
+    
+    item_iterator& operator++() {  // Preincrement
+      if (!NumItemsInBucketLeft) {
+        // 'Items' starts with a 16-bit unsigned integer representing the
+        // number of items in this bucket.
+        NumItemsInBucketLeft = io::ReadUnalignedLE16(Ptr);
+      }
+      Ptr += 4; // Skip the hash.
+      // Determine the length of the key and the data.
+      const std::pair<unsigned, unsigned>& L = Info::ReadKeyDataLength(Ptr);
+      Ptr += L.first + L.second;
+      assert(NumItemsInBucketLeft);
+      --NumItemsInBucketLeft;
+      assert(NumEntriesLeft);
+      --NumEntriesLeft;
+      return *this;
+    }
+    item_iterator operator++(int) {  // Postincrement
+      item_iterator tmp = *this; ++*this; return tmp;
+    }
+
+    value_type operator*() const {
+      const unsigned char* LocalPtr = Ptr;
+      if (!NumItemsInBucketLeft)
+        LocalPtr += 2; // number of items in bucket
+      LocalPtr += 4; // Skip the hash.
+
+      // Determine the length of the key and the data.
+      const std::pair<unsigned, unsigned>& L = Info::ReadKeyDataLength(LocalPtr);
+
+      // Read the key.
+      const internal_key_type& Key =
+        InfoObj->ReadKey(LocalPtr, L.first);
+      return std::make_pair(InfoObj->GetExternalKey(Key),
+                          InfoObj->ReadData(Key, LocalPtr + L.first, L.second));
+    }
+  };
+  
+  item_iterator item_begin() {
+    return item_iterator(Base + 4, getNumEntries(), &InfoObj);
+  }
+  item_iterator item_end() { return item_iterator(); }
 
   static OnDiskChainedHashTable* Create(const unsigned char* buckets,
                                         const unsigned char* const base,
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
index 89fae87..cd0da97 100644
--- a/include/clang/Basic/PartialDiagnostic.h
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -59,7 +59,7 @@
   
     /// DiagRanges - The list of ranges added to this diagnostic.  It currently
     /// only support 10 ranges, could easily be extended if needed.
-    SourceRange DiagRanges[10];
+    CharSourceRange DiagRanges[10];
     
     enum { MaxFixItHints = 3 };
     
@@ -142,7 +142,7 @@
     DiagStorage = 0;
   }
   
-  void AddSourceRange(const SourceRange &R) const {
+  void AddSourceRange(const CharSourceRange &R) const {
     if (!DiagStorage)
       DiagStorage = getStorage();
 
@@ -264,10 +264,16 @@
 
   friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
                                                     const SourceRange &R) {
-    PD.AddSourceRange(R);
+    PD.AddSourceRange(CharSourceRange::getTokenRange(R));
     return PD;
   }
 
+  friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                                    const CharSourceRange &R) {
+    PD.AddSourceRange(R);
+    return PD;
+  }
+  
   friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
                                              const FixItHint &Hint) {
     PD.AddFixItHint(Hint);
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index 0bbeffe..35f27fb 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -172,6 +172,56 @@
     return B != X.B || E != X.E;
   }
 };
+  
+/// CharSourceRange - This class represents a character granular source range.
+/// The underlying SourceRange can either specify the starting/ending character
+/// of the range, or it can specify the start or the range and the start of the
+/// last token of the range (a "token range").  In the token range case, the
+/// size of the last token must be measured to determine the actual end of the
+/// range.
+class CharSourceRange { 
+  SourceRange Range;
+  bool IsTokenRange;
+public:
+  CharSourceRange() : IsTokenRange(false) {}
+  CharSourceRange(SourceRange R, bool ITR) : Range(R),IsTokenRange(ITR){}
+
+  static CharSourceRange getTokenRange(SourceRange R) {
+    CharSourceRange Result;
+    Result.Range = R;
+    Result.IsTokenRange = true;
+    return Result;
+  }
+
+  static CharSourceRange getCharRange(SourceRange R) {
+    CharSourceRange Result;
+    Result.Range = R;
+    Result.IsTokenRange = false;
+    return Result;
+  }
+    
+  static CharSourceRange getTokenRange(SourceLocation B, SourceLocation E) {
+    return getTokenRange(SourceRange(B, E));
+  }
+  static CharSourceRange getCharRange(SourceLocation B, SourceLocation E) {
+    return getCharRange(SourceRange(B, E));
+  }
+  
+  /// isTokenRange - Return true if the end of this range specifies the start of
+  /// the last token.  Return false if the end of this range specifies the last
+  /// character in the range.
+  bool isTokenRange() const { return IsTokenRange; }
+  
+  SourceLocation getBegin() const { return Range.getBegin(); }
+  SourceLocation getEnd() const { return Range.getEnd(); }
+  const SourceRange &getAsRange() const { return Range; }
+ 
+  void setBegin(SourceLocation b) { Range.setBegin(b); }
+  void setEnd(SourceLocation e) { Range.setEnd(e); }
+  
+  bool isValid() const { return Range.isValid(); }
+  bool isInvalid() const { return !isValid(); }
+};
 
 /// FullSourceLoc - A SourceLocation and its associated SourceManager.  Useful
 /// for argument passing to functions that expect both objects.
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index 930fb52..7a66117 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -50,13 +50,20 @@
     C_User, C_System, C_ExternCSystem
   };
 
-  /// ContentCache - Once instance of this struct is kept for every file
+  /// ContentCache - One instance of this struct is kept for every file
   /// loaded or used.  This object owns the MemoryBuffer object.
   class ContentCache {
+    enum CCFlags {
+      /// \brief Whether the buffer is invalid.
+      InvalidFlag = 0x01,
+      /// \brief Whether the buffer should not be freed on destruction.
+      DoNotFreeFlag = 0x02
+    };
+    
     /// 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;
+    /// The bits indicate indicates whether the buffer is invalid.
+    mutable llvm::PointerIntPair<const llvm::MemoryBuffer *, 2> Buffer;
 
   public:
     /// Reference to the file entry.  This reference does not own
@@ -103,11 +110,27 @@
       Buffer.setPointer(B);
       Buffer.setInt(false);
     }
+    
+    /// \brief Get the underlying buffer, returning NULL if the buffer is not
+    /// yet available.
+    const llvm::MemoryBuffer *getRawBuffer() const {
+      return Buffer.getPointer();
+    }
 
     /// \brief Replace the existing buffer (which will be deleted)
     /// with the given buffer.
-    void replaceBuffer(const llvm::MemoryBuffer *B);
+    void replaceBuffer(const llvm::MemoryBuffer *B, bool DoNotFree = false);
 
+    /// \brief Determine whether the buffer itself is invalid.
+    bool isBufferInvalid() const {
+      return Buffer.getInt() & InvalidFlag;
+    }
+    
+    /// \brief Determine whether the buffer should be freed.
+    bool shouldFreeBuffer() const {
+      return (Buffer.getInt() & DoNotFreeFlag) == 0;
+    }
+    
     ContentCache(const FileEntry *Ent = 0)
       : Buffer(0, false), Entry(Ent), SourceLineCache(0), NumLines(0) {}
 
@@ -280,6 +303,57 @@
   /// \brief Read the source location entry with index ID.
   virtual void ReadSLocEntry(unsigned ID) = 0;
 };
+  
+
+/// IsBeforeInTranslationUnitCache - This class holds the cache used by
+/// isBeforeInTranslationUnit.  The cache structure is complex enough to be
+/// worth breaking out of SourceManager.
+class IsBeforeInTranslationUnitCache {
+  /// L/R QueryFID - These are the FID's of the cached query.  If these match up
+  /// with a subsequent query, the result can be reused.
+  FileID LQueryFID, RQueryFID;
+  
+  /// CommonFID - This is the file found in common between the two #include
+  /// traces.  It is the nearest common ancestor of the #include tree.
+  FileID CommonFID;
+  
+  /// L/R CommonOffset - This is the offset of the previous query in CommonFID.
+  /// Usually, this represents the location of the #include for QueryFID, but if
+  /// LQueryFID is a parent of RQueryFID (or vise versa) then these can be a
+  /// random token in the parent.
+  unsigned LCommonOffset, RCommonOffset;
+public:
+  
+  /// isCacheValid - Return true if the currently cached values match up with
+  /// the specified LHS/RHS query.  If not, we can't use the cache.
+  bool isCacheValid(FileID LHS, FileID RHS) const {
+    return LQueryFID == LHS && RQueryFID == RHS;
+  }
+  
+  /// getCachedResult - If the cache is valid, compute the result given the
+  /// specified offsets in the LHS/RHS FID's.
+  bool getCachedResult(unsigned LOffset, unsigned ROffset) const {
+    // If one of the query files is the common file, use the offset.  Otherwise,
+    // use the #include loc in the common file.
+    if (LQueryFID != CommonFID) LOffset = LCommonOffset;
+    if (RQueryFID != CommonFID) ROffset = RCommonOffset;
+    return LOffset < ROffset;
+  }
+  
+  // Set up a new query.
+  void setQueryFIDs(FileID LHS, FileID RHS) {
+    LQueryFID = LHS;
+    RQueryFID = RHS;
+  }
+  
+  void setCommonLoc(FileID commonFID, unsigned lCommonOffset,
+                    unsigned rCommonOffset) {
+    CommonFID = commonFID;
+    LCommonOffset = lCommonOffset;
+    RCommonOffset = rCommonOffset;
+  }
+  
+};
 
 /// SourceManager - This file handles loading and caching of source files into
 /// memory.  This object owns the MemoryBuffer objects for all of the loaded
@@ -347,9 +421,7 @@
   mutable unsigned NumLinearScans, NumBinaryProbes;
 
   // Cache results for the isBeforeInTranslationUnit method.
-  mutable FileID LastLFIDForBeforeTUCheck;
-  mutable FileID LastRFIDForBeforeTUCheck;
-  mutable bool   LastResForBeforeTUCheck;
+  mutable IsBeforeInTranslationUnitCache IsBeforeInTUCache;
 
   // SourceManager doesn't support copy construction.
   explicit SourceManager(const SourceManager&);
@@ -372,10 +444,9 @@
   FileID getMainFileID() const { return MainFileID; }
 
   /// createMainFileID - Create the FileID for the main source file.
-  FileID createMainFileID(const FileEntry *SourceFile,
-                          SourceLocation IncludePos) {
+  FileID createMainFileID(const FileEntry *SourceFile) {
     assert(MainFileID.isInvalid() && "MainFileID already set!");
-    MainFileID = createFileID(SourceFile, IncludePos, SrcMgr::C_User);
+    MainFileID = createFileID(SourceFile, SourceLocation(), SrcMgr::C_User);
     return MainFileID;
   }
 
@@ -386,7 +457,7 @@
   /// 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,
+  /// PreallocateID should be non-zero to specify which pre-allocated,
   /// lazily computed source location is being filled in by this operation.
   FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
                       SrcMgr::CharacteristicKind FileCharacter,
@@ -436,14 +507,18 @@
   /// \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 SourceFile the source file whose contents will be overriden.
   ///
   /// \param Buffer the memory buffer whose contents will be used as the
   /// data in the given source file.
   ///
+  /// \param DoNotFree If true, then the buffer will not be freed when the
+  /// source manager is destroyed.
+  ///
   /// \returns true if an error occurred, false otherwise.
   bool overrideFileContents(const FileEntry *SourceFile,
-                            const llvm::MemoryBuffer *Buffer);
+                            const llvm::MemoryBuffer *Buffer,
+                            bool DoNotFree = false);
 
   //===--------------------------------------------------------------------===//
   // FileID manipulation methods.
@@ -719,7 +794,7 @@
   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
+  //  to iterate the entries that were not defined in an AST file (or
   //  any other external source).
   unsigned sloc_loaded_entry_size() const { return SLocEntryLoaded.size(); }
 
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index 9e54762..e757a2f 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -78,6 +78,68 @@
     AS_none
   };
 
+  /// ExprValueKind - The categorization of expression values,
+  /// currently following the C++0x scheme.
+  enum ExprValueKind {
+    /// An r-value expression (a gr-value in the C++0x taxonomy)
+    /// produces a temporary value.
+    VK_RValue,
+
+    /// An l-value expression is a reference to an object with
+    /// independent storage.
+    VK_LValue,
+
+    /// An x-value expression is a reference to an object with
+    /// independent storage but which can be "moved", i.e.
+    /// efficiently cannibalized for its resources.
+    VK_XValue
+  };
+
+  // \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
+  };
+
+  /// \brief Storage classes.
+  enum StorageClass {
+    // These are legal on both functions and variables.
+    SC_None,
+    SC_Extern,
+    SC_Static,
+    SC_PrivateExtern,
+
+    // These are only legal on variables.
+    SC_Auto,
+    SC_Register
+  };
+
+  /// Checks whether the given storage class is legal for functions.
+  inline bool isLegalForFunction(StorageClass SC) {
+    return SC <= SC_PrivateExtern;
+  }
+
+  /// Checks whether the given storage class is legal for variables.
+  inline bool isLegalForVariable(StorageClass SC) {
+    return true;
+  }
 } // end namespace clang
 
 #endif // LLVM_CLANG_BASIC_SPECIFIERS_H
diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td
new file mode 100644
index 0000000..a2f6973
--- /dev/null
+++ b/include/clang/Basic/StmtNodes.td
@@ -0,0 +1,130 @@
+class AttrSubject;
+
+class Stmt<bit abstract = 0> : AttrSubject {
+  bit Abstract = abstract;
+}
+
+class DStmt<Stmt base, bit abstract = 0> : Stmt<abstract> {
+  Stmt Base = base;
+}
+
+// Statements
+def NullStmt : Stmt;
+def CompoundStmt : Stmt;
+def LabelStmt : Stmt;
+def IfStmt : Stmt;
+def SwitchStmt : Stmt;
+def WhileStmt : Stmt;
+def DoStmt : Stmt;
+def ForStmt : Stmt;
+def GotoStmt : Stmt;
+def IndirectGotoStmt : Stmt;
+def ContinueStmt : Stmt;
+def BreakStmt : Stmt;
+def ReturnStmt : Stmt;
+def DeclStmt  : Stmt;
+def SwitchCase : Stmt;
+def CaseStmt : DStmt<SwitchCase>;
+def DefaultStmt : DStmt<SwitchCase>;
+
+// GNU Extensions
+def AsmStmt : Stmt;
+
+// Obj-C statements
+def ObjCAtTryStmt : Stmt;
+def ObjCAtCatchStmt : Stmt;
+def ObjCAtFinallyStmt : Stmt;
+def ObjCAtThrowStmt : Stmt;
+def ObjCAtSynchronizedStmt : Stmt;
+def ObjCForCollectionStmt : Stmt;
+
+// C++ statments
+def CXXCatchStmt : Stmt;
+def CXXTryStmt : Stmt;
+
+// Expressions
+def Expr : Stmt<1>;
+def PredefinedExpr : DStmt<Expr>;
+def DeclRefExpr : DStmt<Expr>;
+def IntegerLiteral : DStmt<Expr>;
+def FloatingLiteral : DStmt<Expr>;
+def ImaginaryLiteral : DStmt<Expr>;
+def StringLiteral : DStmt<Expr>;
+def CharacterLiteral : DStmt<Expr>;
+def ParenExpr : DStmt<Expr>;
+def UnaryOperator : DStmt<Expr>;
+def OffsetOfExpr : DStmt<Expr>;
+def SizeOfAlignOfExpr : DStmt<Expr>;
+def ArraySubscriptExpr : DStmt<Expr>;
+def CallExpr : DStmt<Expr>;
+def MemberExpr : DStmt<Expr>;
+def CastExpr : DStmt<Expr, 1>;
+def BinaryOperator : DStmt<Expr>;
+def CompoundAssignOperator : DStmt<BinaryOperator>;
+def ConditionalOperator : DStmt<Expr>;
+def ImplicitCastExpr : DStmt<CastExpr>;
+def ExplicitCastExpr : DStmt<CastExpr, 1>;
+def CStyleCastExpr : DStmt<ExplicitCastExpr>;
+def CompoundLiteralExpr : DStmt<Expr>;
+def ExtVectorElementExpr : DStmt<Expr>;
+def InitListExpr : DStmt<Expr>;
+def DesignatedInitExpr : DStmt<Expr>;
+def ImplicitValueInitExpr : DStmt<Expr>;
+def ParenListExpr : DStmt<Expr>;
+def VAArgExpr : DStmt<Expr>;
+
+// GNU Extensions.
+def AddrLabelExpr : DStmt<Expr>;
+def StmtExpr : DStmt<Expr>;
+def TypesCompatibleExpr : DStmt<Expr>;
+def ChooseExpr : DStmt<Expr>;
+def GNUNullExpr : DStmt<Expr>;
+
+// C++ Expressions.
+def CXXOperatorCallExpr : DStmt<CallExpr>;
+def CXXMemberCallExpr : DStmt<CallExpr>;
+def CXXNamedCastExpr : DStmt<ExplicitCastExpr, 1>;
+def CXXStaticCastExpr : DStmt<CXXNamedCastExpr>;
+def CXXDynamicCastExpr : DStmt<CXXNamedCastExpr>;
+def CXXReinterpretCastExpr : DStmt<CXXNamedCastExpr>;
+def CXXConstCastExpr : DStmt<CXXNamedCastExpr>;
+def CXXFunctionalCastExpr : DStmt<ExplicitCastExpr>;
+def CXXTypeidExpr : DStmt<Expr>;
+def CXXBoolLiteralExpr : DStmt<Expr>;
+def CXXNullPtrLiteralExpr : DStmt<Expr>;
+def CXXThisExpr : DStmt<Expr>;
+def CXXThrowExpr : DStmt<Expr>;
+def CXXDefaultArgExpr : DStmt<Expr>;
+def CXXScalarValueInitExpr : DStmt<Expr>;
+def CXXNewExpr : DStmt<Expr>;
+def CXXDeleteExpr : DStmt<Expr>;
+def CXXPseudoDestructorExpr : DStmt<Expr>;
+def UnaryTypeTraitExpr : DStmt<Expr>;
+def DependentScopeDeclRefExpr : DStmt<Expr>;
+def CXXConstructExpr : DStmt<Expr>;
+def CXXBindTemporaryExpr : DStmt<Expr>;
+def CXXBindReferenceExpr : DStmt<Expr>;
+def CXXExprWithTemporaries : DStmt<Expr>;
+def CXXTemporaryObjectExpr : DStmt<CXXConstructExpr>;
+def CXXUnresolvedConstructExpr : DStmt<Expr>;
+def CXXDependentScopeMemberExpr : DStmt<Expr>;
+def OverloadExpr : DStmt<Expr, 1>;
+def UnresolvedLookupExpr : DStmt<OverloadExpr>;
+def UnresolvedMemberExpr : DStmt<OverloadExpr>;
+
+// Obj-C Expressions.
+def ObjCStringLiteral : DStmt<Expr>;
+def ObjCEncodeExpr : DStmt<Expr>;
+def ObjCMessageExpr : DStmt<Expr>;
+def ObjCSelectorExpr : DStmt<Expr>;
+def ObjCProtocolExpr : DStmt<Expr>;
+def ObjCIvarRefExpr : DStmt<Expr>;
+def ObjCPropertyRefExpr : DStmt<Expr>;
+def ObjCImplicitSetterGetterRefExpr : DStmt<Expr>;
+def ObjCSuperExpr : DStmt<Expr>;
+def ObjCIsaExpr : DStmt<Expr>;
+
+// Clang Extensions.
+def ShuffleVectorExpr : DStmt<Expr>;
+def BlockExpr : DStmt<Expr>;
+def BlockDeclRefExpr : DStmt<Expr>;
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 1998750..40df9ba 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -16,6 +16,7 @@
 
 // FIXME: Daniel isn't smart enough to use a prototype for this.
 #include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/System/DataTypes.h"
 #include <cassert>
@@ -37,6 +38,22 @@
 
 namespace Builtin { struct Info; }
 
+/// TargetCXXABI - The types of C++ ABIs for which we can generate code.
+enum TargetCXXABI {
+  /// The generic ("Itanium") C++ ABI, documented at:
+  ///   http://www.codesourcery.com/public/cxx-abi/
+  CXXABI_Itanium,
+
+  /// The ARM C++ ABI, based largely on the Itanium ABI but with
+  /// significant differences.
+  ///    http://infocenter.arm.com
+  ///                    /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
+  CXXABI_ARM,
+
+  /// The Visual Studio ABI.  Only scattered official documentation exists.
+  CXXABI_Microsoft
+};
+
 /// TargetInfo - This class exposes information about the current target.
 ///
 class TargetInfo {
@@ -51,12 +68,17 @@
   unsigned char FloatWidth, FloatAlign;
   unsigned char DoubleWidth, DoubleAlign;
   unsigned char LongDoubleWidth, LongDoubleAlign;
+  unsigned char LargeArrayMinWidth, LargeArrayAlign;
   unsigned char LongWidth, LongAlign;
   unsigned char LongLongWidth, LongLongAlign;
   const char *DescriptionString;
   const char *UserLabelPrefix;
   const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat;
   unsigned char RegParmMax, SSERegParmMax;
+  TargetCXXABI CXXABI;
+
+  unsigned HasAlignMac68kSupport : 1;
+  unsigned RealTypeUsesObjCFPRet : 3;
 
   // TargetInfo Constructor.  Default initializes all fields.
   TargetInfo(const std::string &T);
@@ -83,6 +105,13 @@
     SignedLongLong,
     UnsignedLongLong
   };
+
+  enum RealType {
+    Float = 0,
+    Double,
+    LongDouble
+  };
+
 protected:
   IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
           WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType;
@@ -192,6 +221,11 @@
     return *LongDoubleFormat;
   }
 
+  // getLargeArrayMinWidth/Align - Return the minimum array size that is
+  // 'large' and its alignment.
+  unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; }
+  unsigned getLargeArrayAlign() const { return LargeArrayAlign; }
+
   /// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this
   /// target, in bits.
   unsigned getIntMaxTWidth() const {
@@ -210,6 +244,12 @@
     return UseBitFieldTypeAlignment;
   }
 
+  /// hasAlignMac68kSupport - Check whether this target support '#pragma options
+  /// align=mac68k'.
+  bool hasAlignMac68kSupport() const {
+    return HasAlignMac68kSupport;
+  }
+
   /// getTypeName - Return the user string for the specified integer type enum.
   /// For example, SignedShort -> "short".
   static const char *getTypeName(IntType T);
@@ -218,6 +258,12 @@
   /// integer type enum. For example, SignedLong -> "L".
   static const char *getTypeConstantSuffix(IntType T);
 
+  /// \brief Check whether the given real type should use the "fpret" flavor of
+  /// Obj-C message passing on this target.
+  bool useObjCFPRetForRealType(RealType T) const {
+    return RealTypeUsesObjCFPRet & (1 << T);
+  }
+
   ///===---- Other target property query methods --------------------------===//
 
   /// getTargetDefines - Appends the target-specific #define values for this
@@ -382,6 +428,11 @@
     return "";
   }
 
+  /// getCXXABI - Get the C++ ABI in use.
+  virtual TargetCXXABI getCXXABI() const {
+    return CXXABI;
+  }
+
   /// setCPU - Target the specific CPU.
   ///
   /// \return - False on error (invalid CPU name).
@@ -398,6 +449,28 @@
     return false;
   }
 
+  /// setCXXABI - Use this specific C++ ABI.
+  ///
+  /// \return - False on error (invalid C++ ABI name).
+  bool setCXXABI(const std::string &Name) {
+    static const TargetCXXABI Unknown = static_cast<TargetCXXABI>(-1);
+    TargetCXXABI ABI = llvm::StringSwitch<TargetCXXABI>(Name)
+      .Case("arm", CXXABI_ARM)
+      .Case("itanium", CXXABI_Itanium)
+      .Case("microsoft", CXXABI_Microsoft)
+      .Default(Unknown);
+    if (ABI == Unknown) return false;
+    return setCXXABI(ABI);
+  }
+
+  /// setCXXABI - Set the C++ ABI to be used by this implementation.
+  ///
+  /// \return - False on error (ABI not valid on this target)
+  virtual bool setCXXABI(TargetCXXABI ABI) {
+    CXXABI = ABI;
+    return true;
+  }
+
   /// setFeatureEnabled - Enable or disable a specific target feature,
   /// the feature name must be valid.
   ///
@@ -442,7 +515,12 @@
     return -1; 
   }
   
-
+  /// getStaticInitSectionSpecifier - Return the section to use for C++ static 
+  /// initialization functions.
+  virtual const char *getStaticInitSectionSpecifier() const {
+    return 0;
+  }
+  
 protected:
   virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
     return PointerWidth;
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index eeaab15..f3c206f 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -18,7 +18,6 @@
 /// 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;
@@ -29,6 +28,13 @@
   /// If given, the name of the target ABI to use.
   std::string ABI;
 
+  /// If given, the name of the target C++ ABI to use. If not given, defaults
+  /// to "itanium".
+  std::string CXXABI;
+
+  /// If given, the version string of the linker in use.
+  std::string LinkerVersion;
+
   /// 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;
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 52e83f4..11bcab9 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -96,6 +96,7 @@
 TOK(eof)                 // End of file.
 TOK(eom)                 // End of macro (end of line inside a macro).
 TOK(code_completion)     // Code completion marker
+TOK(cxx_defaultarg_end)  // C++ default argument end marker
 
 // C99 6.4.9: Comments.
 TOK(comment)             // Comment (only in -E -C[C] mode)
@@ -220,7 +221,7 @@
 KEYWORD(void                        , KEYALL)
 KEYWORD(volatile                    , KEYALL)
 KEYWORD(while                       , KEYALL)
-KEYWORD(_Bool                       , KEYALL)
+KEYWORD(_Bool                       , KEYNOMS)
 KEYWORD(_Complex                    , KEYALL)
 KEYWORD(_Imaginary                  , KEYALL)
 KEYWORD(__func__                    , KEYALL)
@@ -272,16 +273,11 @@
 
 // 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)
 
@@ -336,6 +332,7 @@
 KEYWORD(__cdecl                     , KEYALL)
 KEYWORD(__stdcall                   , KEYALL)
 KEYWORD(__fastcall                  , KEYALL)
+KEYWORD(__thiscall                  , KEYALL)
 KEYWORD(__forceinline               , KEYALL)
 
 // Altivec Extension.
@@ -372,6 +369,7 @@
 ALIAS("_cdecl"       , __cdecl    , KEYMS)
 ALIAS("_fastcall"    , __fastcall , KEYMS)
 ALIAS("_stdcall"     , __stdcall  , KEYMS)
+ALIAS("_thiscall"    , __thiscall , KEYMS)
 
 //===----------------------------------------------------------------------===//
 // Objective-C @-preceeded keywords.
diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h
index 2e0993a..9948677 100644
--- a/include/clang/Basic/Version.h
+++ b/include/clang/Basic/Version.h
@@ -17,15 +17,7 @@
 
 #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
+#include "clang/Basic/Version.inc"
 
 /// \brief Helper macro for CLANG_VERSION_STRING.
 #define CLANG_MAKE_VERSION_STRING2(X) #X
diff --git a/include/clang/Basic/Version.inc.in b/include/clang/Basic/Version.inc.in
new file mode 100644
index 0000000..ccf8430
--- /dev/null
+++ b/include/clang/Basic/Version.inc.in
@@ -0,0 +1,6 @@
+#define CLANG_VERSION @CLANG_VERSION@
+#define CLANG_VERSION_MAJOR @CLANG_VERSION_MAJOR@
+#define CLANG_VERSION_MINOR @CLANG_VERSION_MINOR@
+#if @CLANG_HAS_VERSION_PATCHLEVEL@
+#define CLANG_VERSION_PATCHLEVEL @CLANG_VERSION_PATCHLEVEL@
+#endif
diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td
new file mode 100644
index 0000000..fa6ebb7
--- /dev/null
+++ b/include/clang/Basic/arm_neon.td
@@ -0,0 +1,343 @@
+//===--- arm_neon.td - ARM NEON compiler 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 TableGen definitions from which the ARM NEON header
+//  file will be generated.  See ARM document DUI0348B.
+//
+//===----------------------------------------------------------------------===//
+
+class Op;
+
+def OP_NONE  : Op;
+def OP_ADD   : Op;
+def OP_SUB   : Op;
+def OP_MUL   : Op;
+def OP_MLA   : Op;
+def OP_MLS   : Op;
+def OP_MUL_N : Op;
+def OP_MLA_N : Op;
+def OP_MLS_N : Op;
+def OP_EQ    : Op;
+def OP_GE    : Op;
+def OP_LE    : Op;
+def OP_GT    : Op;
+def OP_LT    : Op;
+def OP_NEG   : Op;
+def OP_NOT   : Op;
+def OP_AND   : Op;
+def OP_OR    : Op;
+def OP_XOR   : Op;
+def OP_ANDN  : Op;
+def OP_ORN   : Op;
+def OP_CAST  : Op;
+def OP_HI    : Op;
+def OP_LO    : Op;
+def OP_CONC  : Op;
+def OP_DUP   : Op;
+def OP_SEL   : Op;
+def OP_REV64 : Op;
+def OP_REV32 : Op;
+def OP_REV16 : Op;
+
+class Inst <string p, string t, Op o> {
+  string Prototype = p;
+  string Types = t;
+  Op Operand = o;
+  bit isShift = 0;
+}
+
+// Used to generate Builtins.def
+class SInst<string p, string t> : Inst<p, t, OP_NONE> {}
+class IInst<string p, string t> : Inst<p, t, OP_NONE> {}
+class WInst<string p, string t> : Inst<p, t, OP_NONE> {}
+
+// prototype: return (arg, arg, ...)
+// v: void
+// t: best-fit integer (int/poly args)
+// x: signed integer   (int/float args)
+// u: unsigned integer (int/float args)
+// f: float (int args)
+// d: default
+// g: default, ignore 'Q' size modifier.
+// w: double width elements, same num elts
+// n: double width elements, half num elts
+// h: half width elements, double num elts
+// e: half width elements, double num elts, unsigned
+// i: constant int
+// l: constant uint64
+// s: scalar of element type
+// a: scalar of element type (splat to vector type)
+// k: default elt width, double num elts
+// #: array of default vectors
+// p: pointer type
+// c: const pointer type
+
+// sizes:
+// c: char
+// s: short
+// i: int
+// l: long
+// f: float
+// h: half-float
+
+// size modifiers:
+// U: unsigned
+// Q: 128b
+// P: polynomial
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.1 Addition
+def VADD    : Inst<"ddd", "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUl", OP_ADD>;
+def VADDL   : SInst<"wdd", "csiUcUsUi">;
+def VADDW   : SInst<"wwd", "csiUcUsUi">;
+def VHADD   : SInst<"ddd", "csiUcUsUiQcQsQiQUcQUsQUi">;
+def VRHADD  : SInst<"ddd", "csiUcUsUiQcQsQiQUcQUsQUi">;
+def VQADD   : SInst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VADDHN  : IInst<"dww", "csiUcUsUi">;
+def VRADDHN : IInst<"dww", "csiUcUsUi">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.2 Multiplication
+def VMUL     : Inst<"ddd",  "csifUcUsUiPcQcQsQiQfQUcQUsQUiQPc", OP_MUL>;
+def VMLA     : Inst<"dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLA>;
+def VMLAL    : SInst<"wwdd", "csiUcUsUi">;
+def VMLS     : Inst<"dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLS>;
+def VMLSL    : SInst<"wwdd", "csiUcUsUi">;
+def VQDMULH  : SInst<"ddd",  "siQsQi">;
+def VQRDMULH : SInst<"ddd",  "siQsQi">;
+def VQDMLAL  : SInst<"wwdd", "si">;
+def VQDMLSL  : SInst<"wwdd", "si">;
+def VMULL    : SInst<"wdd",  "csiUcUsUiPc">;
+def VQDMULL  : SInst<"wdd",  "si">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.3 Subtraction
+def VSUB    : Inst<"ddd", "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUl", OP_SUB>;
+def VSUBL   : SInst<"wdd", "csiUcUsUi">;
+def VSUBW   : SInst<"wwd", "csiUcUsUi">;
+def VQSUB   : SInst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VHSUB   : SInst<"ddd", "csiUcUsUiQcQsQiQUcQUsQUi">;
+def VSUBHN  : IInst<"dww", "csiUcUsUi">;
+def VRSUBHN : IInst<"dww", "csiUcUsUi">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.4 Comparison
+def VCEQ  : Inst<"udd", "csifUcUsUiPcQcQsQiQfQUcQUsQUiQPc", OP_EQ>;
+def VCGE  : Inst<"udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_GE>;
+def VCLE  : Inst<"udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_LE>;
+def VCGT  : Inst<"udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_GT>;
+def VCLT  : Inst<"udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_LT>;
+def VCAGE : IInst<"udd", "fQf">;
+def VCALE : IInst<"udd", "fQf">;
+def VCAGT : IInst<"udd", "fQf">;
+def VCALT : IInst<"udd", "fQf">;
+def VTST  : WInst<"udd", "csiUcUsUiPcQcQsQiQUcQUsQUiQPc">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.5 Absolute Difference
+def VABD  : SInst<"ddd",  "csiUcUsUifQcQsQiQUcQUsQUiQf">;
+def VABDL : SInst<"wdd",  "csiUcUsUi">;
+def VABA  : SInst<"dddd", "csiUcUsUiQcQsQiQUcQUsQUi">;
+def VABAL : SInst<"wwdd", "csiUcUsUi">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.6 Max/Min
+def VMAX : SInst<"ddd", "csiUcUsUifQcQsQiQUcQUsQUiQf">;
+def VMIN : SInst<"ddd", "csiUcUsUifQcQsQiQUcQUsQUiQf">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.7 Pairdise Addition
+def VPADD  : IInst<"ddd", "csiUcUsUif">;
+def VPADDL : SInst<"nd",  "csiUcUsUiQcQsQiQUcQUsQUi">;
+def VPADAL : SInst<"nnd", "csiUcUsUiQcQsQiQUcQUsQUi">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.8-9 Folding Max/Min
+def VPMAX : SInst<"ddd", "csiUcUsUif">;
+def VPMIN : SInst<"ddd", "csiUcUsUif">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.10 Reciprocal/Sqrt
+def VRECPS  : IInst<"ddd", "fQf">;
+def VRSQRTS : IInst<"ddd", "fQf">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.11 Shifts by signed variable
+def VSHL   : SInst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VQSHL  : SInst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VRSHL  : SInst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VQRSHL : SInst<"ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.12 Shifts by constant
+let isShift = 1 in {
+def VSHR_N     : SInst<"ddi",  "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VSHL_N     : IInst<"ddi",  "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VRSHR_N    : SInst<"ddi",  "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VSRA_N     : SInst<"dddi", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VRSRA_N    : SInst<"dddi", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VQSHL_N    : SInst<"ddi",  "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">;
+def VQSHLU_N   : SInst<"udi",  "csilQcQsQiQl">;
+def VSHRN_N    : IInst<"hki",  "silUsUiUl">;
+def VQSHRUN_N  : SInst<"eki",  "sil">;
+def VQRSHRUN_N : SInst<"eki",  "sil">;
+def VQSHRN_N   : SInst<"hki",  "silUsUiUl">;
+def VRSHRN_N   : IInst<"hki",  "silUsUiUl">;
+def VQRSHRN_N  : SInst<"hki",  "silUsUiUl">;
+def VSHLL_N    : SInst<"wdi",  "csiUcUsUi">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.13 Shifts with insert
+def VSRI_N : WInst<"dddi", "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPs">;
+def VSLI_N : WInst<"dddi", "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPs">;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.14 Loads and stores of a single vector
+def VLD1      : WInst<"dc",   "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VLD1_LANE : WInst<"dcdi", "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VLD1_DUP  : WInst<"dc",   "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VST1      : WInst<"vpd",  "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VST1_LANE : WInst<"vpdi", "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.15 Loads and stores of an N-element structure
+def VLD2      : WInst<"2c",   "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VLD3      : WInst<"3c",   "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VLD4      : WInst<"4c",   "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VLD2_DUP  : WInst<"2c",   "UcUsUiUlcsilhfPcPs">;
+def VLD3_DUP  : WInst<"3c",   "UcUsUiUlcsilhfPcPs">;
+def VLD4_DUP  : WInst<"4c",   "UcUsUiUlcsilhfPcPs">;
+def VLD2_LANE : WInst<"2c2i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
+def VLD3_LANE : WInst<"3c3i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
+def VLD4_LANE : WInst<"4c4i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
+def VST2      : WInst<"vp2",  "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VST3      : WInst<"vp3",  "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VST4      : WInst<"vp4",  "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VST2_LANE : WInst<"vp2i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
+def VST3_LANE : WInst<"vp3i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
+def VST4_LANE : WInst<"vp4i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.16 Extract lanes from a vector
+def VGET_LANE : IInst<"sdi", "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.17 Set lanes within a vector
+def VSET_LANE : IInst<"dsdi", "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.18 Initialize a vector from bit pattern
+def VCREATE: Inst<"dl", "csihfUcUsUiUlPcPsl", OP_CAST>;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.19 Set all lanes to same value
+def VDUP_N : Inst<"ds", "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>;
+def VMOV_N : Inst<"ds", "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>;
+def VDUP_LANE : WInst<"dgi", "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.20 Combining vectors
+def VCOMBINE : Inst<"kdd", "csilhfUcUsUiUlPcPs", OP_CONC>;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.21 Splitting vectors
+def VGET_HIGH : Inst<"dk", "csilhfUcUsUiUlPcPs", OP_HI>;
+def VGET_LOW  : Inst<"dk", "csilhfUcUsUiUlPcPs", OP_LO>;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.22 Converting vectors
+def VCVT_S32     : SInst<"xd",  "fQf">;
+def VCVT_U32     : SInst<"ud",  "fQf">;
+def VCVT_F16     : SInst<"hk",  "f">;
+def VCVT_N_S32   : SInst<"xdi", "fQf">;
+def VCVT_N_U32   : SInst<"udi", "fQf">;
+def VCVT_F32     : SInst<"fd",  "iUiQiQUi">;
+def VCVT_F32_F16 : SInst<"kh",  "f">;
+def VCVT_N_F32   : SInst<"fdi", "iUiQiQUi">;
+def VMOVN        : IInst<"hk",  "silUsUiUl">;
+def VMOVL        : SInst<"wd",  "csiUcUsUi">;
+def VQMOVN       : SInst<"hk",  "silUsUiUl">;
+def VQMOVUN      : SInst<"ek",  "sil">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.23-24 Table lookup, Extended table lookup
+def VTBL1 : WInst<"ddt",  "UccPc">;
+def VTBL2 : WInst<"d2t",  "UccPc">;
+def VTBL3 : WInst<"d3t",  "UccPc">;
+def VTBL4 : WInst<"d4t",  "UccPc">;
+def VTBX1 : WInst<"dddt", "UccPc">;
+def VTBX2 : WInst<"dd2t", "UccPc">;
+def VTBX3 : WInst<"dd3t", "UccPc">;
+def VTBX4 : WInst<"dd4t", "UccPc">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.25 Operations with a scalar value
+def VMLA_LANE     : IInst<"ddddi", "siUsUifQsQiQUsQUiQf">;
+def VMLAL_LANE    : SInst<"wwddi", "siUsUi">;
+def VQDMLAL_LANE  : SInst<"wwddi", "si">; 
+def VMLS_LANE     : IInst<"ddddi", "siUsUifQsQiQUsQUiQf">;
+def VMLSL_LANE    : SInst<"wwddi", "siUsUi">;
+def VQDMLSL_LANE  : SInst<"wwddi", "si">;
+def VMUL_N        : Inst<"dds",    "sifUsUiQsQiQfQUsQUi", OP_MUL_N>;
+def VMULL_N       : SInst<"wda",   "siUsUi">;
+def VMULL_LANE    : SInst<"wddi",  "siUsUi">;
+def VQDMULL_N     : SInst<"wda",   "si">;
+def VQDMULL_LANE  : SInst<"wddi",  "si">;
+def VQDMULH_N     : SInst<"dda",   "siQsQi">;
+def VQDMULH_LANE  : SInst<"dddi",  "siQsQi">;
+def VQRDMULH_N    : SInst<"dda",   "siQsQi">;
+def VQRDMULH_LANE : SInst<"dddi",  "siQsQi">;
+def VMLA_N        : Inst<"ddda",   "siUsUifQsQiQUsQUiQf", OP_MLA_N>;
+def VMLAL_N       : SInst<"wwda",  "siUsUi">;
+def VQDMLAL_N     : SInst<"wwda",  "si">;
+def VMLS_N        : Inst<"ddds",   "siUsUifQsQiQUsQUiQf", OP_MLS_N>;
+def VMLSL_N       : SInst<"wwda",  "siUsUi">;
+def VQDMLSL_N     : SInst<"wwda",  "si">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.26 Vector Extract
+def VEXT : WInst<"dddi", "cUcPcsUsPsiUilUlQcQUcQPcQsQUsQPsQiQUiQlQUl">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.27 Reverse vector elements (sdap endianness)
+def VREV64 : Inst<"dd", "csiUcUsUiPcPsfQcQsQiQUcQUsQUiQPcQPsQf", OP_REV64>;
+def VREV32 : Inst<"dd", "csUcUsPcQcQsQUcQUsQPc", OP_REV32>;
+def VREV16 : Inst<"dd", "cUcPcQcQUcQPc", OP_REV16>;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.28 Other single operand arithmetic
+def VABS    : SInst<"dd", "csifQcQsQiQf">;
+def VQABS   : SInst<"dd", "csiQcQsQi">;
+def VNEG    : Inst<"dd",  "csifQcQsQiQf", OP_NEG>;
+def VQNEG   : SInst<"dd", "csiQcQsQi">;
+def VCLS    : SInst<"dd", "csiQcQsQi">;
+def VCLZ    : IInst<"dd", "csiUcUsUiQcQsQiQUcQUsQUi">;
+def VCNT    : WInst<"dd", "UccPcQUcQcQPc">;
+def VRECPE  : SInst<"dd", "fUiQfQUi">;
+def VRSQRTE : SInst<"dd", "fUiQfQUi">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.29 Logical operations
+def VMVN : Inst<"dd",    "csiUcUsUiPcQcQsQiQUcQUsQUiQPc", OP_NOT>;
+def VAND : Inst<"ddd",   "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_AND>;
+def VORR : Inst<"ddd",   "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_OR>;
+def VEOR : Inst<"ddd",   "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_XOR>;
+def VBIC : Inst<"ddd",   "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ANDN>;
+def VORN : Inst<"ddd",   "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ORN>;
+def VBSL : Inst<"dudd",  "csilUcUsUiUlfPcPsQcQsQiQlQUcQUsQUiQUlQfQPcQPs", OP_SEL>;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.30 Transposition operations
+def VTRN: WInst<"2dd", "csiUcUsUifPcPsQcQsQiQUcQUsQUiQfQPcQPs">;
+def VZIP: WInst<"2dd", "csUcUsfPcPsQcQsQiQUcQUsQUiQfQPcQPs">;
+def VUZP: WInst<"2dd", "csiUcUsUifPcPsQcQsQiQUcQUsQUiQfQPcQPs">;
+
+////////////////////////////////////////////////////////////////////////////////
+// E.3.31 Vector reinterpret cast operations
diff --git a/include/clang/CMakeLists.txt b/include/clang/CMakeLists.txt
index 61d2bf6..e82cf42 100644
--- a/include/clang/CMakeLists.txt
+++ b/include/clang/CMakeLists.txt
@@ -1,2 +1,4 @@
+add_subdirectory(AST)
 add_subdirectory(Basic)
 add_subdirectory(Driver)
+add_subdirectory(Serialization)
diff --git a/include/clang/Checker/AnalysisConsumer.h b/include/clang/Checker/AnalysisConsumer.h
new file mode 100644
index 0000000..c236766
--- /dev/null
+++ b/include/clang/Checker/AnalysisConsumer.h
@@ -0,0 +1,35 @@
+//===--- 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_CHECKER_ANALYSISCONSUMER_H
+#define LLVM_CLANG_CHECKER_ANALYSISCONSUMER_H
+
+#include <string>
+
+namespace clang {
+
+class AnalyzerOptions;
+class ASTConsumer;
+class Preprocessor;
+
+/// 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/Checker/BugReporter/BugReporter.h b/include/clang/Checker/BugReporter/BugReporter.h
index 5b65d52..3749b43 100644
--- a/include/clang/Checker/BugReporter/BugReporter.h
+++ b/include/clang/Checker/BugReporter/BugReporter.h
@@ -70,6 +70,7 @@
 
   virtual void Profile(llvm::FoldingSetNodeID& hash) const {
     hash.AddInteger(getLocation().getRawEncoding());
+    hash.AddString(Description);
   }
 
 public:
diff --git a/include/clang/Checker/FrontendActions.h b/include/clang/Checker/FrontendActions.h
new file mode 100644
index 0000000..1c0bbb7
--- /dev/null
+++ b/include/clang/Checker/FrontendActions.h
@@ -0,0 +1,29 @@
+//===-- 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_CHECKER_FRONTENDACTIONS_H
+#define LLVM_CLANG_CHECKER_FRONTENDACTIONS_H
+
+#include "clang/Frontend/FrontendAction.h"
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+class AnalysisAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Checker/PathDiagnosticClients.h b/include/clang/Checker/PathDiagnosticClients.h
new file mode 100644
index 0000000..d3aa3b2
--- /dev/null
+++ b/include/clang/Checker/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_CHECKER_PATH_DIAGNOSTIC_CLIENTS_H
+#define LLVM_CLANG_CHECKER_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/Checker/PathSensitive/AnalysisManager.h b/include/clang/Checker/PathSensitive/AnalysisManager.h
index 0c59d7b..3855079 100644
--- a/include/clang/Checker/PathSensitive/AnalysisManager.h
+++ b/include/clang/Checker/PathSensitive/AnalysisManager.h
@@ -21,6 +21,11 @@
 
 namespace clang {
 
+namespace idx { 
+  class Indexer;
+  class TranslationUnit; 
+}
+
 class AnalysisManager : public BugReporterData {
   AnalysisContextManager AnaCtxMgr;
   LocationContextManager LocCtxMgr;
@@ -35,10 +40,19 @@
   StoreManagerCreator CreateStoreMgr;
   ConstraintManagerCreator CreateConstraintMgr;
 
+  /// \brief Provide function definitions in other translation units. This is
+  /// NULL if we don't have multiple translation units. AnalysisManager does
+  /// not own the Indexer.
+  idx::Indexer *Idxer;
+
   enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
 
+  // The maximum number of exploded nodes the analyzer will generate.
   unsigned MaxNodes;
 
+  // The maximum number of times the analyzer will go through a loop.
+  unsigned MaxLoop;
+
   bool VisualizeEGDot;
   bool VisualizeEGUbi;
   bool PurgeDead;
@@ -52,19 +66,24 @@
   //   bifurcates paths.
   bool EagerlyAssume;
   bool TrimGraph;
+  bool InlineCall;
 
 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)
+                  ConstraintManagerCreator constraintmgr, 
+                  idx::Indexer *idxer,
+                  unsigned maxnodes, unsigned maxloop,
+                  bool vizdot, bool vizubi, bool purge, bool eager, bool trim,
+                  bool inlinecall, bool useUnoptimizedCFG)
 
-    : Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd),
-      CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
-      AScope(ScopeDecl), MaxNodes(maxnodes),
+    : AnaCtxMgr(useUnoptimizedCFG), Ctx(ctx), Diags(diags), LangInfo(lang),
+      PD(pd),
+      CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),Idxer(idxer),
+      AScope(ScopeDecl), MaxNodes(maxnodes), MaxLoop(maxloop),
       VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
-      EagerlyAssume(eager), TrimGraph(trim) {}
+      EagerlyAssume(eager), TrimGraph(trim), InlineCall(inlinecall) {}
   
   ~AnalysisManager() { FlushDiagnostics(); }
   
@@ -72,6 +91,10 @@
     LocCtxMgr.clear();
     AnaCtxMgr.clear();
   }
+  
+  AnalysisContextManager& getAnalysisContextManager() {
+    return AnaCtxMgr;
+  }
 
   StoreManagerCreator getStoreManagerCreator() {
     return CreateStoreMgr;
@@ -81,6 +104,8 @@
     return CreateConstraintMgr;
   }
 
+  idx::Indexer *getIndexer() const { return Idxer; }
+
   virtual ASTContext &getASTContext() {
     return Ctx;
   }
@@ -108,6 +133,8 @@
 
   unsigned getMaxNodes() const { return MaxNodes; }
 
+  unsigned getMaxLoop() const { return MaxLoop; }
+
   bool shouldVisualizeGraphviz() const { return VisualizeEGDot; }
 
   bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; }
@@ -122,6 +149,12 @@
 
   bool shouldEagerlyAssume() const { return EagerlyAssume; }
 
+  bool shouldInlineCall() const { return InlineCall; }
+
+  bool hasIndexer() const { return Idxer != 0; }
+
+  const AnalysisContext *getAnalysisContextInAnotherTU(const Decl *D);
+
   CFG *getCFG(Decl const *D) {
     return AnaCtxMgr.getContext(D)->getCFG();
   }
@@ -134,9 +167,25 @@
     return AnaCtxMgr.getContext(D)->getParentMap();
   }
 
+  AnalysisContext *getAnalysisContext(const Decl *D) {
+    return AnaCtxMgr.getContext(D);
+  }
+
+  AnalysisContext *getAnalysisContext(const Decl *D, idx::TranslationUnit *TU) {
+    return AnaCtxMgr.getContext(D, TU);
+  }
+
+  const StackFrameContext *getStackFrame(AnalysisContext *Ctx,
+                                         LocationContext const *Parent,
+                                         Stmt const *S, const CFGBlock *Blk,
+                                         unsigned Idx) {
+    return LocCtxMgr.getStackFrame(Ctx, Parent, S, Blk, Idx);
+  }
+
   // Get the top level stack frame.
-  const StackFrameContext *getStackFrame(Decl const *D) {
-    return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), 0, 0, 0, 0);
+  const StackFrameContext *getStackFrame(Decl const *D, 
+                                         idx::TranslationUnit *TU) {
+    return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D, TU), 0, 0, 0, 0);
   }
 
   // Get a stack frame with parent.
diff --git a/include/clang/Checker/PathSensitive/Checker.h b/include/clang/Checker/PathSensitive/Checker.h
index 8cb9cc8..af28fc3 100644
--- a/include/clang/Checker/PathSensitive/Checker.h
+++ b/include/clang/Checker/PathSensitive/Checker.h
@@ -36,18 +36,21 @@
   const GRState *ST;
   const Stmt *statement;
   const unsigned size;
-  bool DoneEvaluating; // FIXME: This is not a permanent API change.
+public:
+  bool *respondsToCallback;
 public:
   CheckerContext(ExplodedNodeSet &dst, GRStmtNodeBuilder &builder,
                  GRExprEngine &eng, ExplodedNode *pred,
                  const void *tag, ProgramPoint::Kind K,
+                 bool *respondsToCB = 0,
                  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()) {}
+      ST(st), statement(stmt), size(Dst.size()),
+      respondsToCallback(respondsToCB) {}
 
   ~CheckerContext();
 
@@ -144,6 +147,7 @@
     // 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)))
+      // state is new or equals to ST.
       GenerateNode(state, true);
     else
       Dst.Add(Pred);
@@ -161,6 +165,10 @@
     Eng.getBugReporter().EmitReport(R);
   }
 
+  AnalysisContext *getCurrentAnalysisContext() const {
+    return Pred->getLocationContext()->getAnalysisContext();
+  }
+
 private:
   ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state,
                              bool markAsSink) {
@@ -188,10 +196,11 @@
                 GRStmtNodeBuilder &Builder,
                 GRExprEngine &Eng,
                 const Stmt *S,
-                ExplodedNode *Pred, void *tag, bool isPrevisit) {
+                ExplodedNode *Pred, void *tag, bool isPrevisit,
+                bool& respondsToCallback) {
     CheckerContext C(Dst, Builder, Eng, Pred, tag,
                      isPrevisit ? ProgramPoint::PreStmtKind :
-                     ProgramPoint::PostStmtKind, S);
+                     ProgramPoint::PostStmtKind, &respondsToCallback, S);
     if (isPrevisit)
       _PreVisit(C, S);
     else
@@ -202,7 +211,7 @@
                           GRExprEngine &Eng, const ObjCMessageExpr *ME,
                           ExplodedNode *Pred, const GRState *state, void *tag) {
     CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
-                     ME, state);
+                     0, ME, state);
     return EvalNilReceiver(C, ME);
   }
 
@@ -210,7 +219,7 @@
                        GRExprEngine &Eng, const CallExpr *CE,
                        ExplodedNode *Pred, void *tag) {
     CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
-                     CE);
+                     0, CE);
     return EvalCallExpr(C, CE);
   }
 
@@ -223,7 +232,7 @@
                     bool isPrevisit) {
     CheckerContext C(Dst, Builder, Eng, Pred, tag,
                      isPrevisit ? ProgramPoint::PreStmtKind :
-                     ProgramPoint::PostStmtKind, StoreE);
+                     ProgramPoint::PostStmtKind, 0, StoreE);
     assert(isPrevisit && "Only previsit supported for now.");
     PreVisitBind(C, AssignE, StoreE, location, val);
   }
@@ -238,7 +247,7 @@
                         void *tag, bool isLoad) {
     CheckerContext C(Dst, Builder, Eng, Pred, tag,
                      isLoad ? ProgramPoint::PreLoadKind :
-                     ProgramPoint::PreStoreKind, S, state);
+                     ProgramPoint::PreStoreKind, 0, S, state);
     VisitLocation(C, S, location);
   }
 
@@ -246,8 +255,8 @@
                           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);
+                     ProgramPoint::PostPurgeDeadSymbolsKind, 0, S);
+    EvalDeadSymbols(C, SymReaper);
   }
 
 public:
@@ -257,14 +266,15 @@
   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 EvalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper) {}
   virtual void EvalEndPath(GREndPathNodeBuilder &B, void *tag,
                            GRExprEngine &Eng) {}
 
+  virtual void MarkLiveSymbols(const GRState *state, SymbolReaper &SymReaper) {}
+
   virtual void VisitBranchCondition(GRBranchNodeBuilder &Builder,
                                     GRExprEngine &Eng,
-                                    Stmt *Condition, void *tag) {}
+                                    const Stmt *Condition, void *tag) {}
 
   virtual bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME) {
     return false;
@@ -275,9 +285,23 @@
   }
 
   virtual const GRState *EvalAssume(const GRState *state, SVal Cond, 
-                                    bool Assumption) {
+                                    bool Assumption, bool *respondsToCallback) {
+    *respondsToCallback = false;
     return state;
   }
+
+  virtual bool WantsRegionChangeUpdate(const GRState *state) { return false; }
+
+  virtual const GRState *EvalRegionChanges(const GRState *state,
+                                           const MemRegion * const *Begin,
+                                           const MemRegion * const *End,
+                                           bool *respondsToCallback) {
+    *respondsToCallback = false;
+    return state;
+  }
+
+  virtual void VisitEndAnalysis(ExplodedGraph &G, BugReporter &B,
+                                GRExprEngine &Eng) {}
 };
 } // end clang namespace
 
diff --git a/include/clang/Checker/PathSensitive/CheckerHelpers.h b/include/clang/Checker/PathSensitive/CheckerHelpers.h
new file mode 100644
index 0000000..ea3c842
--- /dev/null
+++ b/include/clang/Checker/PathSensitive/CheckerHelpers.h
@@ -0,0 +1,40 @@
+//== CheckerHelpers.h - Helper functions 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_CHECKER_PATHSENSITIVE_CHECKERHELPERS
+#define LLVM_CLANG_CHECKER_PATHSENSITIVE_CHECKERHELPERS
+
+#include "clang/AST/Stmt.h"
+
+namespace clang {
+
+bool containsMacro(const Stmt *S);
+bool containsEnum(const Stmt *S);
+bool containsStaticLocal(const Stmt *S);
+bool containsBuiltinOffsetOf(const Stmt *S);
+template <class T> bool containsStmt(const Stmt *S) {
+  if (isa<T>(S))
+      return true;
+
+  for (Stmt::const_child_iterator I = S->child_begin(); I != S->child_end();
+      ++I)
+    if (const Stmt *child = *I)
+      if (containsStmt<T>(child))
+        return true;
+
+  return false;
+}
+
+}
+
+#endif
diff --git a/include/clang/Checker/PathSensitive/CheckerVisitor.h b/include/clang/Checker/PathSensitive/CheckerVisitor.h
index 72f0ae1..e2ba89b 100644
--- a/include/clang/Checker/PathSensitive/CheckerVisitor.h
+++ b/include/clang/Checker/PathSensitive/CheckerVisitor.h
@@ -79,8 +79,13 @@
     }
   }
 
-  void PreVisitStmt(CheckerContext &C, const Stmt *S) {}
-  void PostVisitStmt(CheckerContext &C, const Stmt *S) {}
+  void PreVisitStmt(CheckerContext &C, const Stmt *S) {
+    *C.respondsToCallback = false;
+  }
+
+  void PostVisitStmt(CheckerContext &C, const Stmt *S) {
+    *C.respondsToCallback = false;
+  }
 
   void PreVisitCastExpr(CheckerContext &C, const CastExpr *E) {
     static_cast<ImplClass*>(this)->PreVisitStmt(C, E);
diff --git a/include/clang/Checker/PathSensitive/ConstraintManager.h b/include/clang/Checker/PathSensitive/ConstraintManager.h
index ce7d1b3..97535f5 100644
--- a/include/clang/Checker/PathSensitive/ConstraintManager.h
+++ b/include/clang/Checker/PathSensitive/ConstraintManager.h
@@ -34,9 +34,6 @@
   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),
diff --git a/include/clang/Checker/PathSensitive/Environment.h b/include/clang/Checker/PathSensitive/Environment.h
index b9bbebc..2981731 100644
--- a/include/clang/Checker/PathSensitive/Environment.h
+++ b/include/clang/Checker/PathSensitive/Environment.h
@@ -86,7 +86,7 @@
   Environment BindExpr(Environment Env, const Stmt *S, SVal V,
                        bool Invalidate);
 
-  Environment RemoveDeadBindings(Environment Env, const Stmt *S,
+  Environment RemoveDeadBindings(Environment Env,
                                  SymbolReaper &SymReaper, const GRState *ST,
                           llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
 };
diff --git a/include/clang/Checker/PathSensitive/ExplodedGraph.h b/include/clang/Checker/PathSensitive/ExplodedGraph.h
index c09c893..c875a23 100644
--- a/include/clang/Checker/PathSensitive/ExplodedGraph.h
+++ b/include/clang/Checker/PathSensitive/ExplodedGraph.h
@@ -36,7 +36,6 @@
 
 class GRState;
 class CFG;
-class ASTContext;
 class ExplodedGraph;
 
 //===----------------------------------------------------------------------===//
@@ -240,9 +239,6 @@
   /// and successor groups.
   BumpVectorContext BVC;
 
-  /// Ctx - The ASTContext used to "interpret" CodeDecl.
-  ASTContext& Ctx;
-
   /// NumNodes - The number of nodes in the graph.
   unsigned NumNodes;
 
@@ -256,7 +252,7 @@
                         bool* IsNew = 0);
 
   ExplodedGraph* MakeEmptyGraph() const {
-    return new ExplodedGraph(Ctx);
+    return new ExplodedGraph();
   }
 
   /// addRoot - Add an untyped node to the set of roots.
@@ -271,7 +267,7 @@
     return V;
   }
 
-  ExplodedGraph(ASTContext& ctx) : Ctx(ctx), NumNodes(0) {}
+  ExplodedGraph() : NumNodes(0) {}
 
   ~ExplodedGraph() {}
 
@@ -318,8 +314,6 @@
   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*>
diff --git a/include/clang/Checker/PathSensitive/GRCoreEngine.h b/include/clang/Checker/PathSensitive/GRCoreEngine.h
index 2d8afee..216ecac 100644
--- a/include/clang/Checker/PathSensitive/GRCoreEngine.h
+++ b/include/clang/Checker/PathSensitive/GRCoreEngine.h
@@ -43,6 +43,11 @@
   friend class GRCallEnterNodeBuilder;
   friend class GRCallExitNodeBuilder;
 
+public:
+  typedef std::vector<std::pair<BlockEdge, const ExplodedNode*> >
+            BlocksAborted;
+private:
+
   GRSubEngine& SubEngine;
 
   /// G - The simulation graph.  Each node is a (location,state) pair.
@@ -58,16 +63,20 @@
   ///   number of times different CFGBlocks have been visited along a path.
   GRBlockCounter::Factory BCounterFactory;
 
+  /// The locations where we stopped doing work because we visited a location
+  ///  too many times.
+  BlocksAborted blocksAborted;
+
   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,
+  void HandleBlockExit(const CFGBlock* B, ExplodedNode* Pred);
+  void HandlePostStmt(const PostStmt& S, const CFGBlock* B,
                       unsigned StmtIdx, ExplodedNode *Pred);
 
-  void HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock* B,
+  void HandleBranch(const Stmt* Cond, const Stmt* Term, const CFGBlock* B,
                     ExplodedNode* Pred);
   void HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
                        unsigned Index, ExplodedNode *Pred);
@@ -78,25 +87,42 @@
     return SubEngine.getInitialState(InitLoc);
   }
 
-  void ProcessEndPath(GREndPathNodeBuilder& Builder);
+  void ProcessEndPath(GREndPathNodeBuilder& Builder) {
+    SubEngine.ProcessEndPath(Builder);
+  }
 
-  void ProcessStmt(CFGElement E, GRStmtNodeBuilder& Builder);
+  void ProcessStmt(const CFGElement E, GRStmtNodeBuilder& Builder) {
+    SubEngine.ProcessStmt(E, Builder);
+  }
 
-  bool ProcessBlockEntrance(CFGBlock* Blk, const ExplodedNode *Pred,
-                            GRBlockCounter BC);
+  bool ProcessBlockEntrance(const CFGBlock* Blk, const ExplodedNode *Pred,
+                            GRBlockCounter BC) {
+    return SubEngine.ProcessBlockEntrance(Blk, Pred, BC);
+  }
 
 
-  void ProcessBranch(Stmt* Condition, Stmt* Terminator,
-                     GRBranchNodeBuilder& Builder);
+  void ProcessBranch(const Stmt* Condition, const Stmt* Terminator,
+                     GRBranchNodeBuilder& Builder) {
+    SubEngine.ProcessBranch(Condition, Terminator, Builder);
+  }
 
 
-  void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& Builder);
+  void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& Builder) {
+    SubEngine.ProcessIndirectGoto(Builder);
+  }
 
 
-  void ProcessSwitch(GRSwitchNodeBuilder& Builder);
+  void ProcessSwitch(GRSwitchNodeBuilder& Builder) {
+    SubEngine.ProcessSwitch(Builder);
+  }
 
-  void ProcessCallEnter(GRCallEnterNodeBuilder &Builder);
-  void ProcessCallExit(GRCallExitNodeBuilder &Builder);
+  void ProcessCallEnter(GRCallEnterNodeBuilder &Builder) {
+    SubEngine.ProcessCallEnter(Builder);
+  }
+
+  void ProcessCallExit(GRCallExitNodeBuilder &Builder) {
+    SubEngine.ProcessCallExit(Builder);
+  }
 
 private:
   GRCoreEngine(const GRCoreEngine&); // Do not implement.
@@ -105,16 +131,16 @@
 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)),
+  GRCoreEngine(GRSubEngine& subengine)
+    : SubEngine(subengine), G(new ExplodedGraph()),
       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),
+  GRCoreEngine(GRWorkList* wlist, GRSubEngine& subengine)
+    : SubEngine(subengine), G(new ExplodedGraph()), WList(wlist),
       BCounterFactory(G->getAllocator()) {}
 
   ~GRCoreEngine() {
@@ -130,12 +156,29 @@
 
   /// 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);
+  bool ExecuteWorkList(const LocationContext *L, unsigned Steps,
+                       const GRState *InitState);
+  void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
+                                       const GRState *InitState, 
+                                       ExplodedNodeSet &Dst);
+
+  // Functions for external checking of whether we have unfinished work
+  bool wasBlockAborted() const { return !blocksAborted.empty(); }
+  bool hasWorkRemaining() const { return wasBlockAborted() || WList->hasWork(); }
+
+  GRWorkList *getWorkList() const { return WList; }
+
+  BlocksAborted::const_iterator blocks_aborted_begin() const {
+    return blocksAborted.begin();
+  }
+  BlocksAborted::const_iterator blocks_aborted_end() const {
+    return blocksAborted.end();
+  }
 };
 
 class GRStmtNodeBuilder {
   GRCoreEngine& Eng;
-  CFGBlock& B;
+  const CFGBlock& B;
   const unsigned Idx;
   ExplodedNode* Pred;
   GRStateManager& Mgr;
@@ -157,7 +200,7 @@
   void GenerateAutoTransition(ExplodedNode* N);
 
 public:
-  GRStmtNodeBuilder(CFGBlock* b, unsigned idx, ExplodedNode* N,
+  GRStmtNodeBuilder(const CFGBlock* b, unsigned idx, ExplodedNode* N,
                     GRCoreEngine* e, GRStateManager &mgr);
 
   ~GRStmtNodeBuilder();
@@ -216,11 +259,11 @@
 
   /// getStmt - Return the current block-level expression associated with
   ///  this builder.
-  Stmt* getStmt() const { return B[Idx]; }
+  const Stmt* getStmt() const { return B[Idx]; }
 
   /// getBlock - Return the CFGBlock associated with the block-level expression
   ///  of this builder.
-  CFGBlock* getBlock() const { return &B; }
+  const CFGBlock* getBlock() const { return &B; }
 
   unsigned getIndex() const { return Idx; }
 
@@ -233,15 +276,15 @@
       return Pred->getState();
   }
 
-  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred,
-                   const GRState* St) {
+  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S, 
+                         ExplodedNode* Pred, const GRState* St) {
     return MakeNode(Dst, S, Pred, St, PointKind);
   }
 
-  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred,
+  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S,ExplodedNode* Pred,
                          const GRState* St, ProgramPoint::Kind K);
 
-  ExplodedNode* MakeSinkNode(ExplodedNodeSet& Dst, Stmt* S,
+  ExplodedNode* MakeSinkNode(ExplodedNodeSet& Dst, const Stmt* S,
                        ExplodedNode* Pred, const GRState* St) {
     bool Tmp = BuildSinks;
     BuildSinks = true;
@@ -253,9 +296,9 @@
 
 class GRBranchNodeBuilder {
   GRCoreEngine& Eng;
-  CFGBlock* Src;
-  CFGBlock* DstT;
-  CFGBlock* DstF;
+  const CFGBlock* Src;
+  const CFGBlock* DstT;
+  const CFGBlock* DstF;
   ExplodedNode* Pred;
 
   typedef llvm::SmallVector<ExplodedNode*,3> DeferredTy;
@@ -267,8 +310,8 @@
   bool InFeasibleFalse;
 
 public:
-  GRBranchNodeBuilder(CFGBlock* src, CFGBlock* dstT, CFGBlock* dstF,
-                          ExplodedNode* pred, GRCoreEngine* e)
+  GRBranchNodeBuilder(const CFGBlock* src, const CFGBlock* dstT, 
+                      const CFGBlock* dstF, ExplodedNode* pred, GRCoreEngine* e)
   : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred),
     GeneratedTrue(false), GeneratedFalse(false),
     InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
@@ -283,7 +326,7 @@
 
   ExplodedNode* generateNode(const GRState* State, bool branch);
 
-  CFGBlock* getTargetBlock(bool branch) const {
+  const CFGBlock* getTargetBlock(bool branch) const {
     return branch ? DstT : DstF;
   }
 
@@ -305,31 +348,31 @@
 
 class GRIndirectGotoNodeBuilder {
   GRCoreEngine& Eng;
-  CFGBlock* Src;
-  CFGBlock& DispatchBlock;
-  Expr* E;
+  const CFGBlock* Src;
+  const CFGBlock& DispatchBlock;
+  const 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) {}
+  GRIndirectGotoNodeBuilder(ExplodedNode* pred, const CFGBlock* src, 
+                    const Expr* e, const CFGBlock* dispatch, GRCoreEngine* eng)
+    : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
 
   class iterator {
-    CFGBlock::succ_iterator I;
+    CFGBlock::const_succ_iterator I;
 
     friend class GRIndirectGotoNodeBuilder;
-    iterator(CFGBlock::succ_iterator i) : I(i) {}
+    iterator(CFGBlock::const_succ_iterator i) : I(i) {}
   public:
 
     iterator& operator++() { ++I; return *this; }
     bool operator!=(const iterator& X) const { return I != X.I; }
 
-    LabelStmt* getLabel() const {
+    const LabelStmt* getLabel() const {
       return llvm::cast<LabelStmt>((*I)->getLabel());
     }
 
-    CFGBlock*  getBlock() const {
+    const CFGBlock*  getBlock() const {
       return *I;
     }
   };
@@ -340,37 +383,38 @@
   ExplodedNode* generateNode(const iterator& I, const GRState* State,
                              bool isSink = false);
 
-  Expr* getTarget() const { return E; }
+  const Expr* getTarget() const { return E; }
 
   const GRState* getState() const { return Pred->State; }
 };
 
 class GRSwitchNodeBuilder {
   GRCoreEngine& Eng;
-  CFGBlock* Src;
-  Expr* Condition;
+  const CFGBlock* Src;
+  const Expr* Condition;
   ExplodedNode* Pred;
 
 public:
-  GRSwitchNodeBuilder(ExplodedNode* pred, CFGBlock* src,
-                      Expr* condition, GRCoreEngine* eng)
+  GRSwitchNodeBuilder(ExplodedNode* pred, const CFGBlock* src,
+                      const Expr* condition, GRCoreEngine* eng)
   : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
 
   class iterator {
-    CFGBlock::succ_reverse_iterator I;
+    CFGBlock::const_succ_reverse_iterator I;
 
     friend class GRSwitchNodeBuilder;
-    iterator(CFGBlock::succ_reverse_iterator i) : I(i) {}
+    iterator(CFGBlock::const_succ_reverse_iterator i) : I(i) {}
 
   public:
     iterator& operator++() { ++I; return *this; }
-    bool operator!=(const iterator& X) const { return I != X.I; }
+    bool operator!=(const iterator &X) const { return I != X.I; }
+    bool operator==(const iterator &X) const { return I == X.I; }
 
-    CaseStmt* getCase() const {
+    const CaseStmt* getCase() const {
       return llvm::cast<CaseStmt>((*I)->getLabel());
     }
 
-    CFGBlock* getBlock() const {
+    const CFGBlock* getBlock() const {
       return *I;
     }
   };
@@ -383,21 +427,21 @@
   ExplodedNode* generateDefaultCaseNode(const GRState* State,
                                         bool isSink = false);
 
-  Expr* getCondition() const { return Condition; }
+  const Expr* getCondition() const { return Condition; }
 
   const GRState* getState() const { return Pred->State; }
 };
 
 class GREndPathNodeBuilder {
   GRCoreEngine &Eng;
-  CFGBlock& B;
+  const CFGBlock& B;
   ExplodedNode* Pred;
 
 public:
   bool HasGeneratedNode;
 
 public:
-  GREndPathNodeBuilder(CFGBlock* b, ExplodedNode* N, GRCoreEngine* e)
+  GREndPathNodeBuilder(const CFGBlock* b, ExplodedNode* N, GRCoreEngine* e)
     : Eng(*e), B(*b), Pred(N), HasGeneratedNode(false) {}
 
   ~GREndPathNodeBuilder();
@@ -421,7 +465,7 @@
 
   void GenerateCallExitNode(const GRState *state);
 
-  CFGBlock* getBlock() const { return &B; }
+  const CFGBlock* getBlock() const { return &B; }
 
   const GRState* getState() const {
     return getPredecessor()->getState();
@@ -436,8 +480,8 @@
   // The call site.
   const Stmt *CE;
 
-  // The definition of callee.
-  const FunctionDecl *FD;
+  // The AnalysisContext of the callee.
+  AnalysisContext *CalleeCtx;
 
   // The parent block of the CallExpr.
   const CFGBlock *Block;
@@ -447,9 +491,9 @@
 
 public:
   GRCallEnterNodeBuilder(GRCoreEngine &eng, const ExplodedNode *pred, 
-                         const Stmt *s, const FunctionDecl *fd, 
+                         const Stmt *s, AnalysisContext *callee, 
                          const CFGBlock *blk, unsigned idx)
-    : Eng(eng), Pred(pred), CE(s), FD(fd), Block(blk), Index(idx) {}
+    : Eng(eng), Pred(pred), CE(s), CalleeCtx(callee), Block(blk), Index(idx) {}
 
   const GRState *getState() const { return Pred->getState(); }
 
@@ -459,7 +503,7 @@
 
   const Stmt *getCallExpr() const { return CE; }
 
-  const FunctionDecl *getCallee() const { return FD; }
+  AnalysisContext *getCalleeContext() const { return CalleeCtx; }
 
   const CFGBlock *getBlock() const { return Block; }
 
diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h
index 85c2a69..55dab2a 100644
--- a/include/clang/Checker/PathSensitive/GRExprEngine.h
+++ b/include/clang/Checker/PathSensitive/GRExprEngine.h
@@ -16,6 +16,7 @@
 #ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE
 #define LLVM_CLANG_ANALYSIS_GREXPRENGINE
 
+#include "clang/Checker/PathSensitive/AnalysisManager.h"
 #include "clang/Checker/PathSensitive/GRSubEngine.h"
 #include "clang/Checker/PathSensitive/GRCoreEngine.h"
 #include "clang/Checker/PathSensitive/GRState.h"
@@ -63,7 +64,7 @@
   const GRState* CleanedState;
 
   /// CurrentStmt - The current block-level statement.
-  Stmt* CurrentStmt;
+  const Stmt* CurrentStmt;
 
   // Obj-C Class Identifiers.
   IdentifierInfo* NSExceptionII;
@@ -74,25 +75,52 @@
 
   llvm::OwningPtr<GRSimpleAPICheck> BatchAuditor;
 
+  enum CallbackKind {
+    PreVisitStmtCallback,
+    PostVisitStmtCallback,
+    ProcessAssumeCallback,
+    EvalRegionChangesCallback
+  };
+
+  typedef uint32_t CallbackTag;
+
+  /// GetCallbackTag - Create a tag for a certain kind of callback. The 'Sub'
+  ///  argument can be used to differentiate callbacks that depend on another
+  ///  value from a small set of possibilities, such as statement classes.
+  static inline CallbackTag GetCallbackTag(CallbackKind K, uint32_t Sub = 0) {
+    assert(Sub == ((Sub << 8) >> 8) && "Tag sub-kind must fit into 24 bits");
+    return K | (Sub << 8);
+  }
+
   typedef llvm::DenseMap<void *, unsigned> CheckerMap;
-  CheckerMap CheckerM;
-  
   typedef std::vector<std::pair<void *, Checker*> > CheckersOrdered;
+  typedef llvm::DenseMap<CallbackTag, CheckersOrdered *> CheckersOrderedCache;
+  
+  /// A registration map from checker tag to the index into the
+  ///  ordered checkers vector.
+  CheckerMap CheckerM;
+
+  /// An ordered vector of checkers that are called when evaluating
+  ///  various expressions and statements.
   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.
+  /// A map used for caching the checkers that respond to the callback for
+  ///  a particular callback tag.
+  CheckersOrderedCache COCache;
+
+  /// 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;
+    CallExpr::const_arg_iterator I;
     ExplodedNode *N;
 
-    CallExprWLItem(const CallExpr::arg_iterator &i, ExplodedNode *n)
+    CallExprWLItem(const CallExpr::const_arg_iterator &i, ExplodedNode *n)
       : I(i), N(n) {}
   };
 
@@ -102,13 +130,22 @@
   ~GRExprEngine();
 
   void ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
-    CoreEngine.ExecuteWorkList(L, Steps);
+    CoreEngine.ExecuteWorkList(L, Steps, 0);
+  }
+
+  /// Execute the work list with an initial state. Nodes that reaches the exit
+  /// of the function are added into the Dst set, which represent the exit
+  /// state of the function call.
+  void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
+                                       const GRState *InitState, 
+                                       ExplodedNodeSet &Dst) {
+    CoreEngine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst);
   }
 
   /// getContext - Return the ASTContext associated with this analysis.
-  ASTContext& getContext() const { return G.getContext(); }
+  ASTContext& getContext() const { return AMgr.getASTContext(); }
 
-  AnalysisManager &getAnalysisManager() const { return AMgr; }
+  virtual AnalysisManager &getAnalysisManager() { return AMgr; }
 
   SValuator &getSValuator() { return SVator; }
 
@@ -154,17 +191,18 @@
 
   /// 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);
+  void ProcessStmt(const 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,
+  bool ProcessBlockEntrance(const 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);
+  void ProcessBranch(const Stmt* Condition, const Stmt* Term, 
+                     GRBranchNodeBuilder& builder);
 
   /// ProcessIndirectGoto - Called by GRCoreEngine.  Used to generate successor
   ///  nodes by processing the 'effects' of a computed goto jump.
@@ -178,18 +216,30 @@
   ///  nodes when the control reaches the end of a function.
   void ProcessEndPath(GREndPathNodeBuilder& builder);
 
-  // Generate the entry node of the callee.
+  /// Generate the entry node of the callee.
   void ProcessCallEnter(GRCallEnterNodeBuilder &builder);
 
-  // Generate the first post callsite node.
+  /// Generate the first post callsite node.
   void ProcessCallExit(GRCallExitNodeBuilder &builder);
 
+  /// Called by GRCoreEngine when the analysis worklist has terminated.
+  void ProcessEndWorklist(bool hasWorkRemaining);
+
   /// EvalAssume - Callback function invoked by the ConstraintManager when
   ///  making assumptions about state values.
-  const GRState *ProcessAssume(const GRState *state, SVal cond, bool assumption);
+  const GRState *ProcessAssume(const GRState *state, SVal cond,bool assumption);
 
-  GRStateManager& getStateManager() { return StateMgr; }
-  const GRStateManager& getStateManager() const { return StateMgr; }
+  /// WantsRegionChangeUpdate - Called by GRStateManager to determine if a
+  ///  region change should trigger a ProcessRegionChanges update.
+  bool WantsRegionChangeUpdate(const GRState* state);
+
+  /// ProcessRegionChanges - Called by GRStateManager whenever a change is made
+  ///  to the store. Used to update checkers that track region values.
+  const GRState* ProcessRegionChanges(const GRState *state,
+                                      const MemRegion * const *Begin,
+                                      const MemRegion * const *End);
+
+  virtual GRStateManager& getStateManager() { return StateMgr; }
 
   StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
 
@@ -212,21 +262,29 @@
   SymbolManager& getSymbolManager() { return SymMgr; }
   const SymbolManager& getSymbolManager() const { return SymMgr; }
 
+  // Functions for external checking of whether we have unfinished work
+  bool wasBlockAborted() const { return CoreEngine.wasBlockAborted(); }
+  bool hasWorkRemaining() const {
+    return wasBlockAborted() || CoreEngine.getWorkList()->hasWork();
+  }
+
+  const GRCoreEngine &getCoreEngine() const { return CoreEngine; }
+
 protected:
   const GRState* GetState(ExplodedNode* N) {
     return N == EntryNode ? CleanedState : N->getState();
   }
 
 public:
-  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred, 
-                         const GRState* St,
+  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const 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);
+  void CheckerVisit(const Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 
+                    CallbackKind Kind);
 
   bool CheckerEvalCall(const CallExpr *CE, 
                        ExplodedNodeSet &Dst, 
@@ -244,114 +302,124 @@
 
   /// 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);
+  void Visit(const 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);
+  void VisitLValue(const Expr* Ex, ExplodedNode* Pred, ExplodedNodeSet& Dst);
 
   /// VisitArraySubscriptExpr - Transfer function for array accesses.
-  void VisitArraySubscriptExpr(ArraySubscriptExpr* Ex, ExplodedNode* Pred,
+  void VisitArraySubscriptExpr(const ArraySubscriptExpr* Ex, ExplodedNode* Pred,
                                ExplodedNodeSet& Dst, bool asLValue);
 
   /// VisitAsmStmt - Transfer function logic for inline asm.
-  void VisitAsmStmt(AsmStmt* A, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+  void VisitAsmStmt(const AsmStmt* A, ExplodedNode* Pred, ExplodedNodeSet& Dst);
 
-  void VisitAsmStmtHelperOutputs(AsmStmt* A,
-                                 AsmStmt::outputs_iterator I,
-                                 AsmStmt::outputs_iterator E,
+  void VisitAsmStmtHelperOutputs(const AsmStmt* A,
+                                 AsmStmt::const_outputs_iterator I,
+                                 AsmStmt::const_outputs_iterator E,
                                  ExplodedNode* Pred, ExplodedNodeSet& Dst);
 
-  void VisitAsmStmtHelperInputs(AsmStmt* A,
-                                AsmStmt::inputs_iterator I,
-                                AsmStmt::inputs_iterator E,
+  void VisitAsmStmtHelperInputs(const AsmStmt* A,
+                                AsmStmt::const_inputs_iterator I,
+                                AsmStmt::const_inputs_iterator E,
                                 ExplodedNode* Pred, ExplodedNodeSet& Dst);
   
   /// VisitBlockExpr - Transfer function logic for BlockExprs.
-  void VisitBlockExpr(BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst);
+  void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, 
+                      ExplodedNodeSet &Dst);
 
   /// VisitBinaryOperator - Transfer function logic for binary operators.
-  void VisitBinaryOperator(BinaryOperator* B, ExplodedNode* Pred, 
+  void VisitBinaryOperator(const 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,
+  void VisitCall(const CallExpr* CE, ExplodedNode* Pred,
+                 CallExpr::const_arg_iterator AI, 
+                 CallExpr::const_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,
+  void VisitCast(const CastExpr *CastE, const 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);
+  void VisitCompoundLiteralExpr(const CompoundLiteralExpr* CL, 
+                                ExplodedNode* Pred, ExplodedNodeSet& Dst, 
+                                bool asLValue);
 
   /// VisitDeclRefExpr - Transfer function logic for DeclRefExprs.
-  void VisitDeclRefExpr(DeclRefExpr* DR, ExplodedNode* Pred,
+  void VisitDeclRefExpr(const DeclRefExpr* DR, ExplodedNode* Pred,
                         ExplodedNodeSet& Dst, bool asLValue);
 
   /// VisitBlockDeclRefExpr - Transfer function logic for BlockDeclRefExprs.
-  void VisitBlockDeclRefExpr(BlockDeclRefExpr* DR, ExplodedNode* Pred,
+  void VisitBlockDeclRefExpr(const BlockDeclRefExpr* DR, ExplodedNode* Pred,
                              ExplodedNodeSet& Dst, bool asLValue);
   
-  void VisitCommonDeclRefExpr(Expr* DR, const NamedDecl *D,ExplodedNode* Pred,
-                             ExplodedNodeSet& Dst, bool asLValue);  
+  void VisitCommonDeclRefExpr(const 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);
+  void VisitDeclStmt(const 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);
+  void VisitGuardedExpr(const Expr* Ex, const Expr* L, const 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,
+  void VisitCondInit(const VarDecl *VD, const Stmt *S, ExplodedNode *Pred,
                      ExplodedNodeSet& Dst);
   
-  void VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
+  void VisitInitListExpr(const InitListExpr* E, ExplodedNode* Pred,
                          ExplodedNodeSet& Dst);
 
   /// VisitLogicalExpr - Transfer function logic for '&&', '||'
-  void VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
+  void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode* Pred,
                         ExplodedNodeSet& Dst);
 
   /// VisitMemberExpr - Transfer function for member expressions.
-  void VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred, ExplodedNodeSet& Dst,
-                       bool asLValue);
+  void VisitMemberExpr(const MemberExpr* M, ExplodedNode* Pred, 
+                       ExplodedNodeSet& Dst, bool asLValue);
 
   /// VisitObjCIvarRefExpr - Transfer function logic for ObjCIvarRefExprs.
-  void VisitObjCIvarRefExpr(ObjCIvarRefExpr* DR, ExplodedNode* Pred,
+  void VisitObjCIvarRefExpr(const ObjCIvarRefExpr* DR, ExplodedNode* Pred,
                             ExplodedNodeSet& Dst, bool asLValue);
 
   /// VisitObjCForCollectionStmt - Transfer function logic for
   ///  ObjCForCollectionStmt.
-  void VisitObjCForCollectionStmt(ObjCForCollectionStmt* S, ExplodedNode* Pred,
-                                  ExplodedNodeSet& Dst);
+  void VisitObjCForCollectionStmt(const ObjCForCollectionStmt* S, 
+                                  ExplodedNode* Pred, ExplodedNodeSet& Dst);
 
-  void VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S, 
+  void VisitObjCForCollectionStmtAux(const ObjCForCollectionStmt* S, 
                                      ExplodedNode* Pred,
                                      ExplodedNodeSet& Dst, SVal ElementV);
 
   /// VisitObjCMessageExpr - Transfer function for ObjC message expressions.
-  void VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred, 
+  void VisitObjCMessageExpr(const ObjCMessageExpr* ME, ExplodedNode* Pred, 
                             ExplodedNodeSet& Dst, bool asLValue);
 
   /// VisitReturnStmt - Transfer function logic for return statements.
-  void VisitReturnStmt(ReturnStmt* R, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+  void VisitReturnStmt(const ReturnStmt* R, ExplodedNode* Pred, 
+                       ExplodedNodeSet& Dst);
+  
+  /// VisitOffsetOfExpr - Transfer function for offsetof.
+  void VisitOffsetOfExpr(const OffsetOfExpr* Ex, ExplodedNode* Pred,
+                         ExplodedNodeSet& Dst);
 
   /// VisitSizeOfAlignOfExpr - Transfer function for sizeof.
-  void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex, ExplodedNode* Pred,
+  void VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr* Ex, ExplodedNode* Pred,
                               ExplodedNodeSet& Dst);
 
   /// VisitUnaryOperator - Transfer function logic for unary operators.
-  void VisitUnaryOperator(UnaryOperator* B, ExplodedNode* Pred, 
+  void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode* Pred, 
                           ExplodedNodeSet& Dst, bool asLValue);
 
-  void VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred, 
+  void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 
                         ExplodedNodeSet & Dst);
   
   void VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
@@ -361,17 +429,17 @@
   void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred,
                               ExplodedNodeSet &Dst);
 
-  void VisitCXXNewExpr(CXXNewExpr *CNE, ExplodedNode *Pred,
+  void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
                        ExplodedNodeSet &Dst);
 
-  void VisitCXXDeleteExpr(CXXDeleteExpr *CDE, ExplodedNode *Pred,
+  void VisitCXXDeleteExpr(const 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, 
+  void CreateCXXTemporaryObject(const Expr *Ex, ExplodedNode *Pred, 
                                 ExplodedNodeSet &Dst);
 
   /// Synthesize CXXThisRegion.
@@ -379,14 +447,15 @@
                                         const StackFrameContext *SFC);
 
   /// Evaluate arguments with a work list algorithm.
-  void EvalArguments(ExprIterator AI, ExprIterator AE,
+  void EvalArguments(ConstExprIterator AI, ConstExprIterator 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);
+  void EvalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src, 
+                         const Expr *Ex);
 
   SVal EvalMinus(SVal X) {
     return X.isValid() ? SVator.EvalMinus(cast<NonLoc>(X)) : X;
@@ -414,44 +483,46 @@
   }
   
 protected:
-  void EvalObjCMessageExpr(ExplodedNodeSet& Dst, ObjCMessageExpr* ME, 
+  void EvalObjCMessageExpr(ExplodedNodeSet& Dst, const 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,
+  const GRState* MarkBranch(const GRState* St, const 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,
+  void EvalBind(ExplodedNodeSet& Dst, const Stmt *AssignE,
+                const 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,
+  void EvalLoad(ExplodedNodeSet& Dst, const 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,
+  void EvalStore(ExplodedNodeSet& Dst, const Expr* AssignE, const Expr* StoreE,
                  ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val,
                  const void *tag = 0);
 private:  
-  void EvalLoadCommon(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
+  void EvalLoadCommon(ExplodedNodeSet& Dst, const 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,
+  void EvalLocation(ExplodedNodeSet &Dst, const Stmt *S, ExplodedNode* Pred,
                     const GRState* St, SVal location,
                     const void *tag, bool isLoad);
+
+  bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred);
 };
 
 } // end clang namespace
diff --git a/include/clang/Checker/PathSensitive/GRState.h b/include/clang/Checker/PathSensitive/GRState.h
index 25ba1f8..984118e 100644
--- a/include/clang/Checker/PathSensitive/GRState.h
+++ b/include/clang/Checker/PathSensitive/GRState.h
@@ -77,6 +77,10 @@
   Store St;
   GenericDataMap   GDM;
 
+  /// 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;
+
 public:
 
   /// This ctor is used when creating the first GRState object.
@@ -134,10 +138,6 @@
     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;
 
@@ -211,16 +211,40 @@
 
   const GRState *bindLoc(SVal location, SVal V) const;
 
+  const GRState *bindDefault(SVal loc, SVal V) const;
+
   const GRState *unbindLoc(Loc LV) const;
 
+  /// InvalidateRegion - Returns the state with bindings for the given region
+  ///  cleared from the store. See InvalidateRegions.
+  const GRState *InvalidateRegion(const MemRegion *R,
+                                  const Expr *E, unsigned BlockCount,
+                                  StoreManager::InvalidatedSymbols *IS = NULL)
+                                  const {
+    return InvalidateRegions(&R, &R+1, E, BlockCount, IS, false);
+  }
+
+  /// InvalidateRegions - Returns the state with bindings for the given regions
+  ///  cleared from the store. The regions are provided as a continuous array
+  ///  from Begin to End. Optionally invalidates global regions as well.
+  const GRState *InvalidateRegions(const MemRegion * const *Begin,
+                                   const MemRegion * const *End,
+                                   const Expr *E, unsigned BlockCount,
+                                   StoreManager::InvalidatedSymbols *IS,
+                                   bool invalidateGlobals) const;
+
+  /// EnterStackFrame - Returns the state for entry to the given stack frame,
+  ///  preserving the current state.
+  const GRState *EnterStackFrame(const StackFrameContext *frame) const;
+
   /// Get the lvalue for a variable reference.
-  SVal getLValue(const VarDecl *D, const LocationContext *LC) const;
+  Loc getLValue(const VarDecl *D, const LocationContext *LC) const;
 
   /// Get the lvalue for a StringLiteral.
-  SVal getLValue(const StringLiteral *literal) const;
+  Loc getLValue(const StringLiteral *literal) const;
 
-  SVal getLValue(const CompoundLiteralExpr *literal,
-                 const LocationContext *LC) const;
+  Loc getLValue(const CompoundLiteralExpr *literal, 
+                const LocationContext *LC) const;
 
   /// Get the lvalue for an ivar reference.
   SVal getLValue(const ObjCIvarDecl *decl, SVal base) const;
@@ -373,6 +397,9 @@
   friend class GRState;
   friend class GRExprEngine; // FIXME: Remove.
 private:
+  /// Eng - The GRSubEngine that owns this state manager.
+  GRSubEngine &Eng;
+
   EnvironmentManager                   EnvMgr;
   llvm::OwningPtr<StoreManager>        StoreMgr;
   llvm::OwningPtr<ConstraintManager>   ConstraintMgr;
@@ -402,7 +429,8 @@
                  ConstraintManagerCreator CreateConstraintManager,
                  llvm::BumpPtrAllocator& alloc,
                  GRSubEngine &subeng)
-    : EnvMgr(alloc),
+    : Eng(subeng),
+      EnvMgr(alloc),
       GDMFactory(alloc),
       ValueMgr(alloc, Ctx, *this),
       Alloc(alloc) {
@@ -445,11 +473,16 @@
 
   StoreManager& getStoreManager() { return *StoreMgr; }
   ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
+  GRSubEngine& getOwningEngine() { return Eng; }
 
-  const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc,
+  const GRState* RemoveDeadBindings(const GRState* St,
                                     const StackFrameContext *LCtx,
                                     SymbolReaper& SymReaper);
 
+  /// Marshal a new state for the callee in another translation unit.
+  /// 'state' is owned by the caller's engine.
+  const GRState *MarshalState(const GRState *state, const StackFrameContext *L);
+
 public:
 
   SVal ArrayToPointer(Loc Array) {
@@ -468,9 +501,6 @@
 
   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.
   //==---------------------------------------------------------------------==//
@@ -582,54 +612,20 @@
                                                      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,
+inline Loc GRState::getLValue(const VarDecl* VD,
                                const LocationContext *LC) const {
   return getStateManager().StoreMgr->getLValueVar(VD, LC);
 }
 
-inline SVal GRState::getLValue(const StringLiteral *literal) const {
+inline Loc GRState::getLValue(const StringLiteral *literal) const {
   return getStateManager().StoreMgr->getLValueString(literal);
 }
 
-inline SVal GRState::getLValue(const CompoundLiteralExpr *literal,
+inline Loc GRState::getLValue(const CompoundLiteralExpr *literal,
                                const LocationContext *LC) const {
   return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC);
 }
diff --git a/include/clang/Checker/PathSensitive/GRSubEngine.h b/include/clang/Checker/PathSensitive/GRSubEngine.h
index d2e7457..1904835 100644
--- a/include/clang/Checker/PathSensitive/GRSubEngine.h
+++ b/include/clang/Checker/PathSensitive/GRSubEngine.h
@@ -17,7 +17,7 @@
 
 namespace clang {
 
-class Stmt;
+class AnalysisManager;
 class CFGBlock;
 class CFGElement;
 class ExplodedNode;
@@ -32,6 +32,8 @@
 class GRCallEnterNodeBuilder;
 class GRCallExitNodeBuilder;
 class LocationContext;
+class MemRegion;
+class Stmt;
 
 class GRSubEngine {
 public:
@@ -39,29 +41,31 @@
 
   virtual const GRState* getInitialState(const LocationContext *InitLoc) = 0;
 
-  virtual GRStateManager& getStateManager() = 0;
+  virtual AnalysisManager &getAnalysisManager() = 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;
+  virtual GRStateManager &getStateManager() = 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,
+  /// Called by GRCoreEngine. Used to generate new successor
+  /// nodes by processing the 'effects' of a block-level statement.
+  virtual void ProcessStmt(const CFGElement E, GRStmtNodeBuilder& builder) = 0;
+
+  /// 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(const CFGBlock* B, const ExplodedNode *Pred,
                                     GRBlockCounter BC) = 0;
 
-  /// ProcessBranch - Called by GRCoreEngine.  Used to generate successor
+  /// Called by GRCoreEngine.  Used to generate successor
   ///  nodes by processing the 'effects' of a branch condition.
-  virtual void ProcessBranch(Stmt* Condition, Stmt* Term,
+  virtual void ProcessBranch(const Stmt* Condition, const Stmt* Term,
                              GRBranchNodeBuilder& builder) = 0;
 
-  /// ProcessIndirectGoto - Called by GRCoreEngine.  Used to generate successor
-  ///  nodes by processing the 'effects' of a computed goto jump.
+  /// 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.
+  /// 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
@@ -73,11 +77,30 @@
 
   // 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.
+
+  /// 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;
+
+  /// WantsRegionChangeUpdate - Called by GRStateManager to determine if a
+  ///  region change should trigger a ProcessRegionChanges update.
+  virtual bool WantsRegionChangeUpdate(const GRState* state) = 0;
+
+  /// ProcessRegionChanges - Called by GRStateManager whenever a change is made
+  ///  to the store. Used to update checkers that track region values.
+  virtual const GRState* ProcessRegionChanges(const GRState* state,
+                                              const MemRegion* const *Begin,
+                                              const MemRegion* const *End) = 0;
+
+  inline const GRState* ProcessRegionChange(const GRState* state,
+                                            const MemRegion* MR) {
+    return ProcessRegionChanges(state, &MR, &MR+1);
+  }
+
+  /// Called by GRCoreEngine when the analysis worklist is either empty or the
+  //  maximum number of analysis steps have been reached.
+  virtual void ProcessEndWorklist(bool hasWorkRemaining) = 0;
 };
 }
 
diff --git a/include/clang/Checker/PathSensitive/GRTransferFuncs.h b/include/clang/Checker/PathSensitive/GRTransferFuncs.h
index 13325ed..320b7f7 100644
--- a/include/clang/Checker/PathSensitive/GRTransferFuncs.h
+++ b/include/clang/Checker/PathSensitive/GRTransferFuncs.h
@@ -42,13 +42,13 @@
   virtual void EvalCall(ExplodedNodeSet& Dst,
                         GRExprEngine& Engine,
                         GRStmtNodeBuilder& Builder,
-                        CallExpr* CE, SVal L,
+                        const CallExpr* CE, SVal L,
                         ExplodedNode* Pred) {}
 
   virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst,
                                    GRExprEngine& Engine,
                                    GRStmtNodeBuilder& Builder,
-                                   ObjCMessageExpr* ME,
+                                   const ObjCMessageExpr* ME,
                                    ExplodedNode* Pred,
                                    const GRState *state) {}
 
@@ -66,14 +66,14 @@
                                GRExprEngine& Engine,
                                GRStmtNodeBuilder& Builder,
                                ExplodedNode* Pred,
-                               Stmt* S, const GRState* state,
+                               const GRState* state,
                                SymbolReaper& SymReaper) {}
 
   // Return statements.
   virtual void EvalReturn(ExplodedNodeSet& Dst,
                           GRExprEngine& Engine,
                           GRStmtNodeBuilder& Builder,
-                          ReturnStmt* S,
+                          const ReturnStmt* S,
                           ExplodedNode* Pred) {}
 
   // Assumptions.
diff --git a/include/clang/Checker/PathSensitive/GRWorkList.h b/include/clang/Checker/PathSensitive/GRWorkList.h
index b8f90fa..315b614 100644
--- a/include/clang/Checker/PathSensitive/GRWorkList.h
+++ b/include/clang/Checker/PathSensitive/GRWorkList.h
@@ -27,12 +27,12 @@
 class GRWorkListUnit {
   ExplodedNode* Node;
   GRBlockCounter Counter;
-  CFGBlock* Block;
+  const CFGBlock* Block;
   unsigned BlockIdx; // This is the index of the next statement.
 
 public:
   GRWorkListUnit(ExplodedNode* N, GRBlockCounter C,
-                 CFGBlock* B, unsigned idx)
+                 const CFGBlock* B, unsigned idx)
   : Node(N),
     Counter(C),
     Block(B),
@@ -46,7 +46,7 @@
 
   ExplodedNode* getNode()         const { return Node; }
   GRBlockCounter    getBlockCounter() const { return Counter; }
-  CFGBlock*         getBlock()        const { return Block; }
+  const CFGBlock*   getBlock()        const { return Block; }
   unsigned          getIndex()        const { return BlockIdx; }
 };
 
@@ -58,8 +58,8 @@
 
   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, const CFGBlock* B, unsigned idx) {
+    Enqueue(GRWorkListUnit(N, CurrentCounter, B, idx));
   }
 
   void Enqueue(ExplodedNode* N) {
diff --git a/include/clang/Checker/PathSensitive/MemRegion.h b/include/clang/Checker/PathSensitive/MemRegion.h
index 2ab3b42..96f906a 100644
--- a/include/clang/Checker/PathSensitive/MemRegion.h
+++ b/include/clang/Checker/PathSensitive/MemRegion.h
@@ -20,6 +20,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/Checker/PathSensitive/SVals.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/ADT/FoldingSet.h"
 #include <string>
 
@@ -34,7 +35,25 @@
 class MemSpaceRegion;
 class LocationContext;
 class StackFrameContext;
+class ValueManager;
 class VarRegion;
+class CodeTextRegion;
+
+/// Represent a region's offset within the top level base region.
+class RegionOffset {
+  /// The base region.
+  const MemRegion *R;
+
+  /// The bit offset within the base region. It shouldn't be negative.
+  int64_t Offset;
+
+public:
+  RegionOffset(const MemRegion *r) : R(r), Offset(0) {}
+  RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
+
+  const MemRegion *getRegion() const { return R; }
+  int64_t getOffset() const { return Offset; }
+};
 
 //===----------------------------------------------------------------------===//
 // Base region classes.
@@ -46,14 +65,17 @@
 public:
   enum Kind {
     // Memory spaces.
-    BEG_MEMSPACES,
-    GenericMemSpaceRegionKind = BEG_MEMSPACES,
+    GenericMemSpaceRegionKind,
     StackLocalsSpaceRegionKind,
     StackArgumentsSpaceRegionKind,
     HeapSpaceRegionKind,
     UnknownSpaceRegionKind,
-    GlobalsSpaceRegionKind,
-    END_MEMSPACES = GlobalsSpaceRegionKind,
+    NonStaticGlobalSpaceRegionKind,
+    StaticGlobalSpaceRegionKind,
+    BEG_GLOBAL_MEMSPACES = NonStaticGlobalSpaceRegionKind,
+    END_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind,
+    BEG_MEMSPACES = GenericMemSpaceRegionKind,
+    END_MEMSPACES = StaticGlobalSpaceRegionKind,
     // Untyped regions.
     SymbolicRegionKind,
     AllocaRegionKind,
@@ -106,6 +128,9 @@
   
   bool hasStackParametersStorage() const;
 
+  /// Compute the offset within the top level memory object.
+  RegionOffset getAsOffset() const;
+
   virtual void dumpToStream(llvm::raw_ostream& os) const;
 
   void dump() const;
@@ -146,13 +171,48 @@
 };
   
 class GlobalsSpaceRegion : public MemSpaceRegion {
-  friend class MemRegionManager;
-
-  GlobalsSpaceRegion(MemRegionManager *mgr)
-    : MemSpaceRegion(mgr, GlobalsSpaceRegionKind) {}
+protected:
+  GlobalsSpaceRegion(MemRegionManager *mgr, Kind k)
+    : MemSpaceRegion(mgr, k) {}
 public:
   static bool classof(const MemRegion *R) {
-    return R->getKind() == GlobalsSpaceRegionKind;
+    Kind k = R->getKind();
+    return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
+  }
+};
+  
+class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
+  friend class MemRegionManager;
+
+  const CodeTextRegion *CR;
+  
+  StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
+    : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {}
+
+public:
+  void Profile(llvm::FoldingSetNodeID &ID) const;
+  
+  void dumpToStream(llvm::raw_ostream& os) const;
+
+  const CodeTextRegion *getCodeRegion() const { return CR; }
+
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == StaticGlobalSpaceRegionKind;
+  }
+};
+  
+class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
+  friend class MemRegionManager;
+  
+  NonStaticGlobalSpaceRegion(MemRegionManager *mgr)
+    : GlobalsSpaceRegion(mgr, NonStaticGlobalSpaceRegionKind) {}
+  
+public:
+
+  void dumpToStream(llvm::raw_ostream& os) const;
+
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == NonStaticGlobalSpaceRegionKind;
   }
 };
   
@@ -221,6 +281,7 @@
   }
 };
 
+
 /// SubRegion - A region that subsets another larger region.  Most regions
 ///  are subclasses of SubRegion.
 class SubRegion : public MemRegion {
@@ -232,6 +293,11 @@
     return superRegion;
   }
 
+  /// getExtent - Returns the size of the region in bytes.
+  virtual DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const {
+    return UnknownVal();
+  }
+
   MemRegionManager* getMemRegionManager() const;
 
   bool isSubRegionOf(const MemRegion* R) const;
@@ -242,31 +308,6 @@
 };
 
 //===----------------------------------------------------------------------===//
-// 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.
 //===----------------------------------------------------------------------===//
 
@@ -288,6 +329,8 @@
 
   bool isBoundable() const { return true; }
 
+  DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const;
+
   void Profile(llvm::FoldingSetNodeID& ID) const;
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr* Ex,
@@ -306,25 +349,23 @@
   TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
 
 public:
-  virtual QualType getValueType(ASTContext &C) const = 0;
+  virtual QualType getValueType() const = 0;
 
-  virtual QualType getLocationType(ASTContext& C) const {
+  virtual QualType getLocationType() const {
     // FIXME: We can possibly optimize this later to cache this value.
-    return C.getPointerType(getValueType(C));
+    return getContext().getPointerType(getValueType());
   }
 
-  QualType getDesugaredValueType(ASTContext& C) const {
-    QualType T = getValueType(C);
+  QualType getDesugaredValueType() const {
+    QualType T = getValueType();
     return T.getTypePtr() ? T.getDesugaredType() : T;
   }
 
-  QualType getDesugaredLocationType(ASTContext& C) const {
-    return getLocationType(C).getDesugaredType();
+  QualType getDesugaredLocationType() const {
+    return getLocationType().getDesugaredType();
   }
 
-  bool isBoundable() const {
-    return !getValueType(getContext()).isNull();
-  }
+  bool isBoundable() const { return true; }
 
   static bool classof(const MemRegion* R) {
     unsigned k = R->getKind();
@@ -337,9 +378,8 @@
 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);
+  QualType getValueType() const {
+    assert(0 && "Do not get the object type of a CodeTextRegion.");
     return QualType();
   }
   
@@ -358,8 +398,8 @@
   FunctionTextRegion(const FunctionDecl* fd, const MemRegion* sreg)
     : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {}
   
-  QualType getLocationType(ASTContext &C) const {
-    return C.getPointerType(FD->getType());
+  QualType getLocationType() const {
+    return getContext().getPointerType(FD->getType());
   }
   
   const FunctionDecl *getDecl() const {
@@ -397,7 +437,7 @@
     : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
 
 public:
-  QualType getLocationType(ASTContext &C) const {
+  QualType getLocationType() const {
     return locTy;
   }
   
@@ -502,6 +542,8 @@
 
   bool isBoundable() const { return true; }
 
+  DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const;
+
   void Profile(llvm::FoldingSetNodeID& ID) const;
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
@@ -532,10 +574,12 @@
 
   const StringLiteral* getStringLiteral() const { return Str; }
 
-  QualType getValueType(ASTContext& C) const {
+  QualType getValueType() const {
     return Str->getType();
   }
 
+  DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const;
+
   bool isBoundable() const { return false; }
 
   void Profile(llvm::FoldingSetNodeID& ID) const {
@@ -564,8 +608,8 @@
                             const CompoundLiteralExpr* CL,
                             const MemRegion* superRegion);
 public:
-  QualType getValueType(ASTContext& C) const {
-    return C.getCanonicalType(CL->getType());
+  QualType getValueType() const {
+    return CL->getType();
   }
 
   bool isBoundable() const { return !CL->isFileScope(); }
@@ -595,6 +639,8 @@
   const Decl* getDecl() const { return D; }
   void Profile(llvm::FoldingSetNodeID& ID) const;
 
+  DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const;
+
   static bool classof(const MemRegion* R) {
     unsigned k = R->getKind();
     return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
@@ -620,9 +666,9 @@
 
   const StackFrameContext *getStackFrame() const;
   
-  QualType getValueType(ASTContext& C) const {
+  QualType getValueType() const {
     // FIXME: We can cache this if needed.
-    return C.getCanonicalType(getDecl()->getType());
+    return getDecl()->getType();
   }
 
   void dumpToStream(llvm::raw_ostream& os) const;
@@ -648,10 +694,10 @@
   void Profile(llvm::FoldingSetNodeID &ID) const;
 
 public:  
-  QualType getValueType(ASTContext &C) const {
+  QualType getValueType() const {
     return QualType(ThisPointerTy, 0);
   }
-  
+
   void dumpToStream(llvm::raw_ostream& os) const;
   
   static bool classof(const MemRegion* R) {
@@ -674,11 +720,13 @@
 
   const FieldDecl* getDecl() const { return cast<FieldDecl>(D); }
 
-  QualType getValueType(ASTContext& C) const {
+  QualType getValueType() const {
     // FIXME: We can cache this if needed.
-    return C.getCanonicalType(getDecl()->getType());
+    return getDecl()->getType();
   }
 
+  DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const;
+
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl* FD,
                             const MemRegion* superRegion) {
     DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
@@ -703,7 +751,7 @@
 
 public:
   const ObjCIvarDecl* getDecl() const { return cast<ObjCIvarDecl>(D); }
-  QualType getValueType(ASTContext&) const { return getDecl()->getType(); }
+  QualType getValueType() const { return getDecl()->getType(); }
 
   void dumpToStream(llvm::raw_ostream& os) const;
 
@@ -711,6 +759,30 @@
     return R->getKind() == ObjCIvarRegionKind;
   }
 };
+//===----------------------------------------------------------------------===//
+// 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;
+};
 
 class ElementRegion : public TypedRegion {
   friend class MemRegionManager;
@@ -733,15 +805,15 @@
 
   SVal getIndex() const { return Index; }
 
-  QualType getValueType(ASTContext&) const {
+  QualType getValueType() const {
     return ElementType;
   }
 
   QualType getElementType() const {
     return ElementType;
   }
-
-  RegionRawOffset getAsRawOffset() const;
+  /// Compute the offset within the array. The array might also be a subobject.
+  RegionRawOffset getAsArrayOffset() const;
 
   void dumpToStream(llvm::raw_ostream& os) const;
 
@@ -765,7 +837,7 @@
                             Expr const *E, const MemRegion *sReg);
   
 public:
-  QualType getValueType(ASTContext& C) const {
+  QualType getValueType() const {
     return Ex->getType();
   }
 
@@ -793,12 +865,14 @@
   llvm::BumpPtrAllocator& A;
   llvm::FoldingSet<MemRegion> Regions;
 
-  GlobalsSpaceRegion *globals;
+  NonStaticGlobalSpaceRegion *globals;
   
   llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *> 
     StackLocalsSpaceRegions;
   llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
     StackArgumentsSpaceRegions;
+  llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
+    StaticsGlobalSpaceRegions;
 
   HeapSpaceRegion *heap;
   UnknownSpaceRegion *unknown;
@@ -825,8 +899,8 @@
   getStackArgumentsRegion(const StackFrameContext *STC);
 
   /// getGlobalsRegion - Retrieve the memory region associated with
-  ///  all global variables.
-  const GlobalsSpaceRegion *getGlobalsRegion();
+  ///  global variables.
+  const GlobalsSpaceRegion *getGlobalsRegion(const CodeTextRegion *R = 0);
 
   /// getHeapRegion - Retrieve the memory region associated with the
   ///  generic "heap".
diff --git a/include/clang/Checker/PathSensitive/SVals.h b/include/clang/Checker/PathSensitive/SVals.h
index 040db83..cdb338a 100644
--- a/include/clang/Checker/PathSensitive/SVals.h
+++ b/include/clang/Checker/PathSensitive/SVals.h
@@ -45,15 +45,14 @@
   enum { BaseBits = 2, BaseMask = 0x3 };
 
 protected:
-  void* Data;
+  const void* Data;
   unsigned Kind;
 
 protected:
   SVal(const void* d, bool isLoc, unsigned ValKind)
-  : Data(const_cast<void*>(d)),
-    Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
+  : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
 
-  explicit SVal(BaseKind k, void* D = NULL)
+  explicit SVal(BaseKind k, const void* D = NULL)
     : Data(D), Kind(k) {}
 
 public:
@@ -69,7 +68,7 @@
 
   inline void Profile(llvm::FoldingSetNodeID& ID) const {
     ID.AddInteger((unsigned) getRawKind());
-    ID.AddPointer(reinterpret_cast<void*>(Data));
+    ID.AddPointer(Data);
   }
 
   inline bool operator==(const SVal& R) const {
@@ -98,6 +97,8 @@
 
   bool isConstant() const;
 
+  bool isConstant(int I) const;
+
   bool isZeroConstant() const;
 
   /// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true;
@@ -109,7 +110,7 @@
   const FunctionDecl* getAsFunctionDecl() const;
 
   /// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
-  ///  wraps a symbol, return that SymbolRef.  Otherwise return a SymbolData*
+  ///  wraps a symbol, return that SymbolRef.  Otherwise return NULL.
   SymbolRef getAsLocSymbol() const;
 
   /// Get the symbol in the SVal or its base region.
@@ -161,13 +162,13 @@
 class UndefinedVal : public SVal {
 public:
   UndefinedVal() : SVal(UndefinedKind) {}
-  UndefinedVal(void* D) : SVal(UndefinedKind, D) {}
+  UndefinedVal(const void* D) : SVal(UndefinedKind, D) {}
 
   static inline bool classof(const SVal* V) {
     return V->getBaseKind() == UndefinedKind;
   }
 
-  void* getData() const { return Data; }
+  const void* getData() const { return Data; }
 };
 
 class DefinedOrUnknownSVal : public SVal {
@@ -285,7 +286,7 @@
     : NonLoc(SymExprValKind, reinterpret_cast<const void*>(SE)) {}
 
   const SymExpr *getSymbolicExpression() const {
-    return reinterpret_cast<SymExpr*>(Data);
+    return reinterpret_cast<const SymExpr*>(Data);
   }
 
   static inline bool classof(const SVal* V) {
@@ -303,7 +304,7 @@
   ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
 
   const llvm::APSInt& getValue() const {
-    return *static_cast<llvm::APSInt*>(Data);
+    return *static_cast<const llvm::APSInt*>(Data);
   }
 
   // Transfer functions for binary/unary operations on ConcreteInts.
@@ -366,7 +367,7 @@
 
 public:
   const CompoundValData* getValue() const {
-    return static_cast<CompoundValData*>(Data);
+    return static_cast<const CompoundValData*>(Data);
   }
 
   typedef llvm::ImmutableList<SVal>::iterator iterator;
@@ -417,8 +418,8 @@
 public:
   GotoLabel(LabelStmt* Label) : Loc(GotoLabelKind, Label) {}
 
-  LabelStmt* getLabel() const {
-    return static_cast<LabelStmt*>(Data);
+  const LabelStmt* getLabel() const {
+    return static_cast<const LabelStmt*>(Data);
   }
 
   static inline bool classof(const SVal* V) {
@@ -437,7 +438,7 @@
   MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
 
   const MemRegion* getRegion() const {
-    return static_cast<MemRegion*>(Data);
+    return static_cast<const MemRegion*>(Data);
   }
 
   const MemRegion* StripCasts() const;
@@ -471,7 +472,7 @@
   ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
 
   const llvm::APSInt& getValue() const {
-    return *static_cast<llvm::APSInt*>(Data);
+    return *static_cast<const llvm::APSInt*>(Data);
   }
 
   // Transfer functions for binary/unary operations on ConcreteInts.
diff --git a/include/clang/Checker/PathSensitive/SValuator.h b/include/clang/Checker/PathSensitive/SValuator.h
index 9beb8cb..9192ca7 100644
--- a/include/clang/Checker/PathSensitive/SValuator.h
+++ b/include/clang/Checker/PathSensitive/SValuator.h
@@ -47,11 +47,15 @@
   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 EvalBinOpLL(const GRState *state, 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;
+
+  /// getKnownValue - Evaluates a given SVal. If the SVal has only one possible
+  ///  (integer) value, that value is returned. Otherwise, returns NULL.
+  virtual const llvm::APSInt *getKnownValue(const GRState *state, SVal V) = 0;
   
   SVal EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
                  SVal L, SVal R, QualType T);
diff --git a/include/clang/Checker/PathSensitive/Store.h b/include/clang/Checker/PathSensitive/Store.h
index 41d7c2b..a1a4184 100644
--- a/include/clang/Checker/PathSensitive/Store.h
+++ b/include/clang/Checker/PathSensitive/Store.h
@@ -18,6 +18,7 @@
 #include "clang/Checker/PathSensitive/SVals.h"
 #include "clang/Checker/PathSensitive/ValueManager.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
 
 namespace clang {
 
@@ -63,6 +64,10 @@
   ///   to the location given for \c loc.
   virtual Store Bind(Store store, Loc loc, SVal val) = 0;
 
+  virtual Store BindDefault(Store store, const MemRegion *R, SVal V) {
+    return store;
+  }
+
   virtual Store Remove(Store St, Loc L) = 0;
 
   /// BindCompoundLiteral - Return the store that has the bindings currently
@@ -86,16 +91,16 @@
   //   caller's responsibility to 'delete' the returned map.
   virtual SubRegionMap *getSubRegionMap(Store store) = 0;
 
-  virtual SVal getLValueVar(const VarDecl *VD, const LocationContext *LC) {
+  virtual Loc getLValueVar(const VarDecl *VD, const LocationContext *LC) {
     return ValMgr.makeLoc(MRMgr.getVarRegion(VD, LC));
   }
 
-  virtual SVal getLValueString(const StringLiteral* S) {
+  virtual Loc getLValueString(const StringLiteral* S) {
     return ValMgr.makeLoc(MRMgr.getStringRegion(S));
   }
 
-  SVal getLValueCompoundLiteral(const CompoundLiteralExpr* CL,
-                                const LocationContext *LC) {
+  Loc getLValueCompoundLiteral(const CompoundLiteralExpr* CL,
+                               const LocationContext *LC) {
     return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC));
   }
 
@@ -109,7 +114,8 @@
 
   virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base);
 
-  // FIXME: Make out-of-line.
+  // FIXME: This should soon be eliminated altogether; clients should deal with
+  // region extents directly.
   virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state, 
                                                  const MemRegion *region,
                                                  QualType EleTy) {
@@ -143,8 +149,7 @@
     return UnknownVal();
   }
 
-  virtual Store RemoveDeadBindings(Store store, Stmt* Loc,
-                                   const StackFrameContext *LCtx,
+  virtual Store RemoveDeadBindings(Store store, const StackFrameContext *LCtx,
                                    SymbolReaper& SymReaper,
                       llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0;
 
@@ -153,30 +158,39 @@
   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;
-  
+  typedef llvm::SmallVector<const MemRegion *, 8> InvalidatedRegions;
+
+  /// InvalidateRegions - Clears out the specified regions from the store,
+  ///  marking their values as unknown. Depending on the store, this may also
+  ///  invalidate additional regions that may have changed based on accessing
+  ///  the given regions. Optionally, invalidates non-static globals as well.
+  /// \param[in] store The initial store
+  /// \param[in] Begin A pointer to the first region to invalidate.
+  /// \param[in] End A pointer just past the last region to invalidate.
+  /// \param[in] E The current statement being evaluated. Used to conjure
+  ///   symbols to mark the values of invalidated regions.
+  /// \param[in] Count The current block count. Used to conjure
+  ///   symbols to mark the values of invalidated regions.
+  /// \param[in,out] IS A set to fill with any symbols that are no longer
+  ///   accessible. Pass \c NULL if this information will not be used.
+  /// \param[in] invalidateGlobals If \c true, any non-static global regions
+  ///   are invalidated as well.
+  /// \param[in,out] Regions A vector to fill with any regions being
+  ///   invalidated. This should include any regions explicitly invalidated
+  ///   even if they do not currently have bindings. Pass \c NULL if this
+  ///   information will not be used.
   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;
-  }
+                                  InvalidatedSymbols *IS,
+                                  bool invalidateGlobals,
+                                  InvalidatedRegions *Regions) = 0;
 
   /// 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 Store EnterStackFrame(const GRState *state,
+                                const StackFrameContext *frame);
 
   virtual void print(Store store, llvm::raw_ostream& Out,
                      const char* nl, const char *sep) = 0;
diff --git a/include/clang/Checker/PathSensitive/SymbolManager.h b/include/clang/Checker/PathSensitive/SymbolManager.h
index dea877c..26ed0c1 100644
--- a/include/clang/Checker/PathSensitive/SymbolManager.h
+++ b/include/clang/Checker/PathSensitive/SymbolManager.h
@@ -31,6 +31,7 @@
   class ASTContext;
   class BasicValueFactory;
   class MemRegion;
+  class SubRegion;
   class TypedRegion;
   class VarRegion;
   class StackFrameContext;
@@ -38,7 +39,8 @@
 class SymExpr : public llvm::FoldingSetNode {
 public:
   enum Kind { BEGIN_SYMBOLS,
-              RegionValueKind, ConjuredKind, DerivedKind,
+              RegionValueKind, ConjuredKind, DerivedKind, ExtentKind,
+              MetadataKind,
               END_SYMBOLS,
               SymIntKind, SymSymKind };
 private:
@@ -189,6 +191,82 @@
   }
 };
 
+/// SymbolExtent - Represents the extent (size in bytes) of a bounded region.
+///  Clients should not ask the SymbolManager for a region's extent. Always use
+///  SubRegion::getExtent instead -- the value returned may not be a symbol.
+class SymbolExtent : public SymbolData {
+  const SubRegion *R;
+  
+public:
+  SymbolExtent(SymbolID sym, const SubRegion *r)
+  : SymbolData(ExtentKind, sym), R(r) {}
+
+  const SubRegion *getRegion() const { return R; }
+
+  QualType getType(ASTContext&) const;
+
+  void dumpToStream(llvm::raw_ostream &os) const;
+
+  static void Profile(llvm::FoldingSetNodeID& profile, const SubRegion *R) {
+    profile.AddInteger((unsigned) ExtentKind);
+    profile.AddPointer(R);
+  }
+
+  virtual void Profile(llvm::FoldingSetNodeID& profile) {
+    Profile(profile, R);
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr* SE) {
+    return SE->getKind() == ExtentKind;
+  }
+};
+
+/// SymbolMetadata - Represents path-dependent metadata about a specific region.
+///  Metadata symbols remain live as long as they are marked as in use before
+///  dead-symbol sweeping AND their associated regions are still alive.
+///  Intended for use by checkers.
+class SymbolMetadata : public SymbolData {
+  const MemRegion* R;
+  const Stmt* S;
+  QualType T;
+  unsigned Count;
+  const void* Tag;
+public:
+  SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt* s, QualType t,
+                 unsigned count, const void* tag)
+  : SymbolData(MetadataKind, sym), R(r), S(s), T(t), Count(count), Tag(tag) {}
+
+  const MemRegion *getRegion() const { return R; }
+  const Stmt* getStmt() const { return S; }
+  unsigned getCount() const { return Count; }
+  const void* getTag() const { return Tag; }
+
+  QualType getType(ASTContext&) const;
+
+  void dumpToStream(llvm::raw_ostream &os) const;
+
+  static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion *R,
+                      const Stmt *S, QualType T, unsigned Count,
+                      const void *Tag) {
+    profile.AddInteger((unsigned) MetadataKind);
+    profile.AddPointer(R);
+    profile.AddPointer(S);
+    profile.Add(T);
+    profile.AddInteger(Count);
+    profile.AddPointer(Tag);
+  }
+
+  virtual void Profile(llvm::FoldingSetNodeID& profile) {
+    Profile(profile, R, S, T, Count, Tag);
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr* SE) {
+    return SE->getKind() == MetadataKind;
+  }
+};
+
 // SymIntExpr - Represents symbolic expression like 'x' + 3.
 class SymIntExpr : public SymExpr {
   const SymExpr *LHS;
@@ -305,6 +383,12 @@
   const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol,
                                         const TypedRegion *R);
 
+  const SymbolExtent *getExtentSymbol(const SubRegion *R);
+
+  const SymbolMetadata* getMetadataSymbol(const MemRegion* R, const Stmt* S,
+                                          QualType T, unsigned VisitCount,
+                                          const void* SymbolTag = 0);
+
   const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
                                   const llvm::APSInt& rhs, QualType t);
 
@@ -328,25 +412,40 @@
   typedef llvm::DenseSet<SymbolRef> SetTy;
 
   SetTy TheLiving;
+  SetTy MetadataInUse;
   SetTy TheDead;
   const LocationContext *LCtx;
+  const Stmt *Loc;
   SymbolManager& SymMgr;
 
 public:
-  SymbolReaper(const LocationContext *ctx, SymbolManager& symmgr)
-    : LCtx(ctx), SymMgr(symmgr) {}
+  SymbolReaper(const LocationContext *ctx, const Stmt *s, SymbolManager& symmgr)
+   : LCtx(ctx), Loc(s), SymMgr(symmgr) {}
 
   ~SymbolReaper() {}
 
   const LocationContext *getLocationContext() const { return LCtx; }
+  const Stmt *getCurrentStatement() const { return Loc; }
 
   bool isLive(SymbolRef sym);
+  bool isLive(const Stmt *ExprVal) const;
+  bool isLive(const VarRegion *VR) const;
 
-  bool isLive(const Stmt* Loc, const Stmt* ExprVal) const;
-
-  bool isLive(const Stmt* Loc, const VarRegion *VR) const;
-  
+  // markLive - Unconditionally marks a symbol as live. This should never be
+  //  used by checkers, only by the state infrastructure such as the store and
+  //  environment. Checkers should instead use metadata symbols and markInUse.
   void markLive(SymbolRef sym);
+
+  // markInUse - Marks a symbol as important to a checker. For metadata symbols,
+  //  this will keep the symbol alive as long as its associated region is also
+  //  live. For other symbols, this has no effect; checkers are not permitted
+  //  to influence the life of other symbols. This should be used before any
+  //  symbol marking has occurred, i.e. in the MarkLiveSymbols callback.
+  void markInUse(SymbolRef sym);
+
+  // maybeDead - If a symbol is known to be live, marks the symbol as live.
+  //  Otherwise, if the symbol cannot be proven live, it is marked as dead.
+  //  Returns true if the symbol is dead, false if live.
   bool maybeDead(SymbolRef sym);
 
   typedef SetTy::const_iterator dead_iterator;
@@ -356,6 +455,13 @@
   bool hasDeadSymbols() const {
     return !TheDead.empty();
   }
+
+  /// isDead - Returns whether or not a symbol has been confirmed dead. This
+  ///  should only be called once all marking of dead symbols has completed.
+  ///  (For checkers, this means only in the EvalDeadSymbols callback.)
+  bool isDead(SymbolRef sym) const {
+    return TheDead.count(sym);
+  }
 };
 
 class SymbolVisitor {
diff --git a/include/clang/Checker/PathSensitive/ValueManager.h b/include/clang/Checker/PathSensitive/ValueManager.h
index 5a9d54d..b81e9c1 100644
--- a/include/clang/Checker/PathSensitive/ValueManager.h
+++ b/include/clang/Checker/PathSensitive/ValueManager.h
@@ -106,6 +106,9 @@
   DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
                                                       const TypedRegion *R);
 
+  DefinedSVal getMetadataSymbolVal(const void *SymbolTag, const MemRegion *MR,
+                                   const Expr *E, QualType T, unsigned Count);
+
   DefinedSVal getFunctionPointer(const FunctionDecl *FD);
   
   DefinedSVal getBlockPointer(const BlockDecl *BD, CanQualType locTy,
diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h
new file mode 100644
index 0000000..abcef81
--- /dev/null
+++ b/include/clang/CodeGen/BackendUtil.h
@@ -0,0 +1,37 @@
+//===--- BackendUtil.h - LLVM Backend Utilities -----------------*- 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_CODEGEN_BACKEND_UTIL_H
+#define LLVM_CLANG_CODEGEN_BACKEND_UTIL_H
+
+namespace llvm {
+  class Module;
+  class raw_ostream;
+}
+
+namespace clang {
+  class Diagnostic;
+  class CodeGenOptions;
+  class TargetOptions;
+  
+  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_EmitMCNull,    ///< Run CodeGen, but don't emit anything
+    Backend_EmitObj        ///< Emit native object files
+  };
+  
+  void EmitBackendOutput(Diagnostic &Diags, const CodeGenOptions &CGOpts,
+                         const TargetOptions &TOpts, llvm::Module *M,
+                         BackendAction Action, llvm::raw_ostream *OS);
+}
+
+#endif
diff --git a/include/clang/CodeGen/CodeGenAction.h b/include/clang/CodeGen/CodeGenAction.h
new file mode 100644
index 0000000..cecfcda
--- /dev/null
+++ b/include/clang/CodeGen/CodeGenAction.h
@@ -0,0 +1,79 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_CODE_GEN_ACTION_H
+#define LLVM_CLANG_CODEGEN_CODE_GEN_ACTION_H
+
+#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 bool hasIRSupport() const;
+
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+
+  virtual void ExecuteAction();
+
+  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 EmitCodeGenOnlyAction : public CodeGenAction {
+public:
+  EmitCodeGenOnlyAction();
+};
+
+class EmitObjAction : public CodeGenAction {
+public:
+  EmitObjAction();
+};
+
+}
+
+#endif
diff --git a/include/clang/CodeGen/CodeGenOptions.h b/include/clang/CodeGen/CodeGenOptions.h
deleted file mode 100644
index 54d3ba0..0000000
--- a/include/clang/CodeGen/CodeGenOptions.h
+++ /dev/null
@@ -1,129 +0,0 @@
-//===--- 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
index 2a3aa6a..c45ad08 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -33,6 +33,9 @@
     virtual llvm::Module* ReleaseModule() = 0;
   };
 
+  /// CreateLLVMCodeGen - Create a CodeGenerator instance.
+  /// It is the responsibility of the caller to call delete on
+  /// the allocated CodeGenerator instance.
   CodeGenerator *CreateLLVMCodeGen(Diagnostic &Diags,
                                    const std::string &ModuleName,
                                    const CodeGenOptions &CGO,
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
index ab3162a..4b45c98 100644
--- a/include/clang/Driver/Action.h
+++ b/include/clang/Driver/Action.h
@@ -51,9 +51,10 @@
     AssembleJobClass,
     LinkJobClass,
     LipoJobClass,
+    DsymutilJobClass,
 
     JobClassFirst=PreprocessJobClass,
-    JobClassLast=LipoJobClass
+    JobClassLast=DsymutilJobClass
   };
 
   static const char *getClassName(ActionClass AC);
@@ -211,6 +212,16 @@
   static bool classof(const LipoJobAction *) { return true; }
 };
 
+class DsymutilJobAction : public JobAction {
+public:
+  DsymutilJobAction(ActionList &Inputs, types::ID Type);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == DsymutilJobClass;
+  }
+  static bool classof(const DsymutilJobAction *) { return true; }
+};
+
 } // end namespace driver
 } // end namespace clang
 
diff --git a/include/clang/Driver/Arg.h b/include/clang/Driver/Arg.h
index ebf40d4..a52789e 100644
--- a/include/clang/Driver/Arg.h
+++ b/include/clang/Driver/Arg.h
@@ -10,14 +10,9 @@
 #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 "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
 #include <vector>
 #include <string>
 
@@ -34,19 +29,10 @@
   /// ArgList to provide efficient iteration over all instances of a
   /// particular option.
   class Arg {
-  public:
-    enum ArgClass {
-      FlagClass = 0,
-      PositionalClass,
-      JoinedClass,
-      SeparateClass,
-      CommaJoinedClass,
-      JoinedAndSeparateClass
-    };
+    Arg(const Arg &); // DO NOT IMPLEMENT
+    void operator=(const Arg &); // DO NOT IMPLEMENT
 
   private:
-    ArgClass Kind;
-
     /// The option this argument is an instance of.
     const Option *Opt;
 
@@ -58,20 +44,24 @@
     /// ArgList.
     unsigned Index;
 
-    /// Flag indicating whether this argument was used to effect
-    /// compilation; used for generating "argument unused"
-    /// diagnostics.
-    mutable bool Claimed;
+    /// Was this argument used to effect compilation; used for generating
+    /// "argument unused" diagnostics.
+    mutable unsigned Claimed : 1;
 
-  protected:
-    Arg(ArgClass Kind, const Option *Opt, unsigned Index,
-        const Arg *BaseArg = 0);
+    /// Does this argument own its values.
+    mutable unsigned OwnsValues : 1;
+
+    /// The argument values, as C strings.
+    llvm::SmallVector<const char *, 2> Values;
 
   public:
-    Arg(const Arg &);
-    virtual ~Arg();
+    Arg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0);
+    Arg(const Option *Opt, unsigned Index,
+        const char *Value0, const Arg *BaseArg = 0);
+    Arg(const Option *Opt, unsigned Index,
+        const char *Value0, const char *Value1, const Arg *BaseArg = 0);
+    ~Arg();
 
-    ArgClass getKind() const { return Kind; }
     const Option &getOption() const { return *Opt; }
     unsigned getIndex() const { return Index; }
 
@@ -85,19 +75,32 @@
       BaseArg = _BaseArg;
     }
 
+    bool getOwnsValues() const { return OwnsValues; }
+    void setOwnsValues(bool Value) const { OwnsValues = Value; }
+
     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;
+    unsigned getNumValues() const { return Values.size(); }
+    const char *getValue(const ArgList &Args, unsigned N=0) const {
+      return Values[N];
+    }
+
+    llvm::SmallVectorImpl<const char*> &getValues() {
+      return Values;
+    }
+
+    bool containsValue(llvm::StringRef Value) const {
+      for (unsigned i = 0, e = getNumValues(); i != e; ++i)
+        if (Values[i] == Value)
+          return true;
+      return false;
+    }
 
     /// render - Append the argument onto the given array as strings.
-    virtual void render(const ArgList &Args, ArgStringList &Output) const = 0;
+    void render(const ArgList &Args, ArgStringList &Output) const;
 
     /// renderAsInput - Append the argument, render as an input, onto
     /// the given array as strings. The distinction is that some
@@ -114,116 +117,6 @@
     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
 
diff --git a/include/clang/Driver/ArgList.h b/include/clang/Driver/ArgList.h
index 0a8eaea..257b653 100644
--- a/include/clang/Driver/ArgList.h
+++ b/include/clang/Driver/ArgList.h
@@ -17,12 +17,15 @@
 
 #include <list>
 #include <string>
+#include <vector>
 
 namespace llvm {
   class Twine;
 }
 
 namespace clang {
+  class Diagnostic;
+
 namespace driver {
   class Arg;
   class ArgList;
@@ -49,9 +52,9 @@
     void SkipToNextArg();
 
   public:
-    typedef const Arg*                  value_type;
-    typedef const Arg*                  reference;
-    typedef const Arg*                  pointer;
+    typedef Arg * const *                 value_type;
+    typedef Arg * const &                 reference;
+    typedef Arg * const *                 pointer;
     typedef std::forward_iterator_tag   iterator_category;
     typedef std::ptrdiff_t              difference_type;
 
@@ -64,7 +67,7 @@
 
     operator const Arg*() { return *Current; }
     reference operator*() const { return *Current; }
-    pointer operator->() const { return *Current; }
+    pointer operator->() const { return Current; }
 
     arg_iterator &operator++() {
       ++Current;
@@ -93,6 +96,10 @@
   /// check for the presence of Arg instances for a particular Option
   /// and to iterate over groups of arguments.
   class ArgList {
+  private:
+    ArgList(const ArgList &); // DO NOT IMPLEMENT
+    void operator=(const ArgList &); // DO NOT IMPLEMENT
+
   public:
     typedef llvm::SmallVector<Arg*, 16> arglist_type;
     typedef arglist_type::iterator iterator;
@@ -101,11 +108,11 @@
     typedef arglist_type::const_reverse_iterator const_reverse_iterator;
 
   private:
-    /// The full list of arguments.
-    arglist_type &Args;
+    /// The internal list of arguments.
+    arglist_type Args;
 
   protected:
-    ArgList(arglist_type &Args);
+    ArgList();
 
   public:
     virtual ~ArgList();
@@ -172,9 +179,35 @@
     Arg *getLastArg(OptSpecifier Id) const;
     Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const;
     Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const;
+    Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
+                    OptSpecifier Id3) const;
 
     /// getArgString - Return the input argument string at \arg Index.
     virtual const char *getArgString(unsigned Index) const = 0;
+
+    /// getNumInputArgStrings - Return the number of original argument strings,
+    /// which are guaranteed to be the first strings in the argument string
+    /// list.
+    virtual unsigned getNumInputArgStrings() const = 0;
+
+    /// @}
+    /// @name Argument Lookup Utilities
+    /// @{
+
+    /// getLastArgValue - Return the value of the last argument, or a default.
+    llvm::StringRef getLastArgValue(OptSpecifier Id,
+                                    llvm::StringRef Default = "") const;
+
+    /// getLastArgValue - Return the value of the last argument as an integer,
+    /// or a default. Emits an error if the argument is given, but non-integral.
+    int getLastArgIntValue(OptSpecifier Id, int Default,
+                           Diagnostic &Diags) const;
+
+    /// getAllArgValues - Get the values of all instances of the given argument
+    /// as strings.
+    std::vector<std::string> getAllArgValues(OptSpecifier Id) const;
+
+    /// @}
     /// @name Translation Utilities
     /// @{
 
@@ -227,14 +260,16 @@
     }
     const char *MakeArgString(const llvm::Twine &Str) const;
 
+    /// \brief Create an arg string for (\arg LHS + \arg RHS), reusing the
+    /// string at \arg Index if possible.
+    const char *GetOrMakeJoinedArgString(unsigned Index, llvm::StringRef LHS,
+                                         llvm::StringRef RHS) 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
@@ -254,16 +289,15 @@
 
   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; }
+    virtual unsigned getNumInputArgStrings() const {
+      return NumInputArgStrings;
+    }
 
     /// @name Arg Synthesis
     /// @{
@@ -281,34 +315,71 @@
   /// 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;
+    const InputArgList &BaseArgs;
 
     /// 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(const InputArgList &BaseArgs);
     ~DerivedArgList();
 
     virtual const char *getArgString(unsigned Index) const {
       return BaseArgs.getArgString(Index);
     }
 
+    virtual unsigned getNumInputArgStrings() const {
+      return BaseArgs.getNumInputArgStrings();
+    }
+
+    const InputArgList &getBaseArgs() const {
+      return BaseArgs;
+    }
+
     /// @name Arg Synthesis
     /// @{
 
+    /// AddSynthesizedArg - Add a argument to the list of synthesized arguments
+    /// (to be freed).
+    void AddSynthesizedArg(Arg *A) {
+      SynthesizedArgs.push_back(A);
+    }
+
     virtual const char *MakeArgString(llvm::StringRef Str) const;
 
+    /// AddFlagArg - Construct a new FlagArg for the given option \arg Id and
+    /// append it to the argument list.
+    void AddFlagArg(const Arg *BaseArg, const Option *Opt) {
+      append(MakeFlagArg(BaseArg, Opt));
+    }
+
+    /// AddPositionalArg - Construct a new Positional arg for the given option
+    /// \arg Id, with the provided \arg Value and append it to the argument
+    /// list.
+    void AddPositionalArg(const Arg *BaseArg, const Option *Opt,
+                          llvm::StringRef Value) {
+      append(MakePositionalArg(BaseArg, Opt, Value));
+    }
+
+
+    /// AddSeparateArg - Construct a new Positional arg for the given option
+    /// \arg Id, with the provided \arg Value and append it to the argument
+    /// list.
+    void AddSeparateArg(const Arg *BaseArg, const Option *Opt,
+                        llvm::StringRef Value) {
+      append(MakeSeparateArg(BaseArg, Opt, Value));
+    }
+
+
+    /// AddJoinedArg - Construct a new Positional arg for the given option \arg
+    /// Id, with the provided \arg Value and append it to the argument list.
+    void AddJoinedArg(const Arg *BaseArg, const Option *Opt,
+                      llvm::StringRef Value) {
+      append(MakeJoinedArg(BaseArg, Opt, Value));
+    }
+
+
     /// MakeFlagArg - Construct a new FlagArg for the given option
     /// \arg Id.
     Arg *MakeFlagArg(const Arg *BaseArg, const Option *Opt) const;
diff --git a/include/clang/Driver/CC1AsOptions.h b/include/clang/Driver/CC1AsOptions.h
new file mode 100644
index 0000000..0508213
--- /dev/null
+++ b/include/clang/Driver/CC1AsOptions.h
@@ -0,0 +1,32 @@
+//===--- CC1AsOptions.h - Clang Assembler 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_CC1ASOPTIONS_H
+#define CLANG_DRIVER_CC1ASOPTIONS_H
+
+namespace clang {
+namespace driver {
+  class OptTable;
+
+namespace cc1asoptions {
+  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/CC1AsOptions.inc"
+    LastOption
+#undef OPTION
+  };
+}
+
+  OptTable *createCC1AsOptTable();
+}
+}
+
+#endif
diff --git a/include/clang/Driver/CC1AsOptions.td b/include/clang/Driver/CC1AsOptions.td
new file mode 100644
index 0000000..5c08dc6
--- /dev/null
+++ b/include/clang/Driver/CC1AsOptions.td
@@ -0,0 +1,71 @@
+//===--- CC1AsOptions.td - Options for clang -cc1as -----------------------===//
+//
+//                     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 -cc1as.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the common option parsing interfaces.
+include "OptParser.td"
+
+//===----------------------------------------------------------------------===//
+// Target Options
+//===----------------------------------------------------------------------===//
+
+def triple : Separate<"-triple">,
+  HelpText<"Specify target triple (e.g. x86_64-pc-linux-gnu)">;
+
+//===----------------------------------------------------------------------===//
+// Language Options
+//===----------------------------------------------------------------------===//
+
+def I : JoinedOrSeparate<"-I">, MetaVarName<"<directory>">,
+  HelpText<"Add directory to include search path">;
+def n : Flag<"-n">,
+  HelpText<"Don't automatically start assembly file with a text section">;
+
+//===----------------------------------------------------------------------===//
+// Frontend Options
+//===----------------------------------------------------------------------===//
+
+def o : Separate<"-o">, MetaVarName<"<path>">, HelpText<"Specify output file">;
+
+def filetype : Separate<"-filetype">,
+    HelpText<"Specify the output file type ('asm', 'null', or 'obj')">;
+
+def help : Flag<"-help">,
+  HelpText<"Print this help text">;
+def _help : Flag<"--help">, Alias<help>;
+
+def version : Flag<"-version">,
+  HelpText<"Print the assembler version">;
+def _version : Flag<"--version">, Alias<version>;
+
+// 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">;
+
+//===----------------------------------------------------------------------===//
+// Transliterate Options
+//===----------------------------------------------------------------------===//
+
+def output_asm_variant : Separate<"-output-asm-variant">,
+    HelpText<"Select the asm variant index to use for output">;
+def show_encoding : Flag<"-show-encoding">,
+    HelpText<"Show instruction encoding information in transliterate mode">;
+def show_inst : Flag<"-show-inst">,
+    HelpText<"Show internal instruction representation in transliterate mode">;
+
+//===----------------------------------------------------------------------===//
+// Assemble Options
+//===----------------------------------------------------------------------===//
+
+def relax_all : Flag<"-relax-all">,
+    HelpText<"Relax all fixups (for performance testing)">;
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 18b54ef..bdb918b 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -18,12 +18,16 @@
 // Target Options
 //===----------------------------------------------------------------------===//
 
+def cxx_abi : Separate<"-cxx-abi">,
+  HelpText<"Target a particular C++ ABI type">;
 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 target_linker_version : Separate<"-target-linker-version">,
+  HelpText<"Target linker version">;
 def triple : Separate<"-triple">,
   HelpText<"Specify target triple (e.g. i686-apple-darwin9)">;
 def triple_EQ : Joined<"-triple=">, Alias<triple>;
@@ -36,6 +40,8 @@
   HelpText<"Display Control-Flow Graphs">;
 def analysis_CFGView : Flag<"-cfg-view">,
   HelpText<"View Control-Flow Graphs using GraphViz">;
+def analysis_UnoptimizedCFG : Flag<"-unoptimized-cfg">,
+  HelpText<"Generate unoptimized CFGs for all analyses">;
 def analysis_DisplayLiveVariables : Flag<"-dump-live-variables">,
   HelpText<"Print results of live variable analysis">;
 def analysis_LLVMConventionChecker : Flag<"-analyzer-check-llvm-conventions">,
@@ -56,8 +62,8 @@
   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 analysis_WarnIdempotentOps : Flag<"-analyzer-check-idempotent-operations">,
+  HelpText<"Warn about idempotent operations">;
 
 def analyzer_store : Separate<"-analyzer-store">,
   HelpText<"Source Code Analysis - Abstract Memory Store Models">;
@@ -97,8 +103,12 @@
   HelpText<"Display exploded graph using GraphViz">;
 def analyzer_viz_egraph_ubigraph : Flag<"-analyzer-viz-egraph-ubigraph">,
   HelpText<"Display exploded graph using Ubigraph">;
+def analyzer_inline_call : Flag<"-analyzer-inline-call">,
+  HelpText<"Experimental transfer function inlining callees when its definition is available.">;
 def analyzer_max_nodes : Separate<"-analyzer-max-nodes">,
   HelpText<"The maximum number of nodes the analyzer can generate">;
+def analyzer_max_loop : Separate<"-analyzer-max-loop">,
+  HelpText<"The maximum number of times the analyzer will go through a loop">;
 
 //===----------------------------------------------------------------------===//
 // CodeGen Options
@@ -119,6 +129,8 @@
   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 finstrument_functions : Flag<"-finstrument-functions">,
+  HelpText<"Generate calls to instrument function entry and exit">;
 def fno_merge_all_constants : Flag<"-fno-merge-all-constants">,
   HelpText<"Disallow merging of constants.">;
 def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">,
@@ -129,6 +141,8 @@
   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 funroll_loops : Flag<"-funroll-loops">,
+  HelpText<"Turn on loop unroller">;
 def masm_verbose : Flag<"-masm-verbose">,
   HelpText<"Generate verbose assembly output">;
 def mcode_model : Separate<"-mcode-model">,
@@ -143,8 +157,12 @@
   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 momit_leaf_frame_pointer : Flag<"-momit-leaf-frame-pointer">,
+  HelpText<"Omit frame pointer setup for leaf functions.">;
 def msoft_float : Flag<"-msoft-float">,
   HelpText<"Use software floating point">;
+def mrelax_all : Flag<"-mrelax-all">,
+  HelpText<"Relax all machine instructions">;
 def mrelocation_model : Separate<"-mrelocation-model">,
   HelpText<"The relocation model to use">;
 def munwind_tables : Flag<"-munwind-tables">,
@@ -178,6 +196,9 @@
   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 fshow_overloads_EQ : Joined<"-fshow-overloads=">,
+  HelpText<"Which overload candidates to show when overload resolution fails: "
+           "best|all; defaults to all">;
 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">,
@@ -194,12 +215,19 @@
 
 def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">,
   HelpText<"Print source range spans in numeric form">;
+def fdiagnostics_parseable_fixits : Flag<"-fdiagnostics-parseable-fixits">,
+  HelpText<"Print fix-its in machine parseable form">;
 def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">,
   HelpText<"Print diagnostic name with mappable diagnostics">;
+def fdiagnostics_show_category : Separate<"-fdiagnostics-show-category">,
+  HelpText<"Print diagnostic category">;
+  
 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 fmacro_backtrace_limit : Separate<"-fmacro-backtrace-limit">, MetaVarName<"<N>">,
+  HelpText<"Set the maximum number of entries to print in a macro instantiation backtrace (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>">,
@@ -209,7 +237,7 @@
 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">;
+  HelpText<"Remove const qualifier from string literals">;
 def verify : Flag<"-verify">,
   HelpText<"Verify emitted diagnostics and warnings">;
 
@@ -236,6 +264,10 @@
   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 code_completion_patterns : Flag<"-code-completion-patterns">,
+  HelpText<"Include code patterns in code-completion results">;
+def no_code_completion_globals : Flag<"-no-code-completion-globals">,
+  HelpText<"Do not include global declarations in code-completion results.">;
 def disable_free : Flag<"-disable-free">,
   HelpText<"Disable freeing of memory on exit">;
 def help : Flag<"-help">,
@@ -248,8 +280,11 @@
 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">,
+def plugin : Separate<"-plugin">, MetaVarName<"<name>">,
   HelpText<"Use the named plugin action (use \"help\" to list available options)">;
+def plugin_arg : JoinedAndSeparate<"-plugin-arg-">, 
+    MetaVarName<"<name> <arg>">,
+    HelpText<"Pass <arg> to plugin <name>">;
 def resource_dir : Separate<"-resource-dir">,
   HelpText<"The directory which holds the compiler resource files">;
 def version : Flag<"-version">,
@@ -271,16 +306,15 @@
   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 print_preamble : Flag<"-print-preamble">,
+  HelpText<"Print the \"preamble\" of a file, which is a candidate for implicit"
+           " precompiled headers.">;
 def emit_html : Flag<"-emit-html">,
   HelpText<"Output input source as HTML">;
 def ast_print : Flag<"-ast-print">,
@@ -291,6 +325,8 @@
   HelpText<"Build ASTs and then debug dump them">;
 def ast_view : Flag<"-ast-view">,
   HelpText<"Build ASTs and view them with GraphViz">;
+def boostcon : Flag<"-boostcon">,
+  HelpText<"BoostCon workshop mode">;
 def print_decl_contexts : Flag<"-print-decl-contexts">,
   HelpText<"Print DeclContexts and their Decls">;
 def emit_pth : Flag<"-emit-pth">,
@@ -305,6 +341,8 @@
   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_codegen_only : Flag<"-emit-codegen-only">,
+  HelpText<"Generate machine code, but discard output">;
 def emit_obj : Flag<"-emit-obj">,
   HelpText<"Emit native object files">;
 def rewrite_test : Flag<"-rewrite-test">,
@@ -314,17 +352,25 @@
 def rewrite_macros : Flag<"-rewrite-macros">,
   HelpText<"Expand macros without full preprocessing">;
 
+def create_module : Flag<"-create-module">,
+  HelpText<"Create a module definition file">;
 }
 
+def import_module : Separate<"-import-module">,
+  HelpText<"Import a module definition file">;
+
 def relocatable_pch : Flag<"-relocatable-pch">,
   HelpText<"Whether to build a relocatable precompiled header">;
+def chained_pch : Flag<"-chained-pch">,
+  HelpText<"Whether to chain the new precompiled header to the old one.">;
 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">;
+def fix_what_you_can : Flag<"-fix-what-you-can">,
+  HelpText<"Apply fix-it advice even in the presence of unfixable errors">;
 
 // Generic forwarding to LLVM options. This should only be used for debugging
 // and experimental features.
@@ -364,6 +410,8 @@
   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 fhidden_weak_vtables : Flag<"-fhidden-weak-vtables">,
+  HelpText<"Generate weak vtables and RTTI with hidden visibility">;
 def std_EQ : Joined<"-std=">,
   HelpText<"Language standard to compile for">;
 def fmath_errno : Flag<"-fmath-errno">,
@@ -380,6 +428,8 @@
   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_spell_checking : Flag<"-fno-spell-checking">,
+  HelpText<"Disable spell-checking">;  
 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">,
@@ -401,6 +451,8 @@
   HelpText<"enable objective-c's enhanced nonfragile abi">;
 def ftrapv : Flag<"-ftrapv">,
   HelpText<"Trap on integer overflow">;
+def fwrapv : Flag<"-fwrapv">,
+  HelpText<"Treat signed integer overflow as two's complement">;
 def pic_level : Separate<"-pic-level">,
   HelpText<"Value for __PIC__">;
 def pthread : Flag<"-pthread">,
@@ -409,6 +461,8 @@
   HelpText<"Recognize and construct Pascal-style string literals">;
 def fno_rtti : Flag<"-fno-rtti">,
   HelpText<"Disable generation of rtti information">;
+def fno_validate_pch : Flag<"-fno-validate-pch">,
+  HelpText<"Disable validation of precompiled headers">;
 def fshort_wchar : Flag<"-fshort-wchar">,
   HelpText<"Force wchar_t to be a short unsigned int">;
 def static_define : Flag<"-static-define">,
@@ -417,6 +471,8 @@
   HelpText<"Enable stack protectors">;
 def fvisibility : Separate<"-fvisibility">,
   HelpText<"Default symbol visibility">;
+def fvisibility_inlines_hidden : Flag<"-fvisibility-inlines-hidden">,
+  HelpText<"Give inline C++ member functions default visibility by default">;
 def ftemplate_depth : Separate<"-ftemplate-depth">,
   HelpText<"Maximum depth of recursive template instantiation">;
 def trigraphs : Flag<"-trigraphs">,
@@ -446,6 +502,9 @@
   HelpText<"Add directory to QUOTE include search path">;
 def isystem : JoinedOrSeparate<"-isystem">, MetaVarName<"<directory>">,
   HelpText<"Add directory to SYSTEM include search path">;
+def iwithsysroot : JoinedOrSeparate<"-iwithsysroot">,MetaVarName<"<directory>">,
+  HelpText<"Add directory to SYSTEM include search path, "
+           "absolute paths are relative to -isysroot">;
 def iprefix : JoinedOrSeparate<"-iprefix">, MetaVarName<"<prefix>">,
   HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">;
 def iwithprefix : JoinedOrSeparate<"-iwithprefix">, MetaVarName<"<dir>">,
@@ -471,6 +530,9 @@
   HelpText<"Include precompiled header file">;
 def include_pth : Separate<"-include-pth">, MetaVarName<"<file>">,
   HelpText<"Include file before parsing">;
+def preamble_bytes_EQ : Joined<"-preamble-bytes=">,
+  HelpText<"Assume that the precompiled header is a precompiled preamble "
+           "covering the first N bytes of the main file">;
 def token_cache : Separate<"-token-cache">, MetaVarName<"<path>">,
   HelpText<"Use specified token cache file">;
 def U : JoinedOrSeparate<"-U">, MetaVarName<"<macro>">,
@@ -494,3 +556,5 @@
   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">;
+def H : Flag<"-H">,
+  HelpText<"Show header includes and nesting depth">;
diff --git a/include/clang/Driver/CMakeLists.txt b/include/clang/Driver/CMakeLists.txt
index ed9825b..99be53f 100644
--- a/include/clang/Driver/CMakeLists.txt
+++ b/include/clang/Driver/CMakeLists.txt
@@ -9,3 +9,9 @@
          -gen-opt-parser-defs)
 add_custom_target(ClangCC1Options
   DEPENDS CC1Options.inc)
+
+set(LLVM_TARGET_DEFINITIONS CC1AsOptions.td)
+tablegen(CC1AsOptions.inc
+         -gen-opt-parser-defs)
+add_custom_target(ClangCC1AsOptions
+  DEPENDS CC1AsOptions.inc)
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
index 56786a7..22d6b4e 100644
--- a/include/clang/Driver/Compilation.h
+++ b/include/clang/Driver/Compilation.h
@@ -40,13 +40,18 @@
   /// The original (untranslated) input argument list.
   InputArgList *Args;
 
+  /// The driver translated arguments. Note that toolchains may perform their
+  /// own argument translation.
+  DerivedArgList *TranslatedArgs;
+
   /// The list of actions.
   ActionList Actions;
 
   /// The root list of jobs.
   JobList Jobs;
 
-  /// Cache of translated arguments for a particular tool chain.
+  /// Cache of translated arguments for a particular tool chain and bound
+  /// architecture.
   llvm::DenseMap<std::pair<const ToolChain*, const char*>,
                  DerivedArgList*> TCArgs;
 
@@ -58,14 +63,16 @@
 
 public:
   Compilation(const Driver &D, const ToolChain &DefaultToolChain,
-              InputArgList *Args);
+              InputArgList *Args, DerivedArgList *TranslatedArgs);
   ~Compilation();
 
   const Driver &getDriver() const { return TheDriver; }
 
   const ToolChain &getDefaultToolChain() const { return DefaultToolChain; }
 
-  const InputArgList &getArgs() const { return *Args; }
+  const InputArgList &getInputArgs() const { return *Args; }
+
+  const DerivedArgList &getArgs() const { return *TranslatedArgs; }
 
   ActionList &getActions() { return Actions; }
   const ActionList &getActions() const { return Actions; }
@@ -73,6 +80,8 @@
   JobList &getJobs() { return Jobs; }
   const JobList &getJobs() const { return Jobs; }
 
+  void addCommand(Command *C) { Jobs.addJob(C); }
+
   const ArgStringList &getTempFiles() const { return TempFiles; }
 
   const ArgStringList &getResultFiles() const { return ResultFiles; }
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 90c3a0d..28eff4f 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -31,12 +31,12 @@
   class Action;
   class ArgList;
   class Compilation;
+  class DerivedArgList;
   class HostInfo;
   class InputArgList;
   class InputInfo;
   class JobAction;
   class OptTable;
-  class PipedJob;
   class ToolChain;
 
 /// Driver - Encapsulate logic for constructing compilation processes
@@ -61,6 +61,12 @@
   /// command line.
   std::string Dir;
 
+  /// The original path to the clang executable.
+  std::string ClangExecutable;
+
+  /// The path to the installed clang directory, if any.
+  std::string InstalledDir;
+
   /// The path to the compiler resource directory.
   std::string ResourceDir;
 
@@ -135,8 +141,13 @@
   std::list<std::string> TempFiles;
   std::list<std::string> ResultFiles;
 
+private:
+  /// TranslateInputArgs - Create a new derived argument list from the input
+  /// arguments, after applying the standard argument translations.
+  DerivedArgList *TranslateInputArgs(const InputArgList &Args) const;
+
 public:
-  Driver(llvm::StringRef _Name, llvm::StringRef _Dir,
+  Driver(llvm::StringRef _ClangExecutable,
          llvm::StringRef _DefaultHostTriple,
          llvm::StringRef _DefaultImageName,
          bool IsProduction, bool CXXIsProduction,
@@ -157,6 +168,21 @@
   const std::string &getTitle() { return DriverTitle; }
   void setTitle(std::string Value) { DriverTitle = Value; }
 
+  /// \brief Get the path to the main clang executable.
+  const char *getClangProgramPath() const {
+    return ClangExecutable.c_str();
+  }
+
+  /// \brief Get the path to where the clang executable was installed.
+  const char *getInstalledDir() const {
+    if (!InstalledDir.empty())
+      return InstalledDir.c_str();
+    return Dir.c_str();
+  }
+  void setInstalledDir(llvm::StringRef Value) {
+    InstalledDir = Value;
+  }
+
   /// @}
   /// @name Primary Functionality
   /// @{
@@ -180,16 +206,20 @@
   /// BuildActions - Construct the list of actions to perform for the
   /// given arguments, which are only done for a single architecture.
   ///
+  /// \param TC - The default host tool chain.
   /// \param Args - The input arguments.
   /// \param Actions - The list to store the resulting actions onto.
-  void BuildActions(const ArgList &Args, ActionList &Actions) const;
+  void BuildActions(const ToolChain &TC, 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 TC - The default host tool chain.
   /// \param Args - The input arguments.
   /// \param Actions - The list to store the resulting actions onto.
-  void BuildUniversalActions(const ArgList &Args, ActionList &Actions) const;
+  void BuildUniversalActions(const ToolChain &TC, const ArgList &Args,
+                             ActionList &Actions) const;
 
   /// BuildJobs - Bind actions to concrete tools and translate
   /// arguments to form the list of jobs to run.
@@ -264,7 +294,6 @@
                           const Action *A,
                           const ToolChain *TC,
                           const char *BoundArch,
-                          bool CanAcceptPipe,
                           bool AtTopLevel,
                           const char *LinkingOutput,
                           InputInfo &Result) const;
diff --git a/include/clang/Driver/DriverDiagnostic.h b/include/clang/Driver/DriverDiagnostic.h
index d4a9da7..c20d807 100644
--- a/include/clang/Driver/DriverDiagnostic.h
+++ b/include/clang/Driver/DriverDiagnostic.h
@@ -15,7 +15,7 @@
 namespace clang {
   namespace diag {
     enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
 #define DRIVERSTART
 #include "clang/Basic/DiagnosticDriverKinds.inc"
 #undef DIAG
diff --git a/include/clang/Driver/HostInfo.h b/include/clang/Driver/HostInfo.h
index ca1ee9a..04e7299 100644
--- a/include/clang/Driver/HostInfo.h
+++ b/include/clang/Driver/HostInfo.h
@@ -10,7 +10,6 @@
 #ifndef CLANG_DRIVER_HOSTINFO_H_
 #define CLANG_DRIVER_HOSTINFO_H_
 
-#include "clang/Driver/Types.h"
 #include "llvm/ADT/Triple.h"
 #include <string>
 
@@ -48,10 +47,6 @@
   /// 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).
   ///
@@ -76,12 +71,18 @@
                                       const llvm::Triple& Triple);
 const HostInfo *createFreeBSDHostInfo(const Driver &D,
                                       const llvm::Triple& Triple);
+const HostInfo *createMinixHostInfo(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 *createWindowsHostInfo(const Driver &D,
+                                      const llvm::Triple &Triple);
+const HostInfo *createMinGWHostInfo(const Driver &D,
+                                    const llvm::Triple &Triple);
 const HostInfo *createUnknownHostInfo(const Driver &D,
                                       const llvm::Triple& Triple);
 
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
index 5a789fb..d2767d1 100644
--- a/include/clang/Driver/Job.h
+++ b/include/clang/Driver/Job.h
@@ -29,7 +29,6 @@
 public:
   enum JobClass {
     CommandClass,
-    PipedJobClass,
     JobListClass
   };
 
@@ -86,39 +85,6 @@
   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:
diff --git a/include/clang/Driver/Makefile b/include/clang/Driver/Makefile
index 18f3e58..d829166 100644
--- a/include/clang/Driver/Makefile
+++ b/include/clang/Driver/Makefile
@@ -1,9 +1,9 @@
-LEVEL = ../../../../..
-BUILT_SOURCES = Options.inc CC1Options.inc
+CLANG_LEVEL := ../../..
+BUILT_SOURCES = Options.inc CC1Options.inc CC1AsOptions.inc
 
 TABLEGEN_INC_FILES_COMMON = 1
 
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
 
 $(ObjDir)/Options.inc.tmp : Options.td OptParser.td $(TBLGEN) $(ObjDir)/.dir
 	$(Echo) "Building Clang Driver Option tables with tblgen"
@@ -13,4 +13,6 @@
 	$(Echo) "Building Clang CC1 Option tables with tblgen"
 	$(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
 
-
+$(ObjDir)/CC1AsOptions.inc.tmp : CC1AsOptions.td OptParser.td $(TBLGEN) $(ObjDir)/.dir
+	$(Echo) "Building Clang CC1 Assembler 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
index a9f4289..04efd00 100644
--- a/include/clang/Driver/OptParser.td
+++ b/include/clang/Driver/OptParser.td
@@ -82,6 +82,9 @@
 // arguments to implement hidden help groups.
 def HelpHidden : OptionFlag;
 
+// NoForward - The option should not be implicitly forwarded to other tools.
+def NoForward : OptionFlag;
+
 // Define the option group class.
 
 class OptionGroup<string name> {
diff --git a/include/clang/Driver/OptTable.h b/include/clang/Driver/OptTable.h
index edae75c..08b483c 100644
--- a/include/clang/Driver/OptTable.h
+++ b/include/clang/Driver/OptTable.h
@@ -25,14 +25,16 @@
     HelpHidden       = (1 << 1),
     LinkerInput      = (1 << 2),
     NoArgumentUnused = (1 << 3),
-    RenderAsInput    = (1 << 4),
-    RenderJoined     = (1 << 5),
-    RenderSeparate   = (1 << 6),
-    Unsupported      = (1 << 7)
+    NoForward        = (1 << 4),
+    RenderAsInput    = (1 << 5),
+    RenderJoined     = (1 << 6),
+    RenderSeparate   = (1 << 7),
+    Unsupported      = (1 << 8)
   };
 }
 
   class Arg;
+  class ArgList;
   class InputArgList;
   class Option;
 
@@ -51,7 +53,7 @@
       const char *HelpText;
       const char *MetaVar;
       unsigned char Kind;
-      unsigned char Flags;
+      unsigned short Flags;
       unsigned char Param;
       unsigned short GroupID;
       unsigned short AliasID;
@@ -150,7 +152,7 @@
     /// \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;
+    Arg *ParseOneArg(const ArgList &Args, unsigned &Index) const;
 
     /// ParseArgs - Parse an list of arguments into an InputArgList.
     ///
diff --git a/include/clang/Driver/Option.h b/include/clang/Driver/Option.h
index 08b94b1..9625465 100644
--- a/include/clang/Driver/Option.h
+++ b/include/clang/Driver/Option.h
@@ -21,7 +21,7 @@
 namespace clang {
 namespace driver {
   class Arg;
-  class InputArgList;
+  class ArgList;
   class OptionGroup;
 
   /// Option - Abstract representation for a single form of driver
@@ -50,6 +50,13 @@
       JoinedAndSeparateClass
     };
 
+    enum RenderStyleKind {
+      RenderCommaJoinedStyle,
+      RenderJoinedStyle,
+      RenderSeparateStyle,
+      RenderValuesStyle
+    };
+
   private:
     OptionClass Kind;
 
@@ -65,7 +72,7 @@
     /// Option that this is an alias for, if any.
     const Option *Alias;
 
-    /// Unsupported options will not be rejected.
+    /// Unsupported options will be rejected.
     bool Unsupported : 1;
 
     /// Treat this option like a linker input?
@@ -76,11 +83,8 @@
     // 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;
+    /// The style to using when rendering arguments parsed by this option.
+    unsigned RenderStyle : 2;
 
     /// This option is only consumed by the driver.
     bool DriverOption : 1;
@@ -88,6 +92,9 @@
     /// This option should not report argument unused errors.
     bool NoArgumentUnused : 1;
 
+    /// This option should not be implicitly forwarded.
+    bool NoForward : 1;
+
   protected:
     Option(OptionClass Kind, OptSpecifier ID, const char *Name,
            const OptionGroup *Group, const Option *Alias);
@@ -109,11 +116,10 @@
     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; }
+    RenderStyleKind getRenderStyle() const {
+      return RenderStyleKind(RenderStyle);
+    }
+    void setRenderStyle(RenderStyleKind Value) { RenderStyle = Value; }
 
     bool isDriverOption() const { return DriverOption; }
     void setDriverOption(bool Value) { DriverOption = Value; }
@@ -121,7 +127,12 @@
     bool hasNoArgumentUnused() const { return NoArgumentUnused; }
     void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; }
 
-    bool hasForwardToGCC() const { return !DriverOption && !LinkerInput; }
+    bool hasNoForward() const { return NoForward; }
+    void setNoForward(bool Value) { NoForward = Value; }
+
+    bool hasForwardToGCC() const {
+      return !NoForward && !DriverOption && !LinkerInput;
+    }
 
     /// getUnaliasedOption - Return the final option this option
     /// aliases (itself, if the option has no alias).
@@ -151,7 +162,7 @@
     /// 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;
+    virtual Arg *accept(const ArgList &Args, unsigned &Index) const = 0;
 
     void dump() const;
 
@@ -164,7 +175,7 @@
   public:
     OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group);
 
-    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
 
     static bool classof(const Option *O) {
       return O->getKind() == Option::GroupClass;
@@ -179,7 +190,7 @@
   public:
     InputOption(OptSpecifier ID);
 
-    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
 
     static bool classof(const Option *O) {
       return O->getKind() == Option::InputClass;
@@ -192,7 +203,7 @@
   public:
     UnknownOption(OptSpecifier ID);
 
-    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
 
     static bool classof(const Option *O) {
       return O->getKind() == Option::UnknownClass;
@@ -207,7 +218,7 @@
     FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
                const Option *Alias);
 
-    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
 
     static bool classof(const Option *O) {
       return O->getKind() == Option::FlagClass;
@@ -220,7 +231,7 @@
     JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
                  const Option *Alias);
 
-    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
 
     static bool classof(const Option *O) {
       return O->getKind() == Option::JoinedClass;
@@ -233,7 +244,7 @@
     SeparateOption(OptSpecifier ID, const char *Name,
                    const OptionGroup *Group, const Option *Alias);
 
-    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
 
     static bool classof(const Option *O) {
       return O->getKind() == Option::SeparateClass;
@@ -246,7 +257,7 @@
     CommaJoinedOption(OptSpecifier ID, const char *Name,
                       const OptionGroup *Group, const Option *Alias);
 
-    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
 
     static bool classof(const Option *O) {
       return O->getKind() == Option::CommaJoinedClass;
@@ -267,7 +278,7 @@
 
     unsigned getNumArgs() const { return NumArgs; }
 
-    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
 
     static bool classof(const Option *O) {
       return O->getKind() == Option::MultiArgClass;
@@ -282,7 +293,7 @@
     JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
                            const OptionGroup *Group, const Option *Alias);
 
-    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
 
     static bool classof(const Option *O) {
       return O->getKind() == Option::JoinedOrSeparateClass;
@@ -297,7 +308,7 @@
     JoinedAndSeparateOption(OptSpecifier ID, const char *Name,
                             const OptionGroup *Group, const Option *Alias);
 
-    virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
+    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
 
     static bool classof(const Option *O) {
       return O->getKind() == Option::JoinedAndSeparateClass;
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 1487121..ef0d62f 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -124,11 +124,11 @@
 def D : JoinedOrSeparate<"-D">, Group<CompileOnly_Group>;
 def E : Flag<"-E">, Flags<[DriverOption]>,
   HelpText<"Only run the preprocessor">;
-def F : JoinedOrSeparate<"-F">;
+def F : JoinedOrSeparate<"-F">, Flags<[RenderJoined]>;
 def H : Flag<"-H">;
 def I_ : Flag<"-I-">, Group<I_Group>;
 def I : JoinedOrSeparate<"-I">, Group<I_Group>;
-def L : JoinedOrSeparate<"-L">;
+def L : JoinedOrSeparate<"-L">, Flags<[RenderJoined]>;
 def MD : Flag<"-MD">, Group<M_Group>;
 def MF : JoinedOrSeparate<"-MF">, Group<M_Group>;
 def MG : Flag<"-MG">, Group<M_Group>;
@@ -139,6 +139,7 @@
 def MT : JoinedOrSeparate<"-MT">, Group<M_Group>;
 def Mach : Flag<"-Mach">;
 def M : Flag<"-M">, Group<M_Group>;
+def O0 : Joined<"-O0">, Group<O_Group>;
 def O4 : Joined<"-O4">, Group<O_Group>;
 def ObjCXX : Flag<"-ObjC++">, Flags<[DriverOption]>,
   HelpText<"Treat source input files as Objective-C++ inputs">;
@@ -179,7 +180,8 @@
 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>">;
+  HelpText<"Pass <arg> to the clang compiler">, MetaVarName<"<arg>">,
+  Flags<[NoForward]>;
 def Xlinker : Separate<"-Xlinker">, Flags<[LinkerInput, RenderAsInput]>,
   HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">;
 def Xpreprocessor : Separate<"-Xpreprocessor">,
@@ -229,8 +231,10 @@
 def e : JoinedOrSeparate<"-e">;
 def fPIC : Flag<"-fPIC">, Group<f_Group>;
 def fPIE : Flag<"-fPIE">, Group<f_Group>;
+def fno_PIE : Flag<"-fno-PIE">, Group<f_Group>;
 def faccess_control : Flag<"-faccess-control">, Group<f_Group>;
 def fapple_kext : Flag<"-fapple-kext">, Group<f_Group>;
+def fasm : Flag<"-fasm">, 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>;
@@ -242,13 +246,14 @@
 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 fcaret_diagnostics : Flag<"-fcaret-diagnostics">, 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_cfstrings : Flag<"-fconstant-cfstrings">, Group<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>;
@@ -256,7 +261,9 @@
 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_parseable_fixits : Flag<"-fdiagnostics-parseable-fixits">, Group<f_Group>;
 def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>;
+def fdiagnostics_show_category_EQ : Joined<"-fdiagnostics-show-category=">, 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>;
@@ -264,22 +271,24 @@
 def fexceptions : Flag<"-fexceptions">, Group<f_Group>;
 def fextdirs_EQ : Joined<"-fextdirs=">, Group<f_Group>;
 def fhosted : Flag<"-fhosted">, Group<f_Group>;
+def ffast_math : Flag<"-ffast-math">, Group<clang_ignored_f_Group>;
+def ffinite_math_only : Flag<"-ffinite-math-only">, Group<clang_ignored_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 finstrument_functions : Flag<"-finstrument-functions">, Group<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 fmacro_backtrace_limit_EQ : Joined<"-fmacro-backtrace-limit=">, 
+                                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>;
@@ -289,6 +298,7 @@
 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_asm : Flag<"-fno-asm">, 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>;
@@ -304,10 +314,8 @@
 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_finite_math_only : Flag<"-fno-finite-math-only">, Group<clang_ignored_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>;
@@ -321,14 +329,17 @@
 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_spell_checking : Flag<"-fno-spell-checking">, 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_verbose_asm : Flag<"-fno-verbose-asm">, 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_abi_version_EQ : Joined<"-fobjc-abi-version=">, 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>;
@@ -348,15 +359,19 @@
 def fpch_preprocess : Flag<"-fpch-preprocess">, Group<f_Group>;
 def fpic : Flag<"-fpic">, Group<f_Group>;
 def fpie : Flag<"-fpie">, Group<f_Group>;
+def fno_pie : Flag<"-fno-pie">, 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 frandom_seed_EQ : Joined<"-frandom-seed=">, Group<clang_ignored_f_Group>;
 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_overloads_EQ : Joined<"-fshow-overloads=">, Group<f_Group>;
 def fshow_source_location : Flag<"-fshow-source-location">, Group<f_Group>;
+def fspell_checking : Flag<"-fspell-checking">, 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>;
@@ -373,14 +388,19 @@
 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 funroll_loops : Flag<"-funroll-loops">, 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 fvisibility_inlines_hidden : Flag<"-fvisibility-inlines-hidden">, Group<f_Group>;
+def fwrapv : Flag<"-fwrapv">, 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 ffunction_sections: Flag <"-ffunction-sections">, Group<f_Group>;
+def fdata_sections : Flag <"-fdata-sections">, Group<f_Group>;
 def f : Joined<"-f">, Group<f_Group>;
 def g0 : Joined<"-g0">, Group<g_Group>;
 def g3 : Joined<"-g3">, Group<g_Group>;
@@ -404,7 +424,7 @@
 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 iwithsysroot : JoinedOrSeparate<"-iwithsysroot">, Group<clang_i_Group>;
 def i : Joined<"-i">, Group<i_Group>;
 def keep__private__externs : Flag<"-keep_private_externs">;
 def l : JoinedOrSeparate<"-l">, Flags<[LinkerInput, RenderJoined]>;
@@ -422,10 +442,12 @@
 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 miphoneos_version_min_EQ : Joined<"-miphoneos-version-min=">, Group<m_Group>;
+def mios_version_min_EQ : Joined<"-mios-version-min=">, Alias<miphoneos_version_min_EQ>;
 def mkernel : Flag<"-mkernel">, Group<m_Group>;
+def mlinker_version_EQ : Joined<"-mlinker-version=">, Flags<[NoForward]>;
 def mllvm : Separate<"-mllvm">;
-def mmacosx_version_min_EQ : Joined<"-mmacosx-version-min=">, Group<m_Group>, Flags<[DriverOption]>;
+def mmacosx_version_min_EQ : Joined<"-mmacosx-version-min=">, Group<m_Group>;
 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>;
@@ -433,6 +455,7 @@
 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_relax_all : Flag<"-mno-relax-all">, 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>;
@@ -443,13 +466,17 @@
 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_avx : Flag<"-mno-avx">, 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 mno_omit_leaf_frame_pointer : Flag<"-mno-omit-leaf-frame-pointer">, Group<f_Group>;
+def momit_leaf_frame_pointer : Flag<"-momit-leaf-frame-pointer">, Group<f_Group>;
 def mpascal_strings : Flag<"-mpascal-strings">, Group<m_Group>;
 def mred_zone : Flag<"-mred-zone">, Group<m_Group>;
+def mrelax_all : Flag<"-mrelax-all">, 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>;
@@ -460,6 +487,7 @@
 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 mavx : Flag<"-mavx">, 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">;
@@ -579,7 +607,7 @@
 // options.
 
 def _CLASSPATH_EQ : Joined<"--CLASSPATH=">, Alias<fclasspath_EQ>;
-def _CLASSPATH : Separate<"--CLASSPATH">, Alias<fclasspath_EQ>, Flags<[RenderJoined]>;
+def _CLASSPATH : Separate<"--CLASSPATH">, Alias<fclasspath_EQ>;
 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]>;
@@ -588,82 +616,83 @@
   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_EQ : Joined<"--assert=">, Alias<A>;
 def _assert : Separate<"--assert">, Alias<A>;
 def _bootclasspath_EQ : Joined<"--bootclasspath=">, Alias<fbootclasspath_EQ>;
-def _bootclasspath : Separate<"--bootclasspath">, Alias<fbootclasspath_EQ>, Flags<[RenderJoined]>;
+def _bootclasspath : Separate<"--bootclasspath">, Alias<fbootclasspath_EQ>;
 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 _classpath : Separate<"--classpath">, Alias<fclasspath_EQ>;
+def _combine : Flag<"--combine">, Alias<combine>;
 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 _debug_EQ : Joined<"--debug=">, Alias<g_Flag>;
+def _debug : Flag<"--debug">, Alias<g_Flag>;
 def _define_macro_EQ : Joined<"--define-macro=">, Alias<D>;
-def _define_macro : Separate<"--define-macro">, Alias<D>, Flags<[RenderJoined]>;
+def _define_macro : Separate<"--define-macro">, Alias<D>;
 def _dependencies : Flag<"--dependencies">, Alias<M>;
 def _encoding_EQ : Joined<"--encoding=">, Alias<fencoding_EQ>;
-def _encoding : Separate<"--encoding">, Alias<fencoding_EQ>, Flags<[RenderJoined]>;
+def _encoding : Separate<"--encoding">, Alias<fencoding_EQ>;
 def _entry : Flag<"--entry">, Alias<e>;
 def _extdirs_EQ : Joined<"--extdirs=">, Alias<fextdirs_EQ>;
-def _extdirs : Separate<"--extdirs">, Alias<fextdirs_EQ>, Flags<[RenderJoined]>;
+def _extdirs : Separate<"--extdirs">, Alias<fextdirs_EQ>;
 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 _for_linker_EQ : Joined<"--for-linker=">, Alias<Xlinker>;
+def _for_linker : Separate<"--for-linker">, Alias<Xlinker>;
+def _force_link_EQ : Joined<"--force-link=">, Alias<u>;
 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_EQ : Joined<"--imacros=">, Alias<imacros>;
 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_EQ : Joined<"--include-directory-after=">, Alias<idirafter>;
 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_directory : Separate<"--include-directory">, Alias<I>;
+def _include_prefix_EQ : Joined<"--include-prefix=">, Alias<iprefix>;
 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_EQ : Joined<"--include-with-prefix-after=">, Alias<iwithprefix>;
 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_EQ : Joined<"--include-with-prefix-before=">, Alias<iwithprefixbefore>;
 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_EQ : Joined<"--include-with-prefix=">, Alias<iwithprefix>;
 def _include_with_prefix : Separate<"--include-with-prefix">, Alias<iwithprefix>;
-def _include_EQ : Joined<"--include=">, Alias<include_>, Flags<[RenderSeparate]>;
+def _include_EQ : Joined<"--include=">, Alias<include_>;
 def _include : Separate<"--include">, Alias<include_>;
-def _language_EQ : Joined<"--language=">, Alias<x>, Flags<[RenderSeparate]>;
+def _language_EQ : Joined<"--language=">, Alias<x>;
 def _language : Separate<"--language">, Alias<x>;
-def _library_directory_EQ : Joined<"--library-directory=">, Alias<L>, Flags<[RenderSeparate]>;
+def _library_directory_EQ : Joined<"--library-directory=">, Alias<L>;
 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_ : Joined<"--machine-">, Alias<m_Joined>;
 def _machine_EQ : Joined<"--machine=">, Alias<m_Joined>;
-def _machine : Separate<"--machine">, Alias<m_Joined>, Flags<[RenderJoined]>;
+def _machine : Separate<"--machine">, Alias<m_Joined>;
 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 _optimize_EQ : Joined<"--optimize=">, Alias<O>;
+def _optimize : Flag<"--optimize">, Alias<O>;
 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_class_directory : Separate<"--output-class-directory">, Alias<foutput_class_dir_EQ>;
+def _output_EQ : Joined<"--output=">, Alias<o>;
 def _output : Separate<"--output">, Alias<o>;
 def _param : Separate<"--param">;
-def _param_EQ : Joined<"--param=">, Alias<_param>, Flags<[RenderSeparate]>;
+def _param_EQ : Joined<"--param=">, Alias<_param>;
 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 _pipe : Flag<"--pipe">, Alias<pipe>;
+def _prefix_EQ : Joined<"--prefix=">, Alias<B>;
 def _prefix : Separate<"--prefix">, Alias<B>;
 def _preprocess : Flag<"--preprocess">, Alias<E>;
+def _print_diagnostic_categories : Flag<"--print-diagnostic-categories">;
 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>;
@@ -679,30 +708,33 @@
 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 _resource : Separate<"--resource">, Alias<fcompile_resource_EQ>;
 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 _specs_EQ : Joined<"--specs=">, Alias<specs_EQ>;
+def _specs : Separate<"--specs">, Alias<specs_EQ>;
 def _static : Flag<"--static">, Alias<static>;
 def _std_EQ : Joined<"--std=">, Alias<std_EQ>;
-def _std : Separate<"--std">, Alias<std_EQ>, Flags<[RenderJoined]>;
+def _std : Separate<"--std">, Alias<std_EQ>;
 def _sysroot_EQ : Joined<"--sysroot=">;
-def _sysroot : Separate<"--sysroot">, Alias<_sysroot_EQ>, Flags<[RenderJoined]>;
+def _sysroot : Separate<"--sysroot">, Alias<_sysroot_EQ>;
 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 _undefine_macro : Separate<"--undefine-macro">, Alias<U>;
 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 _warn__EQ : Joined<"--warn-=">, Alias<W_Joined>;
+def _warn_ : Joined<"--warn-">, Alias<W_Joined>;
 def _write_dependencies : Flag<"--write-dependencies">, Alias<MD>;
 def _write_user_dependencies : Flag<"--write-user-dependencies">, Alias<MMD>;
-def _ : Joined<"--">, Alias<f>, Flags<[Unsupported]>;
+def _ : Joined<"--">, Flags<[Unsupported]>;
+
+// Special internal option to handle -Xlinker --no-demangle.
+def Z_Xlinker__no_demangle : Flag<"-Z-Xlinker-no-demangle">, Flags<[Unsupported]>;
diff --git a/include/clang/Driver/Tool.h b/include/clang/Driver/Tool.h
index ef77206..c30fa4c 100644
--- a/include/clang/Driver/Tool.h
+++ b/include/clang/Driver/Tool.h
@@ -30,21 +30,25 @@
   /// The tool name (for debugging).
   const char *Name;
 
+  /// The human readable name for the tool, for use in diagnostics.
+  const char *ShortName;
+
   /// The tool chain this tool is a part of.
   const ToolChain &TheToolChain;
 
 public:
-  Tool(const char *Name, const ToolChain &TC);
+  Tool(const char *Name, const char *ShortName,
+       const ToolChain &TC);
 
 public:
   virtual ~Tool();
 
   const char *getName() const { return Name; }
 
+  const char *getShortName() const { return ShortName; }
+
   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;
 
@@ -55,13 +59,11 @@
   /// 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,
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 1a8ae77..55be4ee 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -10,6 +10,7 @@
 #ifndef CLANG_DRIVER_TOOLCHAIN_H_
 #define CLANG_DRIVER_TOOLCHAIN_H_
 
+#include "clang/Driver/Types.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/System/Path.h"
@@ -17,6 +18,7 @@
 
 namespace clang {
 namespace driver {
+  class ArgList;
   class Compilation;
   class DerivedArgList;
   class Driver;
@@ -53,6 +55,7 @@
   const Driver &getDriver() const;
   const llvm::Triple &getTriple() const { return Triple; }
 
+  llvm::Triple::ArchType getArch() const { return Triple.getArch(); }
   llvm::StringRef getArchName() const { return Triple.getArchName(); }
   llvm::StringRef getPlatform() const { return Triple.getVendorName(); }
   llvm::StringRef getOS() const { return Triple.getOSName(); }
@@ -70,23 +73,29 @@
   // Tool access.
 
   /// TranslateArgs - Create a new derived argument list for any argument
-  /// translations this ToolChain may wish to perform.
+  /// translations this ToolChain may wish to perform, or 0 if no tool chain
+  /// specific translations are needed.
   ///
   /// \param BoundArch - The bound architecture name, or 0.
-  virtual DerivedArgList *TranslateArgs(InputArgList &Args,
-                                        const char *BoundArch) const = 0;
+  virtual DerivedArgList *TranslateArgs(const DerivedArgList &Args,
+                                        const char *BoundArch) const {
+    return 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;
+  std::string GetFilePath(const char *Name) const;
+  std::string GetProgramPath(const char *Name, bool WantFile = false) const;
 
   // Platform defaults information
 
+  /// LookupTypeForExtension - Return the default language type to use for the
+  /// given extension.
+  virtual types::ID LookupTypeForExtension(const char *Ext) const;
+
   /// IsBlocksDefault - Does this tool chain enable -fblocks by default.
   virtual bool IsBlocksDefault() const { return false; }
 
@@ -133,6 +142,17 @@
 
   /// UseSjLjExceptions - Does this tool chain use SjLj exceptions.
   virtual bool UseSjLjExceptions() const { return false; }
+
+  /// ComputeLLVMTriple - Return the LLVM target triple to use, after taking
+  /// command line arguments into account.
+  virtual std::string ComputeLLVMTriple(const ArgList &Args) const;
+
+  /// ComputeEffectiveClangTriple - Return the Clang triple to use for this
+  /// target, which may take into account the command line arguments. For
+  /// example, on Darwin the -mmacosx-version-min= command line argument (which
+  /// sets the deployment target) determines the version in the triple passed to
+  /// Clang.
+  virtual std::string ComputeEffectiveClangTriple(const ArgList &Args) const;
 };
 
 } // end namespace driver
diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def
index 61a5043..06a8690 100644
--- a/include/clang/Driver/Types.def
+++ b/include/clang/Driver/Types.def
@@ -67,15 +67,21 @@
 TYPE("f95-cpp-input",            Fortran,      PP_Fortran,      0,       "u")
 TYPE("java",                     Java,         INVALID,         0,       "u")
 
+// LLVM IR/LTO types. We define separate types for IR and LTO because LTO
+// outputs should use the standard suffixes.
+TYPE("ir",                       LLVM_IR,      INVALID,         "ll",    "u")
+TYPE("ir",                       LLVM_BC,      INVALID,         "bc",    "u")
+TYPE("lto-ir",                   LTO_IR,       INVALID,         "s",     "")
+TYPE("lto-bc",                   LTO_BC,       INVALID,         "o",     "")
+
 // 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("dSYM",                     dSYM,         INVALID,         "dSYM",  "A")
 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
index d933230..9187529 100644
--- a/include/clang/Driver/Types.h
+++ b/include/clang/Driver/Types.h
@@ -59,6 +59,10 @@
   /// isAcceptedByClang - Can clang handle this input type.
   bool isAcceptedByClang(ID Id);
 
+  /// isOnlyAcceptedByClang - Is clang the only compiler that can handle this
+  /// input type.
+  bool isOnlyAcceptedByClang(ID Id);
+
   /// isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
   bool isCXX(ID Id);
 
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 9163a20..cca243d 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -57,27 +57,6 @@
 // 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);
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 9252358..e3fd4b3 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -14,19 +14,26 @@
 #ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H
 #define LLVM_CLANG_FRONTEND_ASTUNIT_H
 
+#include "clang/Index/ASTLocation.h"
+#include "clang/Serialization/ASTBitCodes.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/CodeCompleteConsumer.h"
 #include "clang/Lex/PreprocessingRecord.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang-c/Index.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/ADT/StringMap.h"
 #include "llvm/System/Path.h"
+#include "llvm/Support/Timer.h"
 #include <map>
 #include <string>
 #include <vector>
 #include <cassert>
 #include <utility>
+#include <sys/types.h>
 
 namespace llvm {
   class MemoryBuffer;
@@ -34,6 +41,7 @@
 
 namespace clang {
 class ASTContext;
+class CodeCompleteConsumer;
 class CompilerInvocation;
 class Decl;
 class Diagnostic;
@@ -45,13 +53,14 @@
 class TargetInfo;
 
 using namespace idx;
-
-/// \brief Utility class for loading a ASTContext from a PCH file.
+  
+/// \brief Utility class for loading a ASTContext from an AST file.
 ///
 class ASTUnit {
 public:
   typedef std::map<FileID, std::vector<PreprocessedEntity *> > 
     PreprocessedEntitiesByFileMap;
+  
 private:
   llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics;
   llvm::OwningPtr<FileManager>      FileMgr;
@@ -61,18 +70,32 @@
   llvm::OwningPtr<Preprocessor>     PP;
   llvm::OwningPtr<ASTContext>       Ctx;
   
+  /// \brief The AST consumer that received information about the translation
+  /// unit as it was parsed or loaded.
+  llvm::OwningPtr<ASTConsumer> Consumer;
+  
+  /// \brief The semantic analysis object used to type-check the translation
+  /// unit.
+  llvm::OwningPtr<Sema> TheSema;
+  
   /// 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.
+  /// \brief Whether to capture any diagnostics produced.
+  bool CaptureDiagnostics;
+  
+  /// \brief Track whether the main file was loaded from an AST or not.
   bool MainFileIsAST;
 
+  /// \brief Whether this AST represents a complete translation unit.
+  bool CompleteTranslationUnit;
+
   /// Track the top-level decls which appeared in an ASTUnit which was loaded
   /// from a source file.
   //
@@ -114,12 +137,189 @@
   unsigned int ConcurrencyCheckValue;
   static const unsigned int CheckLocked = 28573289;
   static const unsigned int CheckUnlocked = 9803453;
+
+  /// \brief Counter that determines when we want to try building a
+  /// precompiled preamble.
+  ///
+  /// If zero, we will never build a precompiled preamble. Otherwise,
+  /// it's treated as a counter that decrements each time we reparse
+  /// without the benefit of a precompiled preamble. When it hits 1,
+  /// we'll attempt to rebuild the precompiled header. This way, if
+  /// building the precompiled preamble fails, we won't try again for
+  /// some number of calls.
+  unsigned PreambleRebuildCounter;
+  
+  /// \brief The file in which the precompiled preamble is stored.
+  std::string PreambleFile;
+  
+  /// \brief The contents of the preamble that has been precompiled to
+  /// \c PreambleFile.
+  std::vector<char> Preamble;
+
+  /// \brief Whether the preamble ends at the start of a new line.
+  /// 
+  /// Used to inform the lexer as to whether it's starting at the beginning of
+  /// a line after skipping the preamble.
+  bool PreambleEndsAtStartOfLine;
+  
+  /// \brief The size of the source buffer that we've reserved for the main 
+  /// file within the precompiled preamble.
+  unsigned PreambleReservedSize;
+
+  /// \brief Keeps track of the files that were used when computing the 
+  /// preamble, with both their buffer size and their modification time.
+  ///
+  /// If any of the files have changed from one compile to the next,
+  /// the preamble must be thrown away.
+  llvm::StringMap<std::pair<off_t, time_t> > FilesInPreamble;
+
+  /// \brief When non-NULL, this is the buffer used to store the contents of
+  /// the main file when it has been padded for use with the precompiled
+  /// preamble.
+  llvm::MemoryBuffer *SavedMainFileBuffer;
+
+  /// \brief When non-NULL, this is the buffer used to store the
+  /// contents of the preamble when it has been padded to build the
+  /// precompiled preamble.
+  llvm::MemoryBuffer *PreambleBuffer;
+
+  /// \brief The number of warnings that occurred while parsing the preamble.
+  ///
+  /// This value will be used to restore the state of the \c Diagnostic object
+  /// when re-using the precompiled preamble. Note that only the
+  /// number of warnings matters, since we will not save the preamble
+  /// when any errors are present.
+  unsigned NumWarningsInPreamble;
+
+  /// \brief The number of diagnostics that were stored when parsing
+  /// the precompiled preamble.
+  ///
+  /// This value is used to determine how many of the stored
+  /// diagnostics should be retained when reparsing in the presence of
+  /// a precompiled preamble.
+  unsigned NumStoredDiagnosticsInPreamble;
+
+  /// \brief The group of timers associated with this translation unit.
+  llvm::OwningPtr<llvm::TimerGroup> TimerGroup;  
+
+  /// \brief A list of the serialization ID numbers for each of the top-level
+  /// declarations parsed within the precompiled preamble.
+  std::vector<serialization::DeclID> TopLevelDeclsInPreamble;
+
+  ///
+  /// \defgroup CodeCompleteCaching Code-completion caching
+  ///
+  /// \{
+  ///
+
+  /// \brief Whether we should be caching code-completion results.
+  bool ShouldCacheCodeCompletionResults;
+  
+public:
+  /// \brief A cached code-completion result, which may be introduced in one of
+  /// many different contexts.
+  struct CachedCodeCompletionResult {
+    /// \brief The code-completion string corresponding to this completion
+    /// result.
+    CodeCompletionString *Completion;
+    
+    /// \brief A bitmask that indicates which code-completion contexts should
+    /// contain this completion result.
+    ///
+    /// The bits in the bitmask correspond to the values of 
+    /// CodeCompleteContext::Kind. To map from a completion context kind to a 
+    /// bit, subtract one from the completion context kind and shift 1 by that
+    /// number of bits. Many completions can occur in several different
+    /// contexts.
+    unsigned ShowInContexts;
+    
+    /// \brief The priority given to this code-completion result.
+    unsigned Priority;
+    
+    /// \brief The libclang cursor kind corresponding to this code-completion 
+    /// result.
+    CXCursorKind Kind;
+    
+    /// \brief The availability of this code-completion result.
+    CXAvailabilityKind Availability;
+    
+    /// \brief The simplified type class for a non-macro completion result.
+    SimplifiedTypeClass TypeClass;
+    
+    /// \brief The type of a non-macro completion result, stored as a unique
+    /// integer used by the string map of cached completion types.
+    ///
+    /// This value will be zero if the type is not known, or a unique value
+    /// determined by the formatted type string. Se \c CachedCompletionTypes
+    /// for more information.
+    unsigned Type;
+  };
+  
+  /// \brief Retrieve the mapping from formatted type names to unique type
+  /// identifiers.
+  llvm::StringMap<unsigned> &getCachedCompletionTypes() { 
+    return CachedCompletionTypes; 
+  }
+  
+private:
+  /// \brief The set of cached code-completion results.
+  std::vector<CachedCodeCompletionResult> CachedCompletionResults;
+  
+  /// \brief A mapping from the formatted type name to a unique number for that
+  /// type, which is used for type equality comparisons.
+  llvm::StringMap<unsigned> CachedCompletionTypes;
+  
+  /// \brief The number of top-level declarations present the last time we
+  /// cached code-completion results.
+  ///
+  /// The value is used to help detect when we should repopulate the global
+  /// completion cache.
+  unsigned NumTopLevelDeclsAtLastCompletionCache;
+
+  /// \brief The number of reparses left until we'll consider updating the
+  /// code-completion cache.
+  ///
+  /// This is meant to avoid thrashing during reparsing, by not allowing the
+  /// code-completion cache to be updated on every reparse.
+  unsigned CacheCodeCompletionCoolDown;
+
+  /// \brief Bit used by CIndex to mark when a translation unit may be in an
+  /// inconsistent state, and is not safe to free.
+  unsigned UnsafeToFree : 1;
+
+  /// \brief Cache any "global" code-completion results, so that we can avoid
+  /// recomputing them with each completion.
+  void CacheCodeCompletionResults();
+  
+  /// \brief Clear out and deallocate 
+  void ClearCachedCompletionResults();
+  
+  /// 
+  /// \}
+  ///
+  
+  /// \brief The timers we've created from the various parses, reparses, etc.
+  /// involved in this translation unit.
+  std::vector<llvm::Timer *> Timers;
   
   ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT
   ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT
   
   explicit ASTUnit(bool MainFileIsAST);
 
+  void CleanTemporaryFiles();
+  bool Parse(llvm::MemoryBuffer *OverrideMainBuffer);
+  
+  std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> >
+  ComputePreamble(CompilerInvocation &Invocation, 
+                  unsigned MaxLines, bool &CreatedBuffer);
+  
+  llvm::MemoryBuffer *getMainBufferWithPrecompiledPreamble(
+                                         CompilerInvocation PreambleInvocation,
+                                                     bool AllowRebuild = true,
+                                                        unsigned MaxLines = 0);
+  void RealizeTopLevelDeclsFromPreamble();
+
 public:
   class ConcurrencyCheck {
     volatile ASTUnit &Self;
@@ -143,6 +343,9 @@
 
   bool isMainFileAST() const { return MainFileIsAST; }
 
+  bool isUnsafeToFree() const { return UnsafeToFree; }
+  void setUnsafeToFree(bool Value) { UnsafeToFree = Value; }
+
   const Diagnostic &getDiagnostics() const { return *Diagnostics; }
   Diagnostic &getDiagnostics()             { return *Diagnostics; }
   
@@ -155,11 +358,17 @@
   const ASTContext &getASTContext() const { return *Ctx.get(); }
         ASTContext &getASTContext()       { return *Ctx.get(); }
 
+  bool hasSema() const { return TheSema; }
+  Sema &getSema() const { 
+    assert(TheSema && "ASTUnit does not have a Sema object!");
+    return *TheSema; 
+  }
+  
   const FileManager &getFileManager() const { return *FileMgr; }
         FileManager &getFileManager()       { return *FileMgr; }
 
   const std::string &getOriginalSourceFileName();
-  const std::string &getPCHFileName();
+  const std::string &getASTFileName();
 
   /// \brief Add a temporary file that the ASTUnit depends on.
   ///
@@ -170,16 +379,48 @@
                         
   bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
 
+  /// \brief Retrieve the maximum PCH level of declarations that a
+  /// traversal of the translation unit should consider.
+  unsigned getMaxPCHLevel() const;
+
   void setLastASTLocation(ASTLocation ALoc) { LastLoc = ALoc; }
   ASTLocation getLastASTLocation() const { return LastLoc; }
 
-  std::vector<Decl*> &getTopLevelDecls() {
+  typedef std::vector<Decl *>::iterator top_level_iterator;
+
+  top_level_iterator top_level_begin() {
     assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
-    return TopLevelDecls;
+    if (!TopLevelDeclsInPreamble.empty())
+      RealizeTopLevelDeclsFromPreamble();
+    return TopLevelDecls.begin();
   }
-  const std::vector<Decl*> &getTopLevelDecls() const {
+
+  top_level_iterator top_level_end() {
     assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
-    return TopLevelDecls;
+    if (!TopLevelDeclsInPreamble.empty())
+      RealizeTopLevelDeclsFromPreamble();
+    return TopLevelDecls.end();
+  }
+
+  std::size_t top_level_size() const {
+    assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
+    return TopLevelDeclsInPreamble.size() + TopLevelDecls.size();
+  }
+
+  bool top_level_empty() const {
+    assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
+    return TopLevelDeclsInPreamble.empty() && TopLevelDecls.empty();
+  }
+
+  /// \brief Add a new top-level declaration.
+  void addTopLevelDecl(Decl *D) {
+    TopLevelDecls.push_back(D);
+  }
+
+  /// \brief Add a new top-level declaration, identified by its ID in
+  /// the precompiled preamble.
+  void addTopLevelDeclFromPreamble(serialization::DeclID D) {
+    TopLevelDeclsInPreamble.push_back(D);
   }
 
   /// \brief Retrieve the mapping from File IDs to the preprocessed entities
@@ -202,19 +443,40 @@
     return StoredDiagnostics; 
   }
 
+  typedef std::vector<CachedCodeCompletionResult>::iterator
+    cached_completion_iterator;
+  
+  cached_completion_iterator cached_completion_begin() {
+    return CachedCompletionResults.begin();
+  }
+
+  cached_completion_iterator cached_completion_end() {
+    return CachedCompletionResults.end();
+  }
+
+  unsigned cached_completion_size() const { 
+    return CachedCompletionResults.size(); 
+  }
+  
+  /// \brief Whether this AST represents a complete translation unit.
+  ///
+  /// If false, this AST is only a partial translation unit, e.g., one
+  /// that might still be used as a precompiled header or preamble.
+  bool isCompleteTranslationUnit() const { return CompleteTranslationUnit; }
+
   /// \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.
+  /// \brief Create a ASTUnit from an AST file.
   ///
-  /// \param Filename - The PCH file to load.
+  /// \param Filename - The AST 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,
+  /// \returns - The initialized ASTUnit or null if the AST failed to load.
+  static ASTUnit *LoadFromASTFile(const std::string &Filename,
                                   llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
                                   bool OnlyLocalDecls = false,
                                   RemappedFile *RemappedFiles = 0,
@@ -235,7 +497,10 @@
   static ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI,
                                      llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
                                              bool OnlyLocalDecls = false,
-                                             bool CaptureDiagnostics = false);
+                                             bool CaptureDiagnostics = false,
+                                             bool PrecompilePreamble = false,
+                                          bool CompleteTranslationUnit = true,
+                                       bool CacheCodeCompletionResults = false);
 
   /// LoadFromCommandLine - Create an ASTUnit from a vector of command line
   /// arguments, which must specify exactly one source file.
@@ -258,7 +523,49 @@
                                       bool OnlyLocalDecls = false,
                                       RemappedFile *RemappedFiles = 0,
                                       unsigned NumRemappedFiles = 0,
-                                      bool CaptureDiagnostics = false);
+                                      bool CaptureDiagnostics = false,
+                                      bool PrecompilePreamble = false,
+                                      bool CompleteTranslationUnit = true,
+                                      bool CacheCodeCompletionResults = false);
+  
+  /// \brief Reparse the source files using the same command-line options that
+  /// were originally used to produce this translation unit.
+  ///
+  /// \returns True if a failure occurred that causes the ASTUnit not to
+  /// contain any translation-unit information, false otherwise.  
+  bool Reparse(RemappedFile *RemappedFiles = 0,
+               unsigned NumRemappedFiles = 0);
+
+  /// \brief Perform code completion at the given file, line, and
+  /// column within this translation unit.
+  ///
+  /// \param File The file in which code completion will occur.
+  ///
+  /// \param Line The line at which code completion will occur.
+  ///
+  /// \param Column The column at which code completion will occur.
+  ///
+  /// \param IncludeMacros Whether to include macros in the code-completion 
+  /// results.
+  ///
+  /// \param IncludeCodePatterns Whether to include code patterns (such as a 
+  /// for loop) in the code-completion results.
+  ///
+  /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and
+  /// OwnedBuffers parameters are all disgusting hacks. They will go away.
+  void CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
+                    RemappedFile *RemappedFiles, unsigned NumRemappedFiles,
+                    bool IncludeMacros, bool IncludeCodePatterns,
+                    CodeCompleteConsumer &Consumer,
+                    Diagnostic &Diag, LangOptions &LangOpts,
+                    SourceManager &SourceMgr, FileManager &FileMgr,
+                    llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
+              llvm::SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers);
+
+  /// \brief Save this translation unit to a file with the given name.
+  ///
+  /// \returns True if an error occurred, false otherwise.
+  bool Save(llvm::StringRef File);
 };
 
 } // namespace clang
diff --git a/include/clang/Frontend/Analyses.def b/include/clang/Frontend/Analyses.def
index 287c67e..aaa3920 100644
--- a/include/clang/Frontend/Analyses.def
+++ b/include/clang/Frontend/Analyses.def
@@ -15,22 +15,21 @@
 #define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)
 #endif
 
-ANALYSIS(CFGDump, "cfg-dump",
+ANALYSIS(CFGDump, "cfg-dump", 
          "Display Control-Flow Graphs", Code)
 
-ANALYSIS(CFGView, "cfg-view",
+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)
+         "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)
+         "Check code for LLVM codebase conventions (domain-specific)", 
+         TranslationUnit)
 
 ANALYSIS(WarnDeadStores, "analyzer-check-dead-stores",
          "Warn about stores to dead variables", Code)
@@ -39,15 +38,15 @@
          "Warn about uses of uninitialized variables", Code)
 
 ANALYSIS(WarnObjCMethSigs, "analyzer-check-objc-methodsigs",
- "Warn about Objective-C method signatures with type incompatibilities",
- ObjCImplementation)
+         "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)
+"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)
+         "Warn about private ivars that are never used", ObjCImplementation)
 
 ANALYSIS(ObjCMemChecker, "analyzer-check-objc-mem",
          "Run the [Core] Foundation reference count checker", Code)
@@ -55,10 +54,6 @@
 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
diff --git a/include/clang/Frontend/AnalysisConsumer.h b/include/clang/Frontend/AnalysisConsumer.h
deleted file mode 100644
index 3341bb0..0000000
--- a/include/clang/Frontend/AnalysisConsumer.h
+++ /dev/null
@@ -1,101 +0,0 @@
-//===--- 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/AnalyzerOptions.h b/include/clang/Frontend/AnalyzerOptions.h
new file mode 100644
index 0000000..9ed15ba
--- /dev/null
+++ b/include/clang/Frontend/AnalyzerOptions.h
@@ -0,0 +1,101 @@
+//===--- AnalyzerOptions.h - Analysis Engine Options ------------*- 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 structures necessary for a front-end to specify
+// various analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_ANALYZEROPTIONS_H
+#define LLVM_CLANG_FRONTEND_ANALYZEROPTIONS_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 MaxLoop;
+  unsigned AnalyzeAll : 1;
+  unsigned AnalyzerDisplayProgress : 1;
+  unsigned AnalyzeNestedBlocks : 1;
+  unsigned EagerlyAssume : 1;
+  unsigned IdempotentOps : 1;
+  unsigned PurgeDead : 1;
+  unsigned TrimGraph : 1;
+  unsigned VisualizeEGDot : 1;
+  unsigned VisualizeEGUbi : 1;
+  unsigned EnableExperimentalChecks : 1;
+  unsigned EnableExperimentalInternalChecks : 1;
+  unsigned EnableIdempotentOperationChecker : 1;
+  unsigned InlineCall : 1;
+  unsigned UnoptimizedCFG : 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;
+    UnoptimizedCFG = 0;
+  }
+};
+
+}
+
+#endif
diff --git a/include/clang/Frontend/CodeGenAction.h b/include/clang/Frontend/CodeGenAction.h
deleted file mode 100644
index a1e3c42..0000000
--- a/include/clang/Frontend/CodeGenAction.h
+++ /dev/null
@@ -1,65 +0,0 @@
-//===--- 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/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
new file mode 100644
index 0000000..b3f5709
--- /dev/null
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -0,0 +1,148 @@
+//===--- 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_FRONTEND_CODEGENOPTIONS_H
+#define LLVM_CLANG_FRONTEND_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 debug 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 EmitDeclMetadata  : 1; /// Emit special metadata indicating what Decl*
+                                  /// various IR entities came from.  Only useful
+                                  /// when running CodeGen as a subroutine.
+  unsigned FunctionSections  : 1; /// Set when -ffunction-sections is enabled
+  unsigned HiddenWeakTemplateVTables : 1; /// Emit weak vtables and RTTI for
+                                  /// template classes with hidden visibility
+  unsigned HiddenWeakVTables : 1; /// Emit weak vtables, RTTI, and thunks with
+                                  /// hidden visibility
+  unsigned InstrumentFunctions : 1; /// Set when -finstrument-functions 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 OmitLeafFramePointer : 1; /// Set when -momit-leaf-frame-pointer is
+                                     /// enabled.
+  unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
+  unsigned OptimizeSize      : 1; /// If -Os is specified.
+  unsigned RelaxAll          : 1; /// Relax all machine code instructions.
+  unsigned SimplifyLibCalls  : 1; /// Set when -fbuiltin is enabled.
+  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;
+    EmitDeclMetadata = 0;
+    FunctionSections = 0;
+    HiddenWeakTemplateVTables = 0;
+    HiddenWeakVTables = 0;
+    InstrumentFunctions = 0;
+    MergeAllConstants = 1;
+    NoCommon = 0;
+    NoImplicitFloat = 0;
+    NoZeroInitializedInBSS = 0;
+    ObjCDispatchMethod = Legacy;
+    OmitLeafFramePointer = 0;
+    OptimizationLevel = 0;
+    OptimizeSize = 0;
+    RelaxAll = 0;
+    SimplifyLibCalls = 1;
+    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/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 36720c9..1b3c336 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -34,7 +34,9 @@
 class ExternalASTSource;
 class FileManager;
 class FrontendAction;
+class ASTReader;
 class Preprocessor;
+class Sema;
 class SourceManager;
 class TargetInfo;
 
@@ -66,9 +68,6 @@
   /// 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;
 
@@ -90,6 +89,9 @@
   /// The code completion consumer.
   llvm::OwningPtr<CodeCompleteConsumer> CompletionConsumer;
 
+  /// \brief The semantic analysis object.
+  llvm::OwningPtr<Sema> TheSema;
+  
   /// The frontend timer
   llvm::OwningPtr<llvm::Timer> FrontendTimer;
 
@@ -261,18 +263,11 @@
   void setDiagnostics(Diagnostic *Value);
 
   DiagnosticClient &getDiagnosticClient() const {
-    assert(DiagClient && "Compiler instance has no diagnostic client!");
-    return *DiagClient;
+    assert(Diagnostics && Diagnostics->getClient() && 
+           "Compiler instance has no diagnostic client!");
+    return *Diagnostics->getClient();
   }
 
-  /// 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
   /// {
@@ -368,6 +363,10 @@
   /// takes ownership of \arg Value.
   void setASTContext(ASTContext *Value);
 
+  /// \brief Replace the current Sema; the compiler instance takes ownership
+  /// of S.
+  void setSema(Sema *S);
+  
   /// }
   /// @name ASTConsumer
   /// {
@@ -388,6 +387,18 @@
   void setASTConsumer(ASTConsumer *Value);
 
   /// }
+  /// @name Semantic analysis
+  /// {
+  bool hasSema() const { return TheSema != 0; }
+  
+  Sema &getSema() const { 
+    assert(TheSema && "Compiler instance has no Sema object!");
+    return *TheSema;
+  }
+  
+  Sema *takeSema() { return TheSema.take(); }
+  
+  /// }
   /// @name Code Completion
   /// {
 
@@ -498,14 +509,18 @@
 
   /// Create an external AST source to read a PCH file and attach it to the AST
   /// context.
-  void createPCHExternalASTSource(llvm::StringRef Path);
+  void createPCHExternalASTSource(llvm::StringRef Path,
+                                  bool DisablePCHValidation,
+                                  void *DeserializationListener);
 
   /// 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);
+                             bool DisablePCHValidation,
+                             Preprocessor &PP, ASTContext &Context,
+                             void *DeserializationListener);
 
   /// Create a code completion consumer using the invocation; note that this
   /// will cause the source manager to truncate the input source file at the
@@ -519,8 +534,13 @@
   createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
                                unsigned Line, unsigned Column,
                                bool UseDebugPrinter, bool ShowMacros,
+                               bool ShowCodePatterns, bool ShowGlobals,
                                llvm::raw_ostream &OS);
 
+  /// \brief Create the Sema object to be used for parsing.
+  void createSema(bool CompleteTranslationUnit,
+                  CodeCompleteConsumer *CompletionConsumer);
+  
   /// Create the frontend timer and replace any existing one with it.
   void createFrontendTimer();
 
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index f5a9053..d558ad3 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -12,8 +12,8 @@
 
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/TargetOptions.h"
-#include "clang/CodeGen/CodeGenOptions.h"
-#include "clang/Frontend/AnalysisConsumer.h"
+#include "clang/Frontend/AnalyzerOptions.h"
+#include "clang/Frontend/CodeGenOptions.h"
 #include "clang/Frontend/DependencyOutputOptions.h"
 #include "clang/Frontend/DiagnosticOptions.h"
 #include "clang/Frontend/FrontendOptions.h"
diff --git a/include/clang/Frontend/DeclXML.def b/include/clang/Frontend/DeclXML.def
index e839a8c..1845118 100644
--- a/include/clang/Frontend/DeclXML.def
+++ b/include/clang/Frontend/DeclXML.def
@@ -84,6 +84,7 @@
 
 NODE_XML(Decl, "FIXME_Decl")
   ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclKindName(), "unhandled_decl_name")
 END_NODE_XML
 
 NODE_XML(FunctionDecl, "Function")
@@ -94,10 +95,10 @@
   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__")
+	  ENUM_XML(SC_None, "")
+	  ENUM_XML(SC_Extern, "extern")
+	  ENUM_XML(SC_Static, "static")
+	  ENUM_XML(SC_PrivateExtern, "__private_extern__")
   END_ENUM_XML
   ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
   //ATTRIBUTE_OPT_XML(isVariadic(), "variadic")       // in the type reference
@@ -106,7 +107,7 @@
   SUB_NODE_FN_BODY_XML
 END_NODE_XML
 
-NODE_XML(CXXMethodDecl, "CXXMethodDecl")
+NODE_XML(CXXMethodDecl, "CXXMethod")
   ID_ATTRIBUTE_XML
   ATTRIBUTE_FILE_LOCATION_XML
   ATTRIBUTE_XML(getDeclContext(), "context")
@@ -116,6 +117,79 @@
   ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
   ATTRIBUTE_OPT_XML(isStatic(), "static")
   ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
+  ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access")
+	  ENUM_XML(AS_none,      "")
+	  ENUM_XML(AS_public,    "public")
+	  ENUM_XML(AS_protected, "protected")
+	  ENUM_XML(AS_private,   "private")
+  END_ENUM_XML
+  ATTRIBUTE_XML(getNumParams(), "num_args")
+  SUB_NODE_SEQUENCE_XML(ParmVarDecl)
+  SUB_NODE_FN_BODY_XML
+END_NODE_XML
+
+NODE_XML(CXXConstructorDecl, "CXXConstructor")
+  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(isExplicit(), "is_explicit")
+  ATTRIBUTE_OPT_XML(isDefaultConstructor(), "is_default_ctor")
+  ATTRIBUTE_OPT_XML(isCopyConstructor(), "is_copy_ctor")
+  ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
+  ATTRIBUTE_OPT_XML(isStatic(), "static")
+  ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
+  ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access")
+	  ENUM_XML(AS_none,      "")
+	  ENUM_XML(AS_public,    "public")
+	  ENUM_XML(AS_protected, "protected")
+	  ENUM_XML(AS_private,   "private")
+  END_ENUM_XML
+  ATTRIBUTE_XML(getNumParams(), "num_args")
+  SUB_NODE_SEQUENCE_XML(ParmVarDecl)
+  SUB_NODE_FN_BODY_XML
+END_NODE_XML
+
+NODE_XML(CXXDestructorDecl, "CXXDestructor")
+  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_ENUM_OPT_XML(getAccess(), "access")
+	  ENUM_XML(AS_none,      "")
+	  ENUM_XML(AS_public,    "public")
+	  ENUM_XML(AS_protected, "protected")
+	  ENUM_XML(AS_private,   "private")
+  END_ENUM_XML
+  ATTRIBUTE_XML(getNumParams(), "num_args")
+  SUB_NODE_SEQUENCE_XML(ParmVarDecl)
+  SUB_NODE_FN_BODY_XML
+END_NODE_XML
+
+NODE_XML(CXXConversionDecl, "CXXConversion")
+  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(isExplicit(), "is_explicit")
+  ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
+  ATTRIBUTE_OPT_XML(isStatic(), "static")
+  ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
+  ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access")
+	  ENUM_XML(AS_none,      "")
+	  ENUM_XML(AS_public,    "public")
+	  ENUM_XML(AS_protected, "protected")
+	  ENUM_XML(AS_private,   "private")
+  END_ENUM_XML
   ATTRIBUTE_XML(getNumParams(), "num_args")
   SUB_NODE_SEQUENCE_XML(ParmVarDecl)
   SUB_NODE_FN_BODY_XML
@@ -126,6 +200,7 @@
   ATTRIBUTE_FILE_LOCATION_XML
   ATTRIBUTE_XML(getDeclContext(), "context")
   ATTRIBUTE_XML(getNameAsString(), "name")
+  SUB_NODE_SEQUENCE_XML(DeclContext)
 END_NODE_XML
 
 NODE_XML(UsingDirectiveDecl, "UsingDirective")
@@ -189,6 +264,12 @@
   ATTRIBUTE_XML(getNameAsString(), "name")
   TYPE_ATTRIBUTE_XML(getType())
   ATTRIBUTE_OPT_XML(isMutable(), "mutable")
+  ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access")
+	  ENUM_XML(AS_none,      "")
+	  ENUM_XML(AS_public,    "public")
+	  ENUM_XML(AS_protected, "protected")
+	  ENUM_XML(AS_private,   "private")
+  END_ENUM_XML
   ATTRIBUTE_OPT_XML(isBitField(), "bitfield")
   SUB_NODE_OPT_XML(Expr)                                      // init expr of a bit field
 END_NODE_XML
@@ -208,12 +289,12 @@
   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__")
+	  ENUM_XML(SC_None, "")
+	  ENUM_XML(SC_Auto, "auto")
+	  ENUM_XML(SC_Register, "register")
+	  ENUM_XML(SC_Extern, "extern")
+	  ENUM_XML(SC_Static, "static")
+	  ENUM_XML(SC_PrivateExtern, "__private_extern__")
   END_ENUM_XML
   SUB_NODE_OPT_XML(Expr)                                      // init expr
 END_NODE_XML
@@ -237,6 +318,35 @@
   END_ENUM_XML
 END_NODE_XML
 
+NODE_XML(TemplateDecl, "Template")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+END_NODE_XML
+
+NODE_XML(TemplateTypeParmDecl, "TemplateTypeParm")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+END_NODE_XML
+
+NODE_XML(UsingShadowDecl, "UsingShadow")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getTargetDecl(), "target_decl")
+  ATTRIBUTE_XML(getUsingDecl(), "using_decl")
+END_NODE_XML
+
+NODE_XML(UsingDecl, "Using")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getTargetNestedNameDecl(), "target_nested_namespace_decl")
+  ATTRIBUTE_XML(isTypeName(), "is_typename")
+END_NODE_XML
 
 //===----------------------------------------------------------------------===//
 #undef NODE_XML
diff --git a/include/clang/Frontend/DiagnosticOptions.h b/include/clang/Frontend/DiagnosticOptions.h
index 797cb34..c80bc03 100644
--- a/include/clang/Frontend/DiagnosticOptions.h
+++ b/include/clang/Frontend/DiagnosticOptions.h
@@ -10,6 +10,8 @@
 #ifndef LLVM_CLANG_FRONTEND_DIAGNOSTICOPTIONS_H
 #define LLVM_CLANG_FRONTEND_DIAGNOSTICOPTIONS_H
 
+#include "clang/Basic/Diagnostic.h"
+
 #include <string>
 #include <vector>
 
@@ -28,9 +30,14 @@
   unsigned ShowCarets : 1;       /// Show carets in diagnostics.
   unsigned ShowFixits : 1;       /// Show fixit information.
   unsigned ShowSourceRanges : 1; /// Show source ranges in numeric form.
+  unsigned ShowParseableFixits : 1; /// Show machine parseable fix-its.
   unsigned ShowOptionNames : 1;  /// Show the diagnostic name for mappable
                                  /// diagnostics.
+  unsigned ShowCategories : 2;   /// Show categories: 0 -> none, 1 -> Number,
+                                 /// 2 -> Full Name.
   unsigned ShowColors : 1;       /// Show diagnostics with ANSI color sequences.
+  unsigned ShowOverloads : 1;    /// Overload candidates to show.  Values from
+                                 /// Diagnostic::OverloadsShown
   unsigned VerifyDiagnostics: 1; /// Check that diagnostics match the expected
                                  /// diagnostics, indicated by markers in the
                                  /// input source file.
@@ -39,11 +46,15 @@
                                  /// deserialized by, e.g., the CIndex library.
 
   unsigned ErrorLimit;           /// Limit # errors emitted.
+  unsigned MacroBacktraceLimit;  /// Limit depth of macro instantiation 
+                                 /// backtrace.
   unsigned TemplateBacktraceLimit; /// Limit depth of instantiation backtrace.
 
   /// The distance between tab stops.
   unsigned TabStop;
-  enum { DefaultTabStop = 8, MaxTabStop = 100 };
+  enum { DefaultTabStop = 8, MaxTabStop = 100, 
+         DefaultMacroBacktraceLimit = 6,
+         DefaultTemplateBacktraceLimit = 10 };
 
   /// Column limit for formatting message diagnostics, or 0 if unused.
   unsigned MessageLength;
@@ -66,15 +77,19 @@
     PedanticErrors = 0;
     ShowCarets = 1;
     ShowColors = 0;
+    ShowOverloads = Diagnostic::Ovl_All;
     ShowColumn = 1;
     ShowFixits = 1;
     ShowLocation = 1;
     ShowOptionNames = 0;
+    ShowCategories = 0;
     ShowSourceRanges = 0;
+    ShowParseableFixits = 0;
     VerifyDiagnostics = 0;
     BinaryOutput = 0;
     ErrorLimit = 0;
-    TemplateBacktraceLimit = 0;
+    TemplateBacktraceLimit = DefaultTemplateBacktraceLimit;
+    MacroBacktraceLimit = DefaultMacroBacktraceLimit;
   }
 };
 
diff --git a/include/clang/Frontend/DocumentXML.h b/include/clang/Frontend/DocumentXML.h
index 6693ddb..602d846 100644
--- a/include/clang/Frontend/DocumentXML.h
+++ b/include/clang/Frontend/DocumentXML.h
@@ -114,6 +114,7 @@
   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 NestedNameSpecifier* N);
   void addPtrAttribute(const char* pName, const LabelStmt* L);
   void addPtrAttribute(const char* pName, const char* text);
 
@@ -145,12 +146,22 @@
 //---------------------------------------------------------
 template<class T>
 inline void DocumentXML::addAttribute(const char* pName, const T& value) {
-  Out << ' ' << pName << "=\"" << value << "\"";
+  std::string repr;
+  {
+    llvm::raw_string_ostream buf(repr);
+    buf << value;
+  }
+  
+  Out << ' ' << pName << "=\"" 
+      << DocumentXML::escapeString(repr.c_str(), repr.size())
+      << "\"";
 }
 
 //---------------------------------------------------------
 inline void DocumentXML::addPtrAttribute(const char* pName, const char* text) {
-  Out << ' ' << pName << "=\"" << text << "\"";
+  Out << ' ' << pName << "=\"" 
+      << DocumentXML::escapeString(text, strlen(text))
+      << "\"";
 }
 
 //---------------------------------------------------------
diff --git a/include/clang/Frontend/FixItRewriter.h b/include/clang/Frontend/FixItRewriter.h
deleted file mode 100644
index b432d74..0000000
--- a/include/clang/Frontend/FixItRewriter.h
+++ /dev/null
@@ -1,104 +0,0 @@
-//===--- 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
index 7b7db37..773543a 100644
--- a/include/clang/Frontend/FrontendAction.h
+++ b/include/clang/Frontend/FrontendAction.h
@@ -13,17 +13,40 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/OwningPtr.h"
 #include <string>
+#include <vector>
+
+namespace llvm {
+  class raw_ostream;
+}
 
 namespace clang {
-class ASTUnit;
 class ASTConsumer;
-class CompilerInstance;
 class ASTMergeAction;
+class ASTUnit;
+class CompilerInstance;
+
+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,
+  IK_LLVM_IR
+};
+
 
 /// FrontendAction - Abstract base class for actions which can be performed by
 /// the frontend.
 class FrontendAction {
   std::string CurrentFile;
+  InputKind CurrentFileKind;
   llvm::OwningPtr<ASTUnit> CurrentASTUnit;
   CompilerInstance *Instance;
   friend class ASTMergeAction;
@@ -101,6 +124,11 @@
     return CurrentFile;
   }
 
+  InputKind getCurrentFileKind() const {
+    assert(!CurrentFile.empty() && "No current file!");
+    return CurrentFileKind;
+  }
+
   ASTUnit &getCurrentASTUnit() const {
     assert(!CurrentASTUnit && "No current AST unit!");
     return *CurrentASTUnit;
@@ -110,15 +138,15 @@
     return CurrentASTUnit.take();
   }
 
-  void setCurrentFile(llvm::StringRef Value, ASTUnit *AST = 0);
+  void setCurrentFile(llvm::StringRef Value, InputKind Kind, 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.
+  /// no AST context will be created and this action will be invalid with AST
+  /// file inputs.
   virtual bool usesPreprocessorOnly() const = 0;
 
   /// usesCompleteTranslationUnit - For AST based actions, should the
@@ -128,8 +156,11 @@
   /// 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(); }
+  /// hasASTFileSupport - Does this action support use with AST files?
+  virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); }
+
+  /// hasIRSupport - Does this action support use with IR files?
+  virtual bool hasIRSupport() const { return false; }
 
   /// hasCodeCompletionSupport - Does this action support use with code
   /// completion?
@@ -150,17 +181,18 @@
   /// \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().
+  /// \param InputKind - The type of input. Some input kinds are handled
+  /// specially, for example AST inputs, 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);
+                       InputKind Kind);
 
   /// Execute - Set the source managers main input file, and run the action.
   void Execute();
@@ -175,6 +207,7 @@
 /// ASTFrontendAction - Abstract base class to use for AST consumer based
 /// frontend actions.
 class ASTFrontendAction : public FrontendAction {
+protected:
   /// ExecuteAction - Implement the ExecuteAction interface by running Sema on
   /// the already initialized AST consumer.
   ///
@@ -186,6 +219,22 @@
   virtual bool usesPreprocessorOnly() const { return false; }
 };
 
+class PluginASTAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile) = 0;
+
+public:
+  /// ParseArgs - Parse the given plugin command line arguments.
+  ///
+  /// \param CI - The compiler instance, for use in reporting diagnostics.
+  /// \return True if the parsing succeeded; otherwise the plugin will be
+  /// destroyed and no action run. The plugin is responsible for using the
+  /// CompilerInstance's Diagnostic object to report errors.
+  virtual bool ParseArgs(const CompilerInstance &CI,
+                         const std::vector<std::string> &arg) = 0;
+};
+
 /// PreprocessorFrontendAction - Abstract base class to use for preprocessor
 /// based frontend actions.
 class PreprocessorFrontendAction : public FrontendAction {
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index 3ddd77d..7b8063c 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -15,8 +15,6 @@
 #include <vector>
 
 namespace clang {
-class FixItRewriter;
-class FixItPathRewriter;
 
 //===----------------------------------------------------------------------===//
 // Custom Consumer Actions
@@ -38,12 +36,6 @@
 // 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,
@@ -74,28 +66,6 @@
                                          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,
@@ -103,13 +73,18 @@
 
   virtual bool usesCompleteTranslationUnit() { return false; }
 
-  virtual bool hasASTSupport() const { return false; }
-};
+  virtual bool hasASTFileSupport() const { return false; }
 
-class HTMLPrintAction : public ASTFrontendAction {
-protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         llvm::StringRef InFile);
+public:
+  /// \brief Compute the AST consumer arguments that will be used to
+  /// create the PCHGenerator instance returned by CreateASTConsumer.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  static bool ComputeASTConsumerArguments(CompilerInstance &CI,
+                                          llvm::StringRef InFile,
+                                          std::string &Sysroot,
+                                          llvm::raw_ostream *&OS,
+                                          bool &Chaining);
 };
 
 class InheritanceViewAction : public ASTFrontendAction {
@@ -118,12 +93,6 @@
                                          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,
@@ -133,6 +102,12 @@
   virtual bool hasCodeCompletionSupport() const { return true; }
 };
 
+class BoostConAction : public SyntaxOnlyAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+};
+
 /**
  * \brief Frontend action adaptor that merges ASTs together.
  *
@@ -166,10 +141,20 @@
   virtual bool usesPreprocessorOnly() const;
   virtual bool usesCompleteTranslationUnit();
   virtual bool hasPCHSupport() const;
-  virtual bool hasASTSupport() const;
+  virtual bool hasASTFileSupport() const;
   virtual bool hasCodeCompletionSupport() const;
 };
 
+class PrintPreambleAction : public FrontendAction {
+protected:
+  void ExecuteAction();
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &, llvm::StringRef) { 
+    return 0; 
+  }
+  
+  virtual bool usesPreprocessorOnly() const { return true; }
+};
+  
 //===----------------------------------------------------------------------===//
 // Preprocessor Actions
 //===----------------------------------------------------------------------===//
@@ -189,38 +174,18 @@
   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
index a044586..61ad22c 100644
--- a/include/clang/Frontend/FrontendDiagnostic.h
+++ b/include/clang/Frontend/FrontendDiagnostic.h
@@ -15,7 +15,7 @@
 namespace clang {
   namespace diag {
     enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
 #define FRONTENDSTART
 #include "clang/Basic/DiagnosticFrontendKinds.inc"
 #undef DIAG
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index 60512ed..4c16d08 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -11,6 +11,7 @@
 #define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
 
 #include "clang/Frontend/CommandLineSourceLoc.h"
+#include "clang/Frontend/FrontendAction.h"
 #include "llvm/ADT/StringRef.h"
 #include <string>
 #include <vector>
@@ -23,24 +24,26 @@
     ASTPrint,               ///< Parse ASTs and print them.
     ASTPrintXML,            ///< Parse ASTs and print them in XML.
     ASTView,                ///< Parse ASTs and view them in Graphviz.
+    BoostCon,               ///< BoostCon mode.
+    CreateModule,           ///< Create module definition
     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
+    EmitLLVMOnly,           ///< Generate LLVM IR, but do not emit anything.
+    EmitCodeGenOnly,        ///< Generate machine code, but don't emit anything.
     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.
+    PrintPreamble,          ///< Print the "preamble" of the input file
     PrintPreprocessedInput, ///< -E mode.
     RewriteMacros,          ///< Expand macros but not #includes.
     RewriteObjC,            ///< ObjC->C Rewriter.
@@ -53,35 +56,29 @@
 /// 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
+                                           /// instruct the AST writer to create
                                            /// relocatable PCH files.
+  unsigned ChainedPCH : 1;                 ///< When generating PCH files,
+                                           /// instruct the AST writer to create
+                                           /// chained PCH files.
   unsigned ShowHelp : 1;                   ///< Show the -help text.
   unsigned ShowMacrosInCodeCompletion : 1; ///< Show macros in code completion
                                            /// results.
+  unsigned ShowCodePatternsInCodeCompletion : 1; ///< Show code patterns in code
+                                                 /// completion results.
+  unsigned ShowGlobalSymbolsInCodeCompletion : 1; ///< Show top-level decls 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.
+  unsigned FixWhatYouCan : 1;              ///< Apply fixes even if there are
+                                           /// unfixable errors.
 
   /// The input files and their types.
   std::vector<std::pair<InputKind, std::string> > Inputs;
@@ -104,12 +101,18 @@
   /// The name of the action to run when using a plugin action.
   std::string ActionName;
 
+  /// Arg to pass to the plugin
+  std::vector<std::string> PluginArgs;
+
   /// 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 The list of modules to import.
+  std::vector<std::string> Modules;
+
   /// \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;
@@ -121,8 +124,11 @@
     ProgramAction = frontend::ParseSyntaxOnly;
     ActionName = "";
     RelocatablePCH = 0;
+    ChainedPCH = 0;
     ShowHelp = 0;
     ShowMacrosInCodeCompletion = 0;
+    ShowCodePatternsInCodeCompletion = 0;
+    ShowGlobalSymbolsInCodeCompletion = 1;
     ShowStats = 0;
     ShowTimers = 0;
     ShowVersion = 0;
diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h
index 8341492..ec925ad 100644
--- a/include/clang/Frontend/FrontendPluginRegistry.h
+++ b/include/clang/Frontend/FrontendPluginRegistry.h
@@ -16,7 +16,7 @@
 namespace clang {
 
 /// The frontend plugin registry.
-typedef llvm::Registry<FrontendAction> FrontendPluginRegistry;
+typedef llvm::Registry<PluginASTAction> FrontendPluginRegistry;
 
 } // end namespace clang
 
diff --git a/include/clang/Frontend/HeaderSearchOptions.h b/include/clang/Frontend/HeaderSearchOptions.h
index c668245..588d32b 100644
--- a/include/clang/Frontend/HeaderSearchOptions.h
+++ b/include/clang/Frontend/HeaderSearchOptions.h
@@ -35,11 +35,16 @@
     frontend::IncludeDirGroup Group;
     unsigned IsUserSupplied : 1;
     unsigned IsFramework : 1;
+    
+    /// IsSysRootRelative - This is true if an absolute path should be treated
+    /// relative to the sysroot, or false if it should always be the absolute
+    /// path.
+    unsigned IsSysRootRelative : 1;
 
-    Entry(llvm::StringRef _Path, frontend::IncludeDirGroup _Group,
-          bool _IsUserSupplied, bool _IsFramework)
-      : Path(_Path), Group(_Group), IsUserSupplied(_IsUserSupplied),
-        IsFramework(_IsFramework) {}
+    Entry(llvm::StringRef path, frontend::IncludeDirGroup group,
+          bool isUserSupplied, bool isFramework, bool isSysRootRelative)
+      : Path(path), Group(group), IsUserSupplied(isUserSupplied),
+        IsFramework(isFramework), IsSysRootRelative(isSysRootRelative) {}
   };
 
   /// If non-empty, the directory to use as a "virtual system root" for include
@@ -85,8 +90,9 @@
 
   /// 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));
+               bool IsUserSupplied, bool IsFramework, bool IsSysRootRelative) {
+    UserEntries.push_back(Entry(Path, Group, IsUserSupplied, IsFramework,
+                                IsSysRootRelative));
   }
 };
 
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
deleted file mode 100644
index 457e633..0000000
--- a/include/clang/Frontend/PCHBitCodes.h
+++ /dev/null
@@ -1,729 +0,0 @@
-//===- 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
deleted file mode 100644
index c235230..0000000
--- a/include/clang/Frontend/PCHReader.h
+++ /dev/null
@@ -1,809 +0,0 @@
-//===--- 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
deleted file mode 100644
index e006de5..0000000
--- a/include/clang/Frontend/PCHWriter.h
+++ /dev/null
@@ -1,350 +0,0 @@
-//===--- 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
deleted file mode 100644
index f8d2eeb..0000000
--- a/include/clang/Frontend/PathDiagnosticClients.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//===--- 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
index 891359b..851c1f0 100644
--- a/include/clang/Frontend/PreprocessorOptions.h
+++ b/include/clang/Frontend/PreprocessorOptions.h
@@ -43,6 +43,17 @@
   /// The implicit PCH included at the start of the translation unit, or empty.
   std::string ImplicitPCHInclude;
 
+  /// \brief When true, disables most of the normal validation performed on
+  /// precompiled headers.
+  bool DisablePCHValidation;
+  
+  /// \brief If non-zero, the implicit PCH include is actually a precompiled
+  /// preamble that covers this number of bytes in the main source file.
+  ///
+  /// The boolean indicates whether the preamble ends at the start of a new
+  /// line.
+  std::pair<unsigned, bool> PrecompiledPreambleBytes;
+  
   /// The implicit PTH input included at the start of the translation unit, or
   /// empty.
   std::string ImplicitPTHInclude;
@@ -62,26 +73,53 @@
   std::vector<std::pair<std::string, const llvm::MemoryBuffer *> > 
     RemappedFileBuffers;
   
-  typedef std::vector<std::pair<std::string, std::string> >::const_iterator
+  /// \brief Whether the compiler instance should retain (i.e., not free)
+  /// the buffers associated with remapped files.
+  ///
+  /// This flag defaults to false; it can be set true only through direct
+  /// manipulation of the compiler invocation object, in cases where the 
+  /// compiler invocation and its buffers will be reused.
+  bool RetainRemappedFileBuffers;
+  
+  typedef std::vector<std::pair<std::string, std::string> >::iterator
     remapped_file_iterator;
-  remapped_file_iterator remapped_file_begin() const { 
+  typedef std::vector<std::pair<std::string, std::string> >::const_iterator
+    const_remapped_file_iterator;
+  remapped_file_iterator remapped_file_begin() { 
     return RemappedFiles.begin();
   }
-  remapped_file_iterator remapped_file_end() const { 
+  const_remapped_file_iterator remapped_file_begin() const {
+    return RemappedFiles.begin();
+  }
+  remapped_file_iterator remapped_file_end() { 
+    return RemappedFiles.end();
+  }
+  const_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 {
+                                  iterator remapped_file_buffer_iterator;
+  typedef std::vector<std::pair<std::string, const llvm::MemoryBuffer *> >::
+                            const_iterator const_remapped_file_buffer_iterator;
+  remapped_file_buffer_iterator remapped_file_buffer_begin() {
     return RemappedFileBuffers.begin();
   }
-  remapped_file_buffer_iterator remapped_file_buffer_end() const {
+  const_remapped_file_buffer_iterator remapped_file_buffer_begin() const {
+    return RemappedFileBuffers.begin();
+  }
+  remapped_file_buffer_iterator remapped_file_buffer_end() {
+    return RemappedFileBuffers.end();
+  }
+  const_remapped_file_buffer_iterator remapped_file_buffer_end() const {
     return RemappedFileBuffers.end();
   }
   
 public:
-  PreprocessorOptions() : UsePredefines(true), DetailedRecord(false) {}
+  PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
+                          DisablePCHValidation(false),
+                          PrecompiledPreambleBytes(0, true),
+                          RetainRemappedFileBuffers(false) { }
 
   void addMacroDef(llvm::StringRef Name) {
     Macros.push_back(std::make_pair(Name, false));
@@ -92,9 +130,24 @@
   void addRemappedFile(llvm::StringRef From, llvm::StringRef To) {
     RemappedFiles.push_back(std::make_pair(From, To));
   }
+  
+  remapped_file_iterator eraseRemappedFile(remapped_file_iterator Remapped) {
+    return RemappedFiles.erase(Remapped);
+  }
+  
   void addRemappedFile(llvm::StringRef From, const llvm::MemoryBuffer * To) {
     RemappedFileBuffers.push_back(std::make_pair(From, To));
   }
+  
+  remapped_file_buffer_iterator
+  eraseRemappedFile(remapped_file_buffer_iterator Remapped) {
+    return RemappedFileBuffers.erase(Remapped);
+  }
+  
+  void clearRemappedFiles() {
+    RemappedFiles.clear();
+    RemappedFileBuffers.clear();
+  }
 };
 
 } // end namespace clang
diff --git a/include/clang/Frontend/PreprocessorOutputOptions.h b/include/clang/Frontend/PreprocessorOutputOptions.h
index a712a3d..82517c5 100644
--- a/include/clang/Frontend/PreprocessorOutputOptions.h
+++ b/include/clang/Frontend/PreprocessorOutputOptions.h
@@ -16,19 +16,21 @@
 /// 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.
+  unsigned ShowCPP : 1;            ///< Print normal preprocessed output.
+  unsigned ShowComments : 1;       ///< Show comments.
+  unsigned ShowHeaderIncludes : 1; ///< Show header inclusions (-H).
+  unsigned ShowLineMarkers : 1;    ///< Show #line markers.
+  unsigned ShowMacroComments : 1;  ///< Show comments, even in macros.
+  unsigned ShowMacros : 1;         ///< Print macro definitions.
 
 public:
   PreprocessorOutputOptions() {
     ShowCPP = 1;
-    ShowMacros = 0;
-    ShowLineMarkers = 1;
     ShowComments = 0;
+    ShowHeaderIncludes = 0;
+    ShowLineMarkers = 1;
     ShowMacroComments = 0;
+    ShowMacros = 0;
   }
 };
 
diff --git a/include/clang/Frontend/StmtXML.def b/include/clang/Frontend/StmtXML.def
index 2f0da9e..c03a5a8 100644
--- a/include/clang/Frontend/StmtXML.def
+++ b/include/clang/Frontend/StmtXML.def
@@ -241,20 +241,19 @@
   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")
+    ENUM_XML(UO_PostInc, "postinc")
+    ENUM_XML(UO_PostDec, "postdec")
+    ENUM_XML(UO_PreInc,  "preinc")
+    ENUM_XML(UO_PreDec,  "predec")
+    ENUM_XML(UO_AddrOf,  "addrof")
+    ENUM_XML(UO_Deref,   "deref")
+    ENUM_XML(UO_Plus,    "plus")
+    ENUM_XML(UO_Minus,   "minus")
+    ENUM_XML(UO_Not,     "not")             // bitwise not
+    ENUM_XML(UO_LNot,    "lnot")            // boolean not
+    ENUM_XML(UO_Real,    "__real")
+    ENUM_XML(UO_Imag,    "__imag")
+    ENUM_XML(UO_Extension, "__extension__")
   END_ENUM_XML
   SUB_NODE_XML(Expr)                                    // expr
 END_NODE_XML
@@ -263,38 +262,38 @@
   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")
+    ENUM_XML(BO_PtrMemD  , "ptrmemd")
+    ENUM_XML(BO_PtrMemI  , "ptrmemi")
+    ENUM_XML(BO_Mul      , "mul")
+    ENUM_XML(BO_Div      , "div")
+    ENUM_XML(BO_Rem      , "rem")
+    ENUM_XML(BO_Add      , "add")
+    ENUM_XML(BO_Sub      , "sub")
+    ENUM_XML(BO_Shl      , "shl")
+    ENUM_XML(BO_Shr      , "shr")
+    ENUM_XML(BO_LT       , "lt")
+    ENUM_XML(BO_GT       , "gt")
+    ENUM_XML(BO_LE       , "le")
+    ENUM_XML(BO_GE       , "ge")
+    ENUM_XML(BO_EQ       , "eq")
+    ENUM_XML(BO_NE       , "ne")
+    ENUM_XML(BO_And      , "and")          // bitwise and
+    ENUM_XML(BO_Xor      , "xor")
+    ENUM_XML(BO_Or       , "or")           // bitwise or
+    ENUM_XML(BO_LAnd     , "land")         // boolean and
+    ENUM_XML(BO_LOr      , "lor")          // boolean or
+    ENUM_XML(BO_Assign   , "assign")
+    ENUM_XML(BO_MulAssign, "mulassign")
+    ENUM_XML(BO_DivAssign, "divassign")
+    ENUM_XML(BO_RemAssign, "remassign")
+    ENUM_XML(BO_AddAssign, "addassign")
+    ENUM_XML(BO_SubAssign, "subassign")
+    ENUM_XML(BO_ShlAssign, "shlassign")
+    ENUM_XML(BO_ShrAssign, "shrassign")
+    ENUM_XML(BO_AndAssign, "andassign")
+    ENUM_XML(BO_XorAssign, "xorassign")
+    ENUM_XML(BO_OrAssign , "orassign")
+    ENUM_XML(BO_Comma    , "comma")
   END_ENUM_XML
   SUB_NODE_XML(Expr)                                    // expr1
   SUB_NODE_XML(Expr)                                    // expr2
@@ -311,6 +310,13 @@
   SUB_NODE_XML(Expr)                                    // expr3
 END_NODE_XML
 
+NODE_XML(OffsetOfExpr, "OffsetOfExpr")                  // offsetof(basetype, components)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getTypeSourceInfo()->getType())
+  ATTRIBUTE_XML(getNumComponents(), "num_components")
+  SUB_NODE_SEQUENCE_XML(OffsetOfExpr::OffsetOfNode)
+END_NODE_XML
+
 NODE_XML(SizeOfAlignOfExpr, "SizeOfAlignOfExpr")        // sizeof(expr) or alignof(expr)
   ATTRIBUTE_FILE_LOCATION_XML
   TYPE_ATTRIBUTE_XML(getType())
@@ -438,6 +444,14 @@
   SUB_NODE_SEQUENCE_XML(Expr)                           // arg1..argN
 END_NODE_XML
 
+NODE_XML(CXXConstructExpr, "CXXConstructExpr")         // ctor(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())
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
index 3367136..f530294 100644
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -18,14 +18,9 @@
 #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;
@@ -60,23 +55,26 @@
 
   void PrintIncludeStack(SourceLocation Loc, const SourceManager &SM);
 
-  void HighlightRange(const SourceRange &R,
+  void HighlightRange(const CharSourceRange &R,
                       const SourceManager &SrcMgr,
                       unsigned LineNo, FileID FID,
                       std::string &CaretLine,
                       const std::string &SourceLine);
 
   void EmitCaretDiagnostic(SourceLocation Loc,
-                           SourceRange *Ranges, unsigned NumRanges,
+                           CharSourceRange *Ranges, unsigned NumRanges,
                            const SourceManager &SM,
                            const FixItHint *Hints,
                            unsigned NumHints,
-                           unsigned Columns);
+                           unsigned Columns,  
+                           unsigned OnMacroInst,
+                           unsigned MacroSkipStart,
+                           unsigned MacroSkipEnd);
 
   virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
                                 const DiagnosticInfo &Info);
 };
 
-} // end namspace clang
+} // end namespace clang
 
 #endif
diff --git a/include/clang/Frontend/TypeXML.def b/include/clang/Frontend/TypeXML.def
index 3add99a..1536c92 100644
--- a/include/clang/Frontend/TypeXML.def
+++ b/include/clang/Frontend/TypeXML.def
@@ -61,6 +61,10 @@
 #  define CONTEXT_ATTRIBUTE_XML( FN )  ATTRIBUTE_XML(FN, "context")
 #endif
 
+NODE_XML(Type, "FIXME_Type")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getTypeClassName(), "unhandled_type_name")
+END_NODE_XML
 
 NODE_XML(QualType, "CvQualifiedType")
   ID_ATTRIBUTE_XML
@@ -207,9 +211,9 @@
   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")
+    ENUM_XML(TTK_Struct, "struct")
+    ENUM_XML(TTK_Union, "union")
+    ENUM_XML(TTK_Class, "class")
   END_ENUM_XML
   CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext())
 END_NODE_XML
@@ -228,15 +232,32 @@
   ID_ATTRIBUTE_XML
 END_NODE_XML
 
-NODE_XML(QualifiedNameType, "QualifiedNameType")
+NODE_XML(ElaboratedType, "ElaboratedType")
   ID_ATTRIBUTE_XML
+  ATTRIBUTE_ENUM_XML(getKeyword(), "keyword")
+    ENUM_XML(ETK_None, "none")
+    ENUM_XML(ETK_Typename, "typename")
+    ENUM_XML(ETK_Struct, "struct")
+    ENUM_XML(ETK_Union, "union")
+    ENUM_XML(ETK_Class, "class")
+    ENUM_XML(ETK_Enum, "enum")
+  END_ENUM_XML
   TYPE_ATTRIBUTE_XML(getNamedType())
 END_NODE_XML
 
+NODE_XML(InjectedClassNameType, "InjectedClassNameType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
 NODE_XML(DependentNameType, "DependentNameType")
   ID_ATTRIBUTE_XML
 END_NODE_XML
 
+NODE_XML(DependentTemplateSpecializationType,
+         "DependentTemplateSpecializationType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
 NODE_XML(ObjCInterfaceType, "ObjCInterfaceType")
   ID_ATTRIBUTE_XML
 END_NODE_XML
@@ -245,6 +266,21 @@
   ID_ATTRIBUTE_XML
 END_NODE_XML
 
+NODE_XML(SubstTemplateTypeParmType, "SubstTemplateTypeParm")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(DependentSizedExtVectorType, "DependentSizedExtVector")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(UnresolvedUsingType, "UnresolvedUsing")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(DecltypeType, "Decltype")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
 
 //===----------------------------------------------------------------------===//
 #undef NODE_XML
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index c1d4831..fe722db 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -23,6 +23,7 @@
 
 namespace clang {
 class ASTConsumer;
+class CompilerInstance;
 class Decl;
 class DependencyOutputOptions;
 class Diagnostic;
@@ -31,7 +32,6 @@
 class HeaderSearchOptions;
 class IdentifierTable;
 class LangOptions;
-class MinimalAction;
 class Preprocessor;
 class PreprocessorOptions;
 class PreprocessorOutputOptions;
@@ -65,17 +65,6 @@
 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);
 
diff --git a/include/clang/Frontend/VerifyDiagnosticsClient.h b/include/clang/Frontend/VerifyDiagnosticsClient.h
index 08adbb0..6f45e49 100644
--- a/include/clang/Frontend/VerifyDiagnosticsClient.h
+++ b/include/clang/Frontend/VerifyDiagnosticsClient.h
@@ -25,7 +25,10 @@
 /// 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}"
+/// comment on the line that has the diagnostic, use:
+///
+///     expected-{error,warning,note}
+///
 /// 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.
@@ -45,6 +48,20 @@
 ///
 ///   void f(); // expected-note 2 {{previous declaration is here}}
 ///
+/// Regex matching mode may be selected by appending '-re' to type. Example:
+///
+///   expected-error-re
+///
+/// Examples matching error: "variable has incomplete type 'struct s'"
+///
+///   // expected-error {{variable has incomplete type 'struct s'}}
+///   // expected-error {{variable has incomplete type}}
+///
+///   // expected-error-re {{variable has has type 'struct .'}}
+///   // expected-error-re {{variable has has type 'struct .*'}}
+///   // expected-error-re {{variable has has type 'struct (.*)'}}
+///   // expected-error-re {{variable has has type 'struct[[:space:]](.*)'}}
+///
 class VerifyDiagnosticsClient : public DiagnosticClient {
 public:
   Diagnostic &Diags;
diff --git a/include/clang/FrontendTool/Utils.h b/include/clang/FrontendTool/Utils.h
new file mode 100644
index 0000000..031ee7d
--- /dev/null
+++ b/include/clang/FrontendTool/Utils.h
@@ -0,0 +1,30 @@
+//===--- 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
+//  which were split from Frontend to minimise Frontend's dependencies.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTENDTOOL_UTILS_H
+#define LLVM_CLANG_FRONTENDTOOL_UTILS_H
+
+namespace clang {
+
+class CompilerInstance;
+
+/// ExecuteCompilerInvocation - Execute the given actions described by the
+/// compiler invocation object in the given compiler instance.
+///
+/// \return - True on success.
+bool ExecuteCompilerInvocation(CompilerInstance *Clang);
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Index/CallGraph.h b/include/clang/Index/CallGraph.h
index 5edfe6f..336bf47 100644
--- a/include/clang/Index/CallGraph.h
+++ b/include/clang/Index/CallGraph.h
@@ -54,7 +54,7 @@
 
 class CallGraph {
   /// Program manages all Entities.
-  idx::Program Prog;
+  idx::Program &Prog;
 
   typedef std::map<idx::Entity, CallGraphNode *> FunctionMapTy;
 
@@ -71,7 +71,7 @@
   CallGraphNode *ExternalCallingNode;
 
 public:
-  CallGraph();
+  CallGraph(idx::Program &P);
   ~CallGraph();
 
   typedef FunctionMapTy::iterator iterator;
diff --git a/include/clang/Index/Entity.h b/include/clang/Index/Entity.h
index c2aab62..9863963 100644
--- a/include/clang/Index/Entity.h
+++ b/include/clang/Index/Entity.h
@@ -17,6 +17,7 @@
 
 #include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
 #include <string>
 
 namespace clang {
@@ -71,6 +72,9 @@
   /// \returns invalid Entity if an Entity cannot refer to this Decl.
   static Entity get(Decl *D, Program &Prog);
 
+  /// \brief Get an Entity associated with a name in the global namespace.
+  static Entity get(llvm::StringRef Name, Program &Prog);
+
   /// \brief true if the Entity is not visible outside the trasnlation unit.
   bool isInternalToTU() const {
     assert(isValid() && "This Entity is not valid!");
diff --git a/include/clang/Index/Indexer.h b/include/clang/Index/Indexer.h
index 361e729..96c585d 100644
--- a/include/clang/Index/Indexer.h
+++ b/include/clang/Index/Indexer.h
@@ -23,6 +23,7 @@
 
 namespace clang {
   class ASTContext;
+  class FunctionDecl;
 
 namespace idx {
   class Program;
@@ -35,6 +36,7 @@
   typedef llvm::DenseMap<ASTContext *, TranslationUnit *> CtxTUMapTy;
   typedef std::map<Entity, TUSetTy> MapTy;
   typedef std::map<GlobalSelector, TUSetTy> SelMapTy;
+  typedef std::map<Entity, std::pair<FunctionDecl*,TranslationUnit*> > DefMapTy;
 
   explicit Indexer(Program &prog) :
     Prog(prog) { }
@@ -49,10 +51,15 @@
   virtual void GetTranslationUnitsFor(GlobalSelector Sel,
                                       TranslationUnitHandler &Handler);
 
+  std::pair<FunctionDecl*, TranslationUnit*> getDefinitionFor(Entity Ent);
+
 private:
   Program &Prog;
 
   MapTy Map;
+  // Map a function Entity to the its definition.
+  DefMapTy DefMap;
+
   CtxTUMapTy CtxTUMap;
   SelMapTy SelMap;
 };
diff --git a/include/clang/Index/TranslationUnit.h b/include/clang/Index/TranslationUnit.h
index bf9e78f..0099d63 100644
--- a/include/clang/Index/TranslationUnit.h
+++ b/include/clang/Index/TranslationUnit.h
@@ -16,6 +16,8 @@
 
 namespace clang {
   class ASTContext;
+  class Diagnostic;
+  class Preprocessor;
 
 namespace idx {
   class DeclReferenceMap;
@@ -26,6 +28,8 @@
 public:
   virtual ~TranslationUnit();
   virtual ASTContext &getASTContext() = 0;
+  virtual Preprocessor &getPreprocessor() = 0;
+  virtual Diagnostic &getDiagnostic() = 0;
   virtual DeclReferenceMap &getDeclReferenceMap() = 0;
   virtual SelectorMap &getSelectorMap() = 0;
 };
diff --git a/include/clang/Index/Utils.h b/include/clang/Index/Utils.h
deleted file mode 100644
index f8e01f7..0000000
--- a/include/clang/Index/Utils.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===--- 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/CodeCompletionHandler.h b/include/clang/Lex/CodeCompletionHandler.h
new file mode 100644
index 0000000..d28a3aa
--- /dev/null
+++ b/include/clang/Lex/CodeCompletionHandler.h
@@ -0,0 +1,67 @@
+//===--- CodeCompletionHandler.h - Preprocessor 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 CodeCompletionHandler interface, which provides
+//  code-completion callbacks for the preprocessor.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H
+#define LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H
+
+namespace clang {
+
+class IdentifierInfo;
+class MacroInfo;
+  
+/// \brief Callback handler that receives notifications when performing code 
+/// completion within the preprocessor.
+class CodeCompletionHandler {
+public:
+  virtual ~CodeCompletionHandler();
+  
+  /// \brief Callback invoked when performing code completion for a preprocessor
+  /// directive.
+  ///
+  /// This callback will be invoked when the preprocessor processes a '#' at the
+  /// start of a line, followed by the code-completion token.
+  ///
+  /// \param InConditional Whether we're inside a preprocessor conditional
+  /// already.
+  virtual void CodeCompleteDirective(bool InConditional) { }
+  
+  /// \brief Callback invoked when performing code completion within a block of
+  /// code that was excluded due to preprocessor conditionals.
+  virtual void CodeCompleteInConditionalExclusion() { }
+  
+  /// \brief Callback invoked when performing code completion in a context
+  /// where the name of a macro is expected.
+  ///
+  /// \param IsDefinition Whether this is the definition of a macro, e.g.,
+  /// in a #define.
+  virtual void CodeCompleteMacroName(bool IsDefinition) { }
+  
+  /// \brief Callback invoked when performing code completion in a preprocessor
+  /// expression, such as the condition of an #if or #elif directive.
+  virtual void CodeCompletePreprocessorExpression() { }
+  
+  /// \brief Callback invoked when performing code completion inside a 
+  /// function-like macro argument.
+  virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro,
+                                         MacroInfo *MacroInfo,
+                                         unsigned ArgumentIndex) { }
+
+  /// \brief Callback invoked when performing code completion in a part of the
+  /// file where we expect natural language, e.g., a comment, string, or 
+  /// #error directive.
+  virtual void CodeCompleteNaturalLanguage() { }
+};
+  
+}
+
+#endif // LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h
index af5c389..791d3fe 100644
--- a/include/clang/Lex/ExternalPreprocessorSource.h
+++ b/include/clang/Lex/ExternalPreprocessorSource.h
@@ -19,7 +19,7 @@
 /// \brief Abstract interface for external sources of preprocessor 
 /// information.
 ///
-/// This abstract class allows an external sources (such as the \c PCHReader) 
+/// This abstract class allows an external sources (such as the \c ASTReader) 
 /// to provide additional macro definitions.
 class ExternalPreprocessorSource {
 public:
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 978585c..80b38de 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -219,7 +219,7 @@
   header_file_iterator header_file_end() const { return FileInfo.end(); }
   unsigned header_file_size() const { return FileInfo.size(); }
 
-  // Used by PCHReader.
+  // Used by ASTReader.
   void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID);
 
   void PrintStats();
diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h
index a470aa0..2d941e4 100644
--- a/include/clang/Lex/LexDiagnostic.h
+++ b/include/clang/Lex/LexDiagnostic.h
@@ -15,7 +15,7 @@
 namespace clang {
   namespace diag {
     enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
 #define LEXSTART
 #include "clang/Basic/DiagnosticLexKinds.inc"
 #undef DIAG
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 6a6e319..9e0fb7e 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -219,6 +219,33 @@
                                      const SourceManager &SM,
                                      const LangOptions &LangOpts);
 
+  /// \brief Given a location any where in a source buffer, find the location
+  /// that corresponds to the beginning of the token in which the original
+  /// source location lands.
+  ///
+  /// \param Loc 
+  static SourceLocation GetBeginningOfToken(SourceLocation Loc,
+                                            const SourceManager &SM,
+                                            const LangOptions &LangOpts);
+  
+  /// \brief Compute the preamble of the given file.
+  ///
+  /// The preamble of a file contains the initial comments, include directives,
+  /// and other preprocessor directives that occur before the code in this
+  /// particular file actually begins. The preamble of the main source file is
+  /// a potential prefix header.
+  ///
+  /// \param Buffer The memory buffer containing the file's contents.
+  ///
+  /// \param MaxLines If non-zero, restrict the length of the preamble
+  /// to fewer than this number of lines.
+  ///
+  /// \returns The offset into the file where the preamble ends and the rest
+  /// of the file begins along with a boolean value indicating whether 
+  /// the preamble ends at the beginning of a new line.
+  static std::pair<unsigned, bool>
+  ComputePreamble(const llvm::MemoryBuffer *Buffer, unsigned MaxLines = 0);
+                                        
   //===--------------------------------------------------------------------===//
   // Internal implementation interfaces.
 private:
@@ -361,6 +388,8 @@
   //===--------------------------------------------------------------------===//
   // Other lexer functions.
 
+  void SkipBytes(unsigned Bytes, bool StartOfLine);
+  
   // 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);
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index 2334d72..ba46fb1 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -147,7 +147,7 @@
   char *ResultPtr; // cursor
 public:
   StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
-                      Preprocessor &PP);
+                      Preprocessor &PP, bool Complain = true);
   bool hadError;
   bool AnyWide;
   bool Pascal;
@@ -164,7 +164,7 @@
   /// 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);
+                                        Preprocessor &PP, bool Complain = true);
 };
 
 }  // end namespace clang
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index 5887041..90f95b7 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -62,6 +62,9 @@
   /// it has not yet been redefined or undefined.
   bool IsBuiltinMacro : 1;
 
+  /// IsFromAST - True if this macro was loaded from an AST file.
+  bool IsFromAST : 1;
+
 private:
   //===--------------------------------------------------------------------===//
   // State that changes as the macro is used.
@@ -76,24 +79,28 @@
   /// emit -Wunused-macros diagnostics.
   bool IsUsed : 1;
 
-  ~MacroInfo() {
+  /// AllowRedefinitionsWithoutWarning - True if this macro can be redefined
+  /// without emitting a warning.
+  bool IsAllowRedefinitionsWithoutWarning : 1;
+   
+   ~MacroInfo() {
     assert(ArgumentList == 0 && "Didn't call destroy before dtor!");
   }
 
 public:
   MacroInfo(SourceLocation DefLoc);
-
+  MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator);
+  
   /// 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);
+  void FreeArgumentList() {
     ArgumentList = 0;
     NumArguments = 0;
   }
 
   /// Destroy - destroy this MacroInfo object.
-  void Destroy(llvm::BumpPtrAllocator &PPAllocator) {
-    FreeArgumentList(PPAllocator);
+  void Destroy() {
+    FreeArgumentList();
     this->~MacroInfo();
   }
 
@@ -125,6 +132,12 @@
     IsUsed = Val;
   }
 
+  /// setIsAllowRedefinitionsWithoutWarning - Set the value of the 
+  /// IsAllowRedefinitionsWithoutWarning flag.
+  void setIsAllowRedefinitionsWithoutWarning(bool Val) {
+    IsAllowRedefinitionsWithoutWarning = Val;
+  }
+
   /// setArgumentList - Set the specified list of identifiers as the argument
   /// list for this macro.
   void setArgumentList(IdentifierInfo* const *List, unsigned NumArgs,
@@ -172,10 +185,22 @@
   /// __LINE__, which requires processing before expansion.
   bool isBuiltinMacro() const { return IsBuiltinMacro; }
 
+  /// isFromAST - Return true if this macro was loaded from an AST file.
+  bool isFromAST() const { return IsFromAST; }
+
+  /// setIsFromAST - Set whether this macro was loaded from an AST file.
+  void setIsFromAST(bool FromAST = true) { IsFromAST = FromAST; }
+
   /// isUsed - Return false if this macro is defined in the main file and has
   /// not yet been used.
   bool isUsed() const { return IsUsed; }
 
+  /// isAllowRedefinitionsWithoutWarning - Return true if this macro can be
+  /// redefined without warning.
+  bool isAllowRedefinitionsWithoutWarning() const {
+    return IsAllowRedefinitionsWithoutWarning;
+  }
+
   /// getNumTokens - Return the number of tokens that this macro expands to.
   ///
   unsigned getNumTokens() const {
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index d74124e..782f2d5 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -16,6 +16,7 @@
 
 #include "clang/Lex/DirectoryLookup.h"
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/StringRef.h"
 #include <string>
 
 namespace clang {
@@ -70,6 +71,12 @@
                              const std::string &Str) {
   }
 
+  /// PragmaMessage - This callback is invoked when a #pragma message directive
+  /// is read.
+  ///
+  virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) {
+  }
+
   /// MacroExpands - This is called by
   /// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
   /// found.
@@ -82,7 +89,8 @@
 
   /// 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) {
+  virtual void MacroUndefined(SourceLocation Loc, const IdentifierInfo *II,
+                              const MacroInfo *MI) {
   }
 };
 
@@ -127,6 +135,11 @@
     Second->PragmaComment(Loc, Kind, Str);
   }
 
+  virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) {
+    First->PragmaMessage(Loc, Str);
+    Second->PragmaMessage(Loc, Str);
+  }
+
   virtual void MacroExpands(const Token &Id, const MacroInfo* MI) {
     First->MacroExpands(Id, MI);
     Second->MacroExpands(Id, MI);
@@ -137,9 +150,10 @@
     Second->MacroDefined(II, MI);
   }
 
-  virtual void MacroUndefined(const IdentifierInfo *II, const MacroInfo *MI) {
-    First->MacroUndefined(II, MI);
-    Second->MacroUndefined(II, MI);
+  virtual void MacroUndefined(SourceLocation Loc, const IdentifierInfo *II,
+                              const MacroInfo *MI) {
+    First->MacroUndefined(Loc, II, MI);
+    Second->MacroUndefined(Loc, II, MI);
   }
 };
 
diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h
index e96a8c5..0b5a76c 100644
--- a/include/clang/Lex/PTHLexer.h
+++ b/include/clang/Lex/PTHLexer.h
@@ -50,6 +50,8 @@
 
   /// ReadToken - Used by PTHLexer to read tokens TokBuf.
   void ReadToken(Token& T);
+  
+  bool LexEndOfFile(Token &Result);
 
   /// PTHMgr - The PTHManager object that created this PTHLexer.
   PTHManager& PTHMgr;
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
index ef367fe..c68555b 100644
--- a/include/clang/Lex/Pragma.h
+++ b/include/clang/Lex/Pragma.h
@@ -14,6 +14,8 @@
 #ifndef LLVM_CLANG_PRAGMA_H
 #define LLVM_CLANG_PRAGMA_H
 
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
 #include <cassert>
 #include <vector>
 
@@ -33,12 +35,13 @@
 /// we treat "#pragma STDC" and "#pragma GCC" as namespaces that contain other
 /// pragmas.
 class PragmaHandler {
-  const IdentifierInfo *Name;
+  std::string Name;
 public:
-  PragmaHandler(const IdentifierInfo *name) : Name(name) {}
+  explicit PragmaHandler(llvm::StringRef name) : Name(name) {}
+  PragmaHandler() {}
   virtual ~PragmaHandler();
 
-  const IdentifierInfo *getName() const { return Name; }
+  llvm::StringRef getName() const { return Name; }
   virtual void HandlePragma(Preprocessor &PP, Token &FirstToken) = 0;
 
   /// getIfNamespace - If this is a namespace, return it.  This is equivalent to
@@ -46,30 +49,38 @@
   virtual PragmaNamespace *getIfNamespace() { return 0; }
 };
 
+/// EmptyPragmaHandler - A pragma handler which takes no action, which can be
+/// used to ignore particular pragmas.
+class EmptyPragmaHandler : public PragmaHandler {
+public:
+  EmptyPragmaHandler();
+
+  virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
+};
+
 /// 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.
+  /// Handlers - This is a map of the handlers in this namespace with their name
+  /// as key.
   ///
-  std::vector<PragmaHandler*> Handlers;
+  llvm::StringMap<PragmaHandler*> Handlers;
 public:
-  PragmaNamespace(const IdentifierInfo *Name) : PragmaHandler(Name) {}
+  explicit PragmaNamespace(llvm::StringRef 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
+  /// specified name.  If not, return the handler for the null name 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,
+  PragmaHandler *FindHandler(llvm::StringRef Name,
                              bool IgnoreNull = true) const;
 
   /// AddPragma - Add a pragma to this namespace.
   ///
-  void AddPragma(PragmaHandler *Handler) {
-    Handlers.push_back(Handler);
-  }
+  void AddPragma(PragmaHandler *Handler);
 
   /// RemovePragmaHandler - Remove the given handler from the
   /// namespace.
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index ef28af9..730f04f 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -257,7 +257,8 @@
     
     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);
+    virtual void MacroUndefined(SourceLocation Loc, const IdentifierInfo *II,
+                                const MacroInfo *MI);
   };
 } // end namespace clang
 
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 20d9fc5..018d194 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -42,6 +42,7 @@
 class ScratchBuffer;
 class TargetInfo;
 class PPCallbacks;
+class CodeCompletionHandler;
 class DirectoryLookup;
 class PreprocessingRecord;
   
@@ -117,7 +118,7 @@
   /// 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.
+  /// the lifetime of the preprocessor.
   SelectorTable Selectors;
 
   /// BuiltinInfo - Information about builtins.
@@ -131,9 +132,18 @@
   /// with this preprocessor.
   std::vector<CommentHandler *> CommentHandlers;
 
+  /// \brief The code-completion handler.
+  CodeCompletionHandler *CodeComplete;
+  
   /// \brief The file that we're performing code-completion for, if any.
   const FileEntry *CodeCompletionFile;
 
+  /// \brief The number of bytes that we will initially skip when entering the
+  /// main file, which is used when loading a precompiled preamble, along
+  /// with a flag that indicates whether skipping this number of bytes will
+  /// place the lexer at the start of a line.
+  std::pair<unsigned, bool> SkipMainFilePreamble;
+  
   /// 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.
@@ -192,6 +202,11 @@
   /// reused for quick allocation.
   MacroArgs *MacroArgCache;
   friend class MacroArgs;
+ 
+  /// PragmaPushMacroInfo - For each IdentifierInfo used in a #pragma 
+  /// push_macro directive, we keep a MacroInfo stack used to restore 
+  /// previous macro value.
+  llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo;
 
   // Various statistics we track for performance analysis.
   unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma;
@@ -290,8 +305,8 @@
   /// 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
+  /// 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;
 
@@ -340,13 +355,19 @@
   /// 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);
+  void AddPragmaHandler(llvm::StringRef Namespace, PragmaHandler *Handler);
+  void AddPragmaHandler(PragmaHandler *Handler) {
+    AddPragmaHandler(llvm::StringRef(), 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);
+  void RemovePragmaHandler(llvm::StringRef Namespace, PragmaHandler *Handler);
+  void RemovePragmaHandler(PragmaHandler *Handler) {
+    RemovePragmaHandler(llvm::StringRef(), Handler);
+  }
 
   /// \brief Add the specified comment handler to the preprocessor.
   void AddCommentHandler(CommentHandler *Handler);
@@ -356,6 +377,25 @@
   /// It is an error to remove a handler that has not been registered.
   void RemoveCommentHandler(CommentHandler *Handler);
 
+  /// \brief Set the code completion handler to the given object.
+  void setCodeCompletionHandler(CodeCompletionHandler &Handler) {
+    CodeComplete = &Handler;
+  }
+  
+  /// \brief Retrieve the current code-completion handler.
+  CodeCompletionHandler *getCodeCompletionHandler() const {
+    return CodeComplete;
+  }
+  
+  /// \brief Clear out the code completion handler.
+  void clearCodeCompletionHandler() {
+    CodeComplete = 0;
+  }
+  
+  /// \brief Hook used by the lexer to invoke the "natural language" code
+  /// completion point.
+  void CodeCompleteNaturalLanguage();
+  
   /// \brief Retrieve the preprocessing record, or NULL if there is no
   /// preprocessing record.
   PreprocessingRecord *getPreprocessingRecord() const { return Record; }
@@ -550,6 +590,18 @@
   /// for which we are performing code completion.
   bool isCodeCompletionFile(SourceLocation FileLoc) const;
 
+  /// \brief Instruct the preprocessor to skip part of the main
+  /// the main source file.
+  ///
+  /// \brief Bytes The number of bytes in the preamble to skip.
+  ///
+  /// \brief StartOfLine Whether skipping these bytes puts the lexer at the
+  /// start of a line.
+  void setSkipMainFilePreamble(unsigned Bytes, bool StartOfLine) { 
+    SkipMainFilePreamble.first = Bytes;
+    SkipMainFilePreamble.second = StartOfLine;
+  }
+  
   /// 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.
@@ -720,7 +772,10 @@
 
   /// AllocateMacroInfo - Allocate a new MacroInfo object with the provide
   ///  SourceLocation.
-  MacroInfo* AllocateMacroInfo(SourceLocation L);
+  MacroInfo *AllocateMacroInfo(SourceLocation L);
+
+  /// CloneMacroInfo - Allocate a new MacroInfo object which is clone of MI.
+  MacroInfo *CloneMacroInfo(const MacroInfo &MI);
 
   /// GetIncludeFilenameSpelling - Turn the specified lexer token into a fully
   /// checked and spelled filename, e.g. as an operand of #include. This returns
@@ -753,9 +808,9 @@
   ///    #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.
+  /// 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:
@@ -778,6 +833,9 @@
     IncludeMacroStack.pop_back();
   }
 
+  /// AllocateMacroInfo - Allocate a new MacroInfo object.
+  MacroInfo *AllocateMacroInfo();
+
   /// ReleaseMacroInfo - Release the specified MacroInfo.  This memory will
   ///  be reused for allocating new MacroInfo objects.
   void ReleaseMacroInfo(MacroInfo* MI);
@@ -871,7 +929,12 @@
   //===--------------------------------------------------------------------===//
   // Caching stuff.
   void CachingLex(Token &Result);
-  bool InCachingLexMode() const { return CurPPLexer == 0 && CurTokenLexer == 0;}
+  bool InCachingLexMode() const {
+    // If the Lexer pointers are 0 and IncludeMacroStack is empty, it means
+    // that we are past EOF, not that we are in CachingLex mode.
+    return CurPPLexer == 0 && CurTokenLexer == 0 && CurPTHLexer == 0 && 
+           !IncludeMacroStack.empty();
+  }
   void EnterCachingLexMode();
   void ExitCachingLexMode() {
     if (InCachingLexMode())
@@ -900,8 +963,6 @@
   // Macro handling.
   void HandleDefineDirective(Token &Tok);
   void HandleUndefDirective(Token &Tok);
-  // HandleAssertDirective(Token &Tok);
-  // HandleUnassertDirective(Token &Tok);
 
   // Conditional Inclusion.
   void HandleIfdefDirective(Token &Tok, bool isIfndef,
@@ -920,6 +981,11 @@
   void HandlePragmaSystemHeader(Token &SysHeaderTok);
   void HandlePragmaDependency(Token &DependencyTok);
   void HandlePragmaComment(Token &CommentTok);
+  void HandlePragmaMessage(Token &MessageTok);
+  void HandlePragmaPushMacro(Token &Tok);
+  void HandlePragmaPopMacro(Token &Tok);
+  IdentifierInfo *ParsePragmaPushOrPopMacro(Token &Tok);
+
   // 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);
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index b5dde9a..bd9b468 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -148,6 +148,7 @@
     Kind = tok::unknown;
     Flags = 0;
     PtrData = 0;
+    UintData = 0;
     Loc = SourceLocation();
   }
 
@@ -169,7 +170,7 @@
   }
   void setLiteralData(const char *Ptr) {
     assert(isLiteral() && "Cannot set literal data of non-literal");
-    PtrData = (void*)Ptr;
+    PtrData = const_cast<char*>(Ptr);
   }
 
   void *getAnnotationValue() const {
@@ -254,4 +255,9 @@
 
 }  // end namespace clang
 
+namespace llvm {
+  template <>
+  struct isPodLike<clang::Token> { static const bool value = true; };
+}  // end namespace llvm
+
 #endif
diff --git a/include/clang/Makefile b/include/clang/Makefile
index 624292a..030b072 100644
--- a/include/clang/Makefile
+++ b/include/clang/Makefile
@@ -1,4 +1,31 @@
-LEVEL = ../../../..
-DIRS := Basic Driver
+CLANG_LEVEL := ../..
+DIRS := AST Basic Driver Serialization
 
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
+
+install-local::
+	$(Echo) Installing Clang include files
+	$(Verb) $(MKDIR) $(DESTDIR)$(PROJ_includedir)
+	$(Verb) if test -d "$(PROJ_SRC_ROOT)/tools/clang/include/clang" ; then \
+	  cd $(PROJ_SRC_ROOT)/tools/clang/include && \
+	  for  hdr in `find clang -type f '!' '(' -name '*~' \
+	      -o -name '.#*' -o -name '*.in' -o -name '*.txt' \
+	      -o -name 'Makefile' -o -name '*.td' -o -name '*.orig' ')' -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/clang" ; then \
+	  cd $(PROJ_OBJ_ROOT)/tools/clang/include && \
+	  for hdr in `find clang -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/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
deleted file mode 100644
index 6b16522..0000000
--- a/include/clang/Parse/Action.h
+++ /dev/null
@@ -1,3073 +0,0 @@
-//===--- 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
deleted file mode 100644
index 37acab9..0000000
--- a/include/clang/Parse/AttributeList.h
+++ /dev/null
@@ -1,221 +0,0 @@
-//===--- 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
deleted file mode 100644
index 9c19a67..0000000
--- a/include/clang/Parse/DeclSpec.h
+++ /dev/null
@@ -1,1323 +0,0 @@
-//===--- 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
deleted file mode 100644
index 255af59..0000000
--- a/include/clang/Parse/Designator.h
+++ /dev/null
@@ -1,239 +0,0 @@
-//===--- 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
deleted file mode 100644
index 5eb9635..0000000
--- a/include/clang/Parse/Ownership.h
+++ /dev/null
@@ -1,830 +0,0 @@
-//===--- 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/ParseAST.h b/include/clang/Parse/ParseAST.h
new file mode 100644
index 0000000..0d37e21
--- /dev/null
+++ b/include/clang/Parse/ParseAST.h
@@ -0,0 +1,47 @@
+//===--- 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_PARSE_PARSEAST_H
+#define LLVM_CLANG_PARSE_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);
+
+  /// \brief Parse the main file known to the preprocessor, producing an 
+  /// abstract syntax tree.
+  void ParseAST(Sema &S, bool PrintStats = false);
+  
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/ParseDiagnostic.h b/include/clang/Parse/ParseDiagnostic.h
index c702e2f..d7c5eee 100644
--- a/include/clang/Parse/ParseDiagnostic.h
+++ b/include/clang/Parse/ParseDiagnostic.h
@@ -15,7 +15,7 @@
 namespace clang {
   namespace diag {
     enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
 #define PARSESTART
 #include "clang/Basic/DiagnosticParseKinds.inc"
 #undef DIAG
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 42a41d6..f1c1a5b 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -16,8 +16,10 @@
 
 #include "clang/Basic/Specifiers.h"
 #include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/Action.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Lex/CodeCompletionHandler.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/DeclSpec.h"
+#include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/ADT/OwningPtr.h"
 #include <stack>
 #include <list>
@@ -27,6 +29,7 @@
   struct CXX0XAttributeList;
   class PragmaHandler;
   class Scope;
+  class DeclGroupRef;
   class DiagnosticBuilder;
   class Parser;
   class PragmaUnusedHandler;
@@ -69,9 +72,10 @@
 /// parsing units of the grammar, productions are invoked to handle whatever has
 /// been read.
 ///
-class Parser {
+class Parser : public CodeCompletionHandler {
   friend class PragmaUnusedHandler;
   friend class ColonProtectionRAIIObject;
+  friend class ParenBraceBracketBalancer;
   PrettyStackTraceParserEntry CrashInfo;
 
   Preprocessor &PP;
@@ -89,11 +93,9 @@
   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;
+  /// in the file. 
+  Sema &Actions;
 
-  Scope *CurScope;
   Diagnostic &Diags;
 
   /// ScopeCache - Cache scopes to reduce malloc traffic.
@@ -110,6 +112,9 @@
   IdentifierInfo *Ident_vector;
   IdentifierInfo *Ident_pixel;
 
+  llvm::OwningPtr<PragmaHandler> AlignHandler;
+  llvm::OwningPtr<PragmaHandler> GCCVisibilityHandler;
+  llvm::OwningPtr<PragmaHandler> OptionsHandler;
   llvm::OwningPtr<PragmaHandler> PackHandler;
   llvm::OwningPtr<PragmaHandler> UnusedHandler;
   llvm::OwningPtr<PragmaHandler> WeakHandler;
@@ -130,60 +135,56 @@
   unsigned TemplateParameterDepth;
 
 public:
-  Parser(Preprocessor &PP, Action &Actions);
+  Parser(Preprocessor &PP, Sema &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; }
+  Sema &getActions() const { return Actions; }
 
   const Token &getCurToken() const { return Tok; }
-
+  Scope *getCurScope() const { return Actions.getCurScope(); }
+  
   // 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 Expr ExprTy;
+  typedef Stmt StmtTy;
+  typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
+  typedef CXXBaseSpecifier BaseTy;
+  typedef CXXBaseOrMemberInitializer MemInitTy;
+  typedef NestedNameSpecifier CXXScopeTy;
+  typedef TemplateParameterList TemplateParamsTy;
+  typedef OpaquePtr<TemplateName> TemplateTy;
 
-  typedef llvm::SmallVector<TemplateParamsTy *, 4> TemplateParameterLists;
+  typedef llvm::SmallVector<TemplateParameterList *, 4> TemplateParameterLists;
 
-  typedef Action::ExprResult        ExprResult;
-  typedef Action::StmtResult        StmtResult;
-  typedef Action::BaseResult        BaseResult;
-  typedef Action::MemInitResult     MemInitResult;
-  typedef Action::TypeResult        TypeResult;
+  typedef clang::ExprResult        ExprResult;
+  typedef clang::StmtResult        StmtResult;
+  typedef clang::BaseResult        BaseResult;
+  typedef clang::MemInitResult     MemInitResult;
+  typedef clang::TypeResult        TypeResult;
 
-  typedef Action::OwningExprResult OwningExprResult;
-  typedef Action::OwningStmtResult OwningStmtResult;
+  typedef Expr *ExprArg;
+  typedef ASTMultiPtr<Stmt*> MultiStmtArg;
+  typedef Sema::FullExprArg FullExprArg;
 
-  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 ExprResult with Actions to make it an ExprResult
+  ExprResult Owned(ExprResult res) {
+    return ExprResult(res);
   }
-  /// Adorns a StmtResult with Actions to make it an OwningStmtResult
-  OwningStmtResult Owned(StmtResult res) {
-    return OwningStmtResult(Actions, res);
+  /// Adorns a StmtResult with Actions to make it an StmtResult
+  StmtResult Owned(StmtResult res) {
+    return StmtResult(res);
   }
 
-  OwningExprResult ExprError() { return OwningExprResult(Actions, true); }
-  OwningStmtResult StmtError() { return OwningStmtResult(Actions, true); }
+  ExprResult ExprError() { return ExprResult(true); }
+  StmtResult StmtError() { return StmtResult(true); }
 
-  OwningExprResult ExprError(const DiagnosticBuilder &) { return ExprError(); }
-  OwningStmtResult StmtError(const DiagnosticBuilder &) { return StmtError(); }
+  ExprResult ExprError(const DiagnosticBuilder &) { return ExprError(); }
+  StmtResult StmtError(const DiagnosticBuilder &) { return StmtError(); }
 
-  OwningExprResult ExprEmpty() { return OwningExprResult(Actions, false); }
+  ExprResult ExprEmpty() { return ExprResult(false); }
 
   // Parsing methods.
 
@@ -199,7 +200,7 @@
   /// the EOF was encountered.
   bool ParseTopLevelDecl(DeclGroupPtrTy &Result);
 
-  DeclGroupPtrTy RetrievePendingObjCImpDecl();
+  DeclGroupPtrTy FinishPendingObjCActions();
 
 private:
   //===--------------------------------------------------------------------===//
@@ -234,6 +235,11 @@
     assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
            !isTokenBrace() &&
            "Should consume special tokens with Consume*Token");
+    if (Tok.is(tok::code_completion)) {
+      CodeCompletionRecovery();
+      return ConsumeCodeCompletionToken();
+    }
+    
     PrevTokLocation = Tok.getLocation();
     PP.Lex(Tok);
     return PrevTokLocation;
@@ -308,6 +314,22 @@
     return PrevTokLocation;
   }
 
+  /// \brief Consume the current code-completion token.
+  ///
+  /// This routine should be called to consume the code-completion token once
+  /// a code-completion action has already been invoked.
+  SourceLocation ConsumeCodeCompletionToken() {
+    assert(Tok.is(tok::code_completion));
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;    
+  }
+  
+  ///\ brief When we are consuming a code-completion token within having 
+  /// matched specific position in the grammar, provide code-completion results
+  /// based on context.
+  void CodeCompletionRecovery();
+
   /// 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.
@@ -326,6 +348,15 @@
     return PP.LookAhead(0);
   }
 
+  /// getTypeAnnotation - Read a parsed type out of an annotation token.
+  static ParsedType getTypeAnnotation(Token &Tok) {
+    return ParsedType::getFromOpaquePtr(Tok.getAnnotationValue());
+  }
+
+  static void setTypeAnnotation(Token &Tok, ParsedType T) {
+    Tok.setAnnotationValue(T.getAsOpaquePtr());
+  }
+
   /// 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
@@ -515,7 +546,7 @@
   // Lexing and parsing of C++ inline methods.
 
   struct LexedMethod {
-    Action::DeclPtrTy D;
+    Decl *D;
     CachedTokens Toks;
 
     /// \brief Whether this member function had an associated template
@@ -523,7 +554,7 @@
     /// othewise, it is a member function declaration.
     bool TemplateScope;
 
-    explicit LexedMethod(Action::DeclPtrTy MD) : D(MD), TemplateScope(false) {}
+    explicit LexedMethod(Decl *MD) : D(MD), TemplateScope(false) {}
   };
 
   /// LateParsedDefaultArgument - Keeps track of a parameter that may
@@ -531,12 +562,12 @@
   /// occurs within a member function declaration inside the class
   /// (C++ [class.mem]p2).
   struct LateParsedDefaultArgument {
-    explicit LateParsedDefaultArgument(Action::DeclPtrTy P,
+    explicit LateParsedDefaultArgument(Decl *P,
                                        CachedTokens *Toks = 0)
       : Param(P), Toks(Toks) { }
 
     /// Param - The parameter declaration for this parameter.
-    Action::DeclPtrTy Param;
+    Decl *Param;
 
     /// Toks - The sequence of tokens that comprises the default
     /// argument expression, not including the '=' or the terminating
@@ -550,11 +581,11 @@
   /// until the class itself is completely-defined, such as a default
   /// argument (C++ [class.mem]p2).
   struct LateParsedMethodDeclaration {
-    explicit LateParsedMethodDeclaration(Action::DeclPtrTy M)
+    explicit LateParsedMethodDeclaration(Decl *M)
       : Method(M), TemplateScope(false) { }
 
     /// Method - The method declaration.
-    Action::DeclPtrTy Method;
+    Decl *Method;
 
     /// \brief Whether this member function had an associated template
     /// scope. When true, D is a template declaration.
@@ -585,7 +616,7 @@
   /// 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)
+    ParsingClass(Decl *TagOrTemplate, bool TopLevelClass)
       : TopLevelClass(TopLevelClass), TemplateScope(false),
         TagOrTemplate(TagOrTemplate) { }
 
@@ -599,7 +630,7 @@
     bool TemplateScope : 1;
 
     /// \brief The class or class template whose definition we are parsing.
-    DeclPtrTy TagOrTemplate;
+    Decl *TagOrTemplate;
 
     /// MethodDecls - Method declarations that contain pieces whose
     /// parsing will be delayed until the class is fully defined.
@@ -628,15 +659,28 @@
   /// variable's initializer, but not when parsing the body of a
   /// class or function definition.
   class ParsingDeclRAIIObject {
-    Action &Actions;
-    Action::ParsingDeclStackState State;
+    Sema &Actions;
+    Sema::ParsingDeclStackState State;
     bool Popped;
-    
+
   public:
     ParsingDeclRAIIObject(Parser &P) : Actions(P.Actions) {
       push();
     }
 
+    ParsingDeclRAIIObject(Parser &P, ParsingDeclRAIIObject *Other)
+        : Actions(P.Actions) {
+      if (Other) steal(*Other);
+      else push();
+    }
+
+    /// Creates a RAII object which steals the state from a different
+    /// object instead of pushing.
+    ParsingDeclRAIIObject(ParsingDeclRAIIObject &Other)
+        : Actions(Other.Actions) {
+      steal(Other);
+    }
+
     ~ParsingDeclRAIIObject() {
       abort();
     }
@@ -650,21 +694,27 @@
     /// Signals that the context was completed without an appropriate
     /// declaration being parsed.
     void abort() {
-      pop(DeclPtrTy());
+      pop(0);
     }
 
-    void complete(DeclPtrTy D) {
+    void complete(Decl *D) {
       assert(!Popped && "ParsingDeclaration has already been popped!");
       pop(D);
     }
 
   private:
+    void steal(ParsingDeclRAIIObject &Other) {
+      State = Other.State;
+      Popped = Other.Popped;
+      Other.Popped = true;
+    }
+    
     void push() {
       State = Actions.PushParsingDeclaration();
       Popped = false;
     }
 
-    void pop(DeclPtrTy D) {
+    void pop(Decl *D) {
       if (!Popped) {
         Actions.PopParsingDeclaration(State, D);
         Popped = true;
@@ -677,10 +727,12 @@
     ParsingDeclRAIIObject ParsingRAII;
 
   public:
-    ParsingDeclSpec(Parser &P) : ParsingRAII(P) {
-    }
+    ParsingDeclSpec(Parser &P) : ParsingRAII(P) {}
+    ParsingDeclSpec(ParsingDeclRAIIObject &RAII) : ParsingRAII(RAII) {}
+    ParsingDeclSpec(Parser &P, ParsingDeclRAIIObject *RAII)
+      : ParsingRAII(P, RAII) {}
 
-    void complete(DeclPtrTy D) {
+    void complete(Decl *D) {
       ParsingRAII.complete(D);
     }
 
@@ -711,7 +763,7 @@
       ParsingRAII.reset();
     }
 
-    void complete(DeclPtrTy D) {
+    void complete(Decl *D) {
       ParsingRAII.complete(D);
     }
   };
@@ -722,7 +774,7 @@
     bool Popped;
 
   public:
-    ParsingClassDefinition(Parser &P, DeclPtrTy TagOrTemplate, bool TopLevelClass)
+    ParsingClassDefinition(Parser &P, Decl *TagOrTemplate, bool TopLevelClass)
       : P(P), Popped(false) {
       P.PushParsingClass(TagOrTemplate, TopLevelClass);
     }
@@ -788,12 +840,12 @@
     bool LastParameterListWasEmpty;
   };
 
-  void PushParsingClass(DeclPtrTy TagOrTemplate, bool TopLevelClass);
+  void PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass);
   void DeallocateParsedClasses(ParsingClass *Class);
   void PopParsingClass();
 
-  DeclPtrTy ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
-                                    const ParsedTemplateInfo &TemplateInfo);
+  Decl *ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
+                                     const ParsedTemplateInfo &TemplateInfo);
   void ParseLexedMethodDeclarations(ParsingClass &Class);
   void ParseLexedMethodDefs(ParsingClass &Class);
   bool ConsumeAndStoreUntil(tok::TokenKind T1,
@@ -809,49 +861,50 @@
 
   //===--------------------------------------------------------------------===//
   // C99 6.9: External Definitions.
-  DeclGroupPtrTy ParseExternalDeclaration(CXX0XAttributeList Attr);
-  bool isDeclarationAfterDeclarator();
-  bool isStartOfFunctionDefinition();
+  DeclGroupPtrTy ParseExternalDeclaration(CXX0XAttributeList Attr,
+                                          ParsingDeclSpec *DS = 0);
+  bool isDeclarationAfterDeclarator() const;
+  bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
   DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
             AccessSpecifier AS = AS_none);
   DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
                                                   AttributeList *Attr,
                                                   AccessSpecifier AS = AS_none);
   
-  DeclPtrTy ParseFunctionDefinition(ParsingDeclarator &D,
+  Decl *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();
+  ExprResult ParseSimpleAsm(SourceLocation *EndLoc = 0);
+  ExprResult ParseAsmStringLiteral();
 
   // Objective-C External Declarations
-  DeclPtrTy ParseObjCAtDirectives();
-  DeclPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
-  DeclPtrTy ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
+  Decl *ParseObjCAtDirectives();
+  Decl *ParseObjCAtClassDeclaration(SourceLocation atLoc);
+  Decl *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
                                           AttributeList *prefixAttrs = 0);
-  void ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
+  void ParseObjCClassInstanceVariables(Decl *interfaceDecl,
                                        tok::ObjCKeywordKind visibility,
                                        SourceLocation atLoc);
-  bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &P,
+  bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<Decl *> &P,
                                    llvm::SmallVectorImpl<SourceLocation> &PLocs,
                                    bool WarnOnDeclarations,
                                    SourceLocation &LAngleLoc,
                                    SourceLocation &EndProtoLoc);
-  void ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
+  void ParseObjCInterfaceDeclList(Decl *interfaceDecl,
                                   tok::ObjCKeywordKind contextKey);
-  DeclPtrTy ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
+  Decl *ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
                                            AttributeList *prefixAttrs = 0);
 
-  DeclPtrTy ObjCImpDecl;
-  llvm::SmallVector<DeclPtrTy, 4> PendingObjCImpDecl;
+  Decl *ObjCImpDecl;
+  llvm::SmallVector<Decl *, 4> PendingObjCImpDecl;
 
-  DeclPtrTy ParseObjCAtImplementationDeclaration(SourceLocation atLoc);
-  DeclPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
-  DeclPtrTy ParseObjCAtAliasDeclaration(SourceLocation atLoc);
-  DeclPtrTy ParseObjCPropertySynthesize(SourceLocation atLoc);
-  DeclPtrTy ParseObjCPropertyDynamic(SourceLocation atLoc);
+  Decl *ParseObjCAtImplementationDeclaration(SourceLocation atLoc);
+  Decl *ParseObjCAtEndDeclaration(SourceRange atEnd);
+  Decl *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
+  Decl *ParseObjCPropertySynthesize(SourceLocation atLoc);
+  Decl *ParseObjCPropertyDynamic(SourceLocation atLoc);
 
   IdentifierInfo *ParseObjCSelectorPiece(SourceLocation &MethodLocation);
   // Definitions for Objective-c context sensitive keywords recognition.
@@ -863,58 +916,69 @@
 
   bool isTokIdentifier_in() const;
 
-  TypeTy *ParseObjCTypeName(ObjCDeclSpec &DS);
+  ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, bool IsParameter);
   void ParseObjCMethodRequirement();
-  DeclPtrTy ParseObjCMethodPrototype(DeclPtrTy classOrCat,
+  Decl *ParseObjCMethodPrototype(Decl *classOrCat,
             tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
-  DeclPtrTy ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
-                                DeclPtrTy classDecl,
+  Decl *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
+                                Decl *classDecl,
             tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
-  void ParseObjCPropertyAttribute(ObjCDeclSpec &DS, DeclPtrTy ClassDecl,
-                                  DeclPtrTy *Methods, unsigned NumMethods);
+  void ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl,
+                                  Decl **Methods, unsigned NumMethods);
 
-  DeclPtrTy ParseObjCMethodDefinition();
+  Decl *ParseObjCMethodDefinition();
 
   //===--------------------------------------------------------------------===//
   // C99 6.5: Expressions.
   
-  OwningExprResult ParseExpression();
-  OwningExprResult ParseConstantExpression();
+  ExprResult ParseExpression();
+  ExprResult ParseConstantExpression();
   // Expr that doesn't include commas.
-  OwningExprResult ParseAssignmentExpression();
+  ExprResult ParseAssignmentExpression();
 
-  OwningExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
+  ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
 
-  OwningExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc);
+  ExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc);
 
-  OwningExprResult ParseRHSOfBinaryExpression(OwningExprResult LHS,
+  ExprResult ParseRHSOfBinaryExpression(ExprResult LHS,
                                               prec::Level MinPrec);
-  OwningExprResult ParseCastExpression(bool isUnaryExpression,
+  ExprResult ParseCastExpression(bool isUnaryExpression,
                                        bool isAddressOfOperand,
                                        bool &NotCastExpr,
-                                       TypeTy *TypeOfCast);
-  OwningExprResult ParseCastExpression(bool isUnaryExpression,
+                                       ParsedType TypeOfCast);
+  ExprResult ParseCastExpression(bool isUnaryExpression,
                                        bool isAddressOfOperand = false,
-                                       TypeTy *TypeOfCast = 0);
-  OwningExprResult ParsePostfixExpressionSuffix(OwningExprResult LHS);
-  OwningExprResult ParseSizeofAlignofExpression();
-  OwningExprResult ParseBuiltinPrimaryExpression();
+                                       ParsedType TypeOfCast = ParsedType());
 
-  OwningExprResult ParseExprAfterTypeofSizeofAlignof(const Token &OpTok,
+  /// Returns true if the next token would start a postfix-expression
+  /// suffix.
+  bool isPostfixExpressionSuffixStart() {
+    tok::TokenKind K = Tok.getKind();
+    return (K == tok::l_square || K == tok::l_paren ||
+            K == tok::period || K == tok::arrow ||
+            K == tok::plusplus || K == tok::minusminus);
+  }
+
+  ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
+  ExprResult ParseSizeofAlignofExpression();
+  ExprResult ParseBuiltinPrimaryExpression();
+
+  ExprResult ParseExprAfterTypeofSizeofAlignof(const Token &OpTok,
                                                      bool &isCastExpr,
-                                                     TypeTy *&CastTy,
+                                                     ParsedType &CastTy,
                                                      SourceRange &CastRange);
 
-  static const unsigned ExprListSize = 12;
-  typedef llvm::SmallVector<ExprTy*, ExprListSize> ExprListTy;
-  typedef llvm::SmallVector<SourceLocation, ExprListSize> CommaLocsTy;
+  typedef llvm::SmallVector<Expr*, 20> ExprListTy;
+  typedef llvm::SmallVector<SourceLocation, 20> 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);
+  bool ParseExpressionList(llvm::SmallVectorImpl<Expr*> &Exprs,
+                           llvm::SmallVectorImpl<SourceLocation> &CommaLocs,
+                           void (Sema::*Completer)(Scope *S,
+                                                   Expr *Data,
+                                                   Expr **Args,
+                                                   unsigned NumArgs) = 0,
+                           Expr *Data = 0);
 
   /// ParenParseOption - Control what ParseParenExpression will parse.
   enum ParenParseOption {
@@ -923,67 +987,67 @@
     CompoundLiteral, // Also allow '(' type-name ')' '{' ... '}'
     CastExpr         // Also allow '(' type-name ')' <anything>
   };
-  OwningExprResult ParseParenExpression(ParenParseOption &ExprType,
+  ExprResult ParseParenExpression(ParenParseOption &ExprType,
                                         bool stopIfCastExpr,
-                                        TypeTy *TypeOfCast,
-                                        TypeTy *&CastTy,
+                                        ParsedType TypeOfCast,
+                                        ParsedType &CastTy,
                                         SourceLocation &RParenLoc);
 
-  OwningExprResult ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
-                                                    TypeTy *&CastTy,
+  ExprResult ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
+                                                    ParsedType &CastTy,
                                                     SourceLocation LParenLoc,
                                                     SourceLocation &RParenLoc);
 
-  OwningExprResult ParseCompoundLiteralExpression(TypeTy *Ty,
+  ExprResult ParseCompoundLiteralExpression(ParsedType Ty,
                                                   SourceLocation LParenLoc,
                                                   SourceLocation RParenLoc);
 
-  OwningExprResult ParseStringLiteralExpression();
+  ExprResult ParseStringLiteralExpression();
 
   //===--------------------------------------------------------------------===//
   // C++ Expressions
-  OwningExprResult ParseCXXIdExpression(bool isAddressOfOperand = false);
+  ExprResult ParseCXXIdExpression(bool isAddressOfOperand = false);
 
   bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
-                                      TypeTy *ObjectType,
+                                      ParsedType ObjectType,
                                       bool EnteringContext,
                                       bool *MayBePseudoDestructor = 0);
 
   //===--------------------------------------------------------------------===//
   // C++ 5.2p1: C++ Casts
-  OwningExprResult ParseCXXCasts();
+  ExprResult ParseCXXCasts();
 
   //===--------------------------------------------------------------------===//
   // C++ 5.2p1: C++ Type Identification
-  OwningExprResult ParseCXXTypeid();
+  ExprResult ParseCXXTypeid();
 
   //===--------------------------------------------------------------------===//
   // C++ 5.2.4: C++ Pseudo-Destructor Expressions
-  OwningExprResult ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc,
+  ExprResult ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc,
                                             tok::TokenKind OpKind,
                                             CXXScopeSpec &SS,
-                                            Action::TypeTy *ObjectType);
+                                            ParsedType ObjectType);
 
   //===--------------------------------------------------------------------===//
   // C++ 9.3.2: C++ 'this' pointer
-  OwningExprResult ParseCXXThis();
+  ExprResult ParseCXXThis();
 
   //===--------------------------------------------------------------------===//
   // C++ 15: C++ Throw Expression
-  OwningExprResult ParseThrowExpression();
+  ExprResult 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,
+                                   llvm::SmallVectorImpl<ParsedType> &Exns,
+                                   llvm::SmallVectorImpl<SourceRange> &Ranges,
                                    bool &hasAnyExceptionSpec);
 
   //===--------------------------------------------------------------------===//
   // C++ 2.13.5: C++ Boolean Literals
-  OwningExprResult ParseCXXBoolLiteral();
+  ExprResult ParseCXXBoolLiteral();
 
   //===--------------------------------------------------------------------===//
   // C++ 5.2.3: Explicit type conversion (functional notation)
-  OwningExprResult ParseCXXTypeConstructExpression(const DeclSpec &DS);
+  ExprResult ParseCXXTypeConstructExpression(const DeclSpec &DS);
 
   bool isCXXSimpleTypeSpecifier() const;
 
@@ -996,15 +1060,17 @@
 
   //===--------------------------------------------------------------------===//
   // C++ 5.3.4 and 5.3.5: C++ new and delete
-  bool ParseExpressionListOrTypeId(ExprListTy &Exprs, Declarator &D);
+  bool ParseExpressionListOrTypeId(llvm::SmallVectorImpl<Expr*> &Exprs,
+                                   Declarator &D);
   void ParseDirectNewDeclarator(Declarator &D);
-  OwningExprResult ParseCXXNewExpression(bool UseGlobal, SourceLocation Start);
-  OwningExprResult ParseCXXDeleteExpression(bool UseGlobal,
+  ExprResult ParseCXXNewExpression(bool UseGlobal, SourceLocation Start);
+  ExprResult ParseCXXDeleteExpression(bool UseGlobal,
                                             SourceLocation Start);
 
   //===--------------------------------------------------------------------===//
   // C++ if/switch/while condition expression.
-  bool ParseCXXCondition(OwningExprResult &ExprResult, DeclPtrTy &DeclResult);
+  bool ParseCXXCondition(ExprResult &ExprResult, Decl *&DeclResult,
+                         SourceLocation Loc, bool ConvertToBoolean);
 
   //===--------------------------------------------------------------------===//
   // C++ types
@@ -1016,62 +1082,65 @@
   ///       initializer: [C99 6.7.8]
   ///         assignment-expression
   ///         '{' ...
-  OwningExprResult ParseInitializer() {
+  ExprResult ParseInitializer() {
     if (Tok.isNot(tok::l_brace))
       return ParseAssignmentExpression();
     return ParseBraceInitializer();
   }
-  OwningExprResult ParseBraceInitializer();
-  OwningExprResult ParseInitializerWithPotentialDesignator();
+  ExprResult ParseBraceInitializer();
+  ExprResult ParseInitializerWithPotentialDesignator();
 
   //===--------------------------------------------------------------------===//
   // clang Expressions
 
-  OwningExprResult ParseBlockLiteralExpression();  // ^{...}
+  ExprResult 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,
+  ExprResult ParseObjCAtExpression(SourceLocation AtLocation);
+  ExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
+  ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
+  ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
+  ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
+  bool isSimpleObjCMessageExpression();
+  ExprResult ParseObjCMessageExpression();
+  ExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
                                                   SourceLocation SuperLoc,
-                                                  TypeTy *ReceiverType,
+                                                  ParsedType ReceiverType,
                                                   ExprArg ReceiverExpr);
-  OwningExprResult ParseAssignmentExprWithObjCMessageExprStart(
+  ExprResult ParseAssignmentExprWithObjCMessageExprStart(
       SourceLocation LBracloc, SourceLocation SuperLoc,
-      TypeTy *ReceiverType, ExprArg ReceiverExpr);
+      ParsedType ReceiverType, ExprArg ReceiverExpr);
   bool ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr);
 
   //===--------------------------------------------------------------------===//
   // C99 6.8: Statements and Blocks.
 
-  OwningStmtResult ParseStatement() {
+  StmtResult 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,
+  StmtResult ParseStatementOrDeclaration(bool OnlyStatement = false);
+  StmtResult ParseLabeledStatement(AttributeList *Attr);
+  StmtResult ParseCaseStatement(AttributeList *Attr);
+  StmtResult ParseDefaultStatement(AttributeList *Attr);
+  StmtResult 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();
+  StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
+  bool ParseParenExprOrCondition(ExprResult &ExprResult,
+                                 Decl *&DeclResult,
+                                 SourceLocation Loc,
+                                 bool ConvertToBoolean);
+  StmtResult ParseIfStatement(AttributeList *Attr);
+  StmtResult ParseSwitchStatement(AttributeList *Attr);
+  StmtResult ParseWhileStatement(AttributeList *Attr);
+  StmtResult ParseDoStatement(AttributeList *Attr);
+  StmtResult ParseForStatement(AttributeList *Attr);
+  StmtResult ParseGotoStatement(AttributeList *Attr);
+  StmtResult ParseContinueStatement(AttributeList *Attr);
+  StmtResult ParseBreakStatement(AttributeList *Attr);
+  StmtResult ParseReturnStatement(AttributeList *Attr);
+  StmtResult ParseAsmStatement(bool &msAsm);
+  StmtResult FuzzyParseMicrosoftAsmStatement();
   bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
                            llvm::SmallVectorImpl<ExprTy *> &Constraints,
                            llvm::SmallVectorImpl<ExprTy *> &Exprs);
@@ -1079,17 +1148,17 @@
   //===--------------------------------------------------------------------===//
   // C++ 6: Statements and Blocks
 
-  OwningStmtResult ParseCXXTryBlock(AttributeList *Attr);
-  OwningStmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc);
-  OwningStmtResult ParseCXXCatchBlock();
+  StmtResult ParseCXXTryBlock(AttributeList *Attr);
+  StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc);
+  StmtResult ParseCXXCatchBlock();
 
   //===--------------------------------------------------------------------===//
   // Objective-C Statements
 
-  OwningStmtResult ParseObjCAtStatement(SourceLocation atLoc);
-  OwningStmtResult ParseObjCTryStmt(SourceLocation atLoc);
-  OwningStmtResult ParseObjCThrowStmt(SourceLocation atLoc);
-  OwningStmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
+  StmtResult ParseObjCAtStatement(SourceLocation atLoc);
+  StmtResult ParseObjCTryStmt(SourceLocation atLoc);
+  StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
+  StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
 
 
   //===--------------------------------------------------------------------===//
@@ -1113,10 +1182,10 @@
   DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
                                 bool AllowFunctionDefinitions,
                                 SourceLocation *DeclEnd = 0);
-  DeclPtrTy ParseDeclarationAfterDeclarator(Declarator &D,
+  Decl *ParseDeclarationAfterDeclarator(Declarator &D,
                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
-  DeclPtrTy ParseFunctionStatementBody(DeclPtrTy Decl);
-  DeclPtrTy ParseFunctionTryBlock(DeclPtrTy Decl);
+  Decl *ParseFunctionStatementBody(Decl *Decl);
+  Decl *ParseFunctionTryBlock(Decl *Decl);
 
   bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
                         const ParsedTemplateInfo &TemplateInfo,
@@ -1134,16 +1203,16 @@
 
   void ParseSpecifierQualifierList(DeclSpec &DS);
 
-  void ParseObjCTypeQualifierList(ObjCDeclSpec &DS);
+  void ParseObjCTypeQualifierList(ObjCDeclSpec &DS, bool IsParameter);
 
   void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
                 const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),                          AccessSpecifier AS = AS_none);
-  void ParseEnumBody(SourceLocation StartLoc, DeclPtrTy TagDecl);
+  void ParseEnumBody(SourceLocation StartLoc, Decl *TagDecl);
   void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
-                            DeclPtrTy TagDecl);
+                            Decl *TagDecl);
 
   struct FieldCallback {
-    virtual DeclPtrTy invoke(FieldDeclarator &Field) = 0;
+    virtual Decl *invoke(FieldDeclarator &Field) = 0;
     virtual ~FieldCallback() {}
 
   private:
@@ -1299,7 +1368,7 @@
   void ParseTypeofSpecifier(DeclSpec &DS);
   void ParseDecltypeSpecifier(DeclSpec &DS);
   
-  OwningExprResult ParseCXX0XAlignArgument(SourceLocation Start);
+  ExprResult ParseCXX0XAlignArgument(SourceLocation Start);
 
   /// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to
   /// enter a new C++ declarator scope and exit it when the function is
@@ -1320,14 +1389,14 @@
       CreatedScope = true;
       P.EnterScope(0); // Not a decl scope.
 
-      if (!P.Actions.ActOnCXXEnterDeclaratorScope(P.CurScope, SS))
+      if (!P.Actions.ActOnCXXEnterDeclaratorScope(P.getCurScope(), SS))
         EnteredScope = true;
     }
 
     ~DeclaratorScopeObj() {
       if (EnteredScope) {
         assert(SS.isSet() && "C++ scope was cleared ?");
-        P.Actions.ActOnCXXExitDeclaratorScope(P.CurScope, SS);
+        P.Actions.ActOnCXXExitDeclaratorScope(P.getCurScope(), SS);
       }
       if (CreatedScope)
         P.ExitScope();
@@ -1348,6 +1417,8 @@
                                AttributeList *AttrList = 0,
                                bool RequiresArg = false);
   void ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
+                                             IdentifierInfo *FirstIdent,
+                                             SourceLocation FirstIdentLoc,
                                              Declarator &D);
   void ParseBracketDeclarator(Declarator &D);
 
@@ -1357,21 +1428,21 @@
   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);
+  Decl *ParseNamespace(unsigned Context, SourceLocation &DeclEnd,
+                       SourceLocation InlineLoc = SourceLocation());
+  Decl *ParseLinkage(ParsingDeclSpec &DS, unsigned Context);
+  Decl *ParseUsingDirectiveOrDeclaration(unsigned Context,
+                                         SourceLocation &DeclEnd,
+                                         CXX0XAttributeList Attrs);
+  Decl *ParseUsingDirective(unsigned Context, SourceLocation UsingLoc,
+                            SourceLocation &DeclEnd, AttributeList *Attr);
+  Decl *ParseUsingDeclaration(unsigned Context, SourceLocation UsingLoc,
+                              SourceLocation &DeclEnd,
+                              AccessSpecifier AS = AS_none);
+  Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
+  Decl *ParseNamespaceAlias(SourceLocation NamespaceLoc,
+                            SourceLocation AliasLoc, IdentifierInfo *Alias,
+                            SourceLocation &DeclEnd);
 
   //===--------------------------------------------------------------------===//
   // C++ 9: classes [class] and C structs/unions.
@@ -1383,63 +1454,65 @@
                            AccessSpecifier AS = AS_none,
                            bool SuppressDeclarations = false);
   void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
-                                   DeclPtrTy TagDecl);
+                                   Decl *TagDecl);
   void ParseCXXClassMemberDeclaration(AccessSpecifier AS,
-                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
-  void ParseConstructorInitializer(DeclPtrTy ConstructorDecl);
-  MemInitResult ParseMemInitializer(DeclPtrTy ConstructorDecl);
+                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+                                 ParsingDeclRAIIObject *DiagsFromTParams = 0);
+  void ParseConstructorInitializer(Decl *ConstructorDecl);
+  MemInitResult ParseMemInitializer(Decl *ConstructorDecl);
   void HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
-                                       DeclPtrTy ThisDecl);
+                                       Decl *ThisDecl);
 
   //===--------------------------------------------------------------------===//
   // C++ 10: Derived classes [class.derived]
-  void ParseBaseClause(DeclPtrTy ClassDecl);
-  BaseResult ParseBaseSpecifier(DeclPtrTy ClassDecl);
+  void ParseBaseClause(Decl *ClassDecl);
+  BaseResult ParseBaseSpecifier(Decl *ClassDecl);
   AccessSpecifier getAccessSpecifierIfPresent() const;
 
   bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, 
                                     IdentifierInfo *Name,
                                     SourceLocation NameLoc,
                                     bool EnteringContext,
-                                    TypeTy *ObjectType,
+                                    ParsedType ObjectType,
                                     UnqualifiedId &Id,
-                                    bool AssumeTemplateId = false);
+                                    bool AssumeTemplateId,
+                                    SourceLocation TemplateKWLoc);
   bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
-                                  TypeTy *ObjectType,
+                                  ParsedType ObjectType,
                                   UnqualifiedId &Result);
   bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
                           bool AllowDestructorName,
                           bool AllowConstructorName,
-                          TypeTy *ObjectType,
+                          ParsedType ObjectType,
                           UnqualifiedId &Result);
     
   //===--------------------------------------------------------------------===//
   // C++ 14: Templates [temp]
-  typedef llvm::SmallVector<DeclPtrTy, 4> TemplateParameterList;
 
   // C++ 14.1: Template Parameters [temp.param]
-  DeclPtrTy ParseDeclarationStartingWithTemplate(unsigned Context,
+  Decl *ParseDeclarationStartingWithTemplate(unsigned Context,
                                                  SourceLocation &DeclEnd,
                                                  AccessSpecifier AS = AS_none);
-  DeclPtrTy ParseTemplateDeclarationOrSpecialization(unsigned Context,
+  Decl *ParseTemplateDeclarationOrSpecialization(unsigned Context,
                                                      SourceLocation &DeclEnd,
                                                      AccessSpecifier AS);
-  DeclPtrTy ParseSingleDeclarationAfterTemplate(
+  Decl *ParseSingleDeclarationAfterTemplate(
                                        unsigned Context,
                                        const ParsedTemplateInfo &TemplateInfo,
+                                       ParsingDeclRAIIObject &DiagsFromParams,
                                        SourceLocation &DeclEnd,
                                        AccessSpecifier AS=AS_none);
   bool ParseTemplateParameters(unsigned Depth,
-                               TemplateParameterList &TemplateParams,
+                               llvm::SmallVectorImpl<Decl*> &TemplateParams,
                                SourceLocation &LAngleLoc,
                                SourceLocation &RAngleLoc);
   bool ParseTemplateParameterList(unsigned Depth,
-                                  TemplateParameterList &TemplateParams);
+                                  llvm::SmallVectorImpl<Decl*> &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);
+  Decl *ParseTemplateParameter(unsigned Depth, unsigned Position);
+  Decl *ParseTypeParameter(unsigned Depth, unsigned Position);
+  Decl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
+  Decl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
   // C++ 14.3: Template arguments [temp.arg]
   typedef llvm::SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
 
@@ -1457,16 +1530,28 @@
                                SourceLocation TemplateKWLoc = SourceLocation(),
                                bool AllowTypeAnnotation = true);
   void AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS = 0);
+  bool IsTemplateArgumentList(unsigned Skip = 0);
   bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
   ParsedTemplateArgument ParseTemplateTemplateArgument();
   ParsedTemplateArgument ParseTemplateArgument();
-  DeclPtrTy ParseExplicitInstantiation(SourceLocation ExternLoc,
-                                       SourceLocation TemplateLoc,
-                                       SourceLocation &DeclEnd);
+  Decl *ParseExplicitInstantiation(SourceLocation ExternLoc,
+                                        SourceLocation TemplateLoc,
+                                        SourceLocation &DeclEnd);
 
   //===--------------------------------------------------------------------===//
   // GNU G++: Type Traits [Type-Traits.html in the GCC manual]
-  OwningExprResult ParseUnaryTypeTrait();
+  ExprResult ParseUnaryTypeTrait();
+
+  //===--------------------------------------------------------------------===//
+  // Preprocessor code-completion pass-through
+  virtual void CodeCompleteDirective(bool InConditional);
+  virtual void CodeCompleteInConditionalExclusion();
+  virtual void CodeCompleteMacroName(bool IsDefinition);
+  virtual void CodeCompletePreprocessorExpression();
+  virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro,
+                                         MacroInfo *MacroInfo,
+                                         unsigned ArgumentIndex);
+  virtual void CodeCompleteNaturalLanguage();
 };
 
 }  // end namespace clang
diff --git a/include/clang/Parse/Scope.h b/include/clang/Parse/Scope.h
deleted file mode 100644
index d7a0e35..0000000
--- a/include/clang/Parse/Scope.h
+++ /dev/null
@@ -1,329 +0,0 @@
-//===--- 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
deleted file mode 100644
index 1f8ccfb..0000000
--- a/include/clang/Parse/Template.h
+++ /dev/null
@@ -1,183 +0,0 @@
-//===--- 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/ASTConsumers.h b/include/clang/Rewrite/ASTConsumers.h
new file mode 100644
index 0000000..5fb107c
--- /dev/null
+++ b/include/clang/Rewrite/ASTConsumers.h
@@ -0,0 +1,45 @@
+//===--- 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 REWRITE_ASTCONSUMERS_H
+#define REWRITE_ASTCONSUMERS_H
+
+#include <string>
+
+namespace llvm {
+  class raw_ostream;
+}
+namespace clang {
+
+class ASTConsumer;
+class Diagnostic;
+class LangOptions;
+class Preprocessor;
+
+// 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);
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Rewrite/FixItRewriter.h b/include/clang/Rewrite/FixItRewriter.h
new file mode 100644
index 0000000..9b2e016
--- /dev/null
+++ b/include/clang/Rewrite/FixItRewriter.h
@@ -0,0 +1,107 @@
+//===--- 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_REWRITE_FIX_IT_REWRITER_H
+#define LLVM_CLANG_REWRITE_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 FixItOptions {
+public:
+  virtual ~FixItOptions();
+
+  /// \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;
+
+  /// \brief Whether to abort fixing a file when not all errors could be fixed.
+  bool FixWhatYouCan;
+};
+
+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.
+  FixItOptions *FixItOpts;
+
+  /// \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, FixItOptions *FixItOpts);
+
+  /// \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_REWRITE_FIX_IT_REWRITER_H
diff --git a/include/clang/Rewrite/FrontendActions.h b/include/clang/Rewrite/FrontendActions.h
new file mode 100644
index 0000000..2b5f88c
--- /dev/null
+++ b/include/clang/Rewrite/FrontendActions.h
@@ -0,0 +1,69 @@
+//===-- 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_REWRITE_FRONTENDACTIONS_H
+#define LLVM_CLANG_REWRITE_FRONTENDACTIONS_H
+
+#include "clang/Frontend/FrontendAction.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+class FixItRewriter;
+class FixItOptions;
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+class HTMLPrintAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+};
+
+class FixItAction : public ASTFrontendAction {
+protected:
+  llvm::OwningPtr<FixItRewriter> Rewriter;
+  llvm::OwningPtr<FixItOptions> FixItOpts;
+
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+
+  virtual bool BeginSourceFileAction(CompilerInstance &CI,
+                                     llvm::StringRef Filename);
+
+  virtual void EndSourceFileAction();
+
+  virtual bool hasASTFileSupport() const { return false; }
+
+public:
+  FixItAction();
+  ~FixItAction();
+};
+
+class RewriteObjCAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile);
+};
+
+class RewriteMacrosAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction();
+};
+
+class RewriteTestAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction();
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Rewrite/RewriteRope.h b/include/clang/Rewrite/RewriteRope.h
index c0bd741..cb3f8a8 100644
--- a/include/clang/Rewrite/RewriteRope.h
+++ b/include/clang/Rewrite/RewriteRope.h
@@ -16,6 +16,7 @@
 
 #include <cstring>
 #include <cassert>
+#include <cstddef>
 #include <iterator>
 
 namespace clang {
diff --git a/include/clang/Rewrite/Rewriter.h b/include/clang/Rewrite/Rewriter.h
index adda866..b3d4035 100644
--- a/include/clang/Rewrite/Rewriter.h
+++ b/include/clang/Rewrite/Rewriter.h
@@ -64,7 +64,7 @@
   /// 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,
+  void InsertText(unsigned OrigOffset, llvm::StringRef Str,
                   bool InsertAfter = true);
 
 
@@ -72,14 +72,14 @@
   /// 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) {
+  void InsertTextBefore(unsigned OrigOffset, 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) {
+  void InsertTextAfter(unsigned OrigOffset, llvm::StringRef Str) {
     InsertText(OrigOffset, Str);
   }
 
@@ -87,7 +87,7 @@
   /// buffer with a new string.  This is effectively a combined "remove/insert"
   /// operation.
   void ReplaceText(unsigned OrigOffset, unsigned OrigLength,
-                   const llvm::StringRef &NewStr);
+                   llvm::StringRef NewStr);
 
 private:  // Methods only usable by Rewriter.
 
@@ -151,6 +151,7 @@
   /// 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;
+  int getRangeSize(const CharSourceRange &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
@@ -163,7 +164,7 @@
   /// 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 InsertText(SourceLocation Loc, llvm::StringRef Str,
                   bool InsertAfter = true);
 
   /// InsertTextAfter - Insert the specified string at the specified location in
@@ -171,7 +172,7 @@
   ///  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) {
+  bool InsertTextAfter(SourceLocation Loc, llvm::StringRef Str) {
     return InsertText(Loc, Str);
   }
 
@@ -180,7 +181,7 @@
   /// 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) {
+  bool InsertTextBefore(SourceLocation Loc, llvm::StringRef Str) {
     return InsertText(Loc, Str, false);
   }
 
@@ -191,7 +192,7 @@
   /// buffer with a new string.  This is effectively a combined "remove/insert"
   /// operation.
   bool ReplaceText(SourceLocation Start, unsigned OrigLength,
-                   const llvm::StringRef &NewStr);
+                   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
diff --git a/include/clang/Rewrite/Rewriters.h b/include/clang/Rewrite/Rewriters.h
new file mode 100644
index 0000000..669cf8c
--- /dev/null
+++ b/include/clang/Rewrite/Rewriters.h
@@ -0,0 +1,31 @@
+//===--- Rewriters.h - Rewriter implementations     -------------*- 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_REWRITE_REWRITERS_H
+#define LLVM_CLANG_REWRITE_REWRITERS_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+class Preprocessor;
+
+/// RewriteMacrosInInput - Implement -rewrite-macros mode.
+void RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream* OS);
+
+/// DoRewriteTest - A simple test for the TokenRewriter class.
+void DoRewriteTest(Preprocessor &PP, llvm::raw_ostream* OS);
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/AnalysisBasedWarnings.h b/include/clang/Sema/AnalysisBasedWarnings.h
new file mode 100644
index 0000000..0a6656e
--- /dev/null
+++ b/include/clang/Sema/AnalysisBasedWarnings.h
@@ -0,0 +1,64 @@
+//=- 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 BlockExpr;
+class Decl;
+class FunctionDecl;
+class ObjCMethodDecl;
+class QualType;
+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;
+
+  void IssueWarnings(Policy P, const Decl *D, QualType BlockTy);
+
+public:
+  AnalysisBasedWarnings(Sema &s);
+
+  Policy getDefaultPolicy() { return DefaultPolicy; }
+
+  void IssueWarnings(Policy P, const BlockExpr *E);
+  void IssueWarnings(Policy P, const FunctionDecl *D);
+  void IssueWarnings(Policy P, const ObjCMethodDecl *D);
+};
+
+}} // end namespace clang::sema
+
+#endif
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
new file mode 100644
index 0000000..c067b0c
--- /dev/null
+++ b/include/clang/Sema/AttributeList.h
@@ -0,0 +1,233 @@
+//===--- AttributeList.h - Parsed attribute sets ----------------*- 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, which is used to collect
+// parsed attributes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_ATTRLIST_H
+#define LLVM_CLANG_SEMA_ATTRLIST_H
+
+#include "clang/Sema/Ownership.h"
+#include "clang/Basic/SourceLocation.h"
+#include <cassert>
+
+namespace clang {
+  class IdentifierInfo;
+  class Expr;
+
+/// 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;
+  Expr **Args;
+  unsigned NumArgs;
+  AttributeList *Next;
+  bool DeclspecAttribute, CXX0XAttribute;
+  mutable bool Invalid; /// True if already diagnosed as invalid.
+  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,
+                Expr **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_IBOutletCollection, // 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_ownership_holds,    // Clang-specific.
+    AT_ownership_returns,  // Clang-specific.
+    AT_ownership_takes,    // Clang-specific.
+    AT_packed,
+    AT_pure,
+    AT_regparm,
+    AT_section,
+    AT_sentinel,
+    AT_stdcall,
+    AT_thiscall,
+    AT_transparent_union,
+    AT_unavailable,
+    AT_unused,
+    AT_used,
+    AT_vecreturn,     // PS3 PPU-specific.
+    AT_vector_size,
+    AT_visibility,
+    AT_warn_unused_result,
+    AT_weak,
+    AT_weakref,
+    AT_weak_import,
+    AT_reqd_wg_size,
+    AT_init_priority,
+    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; }
+
+  bool isInvalid() const { return Invalid; }
+  void setInvalid(bool b = true) const { Invalid = b; }
+
+  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.
+  Expr *getArg(unsigned Arg) const {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return Args[Arg];
+  }
+
+  class arg_iterator {
+    Expr** X;
+    unsigned Idx;
+  public:
+    arg_iterator(Expr** 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);
+    }
+
+    Expr* 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/lib/Sema/CXXFieldCollector.h b/include/clang/Sema/CXXFieldCollector.h
similarity index 100%
rename from lib/Sema/CXXFieldCollector.h
rename to include/clang/Sema/CXXFieldCollector.h
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index 348917a..edc6331 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -13,17 +13,112 @@
 #ifndef LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
 #define LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
 
+#include "clang/AST/Type.h"
+#include "clang/AST/CanonicalType.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "clang-c/Index.h"
 #include <memory>
 #include <string>
 
 namespace llvm {
-class raw_ostream;
+  class raw_ostream;
 }
 
 namespace clang {
 
+/// \brief Default priority values for code-completion results based
+/// on their kind.
+enum {
+  /// \brief Priority for a send-to-super completion.
+  CCP_SuperCompletion = 8,
+  /// \brief Priority for a declaration that is in the local scope.
+  CCP_LocalDeclaration = 8,
+  /// \brief Priority for a member declaration found from the current
+  /// method or member function.
+  CCP_MemberDeclaration = 20,
+  /// \brief Priority for a language keyword (that isn't any of the other
+  /// categories).
+  CCP_Keyword = 30,
+  /// \brief Priority for a code pattern.
+  CCP_CodePattern = 30,
+  /// \brief Priority for a non-type declaration.
+  CCP_Declaration = 50,
+  /// \brief Priority for a constant value (e.g., enumerator).
+  CCP_Constant = 60,
+  /// \brief Priority for a type.
+  CCP_Type = 65,
+  /// \brief Priority for a preprocessor macro.
+  CCP_Macro = 70,
+  /// \brief Priority for a nested-name-specifier.
+  CCP_NestedNameSpecifier = 75,
+  /// \brief Priority for a result that isn't likely to be what the user wants,
+  /// but is included for completeness.
+  CCP_Unlikely = 80
+};
+
+/// \brief Priority value deltas that are added to code-completion results
+/// based on the context of the result.
+enum {
+  /// \brief The result is in a base class.
+  CCD_InBaseClass = 2,
+  /// \brief The result is a type match against void.
+  ///
+  /// Since everything converts to "void", we don't give as drastic an 
+  /// adjustment for matching void.
+  CCD_VoidMatch = -5,
+  /// \brief The result is a C++ non-static member function whose qualifiers
+  /// exactly match the object type on which the member function can be called.
+  CCD_ObjectQualifierMatch = -1,
+  /// \brief The selector of the given message exactly matches the selector
+  /// of the current method, which might imply that some kind of delegation
+  /// is occurring.
+  CCD_SelectorMatch = -3
+};
+
+/// \brief Priority value factors by which we will divide or multiply the
+/// priority of a code-completion result.
+enum {
+  /// \brief Divide by this factor when a code-completion result's type exactly
+  /// matches the type we expect.
+  CCF_ExactTypeMatch = 4,
+  /// \brief Divide by this factor when a code-completion result's type is
+  /// similar to the type we expect (e.g., both arithmetic types, both
+  /// Objective-C object pointer types).
+  CCF_SimilarTypeMatch = 2
+};
+
+/// \brief A simplified classification of types used when determining
+/// "similar" types for code completion.
+enum SimplifiedTypeClass {
+  STC_Arithmetic,
+  STC_Array,
+  STC_Block,
+  STC_Function,
+  STC_ObjectiveC,
+  STC_Other,
+  STC_Pointer,
+  STC_Record,
+  STC_Void
+};
+  
+/// \brief Determine the simplified type class of the given canonical type.
+SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T);
+  
+/// \brief Determine the type that this declaration will have if it is used
+/// as a type or in an expression.
+QualType getDeclUsageType(ASTContext &C, NamedDecl *ND);
+  
+/// \brief Determine the priority to be given to a macro code completion result
+/// with the given name.
+///
+/// \param MacroName The name of the macro.
+///
+/// \param PreferredTypeIsPointer Whether the preferred type for the context
+/// of this macro is a pointer type.
+unsigned getMacroUsagePriority(llvm::StringRef MacroName, 
+                               bool PreferredTypeIsPointer = false);
+
 class FunctionDecl;
 class FunctionType;
 class FunctionTemplateDecl;
@@ -32,6 +127,121 @@
 class NestedNameSpecifier;
 class Sema;
 
+/// \brief The context in which code completion occurred, so that the
+/// code-completion consumer can process the results accordingly.
+class CodeCompletionContext {
+public:
+  enum Kind {
+    /// \brief An unspecified code-completion context.
+    CCC_Other,
+    /// \brief Code completion occurred within a "top-level" completion context,
+    /// e.g., at namespace or global scope.
+    CCC_TopLevel,
+    /// \brief Code completion occurred within an Objective-C interface,
+    /// protocol, or category interface.
+    CCC_ObjCInterface,
+    /// \brief Code completion occurred within an Objective-C implementation
+    /// or category implementation.
+    CCC_ObjCImplementation,
+    /// \brief Code completion occurred within the instance variable list of
+    /// an Objective-C interface, implementation, or category implementation.
+    CCC_ObjCIvarList,
+    /// \brief Code completion occurred within a class, struct, or union.
+    CCC_ClassStructUnion,
+    /// \brief Code completion occurred where a statement (or declaration) is
+    /// expected in a function, method, or block.
+    CCC_Statement,
+    /// \brief Code completion occurred where an expression is expected.
+    CCC_Expression,
+    /// \brief Code completion occurred where an Objective-C message receiver
+    /// is expected.
+    CCC_ObjCMessageReceiver,
+    /// \brief Code completion occurred on the right-hand side of a member
+    /// access expression.
+    ///
+    /// The results of this completion are the members of the type being 
+    /// accessed. The type itself is available via 
+    /// \c CodeCompletionContext::getType().
+    CCC_MemberAccess,
+    /// \brief Code completion occurred after the "enum" keyword, to indicate
+    /// an enumeration name.
+    CCC_EnumTag,
+    /// \brief Code completion occurred after the "union" keyword, to indicate
+    /// a union name.
+    CCC_UnionTag,
+    /// \brief Code completion occurred after the "struct" or "class" keyword,
+    /// to indicate a struct or class name.
+    CCC_ClassOrStructTag,
+    /// \brief Code completion occurred where a protocol name is expected.
+    CCC_ObjCProtocolName,
+    /// \brief Code completion occurred where a namespace or namespace alias
+    /// is expected.
+    CCC_Namespace,
+    /// \brief Code completion occurred where a type name is expected.
+    CCC_Type,
+    /// \brief Code completion occurred where a new name is expected.
+    CCC_Name,
+    /// \brief Code completion occurred where a new name is expected and a
+    /// qualified name is permissible.
+    CCC_PotentiallyQualifiedName,
+    /// \brief Code completion occurred where an macro is being defined.
+    CCC_MacroName,
+    /// \brief Code completion occurred where a macro name is expected
+    /// (without any arguments, in the case of a function-like macro).
+    CCC_MacroNameUse,
+    /// \brief Code completion occurred within a preprocessor expression.
+    CCC_PreprocessorExpression,
+    /// \brief Code completion occurred where a preprocessor directive is 
+    /// expected.
+    CCC_PreprocessorDirective,
+    /// \brief Code completion occurred in a context where natural language is
+    /// expected, e.g., a comment or string literal.
+    ///
+    /// This context usually implies that no completions should be added,
+    /// unless they come from an appropriate natural-language dictionary.
+    CCC_NaturalLanguage,
+    /// \brief Code completion for a selector, as in an @selector expression.
+    CCC_SelectorName,
+    /// \brief Code completion within a type-qualifier list.
+    CCC_TypeQualifiers
+  };
+
+private:
+  enum Kind Kind;
+
+  /// \brief The type that would prefer to see at this point (e.g., the type
+  /// of an initializer or function parameter).
+  QualType PreferredType;
+  
+  /// \brief The type of the base object in a member access expression.
+  QualType BaseType;
+  
+public:
+  /// \brief Construct a new code-completion context of the given kind.
+  CodeCompletionContext(enum Kind Kind) : Kind(Kind) { }
+  
+  /// \brief Construct a new code-completion context of the given kind.
+  CodeCompletionContext(enum Kind Kind, QualType T) : Kind(Kind) { 
+    if (Kind == CCC_MemberAccess)
+      BaseType = T;
+    else
+      PreferredType = T;
+  }
+  
+  /// \brief Retrieve the kind of code-completion context.
+  enum Kind getKind() const { return Kind; }
+  
+  /// \brief Retrieve the type that this expression would prefer to have, e.g.,
+  /// if the expression is a variable initializer or a function argument, the
+  /// type of the corresponding variable or function parameter.
+  QualType getPreferredType() const { return PreferredType; }
+  
+  /// \brief Retrieve the type of the base object in a member-access 
+  /// expression.
+  QualType getBaseType() const { return BaseType; }
+};
+
+
 /// \brief A "string" used to describe how code completion can
 /// be performed for an entity.
 ///
@@ -156,13 +366,14 @@
   
 public:
   CodeCompletionString() { }
-  ~CodeCompletionString();
+  ~CodeCompletionString() { clear(); }
   
   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(); }
+  void clear();
   
   Chunk &operator[](unsigned I) {
     assert(I < size() && "Chunk index out-of-range");
@@ -226,15 +437,182 @@
   std::string getAsString() const; 
   
   /// \brief Clone this code-completion string.
-  CodeCompletionString *Clone() const;
+  ///
+  /// \param Result If non-NULL, points to an empty code-completion
+  /// result that will be given a cloned copy of
+  CodeCompletionString *Clone(CodeCompletionString *Result = 0) 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);
+  ///
+  /// \returns true if successful, false otherwise.
+  bool Deserialize(const char *&Str, const char *StrEnd);
 };
+
+/// \brief Captures a result of code completion.
+class CodeCompletionResult {
+public:
+  /// \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 The priority of this particular code-completion result.
+  unsigned Priority;
+
+  /// \brief The cursor kind that describes this result.
+  CXCursorKind CursorKind;
+    
+  /// \brief The availability of this result.
+  CXAvailabilityKind Availability;
+    
+  /// \brief Specifies 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 Whether we're completing a declaration of the given entity,
+  /// rather than a use of that entity.
+  bool DeclaringEntity : 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.
+  CodeCompletionResult(NamedDecl *Declaration, 
+                       NestedNameSpecifier *Qualifier = 0,
+                       bool QualifierIsInformative = false)
+    : Kind(RK_Declaration), Declaration(Declaration), 
+      Priority(getPriorityFromDecl(Declaration)), 
+      Availability(CXAvailability_Available), StartParameter(0), 
+      Hidden(false), QualifierIsInformative(QualifierIsInformative),
+      StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+      DeclaringEntity(false), Qualifier(Qualifier) { 
+    computeCursorKindAndAvailability();
+  }
+    
+  /// \brief Build a result that refers to a keyword or symbol.
+  CodeCompletionResult(const char *Keyword, unsigned Priority = CCP_Keyword)
+    : Kind(RK_Keyword), Keyword(Keyword), Priority(Priority), 
+      Availability(CXAvailability_Available), 
+      StartParameter(0), Hidden(false), QualifierIsInformative(0), 
+      StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+      DeclaringEntity(false), Qualifier(0) {
+    computeCursorKindAndAvailability();
+  }
+    
+  /// \brief Build a result that refers to a macro.
+  CodeCompletionResult(IdentifierInfo *Macro, unsigned Priority = CCP_Macro)
+    : Kind(RK_Macro), Macro(Macro), Priority(Priority), 
+      Availability(CXAvailability_Available), StartParameter(0), 
+      Hidden(false), QualifierIsInformative(0), 
+      StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+      DeclaringEntity(false), Qualifier(0) { 
+    computeCursorKindAndAvailability();
+  }
+
+  /// \brief Build a result that refers to a pattern.
+  CodeCompletionResult(CodeCompletionString *Pattern,
+                       unsigned Priority = CCP_CodePattern,
+                       CXCursorKind CursorKind = CXCursor_NotImplemented,
+                   CXAvailabilityKind Availability = CXAvailability_Available)
+    : Kind(RK_Pattern), Pattern(Pattern), Priority(Priority), 
+      CursorKind(CursorKind), Availability(Availability), StartParameter(0), 
+      Hidden(false), QualifierIsInformative(0), 
+      StartsNestedNameSpecifier(false), AllParametersAreInformative(false), 
+      DeclaringEntity(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.
+  ///
+  /// \param S The semantic analysis that created the result.
+  ///
+  /// \param Result If non-NULL, the already-allocated, empty
+  /// code-completion string that will be populated with the
+  /// appropriate code completion string for this result.
+  CodeCompletionString *CreateCodeCompletionString(Sema &S,
+                                           CodeCompletionString *Result = 0);
+    
+  void Destroy();
+    
+  /// brief Determine a base priority for the given declaration.
+  static unsigned getPriorityFromDecl(NamedDecl *ND);
+    
+private:
+  void computeCursorKindAndAvailability();
+};
+  
+bool operator<(const CodeCompletionResult &X, const CodeCompletionResult &Y);
+  
+inline bool operator>(const CodeCompletionResult &X, 
+                      const CodeCompletionResult &Y) {
+  return Y < X;
+}
+  
+inline bool operator<=(const CodeCompletionResult &X, 
+                      const CodeCompletionResult &Y) {
+  return !(Y < X);
+}
+
+inline bool operator>=(const CodeCompletionResult &X, 
+                       const CodeCompletionResult &Y) {
+  return !(X < Y);
+}
+
   
 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 
                               const CodeCompletionString &CCS);
@@ -246,114 +624,19 @@
   /// \brief Whether to include macros in the code-completion results.
   bool IncludeMacros;
 
+  /// \brief Whether to include code patterns (such as for loops) within
+  /// the completion results.
+  bool IncludeCodePatterns;
+  
+  /// \brief Whether to include global (top-level) declarations and names in
+  /// the completion results.
+  bool IncludeGlobals;
+  
   /// \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.
@@ -418,14 +701,23 @@
                                                 Sema &S) const;    
   };
   
-  CodeCompleteConsumer() : IncludeMacros(false), OutputIsBinary(false) { }
+  CodeCompleteConsumer() : IncludeMacros(false), IncludeCodePatterns(false),
+                           IncludeGlobals(true), OutputIsBinary(false) { }
   
-  CodeCompleteConsumer(bool IncludeMacros, bool OutputIsBinary)
-    : IncludeMacros(IncludeMacros), OutputIsBinary(OutputIsBinary) { }
+  CodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
+                       bool IncludeGlobals, bool OutputIsBinary)
+    : IncludeMacros(IncludeMacros), IncludeCodePatterns(IncludeCodePatterns),
+      IncludeGlobals(IncludeGlobals), OutputIsBinary(OutputIsBinary) { }
   
   /// \brief Whether the code-completion consumer wants to see macros.
   bool includeMacros() const { return IncludeMacros; }
 
+  /// \brief Whether the code-completion consumer wants to see code patterns.
+  bool includeCodePatterns() const { return IncludeCodePatterns; }
+  
+  /// \brief Whether to include global (top-level) declaration results.
+  bool includeGlobals() const { return IncludeGlobals; }
+  
   /// \brief Determine whether the output of this consumer is binary.
   bool isOutputBinary() const { return OutputIsBinary; }
   
@@ -435,7 +727,9 @@
   /// \name Code-completion callbacks
   //@{
   /// \brief Process the finalized code-completion results.
-  virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
+  virtual void ProcessCodeCompleteResults(Sema &S, 
+                                          CodeCompletionContext Context,
+                                          CodeCompletionResult *Results,
                                           unsigned NumResults) { }
 
   /// \param S the semantic-analyzer object for which code-completion is being
@@ -451,7 +745,7 @@
                                          unsigned NumCandidates) { }
   //@}
 };
-  
+
 /// \brief A simple code-completion consumer that prints the results it 
 /// receives in a simple format.
 class PrintingCodeCompleteConsumer : public CodeCompleteConsumer {
@@ -461,12 +755,16 @@
 public:
   /// \brief Create a new printing code-completion consumer that prints its
   /// results to the given raw output stream.
-  PrintingCodeCompleteConsumer(bool IncludeMacros,
+  PrintingCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
+                               bool IncludeGlobals,
                                llvm::raw_ostream &OS)
-    : CodeCompleteConsumer(IncludeMacros, false), OS(OS) { }
+    : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals,
+                           false), OS(OS) {}
   
   /// \brief Prints the finalized code-completion results.
-  virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
+  virtual void ProcessCodeCompleteResults(Sema &S, 
+                                          CodeCompletionContext Context,
+                                          CodeCompletionResult *Results,
                                           unsigned NumResults);
   
   virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
@@ -484,18 +782,22 @@
   /// \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) { }
+  CIndexCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
+                             bool IncludeGlobals, llvm::raw_ostream &OS)
+    : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals,
+                           true), OS(OS) {}
   
   /// \brief Prints the finalized code-completion results.
-  virtual void ProcessCodeCompleteResults(Sema &S, Result *Results, 
+  virtual void ProcessCodeCompleteResults(Sema &S, 
+                                          CodeCompletionContext Context,
+                                          CodeCompletionResult *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/DeclSpec.h b/include/clang/Sema/DeclSpec.h
new file mode 100644
index 0000000..0893ae7
--- /dev/null
+++ b/include/clang/Sema/DeclSpec.h
@@ -0,0 +1,1386 @@
+//===--- DeclSpec.h - Parsed declaration 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 classes used to store parsed information about
+// declaration-specifiers and declarators.
+//
+//   static const int volatile x, *y, *(*(*z)[10])(const void *x);
+//   ------------------------- -  --  ---------------------------
+//     declaration-specifiers  \  |   /
+//                            declarators
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_DECLSPEC_H
+#define LLVM_CLANG_SEMA_DECLSPEC_H
+
+#include "clang/Sema/AttributeList.h"
+#include "clang/Sema/Ownership.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 NestedNameSpecifier;
+  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;
+  NestedNameSpecifier *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(); }
+
+  NestedNameSpecifier *getScopeRep() const { return ScopeRep; }
+  void setScopeRep(NestedNameSpecifier *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;
+  bool SCS_extern_in_linkage_spec : 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 TypeAltiVecBool : 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;
+
+  union {
+    UnionParsedType TypeRep;
+    Decl *DeclRep;
+    Expr *ExprRep;
+  };
+
+  // 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>".
+  Decl * const *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();
+
+  static bool isTypeRep(TST T) {
+    return (T == TST_typename || T == TST_typeofType);
+  }
+  static bool isExprRep(TST T) {
+    return (T == TST_typeofExpr || T == TST_decltype);
+  }
+  static bool isDeclRep(TST T) {
+    return (T == TST_enum || T == TST_struct ||
+            T == TST_union || T == TST_class);
+  }
+
+  DeclSpec(const DeclSpec&);       // DO NOT IMPLEMENT
+  void operator=(const DeclSpec&); // DO NOT IMPLEMENT
+public:
+
+  DeclSpec()
+    : StorageClassSpec(SCS_unspecified),
+      SCS_thread_specified(false),
+      SCS_extern_in_linkage_spec(false),
+      TypeSpecWidth(TSW_unspecified),
+      TypeSpecComplex(TSC_unspecified),
+      TypeSpecSign(TSS_unspecified),
+      TypeSpecType(TST_unspecified),
+      TypeAltiVecVector(false),
+      TypeAltiVecPixel(false),
+      TypeAltiVecBool(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),
+      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; }
+  bool isExternInLinkageSpec() const { return SCS_extern_in_linkage_spec; }
+  void setExternInLinkageSpec(bool Value) {
+    SCS_extern_in_linkage_spec = Value;
+  }
+
+  SourceLocation getStorageClassSpecLoc() const { return StorageClassSpecLoc; }
+  SourceLocation getThreadSpecLoc() const { return SCS_threadLoc; }
+
+  void ClearStorageClassSpecs() {
+    StorageClassSpec     = DeclSpec::SCS_unspecified;
+    SCS_thread_specified = false;
+    SCS_extern_in_linkage_spec = 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 isTypeAltiVecBool() const { return TypeAltiVecBool; }
+  bool isTypeSpecOwned() const { return TypeSpecOwned; }
+  ParsedType getRepAsType() const {
+    assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type");
+    return TypeRep;
+  }
+  Decl *getRepAsDecl() const {
+    assert(isDeclRep((TST) TypeSpecType) && "DeclSpec does not store a decl");
+    return DeclRep;
+  }
+  Expr *getRepAsExpr() const {
+    assert(isExprRep((TST) TypeSpecType) && "DeclSpec does not store an expr");
+    return ExprRep;
+  }
+  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);
+  bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
+                       unsigned &DiagID, ParsedType Rep);
+  bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
+                       unsigned &DiagID, Decl *Rep, bool Owned);
+  bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
+                       unsigned &DiagID, Expr *Rep);
+  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 UpdateDeclRep(Decl *Rep) {
+    assert(isDeclRep((TST) TypeSpecType));
+    DeclRep = Rep;
+  }
+  void UpdateTypeRep(ParsedType Rep) {
+    assert(isTypeRep((TST) TypeSpecType));
+    TypeRep = Rep;
+  }
+  void UpdateExprRep(Expr *Rep) {
+    assert(isExprRep((TST) TypeSpecType));
+    ExprRep = 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 Decl * const *ProtocolQualifierListTy;
+  ProtocolQualifierListTy getProtocolQualifiers() const {
+    return ProtocolQualifiers;
+  }
+  SourceLocation *getProtocolLocs() const { return ProtocolLocs; }
+  unsigned getNumProtocolQualifiers() const {
+    return NumProtocolQualifiers;
+  }
+  SourceLocation getProtocolLAngleLoc() const { return ProtocolLAngleLoc; }
+  void setProtocolQualifiers(Decl * const *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.
+    UnionParsedType ConversionFunctionId;
+
+    /// \brief When Kind == IK_ConstructorName, the class-name of the type
+    /// whose constructor is being referenced.
+    UnionParsedType ConstructorName;
+    
+    /// \brief When Kind == IK_DestructorName, the type referred to by the
+    /// class-name.
+    UnionParsedType 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, 
+                               ParsedType 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(ParsedType 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,
+                         ParsedType 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.
+    Expr *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;
+    Decl *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,
+              Decl *param,
+              CachedTokens *DefArgTokens = 0)
+      : Ident(ident), IdentLoc(iloc), Param(param),
+        DefaultArgTokens(DefArgTokens) {}
+  };
+
+  struct TypeAndRange {
+    ParsedType 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;
+    }
+
+    /// isKNRPrototype - Return true if this is a K&R style identifier list,
+    /// like "void foo(a,b,c)".  In a function definition, this will be followed
+    /// by the argument type definitions.
+    bool isKNRPrototype() const {
+      return !hasPrototype && NumArgs != 0;
+    }
+    
+    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, Expr *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,
+                                     ParsedType *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.
+  Expr *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(Expr *E) { AsmLabel = E; }
+  Expr *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;
+  Expr *BitfieldSize;
+  explicit FieldDeclarator(DeclSpec &DS) : D(DS, Declarator::MemberContext) {
+    BitfieldSize = 0;
+  }
+};
+  
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h
new file mode 100644
index 0000000..6a9a1bf
--- /dev/null
+++ b/include/clang/Sema/DelayedDiagnostic.h
@@ -0,0 +1,168 @@
+//===--- DelayedDiagnostic.h - Delayed declarator 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 the DelayedDiagnostic class, which is used to
+// record diagnostics that are being conditionally produced during
+// declarator parsing.  Certain kinds of diagnostics --- notably
+// deprecation and access control --- are suppressed based on
+// semantic properties of the parsed declaration that aren't known
+// until it is fully parsed.
+//
+// This file also defines AccessedEntity.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H
+#define LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H
+
+#include "clang/AST/DeclCXX.h"
+
+namespace clang {
+namespace sema {
+
+/// A declaration being accessed, together with information about how
+/// it was accessed.
+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 {
+    assert(!IsMember); 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;
+};
+
+/// A diagnostic message which has been conditionally emitted pending
+/// the complete parsing of the current declaration.
+class DelayedDiagnostic {
+public:
+  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);
+  }
+};
+
+}
+}
+
+#endif
diff --git a/include/clang/Sema/Designator.h b/include/clang/Sema/Designator.h
new file mode 100644
index 0000000..6fe7ab2
--- /dev/null
+++ b/include/clang/Sema/Designator.h
@@ -0,0 +1,218 @@
+//===--- 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 (a la
+// C99 designated initializers) during parsing.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_DESIGNATOR_H
+#define LLVM_CLANG_SEMA_DESIGNATOR_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class Expr;
+class IdentifierInfo;
+class Sema;
+
+/// Designator - A designator in a C99 designated initializer.
+///
+/// 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 {
+    Expr *Index;
+    unsigned LBracketLoc;
+    mutable unsigned  RBracketLoc;
+  };
+  struct ArrayRangeDesignatorInfo {
+    Expr *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);
+  }
+
+  Expr *getArrayIndex() const {
+    assert(isArrayDesignator() && "Invalid accessor");
+    return ArrayInfo.Index;
+  }
+
+  Expr *getArrayRangeStart() const {
+    assert(isArrayRangeDesignator() && "Invalid accessor");
+    return ArrayRangeInfo.Start;
+  }
+  Expr *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(Expr *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(Expr *Start,
+                                  Expr *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(Sema &Actions) {}
+
+  /// FreeExprs - Release any unclaimed memory for the expressions in
+  /// this designator.
+  void FreeExprs(Sema &Actions) {}
+};
+
+
+/// 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(Sema &Actions) {}
+
+  /// FreeExprs - Release any unclaimed memory for the expressions in this
+  /// designation.
+  void FreeExprs(Sema &Actions) {}
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h
index d27e292..7be0033 100644
--- a/include/clang/Sema/ExternalSemaSource.h
+++ b/include/clang/Sema/ExternalSemaSource.h
@@ -13,8 +13,8 @@
 #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"
+#include "clang/Sema/ObjCMethodList.h"
 
 namespace clang {
 
@@ -29,6 +29,8 @@
     ExternalASTSource::SemaSource = true;
   }
 
+  ~ExternalSemaSource();
+
   /// \brief Initialize the semantic source with the Sema instance
   /// being used to perform semantic analysis on the abstract syntax
   /// tree.
diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h
new file mode 100644
index 0000000..7e9d338
--- /dev/null
+++ b/include/clang/Sema/IdentifierResolver.h
@@ -0,0 +1,198 @@
+//===- 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"
+
+namespace clang {
+
+class ASTContext;
+class Decl;
+class DeclContext;
+class DeclarationName;
+class NamedDecl;
+class Scope;
+
+/// 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;
+
+    void incrementSlowCase();
+  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
+        incrementSlowCase();
+      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 AST 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/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
new file mode 100644
index 0000000..0062b3a
--- /dev/null
+++ b/include/clang/Sema/Initialization.h
@@ -0,0 +1,780 @@
+//===--- 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_INITIALIZATION_H
+#define LLVM_CLANG_SEMA_INITIALIZATION_H
+
+#include "clang/Sema/Ownership.h"
+#include "clang/Sema/Overload.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/UnresolvedSet.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,
+    /// \brief The entity being initialized is a field of block descriptor for
+    /// the copied-in c++ object.
+    EK_BlockElement
+  };
+  
+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;
+    
+    struct {
+      /// \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 Whether the 
+      bool NRVO;
+    } LocAndNRVO;
+    
+    /// \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,
+                    bool NRVO = false)
+    : Kind(Kind), Parent(0), Type(Type)
+  {
+    LocAndNRVO.Location = Loc.getRawEncoding();
+    LocAndNRVO.NRVO = NRVO;
+  }
+  
+  /// \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, bool NRVO) {
+    return InitializedEntity(EK_Result, ReturnLoc, Type, NRVO);
+  }
+
+  static InitializedEntity InitializeBlock(SourceLocation BlockVarLoc,
+                                           QualType Type, bool NRVO) {
+    return InitializedEntity(EK_BlockElement, BlockVarLoc, Type, NRVO);
+  }
+  
+  /// \brief Create the initialization entity for an exception object.
+  static InitializedEntity InitializeException(SourceLocation ThrowLoc,
+                                               QualType Type, bool NRVO) {
+    return InitializedEntity(EK_Exception, ThrowLoc, Type, NRVO);
+  }
+
+  /// \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 Determine whether this initialization allows the named return 
+  /// value optimization, which also applies to thrown objects.
+  bool allowsNRVO() 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(LocAndNRVO.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(LocAndNRVO.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];
+  }
+  
+  bool isCopyInit() const { return Kind == SIK_Copy; }
+  
+  /// \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 xvalue.
+    SK_CastDerivedToBaseXValue,
+    /// \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 xvalue.
+    SK_QualificationConversionXValue,
+    /// \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 An initialization that "converts" an Objective-C object
+    /// (not a point to an object) to another Objective-C object type.
+    SK_ObjCObjectConversion
+  };
+  
+  /// \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,
+    /// \brief Initialization of an incomplete type.
+    FK_Incomplete
+  };
+  
+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.
+  ExprResult Perform(Sema &S,
+                     const InitializedEntity &Entity,
+                     const InitializationKind &Kind,
+                     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,
+                                ExprValueKind Category);
+     
+  /// \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,
+                                     ExprValueKind Category);
+  
+  /// \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 Add an Objective-C object conversion step, which is
+  /// always a no-op.
+  void AddObjCObjectConversionStep(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_INITIALIZATION_H
diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h
new file mode 100644
index 0000000..c9b090a
--- /dev/null
+++ b/include/clang/Sema/Lookup.h
@@ -0,0 +1,674 @@
+//===--- 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 "clang/Sema/Sema.h"
+#include "clang/AST/DeclCXX.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, const DeclarationNameInfo &NameInfo,
+               Sema::LookupNameKind LookupKind,
+               Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
+    : ResultKind(NotFound),
+      Paths(0),
+      NamingClass(0),
+      SemaRef(SemaRef),
+      NameInfo(NameInfo),
+      LookupKind(LookupKind),
+      IDNS(0),
+      Redecl(Redecl != Sema::NotForRedeclaration),
+      HideTags(true),
+      Diagnose(Redecl == Sema::NotForRedeclaration)
+  {
+    configure();
+  }
+
+  // TODO: consider whether this constructor should be restricted to take
+  // as input a const IndentifierInfo* (instead of Name),
+  // forcing other cases towards the constructor taking a DNInfo.
+  LookupResult(Sema &SemaRef, DeclarationName Name,
+               SourceLocation NameLoc, Sema::LookupNameKind LookupKind,
+               Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
+    : ResultKind(NotFound),
+      Paths(0),
+      NamingClass(0),
+      SemaRef(SemaRef),
+      NameInfo(Name, 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),
+      NameInfo(Other.NameInfo),
+      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 info to look up.
+  const DeclarationNameInfo &getLookupNameInfo() const {
+    return NameInfo;
+  }
+
+  /// \brief Sets the name info to look up.
+  void setLookupNameInfo(const DeclarationNameInfo &NameInfo) {
+    this->NameInfo = NameInfo;
+  }
+
+  /// Gets the name to look up.
+  DeclarationName getLookupName() const {
+    return NameInfo.getName();
+  }
+
+  /// \brief Sets the name to look up.
+  void setLookupName(DeclarationName Name) {
+    NameInfo.setName(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;
+  }
+
+  /// Determines whether this lookup is suppressing diagnostics.
+  bool isSuppressingDiagnostics() const {
+    return !Diagnose;
+  }
+
+  /// 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 NameInfo.getLoc();
+  }
+
+  /// \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.
+#ifndef NDEBUG
+  void sanity() const;
+#else
+  void sanity() const {}
+#endif
+
+  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;
+  DeclarationNameInfo NameInfo;
+  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/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h
new file mode 100644
index 0000000..225c137
--- /dev/null
+++ b/include/clang/Sema/ObjCMethodList.h
@@ -0,0 +1,38 @@
+//===--- ObjCMethodList.h - A singly linked list of methods -----*- 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 ObjCMethodList, a singly-linked list of methods.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_OBJC_METHOD_LIST_H
+#define LLVM_CLANG_SEMA_OBJC_METHOD_LIST_H
+
+namespace clang {
+
+class ObjCMethodDecl;
+
+/// 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;
+  }
+};
+
+}
+
+#endif
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
new file mode 100644
index 0000000..851d68a
--- /dev/null
+++ b/include/clang/Sema/Overload.h
@@ -0,0 +1,648 @@
+//===--- 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/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/TemplateBase.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;
+  class Sema;
+
+  /// 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.
+  };
+  
+  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
+  };
+
+  /// 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_Vector_Conversion,     ///< Vector conversions
+    ICK_Vector_Splat,          ///< A vector splat from an arithmetic type
+    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.
+  class StandardConversionSequence {
+  public:
+    /// 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();
+    
+    bool isIdentityConversion() const {
+      return First == ICK_Identity && Second == ICK_Identity && 
+             Third == ICK_Identity;
+    }
+    
+    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).
+  class ImplicitConversionSequence {
+  public:
+    /// 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 DiagnoseAmbiguousConversion(Sema &S,
+                                     SourceLocation CaretLoc,
+                                     const PartialDiagnostic &PDiag) const;
+
+    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;
+
+      /// \brief Opaque pointer containing additional data about
+      /// this deduction failure.
+      void *Data;
+      
+      /// \brief Retrieve the template parameter this deduction failure
+      /// refers to, if any.
+      TemplateParameter getTemplateParameter();
+      
+      /// \brief Retrieve the template argument list associated with this
+      /// deduction failure, if any.
+      TemplateArgumentList *getTemplateArgumentList();
+      
+      /// \brief Return the first template argument this deduction failure
+      /// refers to, if any.
+      const TemplateArgument *getFirstArg();
+
+      /// \brief Return the second template argument this deduction failure
+      /// refers to, if any.
+      const TemplateArgument *getSecondArg();
+      
+      /// \brief Free any memory associated with this deduction failure.
+      void Destroy();
+    };
+
+    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;    
+    
+    OverloadCandidateSet(const OverloadCandidateSet &);
+    OverloadCandidateSet &operator=(const OverloadCandidateSet &);
+    
+  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();
+    
+    ~OverloadCandidateSet() { clear(); }
+
+    /// Find the best viable function on this overload set, if it exists.
+    OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc,
+                                         OverloadCandidateSet::iterator& Best);
+
+    void NoteCandidates(Sema &S,
+                        OverloadCandidateDisplayKind OCD,
+                        Expr **Args, unsigned NumArgs,
+                        const char *Opc = 0,
+                        SourceLocation Loc = SourceLocation());
+  };
+
+  bool isBetterOverloadCandidate(Sema &S,
+                                 const OverloadCandidate& Cand1,
+                                 const OverloadCandidate& Cand2,
+                                 SourceLocation Loc);
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_OVERLOAD_H
diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h
new file mode 100644
index 0000000..7739f3a
--- /dev/null
+++ b/include/clang/Sema/Ownership.h
@@ -0,0 +1,462 @@
+//===--- 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_SEMA_OWNERSHIP_H
+#define LLVM_CLANG_SEMA_OWNERSHIP_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+//===----------------------------------------------------------------------===//
+// OpaquePtr
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+  class Attr;
+  class CXXBaseOrMemberInitializer;
+  class CXXBaseSpecifier;
+  class Decl;
+  class DeclGroupRef;
+  class Expr;
+  class NestedNameSpecifier;
+  class QualType;
+  class Sema;
+  class Stmt;
+  class TemplateName;
+  class TemplateParameterList;
+
+  /// 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 <class PtrTy>
+  class OpaquePtr {
+    void *Ptr;
+    explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {}
+
+    typedef llvm::PointerLikeTypeTraits<PtrTy> Traits;
+
+  public:
+    OpaquePtr() : Ptr(0) {}
+
+    static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; }
+
+    template <typename T> T* getAs() const {
+      return get();
+    }
+
+    template <typename T> T getAsVal() const {
+      return get();
+    }
+
+    PtrTy get() const {
+      return Traits::getFromVoidPointer(Ptr);
+    }
+
+    void set(PtrTy P) {
+      Ptr = Traits::getAsVoidPointer(P);
+    }
+
+    operator bool() const { return Ptr != 0; }
+
+    void *getAsOpaquePtr() const { return Ptr; }
+    static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); }
+  };
+
+  /// UnionOpaquePtr - A version of OpaquePtr suitable for membership
+  /// in a union.
+  template <class T> struct UnionOpaquePtr {
+    void *Ptr;
+
+    static UnionOpaquePtr make(OpaquePtr<T> P) {
+      UnionOpaquePtr OP = { P.getAsOpaquePtr() };
+      return OP;
+    }
+
+    OpaquePtr<T> get() const { return OpaquePtr<T>::getFromOpaquePtr(Ptr); }
+    operator OpaquePtr<T>() const { return get(); }
+
+    UnionOpaquePtr &operator=(OpaquePtr<T> P) {
+      Ptr = P.getAsOpaquePtr();
+      return *this;
+    }
+  };
+}
+
+namespace llvm {
+  template <class T>
+  class PointerLikeTypeTraits<clang::OpaquePtr<T> > {
+  public:
+    static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) {
+      // FIXME: Doesn't work? return P.getAs< void >();
+      return P.getAsOpaquePtr();
+    }
+    static inline clang::OpaquePtr<T> getFromVoidPointer(void *P) {
+      return clang::OpaquePtr<T>::getFromOpaquePtr(P);
+    }
+    enum { NumLowBitsAvailable = 0 };
+  };
+}
+
+
+
+// -------------------------- 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.
+
+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<class Ptr>
+  struct IsResultPtrLowBitFree {
+    static const bool value = false;
+  };
+
+  /// 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<class PtrTy,
+           bool CompressInvalid = IsResultPtrLowBitFree<PtrTy>::value>
+  class ActionResult {
+    PtrTy Val;
+    bool Invalid;
+
+  public:
+    ActionResult(bool Invalid = false)
+      : Val(PtrTy()), Invalid(Invalid) {}
+    ActionResult(PtrTy val) : Val(val), Invalid(false) {}
+    ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {}
+
+    // These two overloads prevent void* -> bool conversions.
+    ActionResult(const void *);
+    ActionResult(volatile void *);
+
+    bool isInvalid() const { return Invalid; }
+    bool isUsable() const { return !Invalid && Val; }
+
+    PtrTy get() const { return Val; }
+    PtrTy release() const { return Val; }
+    PtrTy take() const { return Val; }
+    template <typename T> T *takeAs() { return static_cast<T*>(get()); }
+
+    void set(PtrTy V) { Val = V; }
+
+    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<typename PtrTy>
+  class ActionResult<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)) { }
+
+    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) { }
+
+    // These two overloads prevent void* -> bool conversions.
+    ActionResult(const void *);
+    ActionResult(volatile void *);
+
+    bool isInvalid() const { return PtrWithInvalid & 0x01; }
+    bool isUsable() const { return PtrWithInvalid > 0x01; }
+
+    PtrTy get() const {
+      void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01);
+      return PtrTraits::getFromVoidPointer(VP);
+    }
+    PtrTy take() const { return get(); }
+    PtrTy release() const { return get(); }
+    template <typename T> T *takeAs() { return static_cast<T*>(get()); }
+
+    void set(PtrTy V) {
+      void *VP = PtrTraits::getAsVoidPointer(V);
+      PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
+      assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
+    }
+
+    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;
+    }
+  };
+
+  /// ASTMultiPtr - A moveable smart pointer to multiple AST nodes. Only owns
+  /// the individual pointers, not the array holding them.
+  template <typename PtrTy> class ASTMultiPtr;
+
+  template <class PtrTy>
+  class ASTMultiPtr {
+    PtrTy *Nodes;
+    unsigned Count;
+
+  public:
+    // Normal copying implicitly defined
+    ASTMultiPtr() : Nodes(0), Count(0) {}
+    explicit ASTMultiPtr(Sema &) : Nodes(0), Count(0) {}
+    ASTMultiPtr(Sema &, PtrTy *nodes, unsigned count)
+      : Nodes(nodes), Count(count) {}
+    // Fake mover in Parse/AstGuard.h needs this:
+    ASTMultiPtr(PtrTy *nodes, unsigned count) : Nodes(nodes), Count(count) {}
+
+    /// Access to the raw pointers.
+    PtrTy *get() const { return Nodes; }
+
+    /// Access to the count.
+    unsigned size() const { return Count; }
+
+    PtrTy *release() {
+      return Nodes;
+    }
+  };
+
+  class ParsedTemplateArgument;
+    
+  class ASTTemplateArgsPtr {
+    ParsedTemplateArgument *Args;
+    mutable unsigned Count;
+
+  public:
+    ASTTemplateArgsPtr(Sema &actions, ParsedTemplateArgument *args,
+                       unsigned count) :
+      Args(args), Count(count) { }
+
+    // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'.
+    ASTTemplateArgsPtr(ASTTemplateArgsPtr &Other) :
+      Args(Other.Args), Count(Other.Count) {
+    }
+
+    // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'.
+    ASTTemplateArgsPtr& operator=(ASTTemplateArgsPtr &Other)  {
+      Args = Other.Args;
+      Count = Other.Count;
+      return *this;
+    }
+
+    ParsedTemplateArgument *getArgs() const { return Args; }
+    unsigned size() const { return Count; }
+
+    void reset(ParsedTemplateArgument *args, unsigned count) {
+      Args = args;
+      Count = count;
+    }
+
+    const ParsedTemplateArgument &operator[](unsigned Arg) const;
+
+    ParsedTemplateArgument *release() const {
+      return Args;
+    }
+  };
+
+  /// \brief A small vector that owns a set of AST nodes.
+  template <class PtrTy, unsigned N = 8>
+  class ASTOwningVector : public llvm::SmallVector<PtrTy, N> {
+    ASTOwningVector(ASTOwningVector &); // do not implement
+    ASTOwningVector &operator=(ASTOwningVector &); // do not implement
+
+  public:
+    explicit ASTOwningVector(Sema &Actions)
+    { }
+
+    PtrTy *take() {
+      return &this->front();
+    }
+
+    template<typename T> T **takeAs() { return reinterpret_cast<T**>(take()); }
+  };
+
+  /// A SmallVector of statements, with stack size 32 (as that is the only one
+  /// used.)
+  typedef ASTOwningVector<Stmt*, 32> StmtVector;
+  /// A SmallVector of expressions, with stack size 12 (the maximum used.)
+  typedef ASTOwningVector<Expr*, 12> ExprVector;
+
+  template <class T, unsigned N> inline
+  ASTMultiPtr<T> move_arg(ASTOwningVector<T, N> &vec) {
+    return ASTMultiPtr<T>(vec.take(), vec.size());
+  }
+
+  // These versions are hopefully no-ops.
+  template <class T, bool C>
+  inline ActionResult<T,C> move(ActionResult<T,C> &ptr) {
+    return ptr;
+  }
+
+  template <class T> inline
+  ASTMultiPtr<T>& move(ASTMultiPtr<T> &ptr) {
+    return ptr;
+  }
+
+  // We can re-use the low bit of expression, statement, base, and
+  // member-initializer pointers for the "invalid" flag of
+  // ActionResult.
+  template<> struct IsResultPtrLowBitFree<Expr*> {
+    static const bool value = true;
+  };
+  template<> struct IsResultPtrLowBitFree<Stmt*> {
+    static const bool value = true;
+  };
+  template<> struct IsResultPtrLowBitFree<CXXBaseSpecifier*> {
+    static const bool value = true;
+  };
+  template<> struct IsResultPtrLowBitFree<CXXBaseOrMemberInitializer*> {
+    static const bool value = true;
+  };
+
+  /// An opaque type for threading parsed type information through the
+  /// parser.
+  typedef OpaquePtr<QualType> ParsedType;
+  typedef UnionOpaquePtr<QualType> UnionParsedType;
+
+  typedef ActionResult<Expr*> ExprResult;
+  typedef ActionResult<Stmt*> StmtResult;
+  typedef ActionResult<ParsedType> TypeResult;
+  typedef ActionResult<CXXBaseSpecifier*> BaseResult;
+  typedef ActionResult<CXXBaseOrMemberInitializer*> MemInitResult;
+
+  typedef ActionResult<Decl*> DeclResult;
+  typedef OpaquePtr<TemplateName> ParsedTemplateTy;
+
+  inline Expr *move(Expr *E) { return E; }
+  inline Stmt *move(Stmt *S) { return S; }
+
+  typedef ASTMultiPtr<Expr*> MultiExprArg;
+  typedef ASTMultiPtr<Stmt*> MultiStmtArg;
+  typedef ASTMultiPtr<TemplateParameterList*> MultiTemplateParamsArg;
+
+  inline ExprResult ExprError() { return ExprResult(true); }
+  inline StmtResult StmtError() { return StmtResult(true); }
+
+  inline ExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); }
+  inline StmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); }
+
+  inline ExprResult ExprEmpty() { return ExprResult(false); }
+  inline StmtResult StmtEmpty() { return StmtResult(false); }
+
+  inline Expr *AssertSuccess(ExprResult R) {
+    assert(!R.isInvalid() && "operation was asserted to never fail!");
+    return R.get();
+  }
+
+  inline Stmt *AssertSuccess(StmtResult R) {
+    assert(!R.isInvalid() && "operation was asserted to never fail!");
+    return R.get();
+  }
+}
+
+#endif
diff --git a/include/clang/Sema/ParseAST.h b/include/clang/Sema/ParseAST.h
deleted file mode 100644
index f6cff2a..0000000
--- a/include/clang/Sema/ParseAST.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===--- 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/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h
new file mode 100644
index 0000000..da68a49
--- /dev/null
+++ b/include/clang/Sema/ParsedTemplate.h
@@ -0,0 +1,172 @@
+//===--- ParsedTemplate.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_SEMA_PARSEDTEMPLATE_H
+#define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
+
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/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,
+                           ParsedTemplateTy Template, 
+                           SourceLocation TemplateLoc) 
+      : Kind(ParsedTemplateArgument::Template),
+        Arg(Template.getAsOpaquePtr()), 
+        Loc(TemplateLoc), SS(SS) { }
+    
+    /// \brief Determine whether the given template argument is invalid.
+    bool isInvalid() const { 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.
+    ParsedType getAsType() const {
+      assert(Kind == Type && "Not a template type argument");
+      return ParsedType::getFromOpaquePtr(Arg);
+    }
+    
+    /// \brief Retrieve the non-type template argument's expression.
+    Expr *getAsExpr() const {
+      assert(Kind == NonType && "Not a non-type template argument");
+      return static_cast<Expr*>(Arg);
+    }
+    
+    /// \brief Retrieve the template template argument's template name.
+    ParsedTemplateTy getAsTemplate() const {
+      assert(Kind == Template && "Not a template template argument");
+      return ParsedTemplateTy::getFromOpaquePtr(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.
+    ParsedTemplateTy 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); }
+  };
+  
+  
+  inline const ParsedTemplateArgument &
+  ASTTemplateArgsPtr::operator[](unsigned Arg) const { 
+    return Args[Arg]; 
+  }
+}
+
+#endif
diff --git a/include/clang/Sema/PrettyDeclStackTrace.h b/include/clang/Sema/PrettyDeclStackTrace.h
new file mode 100644
index 0000000..b78a1c0
--- /dev/null
+++ b/include/clang/Sema/PrettyDeclStackTrace.h
@@ -0,0 +1,46 @@
+//===- PrettyDeclStackTrace.h - Stack trace for decl 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 an llvm::PrettyStackTraceEntry object for showing
+// that a particular declaration was being processed when a crash
+// occurred.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_PRETTY_DECL_STACK_TRACE_H
+#define LLVM_CLANG_SEMA_PRETTY_DECL_STACK_TRACE_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/Support/PrettyStackTrace.h"
+
+namespace clang {
+
+class Decl;
+class Sema;
+class SourceManager;
+
+/// PrettyDeclStackTraceEntry - If a crash occurs in the parser while
+/// parsing something related to a declaration, include that
+/// declaration in the stack trace.
+class PrettyDeclStackTraceEntry : public llvm::PrettyStackTraceEntry {
+  Sema &S;
+  Decl *TheDecl;
+  SourceLocation Loc;
+  const char *Message;
+  
+public:
+  PrettyDeclStackTraceEntry(Sema &S, Decl *D, SourceLocation Loc, const char *Msg)
+    : S(S), TheDecl(D), Loc(Loc), Message(Msg) {}
+
+  virtual void print(llvm::raw_ostream &OS) const;
+};
+
+}
+
+#endif
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
new file mode 100644
index 0000000..4229c6c
--- /dev/null
+++ b/include/clang/Sema/Scope.h
@@ -0,0 +1,327 @@
+//===--- 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_SEMA_SCOPE_H
+#define LLVM_CLANG_SEMA_SCOPE_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+
+namespace clang {
+
+class Decl;
+class UsingDirectiveDecl;
+
+/// 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
+  };
+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<Decl *, 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<UsingDirectiveDecl *, 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(Decl *D) {
+    DeclsInScope.insert(D);
+  }
+
+  void RemoveDecl(Decl *D) {
+    DeclsInScope.erase(D);
+  }
+
+  /// isDeclScope - Return true if this is the scope that the specified decl is
+  /// declared in.
+  bool isDeclScope(Decl *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(UsingDirectiveDecl *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/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
new file mode 100644
index 0000000..50cfa9b
--- /dev/null
+++ b/include/clang/Sema/ScopeInfo.h
@@ -0,0 +1,137 @@
+//===--- ScopeInfo.h - Information about a semantic context -----*- 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 FunctionScopeInfo and BlockScopeInfo.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H
+#define LLVM_CLANG_SEMA_SCOPE_INFO_H
+
+#include "clang/AST/Type.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class BlockDecl;
+class IdentifierInfo;
+class LabelStmt;
+class ReturnStmt;
+class Scope;
+class SwitchStmt;
+
+namespace sema {
+
+/// \brief Retains information about a function, method, or block that is
+/// currently being parsed.
+class FunctionScopeInfo {
+public:
+
+  /// \brief Whether this scope information structure defined information for
+  /// a block.
+  bool IsBlockInfo;
+
+  /// \brief Whether this function contains a VLA, @try, try, C++
+  /// initializer, or anything else that can't be jumped past.
+  bool HasBranchProtectedScope;
+
+  /// \brief Whether this function contains any switches or direct gotos.
+  bool HasBranchIntoScope;
+
+  /// \brief Whether this function contains any indirect gotos.
+  bool HasIndirectGoto;
+
+  /// \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;
+
+  /// \brief The list of return statements that occur within the function or
+  /// block, if there is any chance of applying the named return value
+  /// optimization.
+  llvm::SmallVector<ReturnStmt *, 4> Returns;
+
+  void setHasBranchIntoScope() {
+    HasBranchIntoScope = true;
+  }
+
+  void setHasBranchProtectedScope() {
+    HasBranchProtectedScope = true;
+  }
+
+  void setHasIndirectGoto() {
+    HasIndirectGoto = true;
+  }
+
+  bool NeedsScopeChecking() const {
+    return HasIndirectGoto ||
+          (HasBranchProtectedScope && HasBranchIntoScope);
+  }
+  
+  FunctionScopeInfo(unsigned NumErrors)
+    : IsBlockInfo(false),
+      HasBranchProtectedScope(false),
+      HasBranchIntoScope(false),
+      HasIndirectGoto(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.
+class BlockScopeInfo : public FunctionScopeInfo {
+public:
+  bool hasBlockDeclRefExprs;
+
+  BlockDecl *TheDecl;
+  
+  /// TheScope - This is the scope for the block itself, which contains
+  /// arguments etc.
+  Scope *TheScope;
+
+  /// ReturnType - The return type of the block, or null if the block
+  /// signature didn't provide an explicit return type.
+  QualType ReturnType;
+
+  /// BlockType - The function type of the block, if one was given.
+  /// Its return type may be BuiltinType::Dependent.
+  QualType FunctionType;
+
+  BlockScopeInfo(unsigned NumErrors, Scope *BlockScope, BlockDecl *Block)
+    : FunctionScopeInfo(NumErrors), 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; }
+};
+
+}
+}
+
+#endif
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
new file mode 100644
index 0000000..5558eae
--- /dev/null
+++ b/include/clang/Sema/Sema.h
@@ -0,0 +1,4521 @@
+//===--- 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_SEMA_SEMA_H
+#define LLVM_CLANG_SEMA_SEMA_H
+
+#include "clang/Sema/Ownership.h"
+#include "clang/Sema/AnalysisBasedWarnings.h"
+#include "clang/Sema/IdentifierResolver.h"
+#include "clang/Sema/ObjCMethodList.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/AST/OperationKinds.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TemplateKinds.h"
+#include "clang/Basic/TypeTraits.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include <deque>
+#include <string>
+
+namespace llvm {
+  class APSInt;
+  template <typename ValueT> struct DenseMapInfo;
+  template <typename ValueT, typename ValueInfoT> class DenseSet;
+}
+
+namespace clang {
+  class ADLResult;
+  class ASTConsumer;
+  class ASTContext;
+  class ArrayType;
+  class AttributeList;
+  class BlockDecl;
+  class CXXBasePath;
+  class CXXBasePaths;
+  typedef llvm::SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
+  class CXXConstructorDecl;
+  class CXXConversionDecl;
+  class CXXDestructorDecl;
+  class CXXFieldCollector;
+  class CXXMemberCallExpr;
+  class CXXMethodDecl;
+  class CXXScopeSpec;
+  class CXXTemporary;
+  class CXXTryStmt;
+  class CallExpr;
+  class ClassTemplateDecl;
+  class ClassTemplatePartialSpecializationDecl;
+  class ClassTemplateSpecializationDecl;
+  class CodeCompleteConsumer;
+  class CodeCompletionResult;
+  class Decl;
+  class DeclAccessPair;
+  class DeclContext;
+  class DeclRefExpr;
+  class DeclaratorDecl;
+  class DeducedTemplateArgument;
+  class DependentDiagnostic;
+  class DesignatedInitExpr;
+  class Designation;
+  class EnumConstantDecl;
+  class Expr;
+  class ExtVectorType;
+  class ExternalSemaSource;
+  class FormatAttr;
+  class FriendDecl;
+  class FullExpr;
+  class FunctionDecl;
+  class FunctionProtoType;
+  class FunctionTemplateDecl;
+  class ImplicitConversionSequence;
+  class InitListExpr;
+  class InitializationKind;
+  class InitializationSequence;
+  class InitializedEntity;
+  class IntegerLiteral;
+  class LabelStmt;
+  class LangOptions;
+  class LocalInstantiationScope;
+  class LookupResult;
+  class MacroInfo;
+  class MultiLevelTemplateArgumentList;
+  class NamedDecl;
+  class NonNullAttr;
+  class ObjCCategoryDecl;
+  class ObjCCategoryImplDecl;
+  class ObjCCompatibleAliasDecl;
+  class ObjCContainerDecl;
+  class ObjCImplDecl;
+  class ObjCImplementationDecl;
+  class ObjCInterfaceDecl;
+  class ObjCIvarDecl;
+  template <class T> class ObjCList;
+  class ObjCMethodDecl;
+  class ObjCPropertyDecl;
+  class ObjCProtocolDecl;
+  class OverloadCandidateSet;
+  class ParenListExpr;
+  class ParmVarDecl;
+  class Preprocessor;
+  class PseudoDestructorTypeStorage;
+  class QualType;
+  class StandardConversionSequence;
+  class Stmt;
+  class StringLiteral;
+  class SwitchStmt;
+  class TargetAttributesSema;
+  class TemplateArgument;
+  class TemplateArgumentList;
+  class TemplateArgumentListBuilder;
+  class TemplateArgumentLoc;
+  class TemplateDecl;
+  class TemplateParameterList;
+  class TemplatePartialOrderingContext;
+  class TemplateTemplateParmDecl;
+  class Token;
+  class TypedefDecl;
+  class UnqualifiedId;
+  class UnresolvedLookupExpr;
+  class UnresolvedMemberExpr;
+  class UnresolvedSetImpl;
+  class UnresolvedSetIterator;
+  class UsingDecl;
+  class UsingShadowDecl;
+  class ValueDecl;
+  class VarDecl;
+  class VisibilityAttr;
+  class VisibleDeclConsumer;
+
+namespace sema {
+  class AccessedEntity;
+  class BlockScopeInfo;
+  class DelayedDiagnostic;
+  class FunctionScopeInfo;
+  class TemplateDeductionInfo;
+}
+
+/// \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 {
+  Sema(const Sema&);           // DO NOT IMPLEMENT
+  void operator=(const Sema&); // DO NOT IMPLEMENT
+  mutable const TargetAttributesSema* TheTargetAttributesSema;
+public:
+  typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
+  typedef OpaquePtr<TemplateName> TemplateTy;
+  typedef OpaquePtr<QualType> TypeTy;
+  typedef Attr AttrTy;
+  typedef CXXBaseSpecifier BaseTy;
+  typedef CXXBaseOrMemberInitializer MemInitTy;
+  typedef Expr ExprTy;
+  typedef Stmt StmtTy;
+  typedef TemplateParameterList TemplateParamsTy;
+  typedef NestedNameSpecifier CXXScopeTy;
+
+  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;
+
+  /// VAListTagName - The declaration name corresponding to __va_list_tag.
+  /// This is used as part of a hack to omit that class from ADL results.
+  DeclarationName VAListTagName;
+
+  /// A RAII object to temporarily push a declaration context.
+  class ContextRAII {
+  private:
+    Sema &S;
+    DeclContext *SavedContext;
+
+  public:
+    ContextRAII(Sema &S, DeclContext *ContextToPush)
+      : S(S), SavedContext(S.CurContext) {
+      assert(ContextToPush && "pushing null context");
+      S.CurContext = ContextToPush;
+    }
+
+    void pop() {
+      if (!SavedContext) return;
+      S.CurContext = SavedContext;
+      SavedContext = 0;
+    }
+
+    ~ContextRAII() {
+      pop();
+    }
+  };
+
+  /// PackContext - Manages the stack for #pragma pack. An alignment
+  /// of 0 indicates default alignment.
+  void *PackContext; // Really a "PragmaPackStack*"
+
+  /// VisContext - Manages the stack for #pragma GCC visibility.
+  void *VisContext; // Really a "PragmaVisStack*"
+
+  /// \brief Stack containing information about each of the nested
+  /// function, block, and method scopes that are currently active.
+  ///
+  /// This array is never empty.  Clients should ignore the first
+  /// element, which is used to cache a single FunctionScopeInfo
+  /// that's used to parse every top-level function.
+  llvm::SmallVector<sema::FunctionScopeInfo *, 4> FunctionScopes;
+
+  /// 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.
+  llvm::SmallVector<VarDecl *, 2> TentativeDefinitions;
+
+  /// \brief The set of file scoped decls seen so far that have not been used
+  /// and must warn if not used. Only contains the first declaration.
+  llvm::SmallVector<const DeclaratorDecl*, 4> UnusedFileScopedDecls;
+
+  /// \brief The stack of diagnostics that were delayed due to being
+  /// produced during the parsing of a declaration.
+  llvm::SmallVector<sema::DelayedDiagnostic, 0> 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.
+  LazyDeclPtr StdNamespace;
+
+  /// \brief The C++ "std::bad_alloc" class, which is defined by the C++
+  /// standard library.
+  LazyDeclPtr 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 llvm::SmallVector<std::pair<SourceLocation, Decl *>, 10>
+    PotentiallyReferencedDecls;
+
+  /// \brief A set of diagnostics that may be emitted.
+  typedef llvm::SmallVector<std::pair<SourceLocation, PartialDiagnostic>, 10>
+    PotentiallyEmittedDiagnostics;
+
+  /// \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 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 std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods;
+  typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool;
+
+  /// Method Pool - 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").
+  GlobalMethodPool MethodPool;
+
+  /// Method selectors used in a @selector expression. Used for implementation 
+  /// of -Wselector.
+  llvm::DenseMap<Selector, SourceLocation> ReferencedSelectors;
+
+
+  GlobalMethodPool::iterator ReadMethodPool(Selector Sel);
+
+  /// 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();
+  
+  /// \brief Perform initialization that occurs after the parser has been
+  /// initialized but before it parses anything.
+  void Initialize();
+  
+  const LangOptions &getLangOptions() const { return LangOpts; }
+  Diagnostic &getDiagnostics() const { return Diags; }
+  SourceManager &getSourceManager() const { return SourceMgr; }
+  const TargetAttributesSema &getTargetAttributesSema() const;
+  Preprocessor &getPreprocessor() const { return PP; }
+  ASTContext &getASTContext() const { return Context; }
+  ASTConsumer &getASTConsumer() const { return Consumer; }
+  
+  /// \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); // in SemaInternal.h
+
+  virtual void DeleteExpr(Expr *E);
+  virtual void DeleteStmt(Stmt *S);
+
+  ExprResult Owned(Expr* E) { return E; }
+  ExprResult Owned(ExprResult R) { return R; }
+  StmtResult Owned(Stmt* S) { return S; }
+
+  virtual void ActOnEndOfTranslationUnit();
+
+  Scope *getScopeForContext(DeclContext *Ctx);
+
+  void PushFunctionScope();
+  void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
+  void PopFunctionOrBlockScope();
+
+  sema::FunctionScopeInfo *getCurFunction() const {
+    return FunctionScopes.back();
+  }
+
+  bool hasAnyErrorsInThisFunction() const;
+
+  /// \brief Retrieve the current block, if any.
+  sema::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 BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs);
+  QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVR) {
+    return BuildQualifiedType(T, Loc, Qualifiers::fromCVRMask(CVR));
+  }
+  QualType BuildPointerType(QualType T,
+                            SourceLocation Loc, DeclarationName Entity);
+  QualType BuildReferenceType(QualType T, bool LValueRef,
+                              SourceLocation Loc, DeclarationName Entity);
+  QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
+                          Expr *ArraySize, unsigned Quals,
+                          SourceRange Brackets, DeclarationName Entity);
+  QualType BuildExtVectorType(QualType T, Expr *ArraySize,
+                              SourceLocation AttrLoc);
+  QualType BuildFunctionType(QualType T,
+                             QualType *ParamTypes, unsigned NumParamTypes,
+                             bool Variadic, unsigned Quals,
+                             SourceLocation Loc, DeclarationName Entity,
+                             const FunctionType::ExtInfo &Info);
+  QualType BuildMemberPointerType(QualType T, QualType Class,
+                                  SourceLocation Loc,
+                                  DeclarationName Entity);
+  QualType BuildBlockPointerType(QualType T,
+                                 SourceLocation Loc, DeclarationName Entity);
+  TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S,
+                                       TagDecl **OwnedDecl = 0);
+  TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
+                                               TypeSourceInfo *ReturnTypeInfo);
+  /// \brief Package the given type and TSI into a ParsedType.
+  ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo);
+  DeclarationNameInfo GetNameForDeclarator(Declarator &D);
+  DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name);
+  static QualType GetTypeFromParser(ParsedType 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);
+
+  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 getElaboratedType(ElaboratedTypeKeyword Keyword,
+                             const CXXScopeSpec &SS, QualType T);
+
+  QualType BuildTypeofExprType(Expr *E);
+  QualType BuildDecltypeType(Expr *E);
+
+  //===--------------------------------------------------------------------===//
+  // Symbol table / Decl tracking callbacks: SemaDecl.cpp.
+  //
+
+  DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr);
+
+  void DiagnoseUseOfUnimplementedSelectors();
+
+  virtual ParsedType getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+                                 Scope *S, CXXScopeSpec *SS = 0,
+                                 bool isClassName = false,
+                                 ParsedType ObjectType = ParsedType());
+  virtual TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S);
+  virtual bool DiagnoseUnknownTypeName(const IdentifierInfo &II,
+                                       SourceLocation IILoc,
+                                       Scope *S,
+                                       CXXScopeSpec *SS,
+                                       ParsedType &SuggestedType);
+
+  virtual Decl *ActOnDeclarator(Scope *S, Declarator &D);
+
+  Decl *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);
+  void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange);
+  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 Decl *ActOnParamDeclarator(Scope *S, Declarator &D);
+  ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC,
+                                          SourceLocation Loc,
+                                          QualType T);
+  ParmVarDecl *CheckParameter(DeclContext *DC,
+                              TypeSourceInfo *TSInfo, QualType T,
+                              IdentifierInfo *Name,
+                              SourceLocation NameLoc,
+                              StorageClass SC,
+                              StorageClass SCAsWritten);
+  virtual void ActOnParamDefaultArgument(Decl *param,
+                                         SourceLocation EqualLoc,
+                                         Expr *defarg);
+  virtual void ActOnParamUnparsedDefaultArgument(Decl *param,
+                                                 SourceLocation EqualLoc,
+                                                 SourceLocation ArgLoc);
+  virtual void ActOnParamDefaultArgumentError(Decl *param);
+  bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,
+                               SourceLocation EqualLoc);
+
+
+  // Contains the locations of the beginning of unparsed default
+  // argument locations.
+  llvm::DenseMap<ParmVarDecl *,SourceLocation> UnparsedDefaultArgLocs;
+
+  virtual void AddInitializerToDecl(Decl *dcl, Expr *init);
+  void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit);
+  void ActOnUninitializedDecl(Decl *dcl, bool TypeContainsUndeducedAuto);
+  virtual void ActOnInitializerError(Decl *Dcl);
+  virtual void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc);
+  virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
+                                                 Decl **Group,
+                                                 unsigned NumDecls);
+  virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
+                                               SourceLocation LocAfterDecls);
+  virtual Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
+  virtual Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D);
+  virtual void ActOnStartOfObjCMethodDef(Scope *S, Decl *D);
+
+  virtual Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body);
+  Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body,
+                                    bool IsInstantiation);
+
+  /// \brief Diagnose any unused parameters in the given sequence of
+  /// ParmVarDecl pointers.
+  void DiagnoseUnusedParameters(ParmVarDecl * const *Begin,
+                                ParmVarDecl * const *End);
+
+  void DiagnoseInvalidJumps(Stmt *Body);
+  virtual Decl *ActOnFileScopeAsmDecl(SourceLocation Loc, Expr *expr);
+
+  /// Scope actions.
+  virtual void ActOnPopScope(SourceLocation Loc, Scope *S);
+  virtual void ActOnTranslationUnitScope(Scope *S);
+
+  /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
+  /// no declarator (e.g. "struct foo;") is parsed.
+  virtual Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
+                                           DeclSpec &DS);
+
+  virtual Decl *BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
+                                            AccessSpecifier AS,
+                                            RecordDecl *Record);
+
+  bool isAcceptableTagRedeclaration(const TagDecl *Previous,
+                                    TagTypeKind NewTag,
+                                    SourceLocation NewTagLoc,
+                                    const IdentifierInfo &Name);
+
+  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;'
+  };
+
+  virtual Decl *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, Decl *TagD, SourceLocation DeclStart,
+                         IdentifierInfo *ClassName,
+                         llvm::SmallVectorImpl<Decl *> &Decls);
+  virtual Decl *ActOnField(Scope *S, Decl *TagD,
+                               SourceLocation DeclStart,
+                               Declarator &D, Expr *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
+  };
+  bool CheckNontrivialField(FieldDecl *FD);
+  void DiagnoseNontrivial(const RecordType* Record, CXXSpecialMember mem);
+  CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD);
+  virtual void ActOnLastBitfield(SourceLocation DeclStart, Decl *IntfDecl, 
+                         llvm::SmallVectorImpl<Decl *> &AllIvarDecls);
+  virtual Decl *ActOnIvar(Scope *S, SourceLocation DeclStart,
+                              Decl *IntfDecl,
+                              Declarator &D, Expr *BitfieldWidth,
+                              tok::ObjCKeywordKind visibility);
+
+  // This is used for both record definitions and ObjC interface declarations.
+  virtual void ActOnFields(Scope* S,
+                           SourceLocation RecLoc, Decl *TagDecl,
+                           Decl **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, Decl *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, Decl *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, Decl *TagDecl,
+                                        SourceLocation RBraceLoc);
+
+  /// ActOnTagDefinitionError - Invoked when there was an unrecoverable
+  /// error parsing the definition of a tag.
+  virtual void ActOnTagDefinitionError(Scope *S, Decl *TagDecl);
+
+  EnumConstantDecl *CheckEnumConstant(EnumDecl *Enum,
+                                      EnumConstantDecl *LastEnumConst,
+                                      SourceLocation IdLoc,
+                                      IdentifierInfo *Id,
+                                      Expr *val);
+
+  virtual Decl *ActOnEnumConstant(Scope *S, Decl *EnumDecl,
+                                      Decl *LastEnumConstant,
+                                      SourceLocation IdLoc, IdentifierInfo *Id,
+                                      SourceLocation EqualLoc, Expr *Val);
+  virtual void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
+                             SourceLocation RBraceLoc, Decl *EnumDecl,
+                             Decl **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.
+  static Scope *getScopeForDeclContext(Scope *S, DeclContext *DC);
+
+  /// 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(Scope *S,
+                             FunctionDecl *New,
+                             const LookupResult &OldDecls,
+                             NamedDecl *&OldDecl,
+                             bool IsForUsingDecl);
+  bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl);
+
+  bool TryImplicitConversion(InitializationSequence &Sequence,
+                             const InitializedEntity &Entity,
+                             Expr *From,
+                             bool SuppressUserConversions,
+                             bool AllowExplicit,
+                             bool InOverloadResolution);
+
+  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 FunctionArgTypesAreEqual (FunctionProtoType* OldType, 
+                                 FunctionProtoType* NewType);
+  
+  bool CheckPointerConversion(Expr *From, QualType ToType,
+                              CastKind &Kind,
+                              CXXCastPath& BasePath,
+                              bool IgnoreBaseAccess);
+  bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType,
+                                 bool InOverloadResolution,
+                                 QualType &ConvertedType);
+  bool CheckMemberPointerConversion(Expr *From, QualType ToType,
+                                    CastKind &Kind,
+                                    CXXCastPath &BasePath,
+                                    bool IgnoreBaseAccess);
+  bool IsQualificationConversion(QualType FromType, QualType ToType);
+  bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
+
+
+  ExprResult PerformCopyInitialization(const InitializedEntity &Entity,
+                                       SourceLocation EqualLoc,
+                                       ExprResult Init);
+  bool PerformObjectArgumentInitialization(Expr *&From,
+                                           NestedNameSpecifier *Qualifier,
+                                           NamedDecl *FoundDecl,
+                                           CXXMethodDecl *Method);
+
+  bool PerformContextuallyConvertToBool(Expr *&From);
+  bool PerformContextuallyConvertToObjCId(Expr *&From);
+
+  ExprResult 
+  ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *FromE,
+                                     const PartialDiagnostic &NotIntDiag,
+                                     const PartialDiagnostic &IncompleteDiag,
+                                     const PartialDiagnostic &ExplicitConvDiag,
+                                     const PartialDiagnostic &ExplicitConvNote,
+                                     const PartialDiagnostic &AmbigDiag,
+                                     const PartialDiagnostic &AmbigNote,
+                                     const PartialDiagnostic &ConvDiag);
+  
+  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);
+
+  void NoteOverloadCandidate(FunctionDecl *Fn);
+
+  FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
+                                                   bool Complain,
+                                                   DeclAccessPair &Found);
+  FunctionDecl *ResolveSingleFunctionTemplateSpecialization(Expr *From);
+
+  Expr *FixOverloadedFunctionReference(Expr *E,
+                                       DeclAccessPair FoundDecl,
+                                       FunctionDecl *Fn);
+  ExprResult FixOverloadedFunctionReference(ExprResult,
+                                                  DeclAccessPair FoundDecl,
+                                                  FunctionDecl *Fn);
+
+  void AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
+                                   Expr **Args, unsigned NumArgs,
+                                   OverloadCandidateSet &CandidateSet,
+                                   bool PartialOverloading = false);
+
+  ExprResult BuildOverloadedCallExpr(Scope *S, Expr *Fn,
+                                           UnresolvedLookupExpr *ULE,
+                                           SourceLocation LParenLoc,
+                                           Expr **Args, unsigned NumArgs,
+                                           SourceLocation *CommaLocs,
+                                           SourceLocation RParenLoc);
+
+  ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc,
+                                           unsigned Opc,
+                                           const UnresolvedSetImpl &Fns,
+                                           Expr *input);
+
+  ExprResult CreateOverloadedBinOp(SourceLocation OpLoc,
+                                         unsigned Opc,
+                                         const UnresolvedSetImpl &Fns,
+                                         Expr *LHS, Expr *RHS);
+
+  ExprResult CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
+                                                      SourceLocation RLoc,
+                                                      Expr *Base,Expr *Idx);
+
+  ExprResult
+  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);
+
+  ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *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 Look up any declaration with any name.
+    LookupAnyName
+  };
+
+  /// \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);
+
+  DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class);
+  CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);
+
+  void ArgumentDependentLookup(DeclarationName Name, bool Operator,
+                               Expr **Args, unsigned NumArgs,
+                               ADLResult &Functions);
+
+  void LookupVisibleDecls(Scope *S, LookupNameKind Kind,
+                          VisibleDeclConsumer &Consumer,
+                          bool IncludeGlobalScope = true);
+  void LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
+                          VisibleDeclConsumer &Consumer,
+                          bool IncludeGlobalScope = true);
+  
+  /// \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 *AL);
+
+  void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
+                           bool &IncompleteImpl, unsigned DiagID);
+  void WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethod,
+                                   ObjCMethodDecl *IntfMethod);
+
+  bool isPropertyReadonly(ObjCPropertyDecl *PropertyDecl,
+                          ObjCInterfaceDecl *IDecl);
+
+  typedef llvm::DenseSet<Selector, llvm::DenseMapInfo<Selector> > SelectorSet;
+
+  /// 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 SelectorSet &InsMap,
+                               const SelectorSet &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(Scope *S, ObjCImplDecl* IMPDecl,
+                                 ObjCContainerDecl* IDecl,
+                                 bool IncompleteImpl = false);
+
+  /// DiagnoseUnimplementedProperties - This routine warns on those properties
+  /// which must be implemented by this implementation.
+  void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
+                                       ObjCContainerDecl *CDecl,
+                                       const SelectorSet &InsMap);
+
+  /// DefaultSynthesizeProperties - This routine default synthesizes all 
+  /// properties which must be synthesized in class's @implementation.
+  void DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
+                                    ObjCInterfaceDecl *IDecl);
+  
+  /// 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,
+            llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap);
+  
+
+  /// 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.
+  Decl *HandlePropertyInClassExtension(Scope *S,
+                                           ObjCCategoryDecl *CDecl,
+                                           SourceLocation AtLoc,
+                                           FieldDeclarator &FD,
+                                           Selector GetterSel,
+                                           Selector SetterSel,
+                                           const bool isAssign,
+                                           const bool isReadWrite,
+                                           const unsigned Attributes,
+                                           bool *isOverridingProperty,
+                                           TypeSourceInfo *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,
+                                       TypeSourceInfo *T,
+                                       tok::ObjCKeywordKind MethodImplKind,
+                                       DeclContext *lexicalDC = 0);
+
+  /// 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,
+                                  bool matchBasedOnStrictEqulity = false);
+
+  /// MatchAllMethodDeclarations - Check methods declaraed in interface or
+  /// or protocol against those declared in their implementations.
+  void MatchAllMethodDeclarations(const SelectorSet &InsMap,
+                                  const SelectorSet &ClsMap,
+                                  SelectorSet &InsMapSeen,
+                                  SelectorSet &ClsMapSeen,
+                                  ObjCImplDecl* IMPDecl,
+                                  ObjCContainerDecl* IDecl,
+                                  bool &IncompleteImpl,
+                                  bool ImmediateClass);
+
+private:
+  /// AddMethodToGlobalPool - Add an instance or factory method to the global
+  /// pool. See descriptoin of AddInstanceMethodToGlobalPool.
+  void AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance);
+
+  /// LookupMethodInGlobalPool - Returns the instance or factory method and
+  /// optionally warns if there are multiple signatures.
+  ObjCMethodDecl *LookupMethodInGlobalPool(Selector Sel, SourceRange R,
+                                           bool receiverIdOrClass,
+                                           bool warn, bool instance);
+
+public:
+  /// 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, bool impl=false) {
+    AddMethodToGlobalPool(Method, impl, /*instance*/true);
+  }
+
+  /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
+  void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) {
+    AddMethodToGlobalPool(Method, impl, /*instance*/false);
+  }
+
+  /// LookupInstanceMethodInGlobalPool - Returns the method and warns if
+  /// there are multiple signatures.
+  ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R,
+                                                   bool receiverIdOrClass=false,
+                                                   bool warn=true) {
+    return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass, 
+                                    warn, /*instance*/true);
+  }
+
+  /// LookupFactoryMethodInGlobalPool - Returns the method and warns if
+  /// there are multiple signatures.
+  ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R,
+                                                  bool receiverIdOrClass=false,
+                                                  bool warn=true) {
+    return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass,
+                                    warn, /*instance*/false);
+  }
+
+  /// LookupImplementedMethodInGlobalPool - Returns the method which has an
+  /// implementation.
+  ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel);
+
+  /// CollectIvarsToConstructOrDestruct - Collect those ivars which require
+  /// initialization.
+  void CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI,
+                                  llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+  //===--------------------------------------------------------------------===//
+  // Statement Parsing Callbacks: SemaStmt.cpp.
+public:
+  class FullExprArg {
+  public:
+    FullExprArg(Sema &actions) : E(0) { }
+                
+    // 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): E(Other.E) {}
+
+    ExprResult release() {
+      return move(E);
+    }
+
+    Expr *get() const { return E; }
+
+    Expr *operator->() {
+      return E;
+    }
+
+  private:
+    // FIXME: No need to make the entire Sema class a friend when it's just
+    // Sema::FullExpr that needs access to the constructor below.
+    friend class Sema;
+
+    explicit FullExprArg(Expr *expr) : E(expr) {}
+
+    Expr *E;
+  };
+
+  FullExprArg MakeFullExpr(Expr *Arg) {
+    return FullExprArg(ActOnFinishFullExpr(Arg).release());
+  }
+
+  virtual StmtResult ActOnExprStmt(FullExprArg Expr);
+
+  virtual StmtResult ActOnNullStmt(SourceLocation SemiLoc);
+  virtual StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
+                                       MultiStmtArg Elts,
+                                       bool isStmtExpr);
+  virtual StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
+                                   SourceLocation StartLoc,
+                                   SourceLocation EndLoc);
+  virtual void ActOnForEachDeclStmt(DeclGroupPtrTy Decl);
+  virtual StmtResult ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
+                                   SourceLocation DotDotDotLoc, Expr *RHSVal,
+                                   SourceLocation ColonLoc);
+  virtual void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt);
+
+  virtual StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
+                                      SourceLocation ColonLoc,
+                                      Stmt *SubStmt, Scope *CurScope);
+  virtual StmtResult ActOnLabelStmt(SourceLocation IdentLoc,
+                                    IdentifierInfo *II,
+                                    SourceLocation ColonLoc,
+                                    Stmt *SubStmt);
+  virtual StmtResult ActOnIfStmt(SourceLocation IfLoc,
+                                 FullExprArg CondVal, Decl *CondVar,
+                                 Stmt *ThenVal,
+                                 SourceLocation ElseLoc, Stmt *ElseVal);
+  virtual StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,
+                                            Expr *Cond,
+                                            Decl *CondVar);
+  virtual StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
+                                           Stmt *Switch, Stmt *Body);
+  virtual StmtResult ActOnWhileStmt(SourceLocation WhileLoc,
+                                    FullExprArg Cond,
+                                    Decl *CondVar, Stmt *Body);
+  virtual StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
+                                 SourceLocation WhileLoc,
+                                 SourceLocation CondLParen, Expr *Cond,
+                                 SourceLocation CondRParen);
+
+  virtual StmtResult ActOnForStmt(SourceLocation ForLoc,
+                                  SourceLocation LParenLoc,
+                                  Stmt *First, FullExprArg Second,
+                                  Decl *SecondVar,
+                                  FullExprArg Third,
+                                  SourceLocation RParenLoc,
+                                  Stmt *Body);
+  virtual StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
+                                       SourceLocation LParenLoc,
+                                       Stmt *First, Expr *Second,
+                                       SourceLocation RParenLoc, Stmt *Body);
+
+  virtual StmtResult ActOnGotoStmt(SourceLocation GotoLoc,
+                                   SourceLocation LabelLoc,
+                                   IdentifierInfo *LabelII);
+  virtual StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
+                                           SourceLocation StarLoc,
+                                           Expr *DestExp);
+  virtual StmtResult ActOnContinueStmt(SourceLocation ContinueLoc,
+                                       Scope *CurScope);
+  virtual StmtResult ActOnBreakStmt(SourceLocation GotoLoc,
+                                    Scope *CurScope);
+
+  virtual StmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
+                                     Expr *RetValExp);
+  StmtResult ActOnBlockReturnStmt(SourceLocation ReturnLoc,
+                                  Expr *RetValExp);
+
+  virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
+                                  bool IsSimple,
+                                  bool IsVolatile,
+                                  unsigned NumOutputs,
+                                  unsigned NumInputs,
+                                  IdentifierInfo **Names,
+                                  MultiExprArg Constraints,
+                                  MultiExprArg Exprs,
+                                  Expr *AsmString,
+                                  MultiExprArg Clobbers,
+                                  SourceLocation RParenLoc,
+                                  bool MSAsm = false);
+
+
+  VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType,
+                                  IdentifierInfo *Name, SourceLocation NameLoc,
+                                  bool Invalid = false);
+
+  virtual Decl *ActOnObjCExceptionDecl(Scope *S, Declarator &D);
+
+  virtual StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
+                                          SourceLocation RParen,
+                                          Decl *Parm, Stmt *Body);
+
+  virtual StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc,
+                                            Stmt *Body);
+
+  virtual StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc,
+                                        Stmt *Try,
+                                        MultiStmtArg Catch,
+                                        Stmt *Finally);
+
+  virtual StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc,
+                                          Expr *Throw);
+  virtual StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
+                                          Expr *Throw,
+                                          Scope *CurScope);
+  virtual StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
+                                                 Expr *SynchExpr,
+                                                 Stmt *SynchBody);
+
+  VarDecl *BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
+                                     TypeSourceInfo *TInfo,
+                                     IdentifierInfo *Name,
+                                     SourceLocation Loc,
+                                     SourceRange Range);
+  virtual Decl *ActOnExceptionDeclarator(Scope *S, Declarator &D);
+
+  virtual StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc,
+                                        Decl *ExDecl,
+                                        Stmt *HandlerBlock);
+  virtual StmtResult ActOnCXXTryBlock(SourceLocation TryLoc,
+                                      Stmt *TryBlock,
+                                      MultiStmtArg Handlers);
+  void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock);
+
+  bool ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const;
+  
+  /// \brief If it's a file scoped decl that must warn if not used, keep track
+  /// of it.
+  void MarkUnusedFileScopedDecl(const DeclaratorDecl *D);
+
+  /// DiagnoseUnusedExprResult - If the statement passed in is an expression
+  /// whose result is unused, warn.
+  void DiagnoseUnusedExprResult(const Stmt *S);
+  void DiagnoseUnusedDecl(const NamedDecl *ND);
+  
+  typedef uintptr_t ParsingDeclStackState;
+
+  ParsingDeclStackState PushParsingDeclaration();
+  void PopParsingDeclaration(ParsingDeclStackState S, Decl *D);
+  void EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc);
+
+  void HandleDelayedDeprecationCheck(sema::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);
+  void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
+  bool DiagRuntimeBehavior(SourceLocation Loc, const PartialDiagnostic &PD);
+
+  // Primary Expressions.
+  virtual SourceRange getExprRange(Expr *E) const;
+
+  virtual ExprResult ActOnIdExpression(Scope *S,
+                                             CXXScopeSpec &SS,
+                                             UnqualifiedId &Name,
+                                             bool HasTrailingLParen,
+                                             bool IsAddressOfOperand);
+
+  bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
+                           CorrectTypoContext CTC = CTC_Unknown);
+
+  ExprResult LookupInObjCMethod(LookupResult &R,
+                                      Scope *S,
+                                      IdentifierInfo *II,
+                                      bool AllowBuiltinCreation=false);
+
+  ExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS,
+                                const DeclarationNameInfo &NameInfo,
+                                              bool isAddressOfOperand,
+                                const TemplateArgumentListInfo *TemplateArgs);
+
+  ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty,
+                                    SourceLocation Loc,
+                                    const CXXScopeSpec *SS = 0);
+  ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty,
+                                    const DeclarationNameInfo &NameInfo,
+                                    const CXXScopeSpec *SS = 0);
+  VarDecl *BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
+                                    llvm::SmallVectorImpl<FieldDecl *> &Path);
+  ExprResult
+  BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
+                                           FieldDecl *Field,
+                                           Expr *BaseObjectExpr = 0,
+                                      SourceLocation OpLoc = SourceLocation());
+  ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
+                                             LookupResult &R,
+                                const TemplateArgumentListInfo *TemplateArgs);
+  ExprResult BuildImplicitMemberExpr(const CXXScopeSpec &SS,
+                                           LookupResult &R,
+                                const TemplateArgumentListInfo *TemplateArgs,
+                                           bool IsDefiniteInstance);
+  bool UseArgumentDependentLookup(const CXXScopeSpec &SS,
+                                  const LookupResult &R,
+                                  bool HasTrailingLParen);
+
+  ExprResult BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
+                                         const DeclarationNameInfo &NameInfo);
+  ExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
+                                const DeclarationNameInfo &NameInfo,
+                                const TemplateArgumentListInfo *TemplateArgs);
+
+  ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS,
+                                            LookupResult &R,
+                                            bool ADL);
+  ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS,
+                                            const DeclarationNameInfo &NameInfo,
+                                            NamedDecl *D);
+
+  virtual ExprResult ActOnPredefinedExpr(SourceLocation Loc,
+                                               tok::TokenKind Kind);
+  virtual ExprResult ActOnNumericConstant(const Token &);
+  virtual ExprResult ActOnCharacterConstant(const Token &);
+  virtual ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
+                                          Expr *Val);
+  virtual ExprResult ActOnParenOrParenListExpr(SourceLocation L,
+                                                     SourceLocation R,
+                                                     MultiExprArg Val,
+                                                     ParsedType TypeOfCast
+                                                       = ParsedType());
+
+  /// ActOnStringLiteral - The specified tokens were lexed as pasted string
+  /// fragments (e.g. "foo" "bar" L"baz").
+  virtual ExprResult ActOnStringLiteral(const Token *Toks,
+                                              unsigned NumToks);
+
+  // Binary/Unary Operators.  'Tok' is the token for the operator.
+  ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc,
+                                  unsigned OpcIn,
+                                  Expr *InputArg);
+  ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc,
+                          UnaryOperatorKind Opc, Expr *input);
+  virtual ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
+                                  tok::TokenKind Op, Expr *Input);
+
+  ExprResult CreateSizeOfAlignOfExpr(TypeSourceInfo *T,
+                                     SourceLocation OpLoc,
+                                     bool isSizeOf, SourceRange R);
+  ExprResult CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
+                                     bool isSizeOf, SourceRange R);
+  virtual ExprResult
+    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 ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
+                                               tok::TokenKind Kind,
+                                               Expr *Input);
+
+  virtual ExprResult ActOnArraySubscriptExpr(Scope *S, Expr *Base,
+                                                   SourceLocation LLoc,
+                                                   Expr *Idx,
+                                                   SourceLocation RLoc);
+  ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base,
+                                                   SourceLocation LLoc,
+                                                   Expr *Idx,
+                                                   SourceLocation RLoc);
+
+  ExprResult BuildMemberReferenceExpr(Expr *Base,
+                                            QualType BaseType,
+                                            SourceLocation OpLoc,
+                                            bool IsArrow,
+                                            CXXScopeSpec &SS,
+                                            NamedDecl *FirstQualifierInScope,
+                                const DeclarationNameInfo &NameInfo,
+                                const TemplateArgumentListInfo *TemplateArgs);
+
+  ExprResult BuildMemberReferenceExpr(Expr *Base,
+                                            QualType BaseType,
+                                            SourceLocation OpLoc, bool IsArrow,
+                                            const CXXScopeSpec &SS,
+                                            NamedDecl *FirstQualifierInScope,
+                                            LookupResult &R,
+                                 const TemplateArgumentListInfo *TemplateArgs,
+                                          bool SuppressQualifierCheck = false);
+
+  ExprResult LookupMemberExpr(LookupResult &R, Expr *&Base,
+                                    bool &IsArrow, SourceLocation OpLoc,
+                                    CXXScopeSpec &SS,
+                                    Decl *ObjCImpDecl,
+                                    bool HasTemplateArgs);
+
+  bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType,
+                                     const CXXScopeSpec &SS,
+                                     const LookupResult &R);
+
+  ExprResult ActOnDependentMemberExpr(Expr *Base,
+                                            QualType BaseType,
+                                            bool IsArrow,
+                                            SourceLocation OpLoc,
+                                            const CXXScopeSpec &SS,
+                                            NamedDecl *FirstQualifierInScope,
+                               const DeclarationNameInfo &NameInfo,
+                               const TemplateArgumentListInfo *TemplateArgs);
+
+  virtual ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base,
+                                                 SourceLocation OpLoc,
+                                                 tok::TokenKind OpKind,
+                                                 CXXScopeSpec &SS,
+                                                 UnqualifiedId &Member,
+                                                 Decl *ObjCImpDecl,
+                                                 bool HasTrailingLParen);
+
+  virtual void ActOnDefaultCtorInitializers(Decl *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 ExprResult ActOnCallExpr(Scope *S, Expr *Fn,
+                                         SourceLocation LParenLoc,
+                                         MultiExprArg Args,
+                                         SourceLocation *CommaLocs,
+                                         SourceLocation RParenLoc);
+  ExprResult BuildResolvedCallExpr(Expr *Fn,
+                                         NamedDecl *NDecl,
+                                         SourceLocation LParenLoc,
+                                         Expr **Args, unsigned NumArgs,
+                                         SourceLocation RParenLoc);
+
+  virtual ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
+                                         ParsedType Ty, SourceLocation RParenLoc,
+                                         Expr *Op);
+  ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc,
+                                       TypeSourceInfo *Ty,
+                                       SourceLocation RParenLoc,
+                                       Expr *Op);
+
+  virtual bool TypeIsVectorType(ParsedType Ty) {
+    return GetTypeFromParser(Ty)->isVectorType();
+  }
+
+  ExprResult MaybeConvertParenListExprToParenExpr(Scope *S, Expr *ME);
+  ExprResult ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
+                                            SourceLocation RParenLoc, Expr *E,
+                                            TypeSourceInfo *TInfo);
+
+  virtual ExprResult ActOnCompoundLiteral(SourceLocation LParenLoc,
+                                                ParsedType Ty,
+                                                SourceLocation RParenLoc,
+                                                Expr *Op);
+
+  ExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc,
+                                            TypeSourceInfo *TInfo,
+                                            SourceLocation RParenLoc,
+                                            Expr *InitExpr);
+
+  virtual ExprResult ActOnInitList(SourceLocation LParenLoc,
+                                         MultiExprArg InitList,
+                                         SourceLocation RParenLoc);
+
+  virtual ExprResult ActOnDesignatedInitializer(Designation &Desig,
+                                                SourceLocation Loc,
+                                                bool GNUSyntax,
+                                                ExprResult Init);
+
+  virtual ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,
+                                tok::TokenKind Kind,
+                                Expr *LHS, Expr *RHS);
+  ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc,
+                        BinaryOperatorKind Opc,
+                        Expr *lhs, Expr *rhs);
+  ExprResult 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 ExprResult ActOnConditionalOp(SourceLocation QuestionLoc,
+                                        SourceLocation ColonLoc,
+                                        Expr *Cond, Expr *LHS,
+                                        Expr *RHS);
+
+  /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
+  virtual ExprResult ActOnAddrLabel(SourceLocation OpLoc,
+                                    SourceLocation LabLoc,
+                                    IdentifierInfo *LabelII);
+
+  virtual ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
+                                   SourceLocation RPLoc); // "({..})"
+
+  // __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;
+  };
+
+  /// __builtin_offsetof(type, a.b[123][456].c)
+  ExprResult BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
+                                  TypeSourceInfo *TInfo,
+                                  OffsetOfComponent *CompPtr,
+                                  unsigned NumComponents,
+                                  SourceLocation RParenLoc);
+  virtual ExprResult ActOnBuiltinOffsetOf(Scope *S,
+                                          SourceLocation BuiltinLoc,
+                                          SourceLocation TypeLoc,
+                                          ParsedType Arg1,
+                                          OffsetOfComponent *CompPtr,
+                                          unsigned NumComponents,
+                                          SourceLocation RParenLoc);
+
+  // __builtin_types_compatible_p(type1, type2)
+  virtual ExprResult ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
+                                              ParsedType arg1,
+                                              ParsedType arg2,
+                                              SourceLocation RPLoc);
+  ExprResult BuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
+                                      TypeSourceInfo *argTInfo1,
+                                      TypeSourceInfo *argTInfo2,
+                                      SourceLocation RPLoc);
+
+  // __builtin_choose_expr(constExpr, expr1, expr2)
+  virtual ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc,
+                                     Expr *cond, Expr *expr1,
+                                     Expr *expr2, SourceLocation RPLoc);
+
+  // __builtin_va_arg(expr, type)
+  virtual ExprResult ActOnVAArg(SourceLocation BuiltinLoc,
+                                      Expr *expr, ParsedType type,
+                                      SourceLocation RPLoc);
+  ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc,
+                                  Expr *expr, TypeSourceInfo *TInfo,
+                                  SourceLocation RPLoc);
+
+  // __null
+  virtual ExprResult 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 ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc,
+                                        Stmt *Body, Scope *CurScope);
+
+  //===---------------------------- C++ Features --------------------------===//
+
+  // Act on C++ namespaces
+  virtual Decl *ActOnStartNamespaceDef(Scope *S, SourceLocation InlineLoc,
+                                       SourceLocation IdentLoc,
+                                       IdentifierInfo *Ident,
+                                       SourceLocation LBrace,
+                                       AttributeList *AttrList);
+  virtual void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace);
+
+  NamespaceDecl *getStdNamespace() const;
+  NamespaceDecl *getOrCreateStdNamespace();
+
+  CXXRecordDecl *getStdBadAlloc() const;
+
+  virtual Decl *ActOnUsingDirective(Scope *CurScope,
+                                        SourceLocation UsingLoc,
+                                        SourceLocation NamespcLoc,
+                                        CXXScopeSpec &SS,
+                                        SourceLocation IdentLoc,
+                                        IdentifierInfo *NamespcName,
+                                        AttributeList *AttrList);
+
+  void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir);
+
+  virtual Decl *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,
+                                   const DeclarationNameInfo &NameInfo,
+                                   AttributeList *AttrList,
+                                   bool IsInstantiation,
+                                   bool IsTypeName,
+                                   SourceLocation TypenameLoc);
+
+  virtual Decl *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(Decl *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.
+  ///
+  /// \param ConstructKind - a CXXConstructExpr::ConstructionKind
+  ExprResult
+  BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
+                        CXXConstructorDecl *Constructor, MultiExprArg Exprs,
+                        bool RequiresZeroInit, unsigned ConstructKind);
+
+  // FIXME: Can re remove this and have the above BuildCXXConstructExpr check if
+  // the constructor can be elidable?
+  ExprResult
+  BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
+                        CXXConstructorDecl *Constructor, bool Elidable,
+                        MultiExprArg Exprs, bool RequiresZeroInit,
+                        unsigned ConstructKind);
+
+  /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
+  /// the default expr if needed.
+  ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,
+                                    FunctionDecl *FD,
+                                    ParmVarDecl *Param);
+
+  /// FinalizeVarWithDestructor - Prepare for calling destructor on the
+  /// constructed variable.
+  void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType);
+
+  /// \brief Declare the implicit default constructor for the given class.
+  ///
+  /// \param ClassDecl The class declaration into which the implicit 
+  /// default constructor will be added.
+  ///
+  /// \returns The implicitly-declared default constructor.
+  CXXConstructorDecl *DeclareImplicitDefaultConstructor(
+                                                     CXXRecordDecl *ClassDecl);
+  
+  /// DefineImplicitDefaultConstructor - Checks for feasibility of
+  /// defining this constructor as the default constructor.
+  void DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
+                                        CXXConstructorDecl *Constructor);
+
+  /// \brief Declare the implicit destructor for the given class.
+  ///
+  /// \param ClassDecl The class declaration into which the implicit 
+  /// destructor will be added.
+  ///
+  /// \returns The implicitly-declared destructor.
+  CXXDestructorDecl *DeclareImplicitDestructor(CXXRecordDecl *ClassDecl);
+                                               
+  /// DefineImplicitDestructor - Checks for feasibility of
+  /// defining this destructor as the default destructor.
+  void DefineImplicitDestructor(SourceLocation CurrentLocation,
+                                CXXDestructorDecl *Destructor);
+
+  /// \brief Declare the implicit copy constructor for the given class.
+  ///
+  /// \param S The scope of the class, which may be NULL if this is a 
+  /// template instantiation.
+  ///
+  /// \param ClassDecl The class declaration into which the implicit 
+  /// copy constructor will be added.
+  ///
+  /// \returns The implicitly-declared copy constructor.
+  CXXConstructorDecl *DeclareImplicitCopyConstructor(CXXRecordDecl *ClassDecl);
+                                                     
+  /// DefineImplicitCopyConstructor - Checks for feasibility of
+  /// defining this constructor as the copy constructor.
+  void DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
+                                     CXXConstructorDecl *Constructor,
+                                     unsigned TypeQuals);
+
+  /// \brief Declare the implicit copy assignment operator for the given class.
+  ///
+  /// \param S The scope of the class, which may be NULL if this is a 
+  /// template instantiation.
+  ///
+  /// \param ClassDecl The class declaration into which the implicit 
+  /// copy-assignment operator will be added.
+  ///
+  /// \returns The implicitly-declared copy assignment operator.
+  CXXMethodDecl *DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl);
+  
+  /// \brief Defined an implicitly-declared copy assignment operator.
+  void DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
+                                    CXXMethodDecl *MethodDecl);
+
+  /// \brief Force the declaration of any implicitly-declared members of this
+  /// class.
+  void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class);
+  
+  /// 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.
+  ExprResult MaybeBindToTemporary(Expr *E);
+
+  bool CompleteConstructorCall(CXXConstructorDecl *Constructor,
+                               MultiExprArg ArgsPtr,
+                               SourceLocation Loc,
+                               ASTOwningVector<Expr*> &ConvertedArgs);
+
+  virtual ParsedType getDestructorName(SourceLocation TildeLoc,
+                                       IdentifierInfo &II, SourceLocation NameLoc,
+                                       Scope *S, CXXScopeSpec &SS,
+                                       ParsedType ObjectType,
+                                       bool EnteringContext);
+
+  /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
+  virtual ExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
+                                             tok::TokenKind Kind,
+                                             SourceLocation LAngleBracketLoc,
+                                             ParsedType Ty,
+                                             SourceLocation RAngleBracketLoc,
+                                             SourceLocation LParenLoc,
+                                             Expr *E,
+                                             SourceLocation RParenLoc);
+
+  ExprResult BuildCXXNamedCast(SourceLocation OpLoc,
+                                     tok::TokenKind Kind,
+                                     TypeSourceInfo *Ty,
+                                     Expr *E,
+                                     SourceRange AngleBrackets,
+                                     SourceRange Parens);
+
+  ExprResult BuildCXXTypeId(QualType TypeInfoType,
+                                  SourceLocation TypeidLoc,
+                                  TypeSourceInfo *Operand,
+                                  SourceLocation RParenLoc);
+  ExprResult BuildCXXTypeId(QualType TypeInfoType,
+                                  SourceLocation TypeidLoc,
+                                  Expr *Operand,
+                                  SourceLocation RParenLoc);
+
+  /// ActOnCXXTypeid - Parse typeid( something ).
+  virtual ExprResult ActOnCXXTypeid(SourceLocation OpLoc,
+                                          SourceLocation LParenLoc, bool isType,
+                                          void *TyOrExpr,
+                                          SourceLocation RParenLoc);
+
+  //// ActOnCXXThis -  Parse 'this' pointer.
+  virtual ExprResult ActOnCXXThis(SourceLocation ThisLoc);
+
+  /// ActOnCXXBoolLiteral - Parse {true,false} literals.
+  virtual ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
+                                               tok::TokenKind Kind);
+
+  /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
+  virtual ExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc);
+
+  //// ActOnCXXThrow -  Parse throw expressions.
+  virtual ExprResult ActOnCXXThrow(SourceLocation OpLoc,
+                                         Expr *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 ExprResult ActOnCXXTypeConstructExpr(SourceRange TypeRange,
+                                                     ParsedType TypeRep,
+                                                     SourceLocation LParenLoc,
+                                                     MultiExprArg Exprs,
+                                                     SourceLocation *CommaLocs,
+                                                     SourceLocation RParenLoc);
+
+  /// ActOnCXXNew - Parsed a C++ 'new' expression.
+  virtual ExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
+                                       SourceLocation PlacementLParen,
+                                       MultiExprArg PlacementArgs,
+                                       SourceLocation PlacementRParen,
+                                       SourceRange TypeIdParens, Declarator &D,
+                                       SourceLocation ConstructorLParen,
+                                       MultiExprArg ConstructorArgs,
+                                       SourceLocation ConstructorRParen);
+  ExprResult BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
+                               SourceLocation PlacementLParen,
+                               MultiExprArg PlacementArgs,
+                               SourceLocation PlacementRParen,
+                               SourceRange TypeIdParens,
+                               QualType AllocType,
+                               SourceLocation TypeLoc,
+                               SourceRange TypeRange,
+                               Expr *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 ExprResult ActOnCXXDelete(SourceLocation StartLoc,
+                                          bool UseGlobal, bool ArrayForm,
+                                          Expr *Operand);
+
+  virtual DeclResult ActOnCXXConditionDeclaration(Scope *S,
+                                                  Declarator &D);
+  ExprResult CheckConditionVariable(VarDecl *ConditionVar,
+                                          SourceLocation StmtLoc,
+                                          bool ConvertToBoolean);
+
+  /// ActOnUnaryTypeTrait - Parsed one of the unary type trait support
+  /// pseudo-functions.
+  virtual ExprResult ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
+                                               SourceLocation KWLoc,
+                                               SourceLocation LParen,
+                                               ParsedType Ty,
+                                               SourceLocation RParen);
+
+  virtual ExprResult ActOnStartCXXMemberReference(Scope *S,
+                                                        Expr *Base,
+                                                        SourceLocation OpLoc,
+                                                        tok::TokenKind OpKind,
+                                                        ParsedType &ObjectType,
+                                                   bool &MayBePseudoDestructor);
+
+  ExprResult DiagnoseDtorReference(SourceLocation NameLoc,
+                                         Expr *MemExpr);
+
+  ExprResult BuildPseudoDestructorExpr(Expr *Base,
+                                             SourceLocation OpLoc,
+                                             tok::TokenKind OpKind,
+                                             const CXXScopeSpec &SS,
+                                             TypeSourceInfo *ScopeType,
+                                             SourceLocation CCLoc,
+                                             SourceLocation TildeLoc,
+                                     PseudoDestructorTypeStorage DestroyedType,
+                                             bool HasTrailingLParen);
+
+  virtual ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *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);
+  ExprResult MaybeCreateCXXExprWithTemporaries(ExprResult SubExpr);
+  FullExpr CreateFullExpr(Expr *SubExpr);
+
+  virtual ExprResult ActOnFinishFullExpr(Expr *Expr);
+
+  // Marks SS invalid if it represents an incomplete type.
+  bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC);
+
+  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 NestedNameSpecifier *
+  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,
+                                            ParsedType ObjectType);
+
+  NestedNameSpecifier *BuildCXXNestedNameSpecifier(Scope *S,
+                                                   CXXScopeSpec &SS,
+                                                   SourceLocation IdLoc,
+                                                   SourceLocation CCLoc,
+                                                   IdentifierInfo &II,
+                                                   QualType ObjectType,
+                                                   NamedDecl *ScopeLookupResult,
+                                                   bool EnteringContext,
+                                                   bool ErrorRecoveryLookup);
+
+  virtual NestedNameSpecifier *ActOnCXXNestedNameSpecifier(Scope *S,
+                                                           CXXScopeSpec &SS,
+                                                           SourceLocation IdLoc,
+                                                           SourceLocation CCLoc,
+                                                           IdentifierInfo &II,
+                                                          ParsedType ObjectType,
+                                                          bool EnteringContext);
+
+  virtual bool IsInvalidUnlessNestedName(Scope *S,
+                                         CXXScopeSpec &SS,
+                                         IdentifierInfo &II,
+                                         ParsedType 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,
+                                                  ParsedType 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, Decl *Dcl);
+
+  /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
+  /// initializer for the declaration 'Dcl'.
+  virtual void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl);
+
+  // ParseObjCStringLiteral - Parse Objective-C string literals.
+  virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
+                                            Expr **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,
+                                               ParsedType 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 Decl *ActOnStartLinkageSpecification(Scope *S,
+                                                   SourceLocation ExternLoc,
+                                                   SourceLocation LangLoc,
+                                                   llvm::StringRef Lang,
+                                                   SourceLocation LBraceLoc);
+  virtual Decl *ActOnFinishLinkageSpecification(Scope *S,
+                                                    Decl *LinkageSpec,
+                                                    SourceLocation RBraceLoc);
+
+
+  //===--------------------------------------------------------------------===//
+  // C++ Classes
+  //
+  virtual bool isCurrentClassName(const IdentifierInfo &II, Scope *S,
+                                  const CXXScopeSpec *SS = 0);
+
+  virtual Decl *ActOnAccessSpecifier(AccessSpecifier Access,
+                                         SourceLocation ASLoc,
+                                         SourceLocation ColonLoc);
+
+  virtual Decl *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
+                                             Declarator &D,
+                                 MultiTemplateParamsArg TemplateParameterLists,
+                                             Expr *BitfieldWidth,
+                                             Expr *Init, bool IsDefinition,
+                                             bool Deleted = false);
+
+  virtual MemInitResult ActOnMemInitializer(Decl *ConstructorD,
+                                            Scope *S,
+                                            CXXScopeSpec &SS,
+                                            IdentifierInfo *MemberOrBase,
+                                            ParsedType TemplateTypeTy,
+                                            SourceLocation IdLoc,
+                                            SourceLocation LParenLoc,
+                                            Expr **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);
+  
+  void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation);
+                           
+
+  /// MarkBaseAndMemberDestructorsReferenced - Given a record decl,
+  /// mark all the non-trivial destructors of its members and bases as
+  /// referenced.
+  void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc,
+                                              CXXRecordDecl *Record);
+
+  /// \brief The list of classes whose vtables have been used within
+  /// this translation unit, and the source locations at which the
+  /// first use occurred.
+  llvm::SmallVector<std::pair<CXXRecordDecl *, SourceLocation>, 16> 
+    VTableUses;
+
+  /// \brief The set of classes whose vtables have been used within
+  /// this translation unit, and a bit that will be true if the vtable is
+  /// required to be emitted (otherwise, it should be emitted only if needed
+  /// by code generation).
+  llvm::DenseMap<CXXRecordDecl *, bool> VTablesUsed;
+
+  /// \brief A list of all of the dynamic classes in this translation
+  /// unit.
+  llvm::SmallVector<CXXRecordDecl *, 16> DynamicClasses;
+
+  /// \brief Note that the vtable for the given class was used at the
+  /// given location.
+  void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,
+                      bool DefinitionRequired = false);
+
+  /// MarkVirtualMembersReferenced - Will mark all virtual members of the given
+  /// CXXRecordDecl referenced.
+  void MarkVirtualMembersReferenced(SourceLocation Loc,
+                                    const CXXRecordDecl *RD);
+
+  /// \brief Define all of the vtables that have been used in this
+  /// translation unit and reference any virtual members used by those
+  /// vtables.
+  ///
+  /// \returns true if any work was done, false otherwise.
+  bool DefineUsedVTables();
+
+  void AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl);
+
+  virtual void ActOnMemInitializers(Decl *ConstructorDecl,
+                                    SourceLocation ColonLoc,
+                                    MemInitTy **MemInits, unsigned NumMemInits,
+                                    bool AnyErrors);
+
+  void CheckCompletedCXXClass(CXXRecordDecl *Record);
+  virtual void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
+                                                 Decl *TagDecl,
+                                                 SourceLocation LBrac,
+                                                 SourceLocation RBrac,
+                                                 AttributeList *AttrList);
+
+  virtual void ActOnReenterTemplateScope(Scope *S, Decl *Template);
+  virtual void ActOnStartDelayedMemberDeclarations(Scope *S,
+                                                   Decl *Record);
+  virtual void ActOnStartDelayedCXXMethodDeclaration(Scope *S,
+                                                     Decl *Method);
+  virtual void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param);
+  virtual void ActOnFinishDelayedCXXMethodDeclaration(Scope *S,
+                                                      Decl *Method);
+  virtual void ActOnFinishDelayedMemberDeclarations(Scope *S,
+                                                    Decl *Record);
+
+  virtual Decl *ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
+                                                 Expr *AssertExpr,
+                                                 Expr *AssertMessageExpr);
+
+  FriendDecl *CheckFriendTypeDecl(SourceLocation FriendLoc,
+                                  TypeSourceInfo *TSInfo);
+  Decl *ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
+                                MultiTemplateParamsArg TemplateParams);
+  Decl *ActOnFriendFunctionDecl(Scope *S, Declarator &D, bool IsDefinition,
+                                    MultiTemplateParamsArg TemplateParams);
+
+  QualType CheckConstructorDeclarator(Declarator &D, QualType R,
+                                      StorageClass& SC);
+  void CheckConstructor(CXXConstructorDecl *Constructor);
+  QualType CheckDestructorDeclarator(Declarator &D, QualType R,
+                                     StorageClass& SC);
+  bool CheckDestructor(CXXDestructorDecl *Destructor);
+  void CheckConversionDeclarator(Declarator &D, QualType &R,
+                                 StorageClass& SC);
+  Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion);
+
+  //===--------------------------------------------------------------------===//
+  // C++ Derived Classes
+  //
+
+  /// ActOnBaseSpecifier - Parsed a base specifier
+  CXXBaseSpecifier *CheckBaseSpecifier(CXXRecordDecl *Class,
+                                       SourceRange SpecifierRange,
+                                       bool Virtual, AccessSpecifier Access,
+                                       TypeSourceInfo *TInfo);
+
+  /// 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(Decl *classdecl,
+                                        SourceRange SpecifierRange,
+                                        bool Virtual, AccessSpecifier Access,
+                                        ParsedType basetype, SourceLocation
+                                        BaseLoc);
+
+  bool AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases,
+                            unsigned NumBases);
+  virtual void ActOnBaseSpecifiers(Decl *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, CXXCastPath &BasePath);
+
+  bool BasePathInvolvesVirtualBase(const CXXCastPath &BasePath);
+
+  bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
+                                    SourceLocation Loc, SourceRange Range,
+                                    CXXCastPath *BasePath = 0,
+                                    bool IgnoreAccess = false);
+  bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
+                                    unsigned InaccessibleBaseID,
+                                    unsigned AmbigiousBaseConvID,
+                                    SourceLocation Loc, SourceRange Range,
+                                    DeclarationName Name,
+                                    CXXCastPath *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,
+                                      bool IsCopyBindingRefToTemp = false);
+  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(sema::DelayedDiagnostic &DD, Decl *Ctx);
+
+  /// A flag to suppress access checking.
+  bool SuppressAccessChecking;
+
+  void ActOnStartSuppressingAccessChecks();
+  void ActOnStopSuppressingAccessChecks();
+
+  enum AbstractDiagSelID {
+    AbstractNone = -1,
+    AbstractReturnType,
+    AbstractParamType,
+    AbstractVariableType,
+    AbstractFieldType,
+    AbstractArrayType
+  };
+
+  bool RequireNonAbstractType(SourceLocation Loc, QualType T,
+                              const PartialDiagnostic &PD);
+  void DiagnoseAbstractType(const CXXRecordDecl *RD);
+
+  bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID,
+                              AbstractDiagSelID SelID = AbstractNone);
+
+  //===--------------------------------------------------------------------===//
+  // 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,
+                          bool &MemberOfUnknownSpecialization);
+
+  virtual TemplateNameKind isTemplateName(Scope *S,
+                                          CXXScopeSpec &SS,
+                                          bool hasTemplateKeyword,
+                                          UnqualifiedId &Name,
+                                          ParsedType ObjectType,
+                                          bool EnteringContext,
+                                          TemplateTy &Template,
+                                          bool &MemberOfUnknownSpecialization);
+
+  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(Decl *&Decl);
+
+  virtual Decl *ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+                                       SourceLocation EllipsisLoc,
+                                       SourceLocation KeyLoc,
+                                       IdentifierInfo *ParamName,
+                                       SourceLocation ParamNameLoc,
+                                       unsigned Depth, unsigned Position,
+                                       SourceLocation EqualLoc,
+                                       ParsedType DefaultArg);
+
+  QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc);
+  virtual Decl *ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
+                                                  unsigned Depth,
+                                                  unsigned Position,
+                                                  SourceLocation EqualLoc,
+                                                  Expr *DefaultArg);
+  virtual Decl *ActOnTemplateTemplateParameter(Scope *S,
+                                                   SourceLocation TmpLoc,
+                                                   TemplateParamsTy *Params,
+                                                   IdentifierInfo *ParamName,
+                                                   SourceLocation ParamNameLoc,
+                                                   unsigned Depth,
+                                                   unsigned Position,
+                                                   SourceLocation EqualLoc,
+                                     const ParsedTemplateArgument &DefaultArg);
+
+  virtual TemplateParamsTy *
+  ActOnTemplateParameterList(unsigned Depth,
+                             SourceLocation ExportLoc,
+                             SourceLocation TemplateLoc,
+                             SourceLocation LAngleLoc,
+                             Decl **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,
+                                          bool &Invalid);
+
+  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,
+                                            TypeSpecifierType TagSpec,
+                                            SourceLocation TagLoc);
+
+  ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS,
+                                       LookupResult &R,
+                                       bool RequiresADL,
+                               const TemplateArgumentListInfo &TemplateArgs);
+  ExprResult BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
+                               const DeclarationNameInfo &NameInfo,
+                               const TemplateArgumentListInfo &TemplateArgs);
+
+  virtual TemplateNameKind ActOnDependentTemplateName(Scope *S,
+                                                  SourceLocation TemplateKWLoc,
+                                                      CXXScopeSpec &SS,
+                                                      UnqualifiedId &Name,
+                                                      ParsedType ObjectType,
+                                                      bool EnteringContext,
+                                                      TemplateTy &Template);
+
+  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 Decl *ActOnTemplateDeclarator(Scope *S,
+                                  MultiTemplateParamsArg TemplateParameterLists,
+                                            Declarator &D);
+
+  virtual Decl *ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
+                                  MultiTemplateParamsArg TemplateParameterLists,
+                                                    Declarator &D);
+
+  bool
+  CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
+                                         TemplateSpecializationKind NewTSK,
+                                         NamedDecl *PrevDecl,
+                                         TemplateSpecializationKind PrevTSK,
+                                         SourceLocation PrevPtOfInstantiation,
+                                         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);
+
+  ExprResult
+  BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
+                                          QualType ParamType,
+                                          SourceLocation Loc);
+  ExprResult
+  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 S The scope in which this typename type occurs.
+  /// \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(Scope *S, 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 S The scope in which this typename type occurs.
+  /// \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(Scope *S, SourceLocation TypenameLoc, 
+                    const CXXScopeSpec &SS, SourceLocation TemplateLoc, 
+                    ParsedType Ty);
+
+  QualType CheckTypenameType(ElaboratedTypeKeyword Keyword,
+                             NestedNameSpecifier *NNS,
+                             const IdentifierInfo &II,
+                             SourceLocation KeywordLoc,
+                             SourceRange NNSRange,
+                             SourceLocation IILoc);
+
+  TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
+                                                    SourceLocation Loc,
+                                                    DeclarationName Name);
+  bool RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS);
+
+  ExprResult RebuildExprInCurrentInstantiation(Expr *E);
+
+  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_Underqualified,
+    /// \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
+  };
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
+                          const TemplateArgumentList &TemplateArgs,
+                          sema::TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                        const TemplateArgumentListInfo &ExplicitTemplateArgs,
+                      llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+                                 llvm::SmallVectorImpl<QualType> &ParamTypes,
+                                      QualType *FunctionType,
+                                      sema::TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
+                      llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+                                  unsigned NumExplicitlySpecified,
+                                  FunctionDecl *&Specialization,
+                                  sema::TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                          const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                          Expr **Args, unsigned NumArgs,
+                          FunctionDecl *&Specialization,
+                          sema::TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                          const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                          QualType ArgFunctionType,
+                          FunctionDecl *&Specialization,
+                          sema::TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                          QualType ToType,
+                          CXXConversionDecl *&Specialization,
+                          sema::TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                          const TemplateArgumentListInfo *ExplicitTemplateArgs,
+                          FunctionDecl *&Specialization,
+                          sema::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,
+                                               const FunctionDecl *Pattern = 0);
+
+  /// \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 The stack of calls expression undergoing template instantiation.
+  ///
+  /// The top of this stack is used by a fixit instantiating unresolved
+  /// function calls to fix the AST to match the textual change it prints.
+  llvm::SmallVector<CallExpr *, 8> CallsUndergoingInstantiation;
+
+  /// \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 RAII class that determines when any errors have occurred
+  /// between the time the instance was created and the time it was
+  /// queried.
+  class ErrorTrap {
+    Sema &SemaRef;
+    unsigned PrevErrors;
+
+  public:
+    explicit ErrorTrap(Sema &SemaRef)
+      : SemaRef(SemaRef), PrevErrors(SemaRef.getDiagnostics().getNumErrors()) {}
+
+    /// \brief Determine whether any errors have occurred since this
+    /// object instance was created.
+    bool hasErrorOccurred() const {
+      return SemaRef.getDiagnostics().getNumErrors() > PrevErrors;
+    }
+  };
+
+  /// \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> PendingInstantiations;
+
+  /// \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 PerformPendingInstantiations(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);
+  ExprResult SubstExpr(Expr *E,
+                            const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  StmtResult 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);
+
+  void InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
+                        Decl *Pattern, Decl *Inst);
+
+  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);
+  DeclarationNameInfo
+  SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+                           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 Decl *ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
+                                             IdentifierInfo *ClassName,
+                                             SourceLocation ClassLoc,
+                                             IdentifierInfo *SuperName,
+                                             SourceLocation SuperLoc,
+                                             Decl * const *ProtoRefs,
+                                             unsigned NumProtoRefs,
+                                             const SourceLocation *ProtoLocs,
+                                             SourceLocation EndProtoLoc,
+                                             AttributeList *AttrList);
+
+  virtual Decl *ActOnCompatiblityAlias(
+                    SourceLocation AtCompatibilityAliasLoc,
+                    IdentifierInfo *AliasName,  SourceLocation AliasLocation,
+                    IdentifierInfo *ClassName, SourceLocation ClassLocation);
+
+  void CheckForwardProtocolDeclarationForCircularDependency(
+    IdentifierInfo *PName,
+    SourceLocation &PLoc, SourceLocation PrevLoc,
+    const ObjCList<ObjCProtocolDecl> &PList);
+
+  virtual Decl *ActOnStartProtocolInterface(
+                    SourceLocation AtProtoInterfaceLoc,
+                    IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
+                    Decl * const *ProtoRefNames, unsigned NumProtoRefs,
+                    const SourceLocation *ProtoLocs,
+                    SourceLocation EndProtoLoc,
+                    AttributeList *AttrList);
+
+  virtual Decl *ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
+                                                IdentifierInfo *ClassName,
+                                                SourceLocation ClassLoc,
+                                                IdentifierInfo *CategoryName,
+                                                SourceLocation CategoryLoc,
+                                                Decl * const *ProtoRefs,
+                                                unsigned NumProtoRefs,
+                                                const SourceLocation *ProtoLocs,
+                                                SourceLocation EndProtoLoc);
+
+  virtual Decl *ActOnStartClassImplementation(
+                    SourceLocation AtClassImplLoc,
+                    IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                    IdentifierInfo *SuperClassname,
+                    SourceLocation SuperClassLoc);
+
+  virtual Decl *ActOnStartCategoryImplementation(
+                                                  SourceLocation AtCatImplLoc,
+                                                  IdentifierInfo *ClassName,
+                                                  SourceLocation ClassLoc,
+                                                  IdentifierInfo *CatName,
+                                                  SourceLocation CatLoc);
+
+  virtual Decl *ActOnForwardClassDeclaration(SourceLocation Loc,
+                                                 IdentifierInfo **IdentList,
+                                                 SourceLocation *IdentLocs,
+                                                 unsigned NumElts);
+
+  virtual Decl *ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc,
+                                            const IdentifierLocPair *IdentList,
+                                                  unsigned NumElts,
+                                                  AttributeList *attrList);
+
+  virtual void FindProtocolDeclaration(bool WarnOnDeclarations,
+                                       const IdentifierLocPair *ProtocolId,
+                                       unsigned NumProtocols,
+                                   llvm::SmallVectorImpl<Decl *> &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(Decl *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, Decl *MergeProtocols);
+
+  void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
+                                        ObjCInterfaceDecl *ID);
+
+  void MatchOneProtocolPropertiesInClass(Decl *CDecl,
+                                         ObjCProtocolDecl *PDecl);
+
+  virtual void ActOnAtEnd(Scope *S, SourceRange AtEnd,
+                          Decl *classDecl,
+                          Decl **allMethods = 0, unsigned allNum = 0,
+                          Decl **allProperties = 0, unsigned pNum = 0,
+                          DeclGroupPtrTy *allTUVars = 0, unsigned tuvNum = 0);
+
+  virtual Decl *ActOnProperty(Scope *S, SourceLocation AtLoc,
+                                  FieldDeclarator &FD, ObjCDeclSpec &ODS,
+                                  Selector GetterSel, Selector SetterSel,
+                                  Decl *ClassCategory,
+                                  bool *OverridingProperty,
+                                  tok::ObjCKeywordKind MethodImplKind);
+
+  virtual Decl *ActOnPropertyImplDecl(Scope *S,
+                                          SourceLocation AtLoc,
+                                          SourceLocation PropertyLoc,
+                                          bool ImplKind,Decl *ClassImplDecl,
+                                          IdentifierInfo *PropertyId,
+                                          IdentifierInfo *PropertyIvar);
+
+  struct ObjCArgInfo {
+    IdentifierInfo *Name;
+    SourceLocation NameLoc;
+    // The Type is null if no type was specified, and the DeclSpec is invalid
+    // in this case.
+    ParsedType Type;
+    ObjCDeclSpec DeclSpec;
+
+    /// ArgAttrs - Attribute list for this argument.
+    AttributeList *ArgAttrs;
+  };
+
+  virtual Decl *ActOnMethodDeclaration(
+    SourceLocation BeginLoc, // location of the + or -.
+    SourceLocation EndLoc,   // location of the ; or {.
+    tok::TokenKind MethodType,
+    Decl *ClassDecl, ObjCDeclSpec &ReturnQT, ParsedType 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);
+
+  ExprResult
+  HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
+                            Expr *BaseExpr,
+                            DeclarationName MemberName,
+                            SourceLocation MemberLoc);
+
+  virtual ExprResult
+  ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
+                            IdentifierInfo &propertyName,
+                            SourceLocation receiverNameLoc,
+                            SourceLocation propertyNameLoc);
+
+  /// \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
+  };
+  
+  virtual ObjCMessageKind getObjCMessageKind(Scope *S,
+                                             IdentifierInfo *Name,
+                                             SourceLocation NameLoc,
+                                             bool IsSuper,
+                                             bool HasTrailingDot,
+                                             ParsedType &ReceiverType);
+
+  virtual ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc,
+                                             Selector Sel,
+                                             SourceLocation LBracLoc,
+                                             SourceLocation SelectorLoc,
+                                             SourceLocation RBracLoc,
+                                             MultiExprArg Args);
+
+  ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
+                                     QualType ReceiverType,
+                                     SourceLocation SuperLoc,
+                                     Selector Sel,
+                                     ObjCMethodDecl *Method,
+                                     SourceLocation LBracLoc,
+                                     SourceLocation RBracLoc,
+                                     MultiExprArg Args);
+
+  virtual ExprResult ActOnClassMessage(Scope *S,
+                                             ParsedType Receiver,
+                                             Selector Sel,
+                                             SourceLocation LBracLoc,
+                                             SourceLocation SelectorLoc,
+                                             SourceLocation RBracLoc,
+                                             MultiExprArg Args);
+
+  ExprResult BuildInstanceMessage(Expr *Receiver,
+                                        QualType ReceiverType,
+                                        SourceLocation SuperLoc,
+                                        Selector Sel,
+                                        ObjCMethodDecl *Method,
+                                        SourceLocation LBracLoc,
+                                        SourceLocation RBracLoc,
+                                        MultiExprArg Args);
+
+  virtual ExprResult ActOnInstanceMessage(Scope *S,
+                                                Expr *Receiver,
+                                                Selector Sel,
+                                                SourceLocation LBracLoc,
+                                                SourceLocation SelectorLoc,
+                                                SourceLocation RBracLoc,
+                                                MultiExprArg Args);
+
+
+  enum PragmaOptionsAlignKind {
+    POAK_Native,  // #pragma options align=native
+    POAK_Natural, // #pragma options align=natural
+    POAK_Packed,  // #pragma options align=packed
+    POAK_Power,   // #pragma options align=power
+    POAK_Mac68k,  // #pragma options align=mac68k
+    POAK_Reset    // #pragma options align=reset
+  };
+
+  /// ActOnPragmaOptionsAlign - Called on well formed #pragma options align.
+  virtual void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
+                                       SourceLocation PragmaLoc,
+                                       SourceLocation KindLoc);
+
+  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,
+                               Expr *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);
+
+  /// ActOnPragmaVisibility - Called on well formed #pragma GCC visibility... .
+  virtual void ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType,
+                                     SourceLocation PragmaLoc);
+
+  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);
+
+  /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to
+  /// a the record decl, to handle '#pragma pack' and '#pragma options align'.
+  void AddAlignmentAttributesForRecord(RecordDecl *RD);
+
+  /// FreePackedContext - Deallocate and null out PackContext.
+  void FreePackedContext();
+
+  /// PushVisibilityAttr - Note that we've entered a context with a
+  /// visibility attribute.
+  void PushVisibilityAttr(const VisibilityAttr *Attr);
+
+  /// AddPushedVisibilityAttribute - If '#pragma GCC visibility' was used,
+  /// add an appropriate visibility attribute.
+  void AddPushedVisibilityAttribute(Decl *RD);
+
+  /// PopPragmaVisibility - Pop the top element of the visibility stack; used
+  /// for '#pragma GCC visibility' and visibility attributes on namespaces.
+  void PopPragmaVisibility();
+
+  /// FreeVisContext - Deallocate and null out VisContext.
+  void FreeVisContext();
+
+  /// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
+  void AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E);
+  void AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *T);
+
+  /// CastCategory - Get the correct forwarded implicit cast result category
+  /// from the inner expression.
+  ExprValueKind CastCategory(Expr *E);
+
+  /// 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, CastKind CK,
+                         ExprValueKind VK = VK_RValue,
+                         const CXXCastPath *BasePath = 0);
+
+  // 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,
+                                        FunctionDecl *FDecl);
+
+  // 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, unsigned Opc);
+  // 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.
+  QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
+  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, bool isPrefix);
+  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,
+                                                      bool &ObjCConversion);
+
+  /// 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,
+                      CastKind &Kind, CXXCastPath &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,
+                       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,
+                          CastKind &Kind);
+
+  /// CXXCheckCStyleCast - Check constraints of a C-style or function-style
+  /// cast under C++ semantics.
+  bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
+                          CastKind &Kind, CXXCastPath &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);
+
+  virtual ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc,
+                                           Expr *SubExpr);
+  
+  /// 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
+  //@{
+  /// \brief Describes the context in which code completion occurs.
+  enum ParserCompletionContext {
+    /// \brief Code completion occurs at top-level or namespace context.
+    PCC_Namespace,
+    /// \brief Code completion occurs within a class, struct, or union.
+    PCC_Class,
+    /// \brief Code completion occurs within an Objective-C interface, protocol,
+    /// or category.
+    PCC_ObjCInterface,
+    /// \brief Code completion occurs within an Objective-C implementation or
+    /// category implementation
+    PCC_ObjCImplementation,
+    /// \brief Code completion occurs within the list of instance variables
+    /// in an Objective-C interface, protocol, category, or implementation.
+    PCC_ObjCInstanceVariableList,
+    /// \brief Code completion occurs following one or more template
+    /// headers.
+    PCC_Template,
+    /// \brief Code completion occurs following one or more template
+    /// headers within a class.
+    PCC_MemberTemplate,
+    /// \brief Code completion occurs within an expression.
+    PCC_Expression,
+    /// \brief Code completion occurs within a statement, which may
+    /// also be an expression or a declaration.
+    PCC_Statement,
+    /// \brief Code completion occurs at the beginning of the
+    /// initialization statement (or expression) in a for loop.
+    PCC_ForInit,
+    /// \brief Code completion occurs within the condition of an if,
+    /// while, switch, or for statement.
+    PCC_Condition,
+    /// \brief Code completion occurs within the body of a function on a 
+    /// recovery path, where we do not have a specific handle on our position
+    /// in the grammar.
+    PCC_RecoveryInFunction,
+    /// \brief Code completion occurs where only a type is permitted.
+    PCC_Type
+  };
+
+  virtual void CodeCompleteOrdinaryName(Scope *S,
+                                     ParserCompletionContext CompletionContext);
+  virtual void CodeCompleteDeclarator(Scope *S,
+                                      bool AllowNonIdentifiers,
+                                      bool AllowNestedNameSpecifiers);
+  
+  struct CodeCompleteExpressionData;
+  virtual void CodeCompleteExpression(Scope *S, 
+                                      const CodeCompleteExpressionData &Data);
+  virtual void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
+                                               SourceLocation OpLoc,
+                                               bool IsArrow);
+  virtual void CodeCompleteTag(Scope *S, unsigned TagSpec);
+  virtual void CodeCompleteTypeQualifiers(DeclSpec &DS);
+  virtual void CodeCompleteCase(Scope *S);
+  virtual void CodeCompleteCall(Scope *S, Expr *Fn,
+                                Expr **Args, unsigned NumArgs);
+  virtual void CodeCompleteInitializer(Scope *S, Decl *D);
+  virtual void CodeCompleteReturn(Scope *S);
+  virtual void CodeCompleteAssignmentRHS(Scope *S, Expr *LHS);
+  
+  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 CodeCompleteConstructorInitializer(Decl *Constructor,
+                                    CXXBaseOrMemberInitializer** Initializers,
+                                                  unsigned NumInitializers);
+  
+  virtual void CodeCompleteObjCAtDirective(Scope *S, Decl *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, Decl *ClassDecl,
+                                              Decl **Methods,
+                                              unsigned NumMethods);
+  virtual void CodeCompleteObjCPropertySetter(Scope *S, Decl *ClassDecl,
+                                              Decl **Methods,
+                                              unsigned NumMethods);
+  virtual void CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS);
+  virtual void CodeCompleteObjCMessageReceiver(Scope *S);
+  virtual void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
+                                            IdentifierInfo **SelIdents,
+                                            unsigned NumSelIdents);
+  virtual void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
+                                            IdentifierInfo **SelIdents,
+                                            unsigned NumSelIdents);
+  void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
+                                    IdentifierInfo **SelIdents,
+                                    unsigned NumSelIdents,
+                                    bool IsSuper);
+  virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
+                                               IdentifierInfo **SelIdents,
+                                               unsigned NumSelIdents);
+  void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
+                                     IdentifierInfo **SelIdents,
+                                     unsigned NumSelIdents,
+                                     bool IsSuper);
+  virtual void CodeCompleteObjCForCollection(Scope *S, 
+                                             DeclGroupPtrTy IterationVar);
+  virtual void CodeCompleteObjCSelector(Scope *S,
+                                        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,
+                                                  Decl *ObjCImpDecl);
+  virtual void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
+                                                  IdentifierInfo *PropertyName,
+                                                      Decl *ObjCImpDecl);
+  virtual void CodeCompleteObjCMethodDecl(Scope *S,
+                                          bool IsInstanceMethod,
+                                          ParsedType ReturnType,
+                                          Decl *IDecl);
+  virtual void CodeCompleteObjCMethodDeclSelector(Scope *S, 
+                                                  bool IsInstanceMethod,
+                                                  bool AtParameterName,
+                                                  ParsedType ReturnType,
+                                                  IdentifierInfo **SelIdents,
+                                                  unsigned NumSelIdents);
+  virtual void CodeCompletePreprocessorDirective(bool InConditional);
+  virtual void CodeCompleteInPreprocessorConditionalExclusion(Scope *S);
+  virtual void CodeCompletePreprocessorMacroName(bool IsDefinition);
+  virtual void CodeCompletePreprocessorExpression();
+  virtual void CodeCompletePreprocessorMacroArgument(Scope *S,
+                                                     IdentifierInfo *Macro,
+                                                     MacroInfo *MacroInfo,
+                                                     unsigned Argument);
+  virtual void CodeCompleteNaturalLanguage();
+  void GatherGlobalCodeCompletions(
+                  llvm::SmallVectorImpl<CodeCompletionResult> &Results);
+  //@}
+
+  void PrintStats() const {}
+
+  //===--------------------------------------------------------------------===//
+  // 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);
+
+  ExprResult CheckBuiltinFunctionCall(unsigned BuiltinID,
+                                                    CallExpr *TheCall);
+  bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+
+  bool SemaBuiltinVAStart(CallExpr *TheCall);
+  bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
+  bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs);
+
+public:
+  // Used by C++ template instantiation.
+  ExprResult SemaBuiltinShuffleVector(CallExpr *TheCall);
+
+private:
+  bool SemaBuiltinPrefetch(CallExpr *TheCall);
+  bool SemaBuiltinObjectSize(CallExpr *TheCall);
+  bool SemaBuiltinLongjmp(CallExpr *TheCall);
+  ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);
+  bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum,
+                              llvm::APSInt &Result);
+
+  bool SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
+                              bool HasVAListArg, unsigned format_idx,
+                              unsigned firstDataArg, bool isPrintf);
+
+  void CheckFormatString(const StringLiteral *FExpr, const Expr *OrigFormatExpr,
+                         const CallExpr *TheCall, bool HasVAListArg,
+                         unsigned format_idx, unsigned firstDataArg,
+                         bool isPrintf);
+
+  void CheckNonNullArguments(const NonNullAttr *NonNull,
+                             const CallExpr *TheCall);
+
+  void CheckPrintfScanfArguments(const CallExpr *TheCall, bool HasVAListArg,
+                                 unsigned format_idx, unsigned firstDataArg,
+                                 bool isPrintf);
+
+  void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
+                            SourceLocation ReturnLoc);
+  void CheckFloatComparison(SourceLocation loc, Expr* lex, Expr* rex);
+  void CheckImplicitConversions(Expr *E);
+
+  /// \brief The parser's current scope.
+  ///
+  /// The parser maintains this state here.
+  Scope *CurScope;
+  
+protected:
+  friend class Parser;
+  
+  /// \brief Retrieve the parser's current scope.
+  Scope *getCurScope() const { return CurScope; }  
+};
+
+/// \brief RAII object that enters a new expression evaluation context.
+class EnterExpressionEvaluationContext {
+  Sema &Actions;
+
+public:
+  EnterExpressionEvaluationContext(Sema &Actions,
+                                   Sema::ExpressionEvaluationContext NewContext)
+    : Actions(Actions) {
+    Actions.PushExpressionEvaluationContext(NewContext);
+  }
+
+  ~EnterExpressionEvaluationContext() {
+    Actions.PopExpressionEvaluationContext();
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h
index d026339..a5a1364 100644
--- a/include/clang/Sema/SemaDiagnostic.h
+++ b/include/clang/Sema/SemaDiagnostic.h
@@ -15,7 +15,7 @@
 namespace clang {
   namespace diag {
     enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
 #define SEMASTART
 #include "clang/Basic/DiagnosticSemaKinds.inc"
 #undef DIAG
diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h
new file mode 100644
index 0000000..64b83e3
--- /dev/null
+++ b/include/clang/Sema/SemaInternal.h
@@ -0,0 +1,30 @@
+//===--- SemaInternal.h - Internal Sema Interfaces --------------*- 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 common API and #includes for the internal
+// implementation of Sema.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_SEMA_INTERNAL_H
+#define LLVM_CLANG_SEMA_SEMA_INTERNAL_H
+
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaDiagnostic.h"
+#include "clang/AST/ASTContext.h"
+
+namespace clang {
+
+inline PartialDiagnostic Sema::PDiag(unsigned DiagID) {
+  return PartialDiagnostic(DiagID, Context.getDiagAllocator());
+}
+
+}
+
+#endif
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h
new file mode 100644
index 0000000..a7b3b84
--- /dev/null
+++ b/include/clang/Sema/Template.h
@@ -0,0 +1,244 @@
+//===------- 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.
+  class MultiLevelTemplateArgumentList {
+  public:
+    typedef std::pair<const TemplateArgument *, unsigned> ArgList;
+    
+  private:
+    /// \brief The template argument lists, stored from the innermost template
+    /// argument list (first) to the outermost template argument list (last).
+    llvm::SmallVector<ArgList, 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) {
+      addOuterTemplateArguments(&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].second);
+      return TemplateArgumentLists[getNumLevels() - Depth - 1].first[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].second)
+        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(
+                                    ArgList(TemplateArgs->getFlatArgumentList(),
+                                            TemplateArgs->flat_size()));
+    }
+    
+    /// \brief Add a new outmost level to the multi-level template argument
+    /// list.
+    void addOuterTemplateArguments(const TemplateArgument *Args, 
+                                   unsigned NumArgs) {
+      TemplateArgumentLists.push_back(ArgList(Args, NumArgs));
+    }
+    
+    /// \brief Retrieve the innermost template argument list.
+    const ArgList &getInnermost() const { 
+      return TemplateArgumentLists.front(); 
+    }
+  };
+  
+  /// \brief The context in which partial ordering of function templates occurs.
+  enum TPOC {
+    /// \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
+  };
+
+  // This is lame but unavoidable in a world without forward
+  // declarations of enums.  The alternatives are to either pollute
+  // Sema.h (by including this file) or sacrifice type safety (by
+  // making Sema.h declare things as enums).
+  class TemplatePartialOrderingContext {
+    TPOC Value;
+  public:
+    TemplatePartialOrderingContext(TPOC Value) : Value(Value) {}
+    operator TPOC() const { return Value; }
+  };
+
+  /// \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;
+    }
+  };
+
+  /// \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, 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 to combine this scope with the outer scope, such that
+    /// lookup will search our outer scope.
+    bool CombineWithOuterScope;
+    
+    // This class is non-copyable
+    LocalInstantiationScope(const LocalInstantiationScope &);
+    LocalInstantiationScope &operator=(const LocalInstantiationScope &);
+
+  public:
+    LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
+      : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
+        Exited(false), CombineWithOuterScope(CombineWithOuterScope)
+    {
+      SemaRef.CurrentInstantiationScope = this;
+    }
+
+    ~LocalInstantiationScope() {
+      Exit();
+    }
+
+    /// \brief Exit this local instantiation scope early.
+    void Exit() {
+      if (Exited)
+        return;
+      
+      SemaRef.CurrentInstantiationScope = Outer;
+      Exited = true;
+    }
+
+    Decl *getInstantiationOf(const Decl *D);
+
+    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);
+  };
+}
+
+#endif // LLVM_CLANG_SEMA_TEMPLATE_H
diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h
new file mode 100644
index 0000000..ac32e9c
--- /dev/null
+++ b/include/clang/Sema/TemplateDeduction.h
@@ -0,0 +1,111 @@
+//===- TemplateDeduction.h - C++ template argument deduction ----*- 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 with Sema's template argument deduction
+// routines.
+//
+//===----------------------------------------------------------------------===/
+#ifndef LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H
+#define LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H
+
+#include "clang/AST/DeclTemplate.h"
+
+namespace clang {
+
+class ASTContext;
+class TemplateArgumentList;
+
+namespace sema {
+
+/// \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;
+};
+
+}
+}
+
+#endif
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
new file mode 100644
index 0000000..d879fdf
--- /dev/null
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -0,0 +1,918 @@
+//===- ASTBitCodes.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 serialized AST 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 "clang/AST/Type.h"
+#include "llvm/Bitcode/BitCodes.h"
+#include "llvm/System/DataTypes.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+  namespace serialization {
+    /// \brief AST file major version number supported by this version of
+    /// Clang.
+    ///
+    /// Whenever the AST file 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 4 of AST files also requires that the version control branch and
+    /// revision match exactly, since there is no backward compatibility of
+    /// AST files at this time.
+    const unsigned VERSION_MAJOR = 4;
+
+    /// \brief AST file minor version number supported by this version of
+    /// Clang.
+    ///
+    /// Whenever the AST 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 an AST file.
+    ///
+    /// The ID numbers of declarations 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 an AST 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 A type index; the type ID with the qualifier bits removed.
+    class TypeIdx {
+      uint32_t Idx;
+    public:
+      TypeIdx() : Idx(0) { }
+      explicit TypeIdx(uint32_t index) : Idx(index) { }
+
+      uint32_t getIndex() const { return Idx; }
+      TypeID asTypeID(unsigned FastQuals) const {
+        return (Idx << Qualifiers::FastWidth) | FastQuals;
+      }
+      static TypeIdx fromTypeID(TypeID ID) {
+        return TypeIdx(ID >> Qualifiers::FastWidth);
+      }
+    };
+
+    /// 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 Map that provides the ID numbers of each type within the
+    /// output stream, plus those deserialized from a chained PCH.
+    ///
+    /// 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.
+    typedef llvm::DenseMap<QualType, TypeIdx, UnsafeQualTypeDenseMapInfo>
+        TypeIdxMap;
+
+    /// \brief An ID number that refers to an identifier in an AST
+    /// file.
+    typedef uint32_t IdentID;
+
+    typedef uint32_t SelectorID;
+
+    /// \brief Describes the various kinds of blocks that occur within
+    /// an AST file.
+    enum BlockIDs {
+      /// \brief The AST block, which acts as a container around the
+      /// full AST block.
+      AST_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 AST file.
+      DECLTYPES_BLOCK_ID
+    };
+
+    /// \brief Record types that occur within the AST block itself.
+    enum ASTRecordTypes {
+      /// \brief Record code for the offsets of each type.
+      ///
+      /// The TYPE_OFFSET constant describes the record that occurs
+      /// within the AST 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 AST 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 AST file metadata, including the AST file version number
+      /// and the target triple used to build the AST 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 AST 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 AST 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 AST 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 an AST 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 AST 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 AST file.
+      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 AST file.
+      VERSION_CONTROL_BRANCH_REVISION = 21,
+      
+      /// \brief Record code for the array of unused file scoped decls.
+      UNUSED_FILESCOPED_DECLS = 22,
+      
+      /// \brief Record code for the table of offsets to macro definition
+      /// entries in the preprocessing record.
+      MACRO_DEFINITION_OFFSETS = 23,
+
+      /// \brief Record code for the array of VTable uses.
+      VTABLE_USES = 24,
+
+      /// \brief Record code for the array of dynamic classes.
+      DYNAMIC_CLASSES = 25,
+
+      /// \brief Record code for the chained AST metadata, including the
+      /// AST file version and the name of the PCH this depends on.
+      CHAINED_METADATA = 26,
+
+      /// \brief Record code for referenced selector pool.
+      REFERENCED_SELECTOR_POOL = 27,
+
+      /// \brief Record code for an update to the TU's lexically contained
+      /// declarations.
+      TU_UPDATE_LEXICAL = 28,
+
+      /// \brief Record code for an update to first decls pointing to the
+      /// latest redeclarations.
+      REDECLS_UPDATE_LATEST = 29,
+
+      /// \brief Record code for declarations that Sema keeps references of.
+      SEMA_DECL_REFS = 30,
+
+      /// \brief Record code for weak undeclared identifiers.
+      WEAK_UNDECLARED_IDENTIFIERS = 31,
+
+      /// \brief Record code for pending implicit instantiations.
+      PENDING_IMPLICIT_INSTANTIATIONS = 32,
+
+      /// \brief Record code for a decl replacement block.
+      ///
+      /// If a declaration is modified after having been deserialized, and then
+      /// written to a dependent AST file, its ID and offset must be added to
+      /// the replacement block.
+      DECL_REPLACEMENTS = 33,
+
+      /// \brief Record code for an update to a decl context's lookup table.
+      ///
+      /// In practice, this should only be used for the TU and namespaces.
+      UPDATE_VISIBLE = 34,
+
+      /// \brief Record code for template specializations introduced after
+      /// serializations of the original template decl.
+      ADDITIONAL_TEMPLATE_SPECIALIZATIONS = 35
+    };
+
+    /// \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 ASTAST AST file AST constants
+    ///
+    /// The constants in this group describe various components of the
+    /// abstract syntax tree within an AST file.
+    ///
+    /// @{
+
+    /// \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 AST 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 An ObjCObjectType record.
+      TYPE_OBJC_OBJECT              = 28,
+      /// \brief An TemplateTypeParmType record.
+      TYPE_TEMPLATE_TYPE_PARM       = 29,
+      /// \brief An TemplateSpecializationType record.
+      TYPE_TEMPLATE_SPECIALIZATION  = 30,
+      /// \brief A DependentNameType record.
+      TYPE_DEPENDENT_NAME           = 31,
+      /// \brief A DependentTemplateSpecializationType record.
+      TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32,
+      /// \brief A DependentSizedArrayType record.
+      TYPE_DEPENDENT_SIZED_ARRAY    = 33
+    };
+
+    /// \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 Whether __[u]int128_t identifier is installed.
+      SPECIAL_TYPE_INT128_INSTALLED            = 16
+    };
+
+    /// \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 a blob that 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 rcord.
+      DECL_NAMESPACE,
+      /// \brief A NamespaceAliasDecl record.
+      DECL_NAMESPACE_ALIAS,
+      /// \brief A UsingDecl record.
+      DECL_USING,
+      /// \brief A UsingShadowDecl record.
+      DECL_USING_SHADOW,
+      /// \brief A UsingDirecitveDecl record.
+      DECL_USING_DIRECTIVE,
+      /// \brief An UnresolvedUsingValueDecl record.
+      DECL_UNRESOLVED_USING_VALUE,
+      /// \brief An UnresolvedUsingTypenameDecl record.
+      DECL_UNRESOLVED_USING_TYPENAME,
+      /// \brief A LinkageSpecDecl record.
+      DECL_LINKAGE_SPEC,
+      /// \brief A CXXRecordDecl record.
+      DECL_CXX_RECORD,
+      /// \brief A CXXMethodDecl record.
+      DECL_CXX_METHOD,
+      /// \brief A CXXConstructorDecl record.
+      DECL_CXX_CONSTRUCTOR,
+      /// \brief A CXXDestructorDecl record.
+      DECL_CXX_DESTRUCTOR,
+      /// \brief A CXXConversionDecl record.
+      DECL_CXX_CONVERSION,
+      /// \brief An AccessSpecDecl record.
+      DECL_ACCESS_SPEC,
+
+      /// \brief A FriendDecl record.
+      DECL_FRIEND,
+      /// \brief A FriendTemplateDecl record.
+      DECL_FRIEND_TEMPLATE,
+      /// \brief A ClassTemplateDecl record.
+      DECL_CLASS_TEMPLATE,
+      /// \brief A ClassTemplateSpecializationDecl record.
+      DECL_CLASS_TEMPLATE_SPECIALIZATION,
+      /// \brief A ClassTemplatePartialSpecializationDecl record.
+      DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
+      /// \brief A FunctionTemplateDecl record.
+      DECL_FUNCTION_TEMPLATE,
+      /// \brief A TemplateTypeParmDecl record.
+      DECL_TEMPLATE_TYPE_PARM,
+      /// \brief A NonTypeTemplateParmDecl record.
+      DECL_NON_TYPE_TEMPLATE_PARM,
+      /// \brief A TemplateTemplateParmDecl record.
+      DECL_TEMPLATE_TEMPLATE_PARM,
+      /// \brief A StaticAssertDecl record.
+      DECL_STATIC_ASSERT
+    };
+
+    /// \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 ParenListExpr record.
+      EXPR_PAREN_LIST,
+      /// \brief A UnaryOperator record.
+      EXPR_UNARY_OPERATOR,
+      /// \brief An OffsetOfExpr record.
+      EXPR_OFFSETOF,
+      /// \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 CXXCatchStmt record.
+      STMT_CXX_CATCH,
+      /// \brief A CXXTryStmt record.
+      STMT_CXX_TRY,
+
+      /// \brief A CXXOperatorCallExpr record.
+      EXPR_CXX_OPERATOR_CALL,
+      /// \brief A CXXMemberCallExpr record.
+      EXPR_CXX_MEMBER_CALL,
+      /// \brief A CXXConstructExpr record.
+      EXPR_CXX_CONSTRUCT,
+      /// \brief A CXXTemporaryObjectExpr record.
+      EXPR_CXX_TEMPORARY_OBJECT,
+      /// \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,
+      EXPR_CXX_NULL_PTR_LITERAL,  // CXXNullPtrLiteralExpr
+      EXPR_CXX_TYPEID_EXPR,       // CXXTypeidExpr (of expr).
+      EXPR_CXX_TYPEID_TYPE,       // CXXTypeidExpr (of type).
+      EXPR_CXX_THIS,              // CXXThisExpr
+      EXPR_CXX_THROW,             // CXXThrowExpr
+      EXPR_CXX_DEFAULT_ARG,       // CXXDefaultArgExpr
+      EXPR_CXX_BIND_TEMPORARY,    // CXXBindTemporaryExpr
+      EXPR_CXX_BIND_REFERENCE,    // CXXBindReferenceExpr
+
+      EXPR_CXX_SCALAR_VALUE_INIT, // CXXScalarValueInitExpr
+      EXPR_CXX_NEW,               // CXXNewExpr
+      EXPR_CXX_DELETE,            // CXXDeleteExpr
+      EXPR_CXX_PSEUDO_DESTRUCTOR, // CXXPseudoDestructorExpr
+      
+      EXPR_CXX_EXPR_WITH_TEMPORARIES, // CXXExprWithTemporaries
+      
+      EXPR_CXX_DEPENDENT_SCOPE_MEMBER, // CXXDependentScopeMemberExpr
+      EXPR_CXX_DEPENDENT_SCOPE_DECL_REF,   // DependentScopeDeclRefExpr
+      EXPR_CXX_UNRESOLVED_CONSTRUCT, // CXXUnresolvedConstructExpr
+      EXPR_CXX_UNRESOLVED_MEMBER,    // UnresolvedMemberExpr
+      EXPR_CXX_UNRESOLVED_LOOKUP,     // UnresolvedLookupExpr
+
+      EXPR_CXX_UNARY_TYPE_TRAIT   // UnaryTypeTraitExpr  
+    };
+
+    /// \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/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h
new file mode 100644
index 0000000..f8114de
--- /dev/null
+++ b/include/clang/Serialization/ASTDeserializationListener.h
@@ -0,0 +1,49 @@
+//===- ASTDeserializationListener.h - Decl/Type PCH Read Events -*- 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 ASTDeserializationListener class, which is notified
+//  by the ASTReader whenever a type or declaration is deserialized.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_AST_DESERIALIZATION_LISTENER_H
+#define LLVM_CLANG_FRONTEND_AST_DESERIALIZATION_LISTENER_H
+
+#include "clang/Serialization/ASTBitCodes.h"
+
+namespace clang {
+
+class Decl;
+class ASTReader;
+class QualType;
+
+class ASTDeserializationListener {
+protected:
+  virtual ~ASTDeserializationListener() {}
+
+public:
+  /// \brief Tell the listener about the reader.
+  virtual void SetReader(ASTReader *Reader) = 0;
+
+  /// \brief An identifier was deserialized from the AST file.
+  virtual void IdentifierRead(serialization::IdentID ID,
+                              IdentifierInfo *II) = 0;
+  /// \brief A type was deserialized from the AST file. The ID here has the
+  ///        qualifier bits already removed, and T is guaranteed to be locally
+  ///        unqualified.
+  virtual void TypeRead(serialization::TypeIdx Idx, QualType T) = 0;
+  /// \brief A decl was deserialized from the AST file.
+  virtual void DeclRead(serialization::DeclID ID, const Decl *D) = 0;
+  /// \brief A selector was read from the AST file.
+  virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) = 0;
+};
+
+}
+
+#endif
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
new file mode 100644
index 0000000..d31be88
--- /dev/null
+++ b/include/clang/Serialization/ASTReader.h
@@ -0,0 +1,1100 @@
+//===--- ASTReader.h - AST File 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 ASTReader class, which reads AST files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_AST_READER_H
+#define LLVM_CLANG_FRONTEND_AST_READER_H
+
+#include "clang/Serialization/ASTBitCodes.h"
+#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/DeclObjC.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/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 NestedNameSpecifier;
+class CXXBaseSpecifier;
+class CXXBaseOrMemberInitializer;
+class GotoStmt;
+class LabelStmt;
+class MacroDefinition;
+class NamedDecl;
+class ASTDeserializationListener;
+class Preprocessor;
+class Sema;
+class SwitchCase;
+class ASTReader;
+class ASTDeclReader;
+struct HeaderFileInfo;
+
+struct PCHPredefinesBlock {
+  /// \brief The file ID for this predefines buffer in a PCH file.
+  FileID BufferID;
+
+  /// \brief This predefines buffer in a PCH file.
+  llvm::StringRef Data;
+};
+typedef llvm::SmallVector<PCHPredefinesBlock, 2> PCHPredefinesBlocks;
+
+/// \brief Abstract interface for callback invocations by the ASTReader.
+///
+/// While reading an AST file, the ASTReader will call the methods of the
+/// listener to pass on specific information. Some of the listener methods can
+/// return true to indicate to the ASTReader that the information (and
+/// consequently the AST file) is invalid.
+class ASTReaderListener {
+public:
+  virtual ~ASTReaderListener();
+
+  /// \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 Buffers Information about the predefines buffers.
+  ///
+  /// \param OriginalFileName The original file name for the AST file, 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(const PCHPredefinesBlocks &Buffers,
+                                    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 ASTReaderListener implementation to validate the information of
+/// the PCH file against an initialized Preprocessor.
+class PCHValidator : public ASTReaderListener {
+  Preprocessor &PP;
+  ASTReader &Reader;
+
+  unsigned NumHeaderInfos;
+
+public:
+  PCHValidator(Preprocessor &PP, ASTReader &Reader)
+    : PP(PP), Reader(Reader), NumHeaderInfos(0) {}
+
+  virtual bool ReadLanguageOptions(const LangOptions &LangOpts);
+  virtual bool ReadTargetTriple(llvm::StringRef Triple);
+  virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
+                                    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 an AST files chain containing the contents of a translation
+/// unit.
+///
+/// The ASTReader class reads bitstreams (produced by the ASTWriter
+/// class) containing the serialized representation of a given
+/// abstract syntax tree and its supporting data structures. An
+/// instance of the ASTReader can be attached to an ASTContext object,
+/// which will provide access to the contents of the AST files.
+///
+/// The AST 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 ASTReader
+  : public ExternalPreprocessorSource,
+    public ExternalPreprocessingRecordSource,
+    public ExternalSemaSource,
+    public IdentifierInfoLookup,
+    public ExternalIdentifierLookup,
+    public ExternalSLocEntrySource {
+public:
+  enum ASTReadResult { Success, Failure, IgnorePCH };
+  friend class PCHValidator;
+  friend class ASTDeclReader;
+private:
+  /// \brief The receiver of some callbacks invoked by ASTReader.
+  llvm::OwningPtr<ASTReaderListener> Listener;
+
+  /// \brief The receiver of deserialization events.
+  ASTDeserializationListener *DeserializationListener;
+
+  SourceManager &SourceMgr;
+  FileManager &FileMgr;
+  Diagnostic &Diags;
+
+  /// \brief The semantic analysis object that will be processing the
+  /// AST files 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 AST files.
+  ASTContext *Context;
+      
+  /// \brief The AST consumer.
+  ASTConsumer *Consumer;
+
+  /// \brief Information that is needed for every file in the chain.
+  struct PerFileData {
+    PerFileData();
+    ~PerFileData();
+
+    /// \brief The AST stat cache installed for this file, if any.
+    ///
+    /// The dynamic type of this stat cache is always ASTStatCache
+    void *StatCache;
+
+    /// \brief The bitstream reader from which we'll read the AST file.
+    llvm::BitstreamReader StreamFile;
+    llvm::BitstreamCursor Stream;
+
+    /// \brief The size of this file, in bits.
+    uint64_t SizeInBits;
+
+    /// \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 AST file.
+    std::string FileName;
+
+    /// \brief The memory buffer that stores the data associated with
+    /// this AST file.
+    llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
+
+    /// \brief Cursor used to read source location entries.
+    llvm::BitstreamCursor SLocEntryCursor;
+
+    /// \brief The number of source location entries in this AST file.
+    unsigned LocalNumSLocEntries;
+
+    /// \brief Offsets for all of the source location entries in the
+    /// AST file.
+    const uint32_t *SLocOffsets;
+
+    /// \brief The number of types in this AST file.
+    unsigned LocalNumTypes;
+
+    /// \brief Offset of each type within the bitstream, indexed by the
+    /// type ID, or the representation of a Type*.
+    const uint32_t *TypeOffsets;
+
+    /// \brief The number of declarations in this AST file.
+    unsigned LocalNumDecls;
+
+    /// \brief Offset of each declaration within the bitstream, indexed
+    /// by the declaration ID (-1).
+    const uint32_t *DeclOffsets;
+
+    /// \brief The number of identifiers in this AST file.
+    unsigned LocalNumIdentifiers;
+
+    /// \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 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 The number of macro definitions in this file.
+    unsigned LocalNumMacroDefinitions;
+
+    /// \brief Offsets of all of the macro definitions in the preprocessing
+    /// record in the AST file.
+    const uint32_t *MacroDefinitionOffsets;
+      
+    /// \brief The number of preallocated preprocessing entities in the
+    /// preprocessing record.
+    unsigned NumPreallocatedPreprocessingEntities;
+
+    /// \brief A pointer to an on-disk hash table of opaque type
+    /// ASTSelectorLookupTable.
+    ///
+    /// This hash table provides the IDs of all selectors, and the associated
+    /// instance and factory methods.
+    void *SelectorLookupTable;
+
+    /// \brief A pointer to the character data that comprises the selector table
+    ///
+    /// The SelectorOffsets table refers into this memory.
+    const unsigned char *SelectorLookupTableData;
+
+    /// \brief Offsets into the method pool lookup table's data array
+    /// where each selector resides.
+    const uint32_t *SelectorOffsets;
+
+    /// \brief The number of selectors new to this file.
+    ///
+    /// This is the number of entries in SelectorOffsets.
+    unsigned LocalNumSelectors;
+  };
+
+  /// \brief The chain of AST files. The first entry is the one named by the
+  /// user, the last one is the one that doesn't depend on anything further.
+  /// That is, the entry I was created with -include-pch I+1.
+  llvm::SmallVector<PerFileData*, 2> Chain;
+
+  /// \brief Types that have already been loaded from the chain.
+  ///
+  /// When the pointer at index I is non-NULL, the type with
+  /// ID = (I + 1) << FastQual::Width has already been loaded
+  std::vector<QualType> TypesLoaded;
+
+  /// \brief Map that provides the ID numbers of each type within the
+  /// output stream, plus those deserialized from a chained PCH.
+  ///
+  /// 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.
+  serialization::TypeIdxMap TypeIdxs;
+
+  /// \brief Declarations that have already been loaded from the chain.
+  ///
+  /// 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<serialization::DeclID,
+                         std::pair<PerFileData *, uint64_t> >
+      DeclReplacementMap;
+  /// \brief Declarations that have been replaced in a later file in the chain.
+  DeclReplacementMap ReplacedDecls;
+
+  /// \brief Information about the contents of a DeclContext.
+  struct DeclContextInfo {
+    void *NameLookupTableData; // a ASTDeclContextNameLookupTable.
+    const serialization::DeclID *LexicalDecls;
+    unsigned NumLexicalDecls;
+  };
+  // In a full chain, there could be multiple updates to every decl context,
+  // so this is a vector. However, typically a chain is only two elements long,
+  // with only one file containing updates, so there will be only one update
+  // per decl context.
+  typedef llvm::SmallVector<DeclContextInfo, 1> DeclContextInfos;
+  typedef llvm::DenseMap<const DeclContext *, DeclContextInfos>
+      DeclContextOffsetsMap;
+  // Updates for visible decls can occur for other contexts than just the
+  // TU, and when we read those update records, the actual context will not
+  // be available yet (unless it's the TU), so have this pending map using the
+  // ID as a key. It will be realized when the context is actually loaded.
+  typedef llvm::SmallVector<void *, 1> DeclContextVisibleUpdates;
+  typedef llvm::DenseMap<serialization::DeclID, DeclContextVisibleUpdates>
+      DeclContextVisibleUpdatesPending;
+
+  /// \brief Offsets of the lexical and visible declarations for each
+  /// DeclContext.
+  DeclContextOffsetsMap DeclContextOffsets;
+
+  /// \brief Updates to the visible declarations of declaration contexts that
+  /// haven't been loaded yet.
+  DeclContextVisibleUpdatesPending PendingVisibleUpdates;
+
+  typedef llvm::DenseMap<serialization::DeclID, serialization::DeclID>
+      FirstLatestDeclIDMap;
+  /// \brief Map of first declarations from a chained PCH that point to the
+  /// most recent declarations in another AST file.
+  FirstLatestDeclIDMap FirstLatestDeclIDs;
+
+  typedef llvm::SmallVector<serialization::DeclID, 4>
+      AdditionalTemplateSpecializations;
+  typedef llvm::DenseMap<serialization::DeclID,
+                         AdditionalTemplateSpecializations>
+      AdditionalTemplateSpecializationsMap;
+
+  /// \brief Additional specializations (including partial) of templates that
+  /// were introduced after the template was serialized.
+  AdditionalTemplateSpecializationsMap AdditionalTemplateSpecializationsPending;
+
+  /// \brief Read the records that describe the contents of declcontexts.
+  bool ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
+                              const std::pair<uint64_t, uint64_t> &Offsets,
+                              DeclContextInfo &Info);
+
+  /// \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 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 The macro definitions we have already loaded.
+  llvm::SmallVector<MacroDefinition *, 16> MacroDefinitionsLoaded;
+
+  /// \name CodeGen-relevant special data
+  /// \brief Fields containing data that is relevant to CodeGen.
+  //@{
+
+  /// \brief The IDs of all declarations that fulfill the criteria of
+  /// "interesting" decls.
+  ///
+  /// This contains the data loaded from all EXTERNAL_DEFINITIONS blocks in the
+  /// chain. The referenced declarations are deserialized and passed to the
+  /// consumer eagerly.
+  llvm::SmallVector<uint64_t, 16> ExternalDefinitions;
+
+  /// \brief The IDs of all tentative definitions stored in the the chain.
+  ///
+  /// Sema keeps track of all tentative definitions in a TU because it has to
+  /// complete them and pass them on to CodeGen. Thus, tentative definitions in
+  /// the PCH chain must be eagerly deserialized.
+  llvm::SmallVector<uint64_t, 16> TentativeDefinitions;
+
+  /// \brief The IDs of all CXXRecordDecls stored in the chain whose VTables are
+  /// used.
+  ///
+  /// CodeGen has to emit VTables for these records, so they have to be eagerly
+  /// deserialized.
+  llvm::SmallVector<uint64_t, 64> VTableUses;
+
+  //@}
+
+  /// \name Diagnostic-relevant special data
+  /// \brief Fields containing data that is used for generating diagnostics
+  //@{
+
+  /// \brief Method selectors used in a @selector expression. Used for
+  /// implementation of -Wselector.
+  llvm::SmallVector<uint64_t, 64> ReferencedSelectorsData;
+
+  /// \brief A snapshot of Sema's unused file-scoped variable tracking, for
+  /// generating warnings.
+  llvm::SmallVector<uint64_t, 16> UnusedFileScopedDecls;
+
+  /// \brief A snapshot of Sema's weak undeclared identifier tracking, for
+  /// generating warnings.
+  llvm::SmallVector<uint64_t, 64> WeakUndeclaredIdentifiers;
+
+  /// \brief The IDs of type aliases for ext_vectors that exist in the chain.
+  ///
+  /// Used by Sema for finding sugared names for ext_vectors in diagnostics.
+  llvm::SmallVector<uint64_t, 4> ExtVectorDecls;
+
+  //@}
+
+  /// \name Sema-relevant special data
+  /// \brief Fields containing data that is used for semantic analysis
+  //@{
+
+  /// \brief The IDs of all locally scoped external decls in the chain.
+  ///
+  /// Sema tracks these to validate that the types are consistent across all
+  /// local external declarations.
+  llvm::SmallVector<uint64_t, 16> LocallyScopedExternalDecls;
+
+  /// \brief A snapshot of the pwnsinf instantiations in the chain.
+  ///
+  /// This record tracks the instantiations that Sema has to perform at the end
+  /// of the TU. It consists of a pair of values for every pending instantiation
+  /// where the first value is the ID of the decl and the second is the
+  /// instantiation location.
+  llvm::SmallVector<uint64_t, 64> PendingInstantiations;
+
+  /// \brief The IDs of all dynamic class declarations in the chain.
+  ///
+  /// Sema tracks these because it checks for the key functions being defined
+  /// at the end of the TU, in which case it directs CodeGen to emit the VTable.
+  llvm::SmallVector<uint64_t, 16> DynamicClasses;
+
+  /// \brief The IDs of the declarations Sema stores directly.
+  ///
+  /// Sema tracks a few important decls, such as namespace std, directly.
+  llvm::SmallVector<uint64_t, 4> SemaDeclRefs;
+
+  /// \brief The IDs of the types ASTContext stores directly.
+  ///
+  /// The AST context tracks a few important types, such as va_list, directly.
+  llvm::SmallVector<uint64_t, 16> SpecialTypes;
+
+  //@}
+
+  /// \brief The original file name that was used to build the primary AST 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 primary
+  /// AST 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 Whether to disable the normal validation performed on precompiled
+  /// headers when they are loaded.
+  bool DisableValidation;
+      
+  /// \brief Mapping from switch-case IDs in the chain to switch-case statements
+  ///
+  /// Statements usually don't have IDs, but switch cases need them, so that the
+  /// switch statement can refer to them.
+  std::map<unsigned, SwitchCase *> SwitchCaseStmts;
+
+  /// \brief Mapping from label statement IDs in the chain to label statements.
+  ///
+  /// Statements usually don't have IDs, but labeled statements need them, so
+  /// that goto statements and address-of-label expressions can refer to them.
+  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 source location entries in the chain.
+  unsigned TotalNumSLocEntries;
+
+  /// \brief The number of statements (and expressions) de-serialized
+  /// from the chain.
+  unsigned NumStatementsRead;
+
+  /// \brief The total number of statements (and expressions) stored
+  /// in the chain.
+  unsigned TotalNumStatements;
+
+  /// \brief The number of macros de-serialized from the chain.
+  unsigned NumMacrosRead;
+
+  /// \brief The total number of macros stored in the chain.
+  unsigned TotalNumMacros;
+
+  /// \brief The number of selectors that have been read.
+  unsigned NumSelectorsRead;
+
+  /// \brief The number of method pool entries that have been read.
+  unsigned NumMethodPoolEntriesRead;
+
+  /// \brief The number of times we have looked up a selector in the method
+  /// pool and not found anything interesting.
+  unsigned NumMethodPoolMisses;
+
+  /// \brief The total number of method pool entries in the selector table.
+  unsigned TotalNumMethodPoolEntries;
+
+  /// Number of lexical decl contexts read/total.
+  unsigned NumLexicalDeclContextsRead, TotalLexicalDeclContexts;
+
+  /// Number of visible decl contexts read/total.
+  unsigned NumVisibleDeclContextsRead, TotalVisibleDeclContexts;
+  
+  /// \brief Number of Decl/types that are currently deserializing.
+  unsigned NumCurrentElementsDeserializing;
+
+  /// \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 AST 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 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.
+  std::deque<Decl *> InterestingDecls;
+
+  /// \brief When reading a Stmt tree, Stmt operands are placed in this stack.
+  llvm::SmallVector<Stmt *, 16> StmtStack;
+
+  /// \brief What kind of records we are reading.
+  enum ReadingKind {
+    Read_Decl, Read_Type, Read_Stmt
+  };
+
+  /// \brief What kind of records we are reading. 
+  ReadingKind ReadingKind;
+
+  /// \brief RAII object to change the reading kind.
+  class ReadingKindTracker {
+    ASTReader &Reader;
+    enum ReadingKind PrevKind;
+
+    ReadingKindTracker(const ReadingKindTracker&); // do not implement
+    ReadingKindTracker &operator=(const ReadingKindTracker&);// do not implement
+
+  public:
+    ReadingKindTracker(enum ReadingKind newKind, ASTReader &reader)
+      : Reader(reader), PrevKind(Reader.ReadingKind) {
+      Reader.ReadingKind = newKind;
+    }
+
+    ~ReadingKindTracker() { Reader.ReadingKind = PrevKind; }
+  };
+
+  /// \brief All predefines buffers in the chain, to be treated as if
+  /// concatenated.
+  PCHPredefinesBlocks PCHPredefinesBuffers;
+
+  /// \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;
+
+  /// \brief Reads a statement from the specified cursor.
+  Stmt *ReadStmtFromStream(llvm::BitstreamCursor &Cursor);
+
+  void MaybeAddSystemRootToFilename(std::string &Filename);
+
+  ASTReadResult ReadASTCore(llvm::StringRef FileName);
+  ASTReadResult ReadASTBlock(PerFileData &F);
+  bool CheckPredefinesBuffers();
+  bool ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record);
+  ASTReadResult ReadSourceManagerBlock(PerFileData &F);
+  ASTReadResult ReadSLocEntryRecord(unsigned ID);
+  llvm::BitstreamCursor &SLocCursorForID(unsigned ID);
+  bool ParseLanguageOptions(const llvm::SmallVectorImpl<uint64_t> &Record);
+
+  typedef std::pair<llvm::BitstreamCursor *, uint64_t> RecordLocation;
+
+  QualType ReadTypeRecord(unsigned Index);
+  RecordLocation TypeCursorForIndex(unsigned Index);
+  void LoadedDecl(unsigned Index, Decl *D);
+  Decl *ReadDeclRecord(unsigned Index, serialization::DeclID ID);
+  RecordLocation DeclCursorForIndex(unsigned Index, serialization::DeclID ID);
+
+  void PassInterestingDeclsToConsumer();
+
+  /// \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 AST file).
+  void Error(const char *Msg);
+
+  ASTReader(const ASTReader&); // do not implement
+  ASTReader &operator=(const ASTReader &); // do not implement
+public:
+  typedef llvm::SmallVector<uint64_t, 64> RecordData;
+
+  /// \brief Load the AST 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 "/".
+  ///
+  /// \param DisableValidation If true, the AST reader will suppress most
+  /// of its regular consistency checking, allowing the use of precompiled
+  /// headers that cannot be determined to be compatible.
+  ASTReader(Preprocessor &PP, ASTContext *Context, const char *isysroot = 0,
+            bool DisableValidation = false);
+
+  /// \brief Load the AST file without using any pre-initialized Preprocessor.
+  ///
+  /// The necessary information to initialize a Preprocessor later can be
+  /// obtained by setting a ASTReaderListener.
+  ///
+  /// \param SourceMgr the source manager into which the AST file will be loaded
+  ///
+  /// \param FileMgr the file manager into which the AST file will be loaded.
+  ///
+  /// \param Diags the diagnostics system to use for reporting errors and
+  /// warnings relevant to loading the AST file.
+  ///
+  /// \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 "/".
+  ///
+  /// \param DisableValidation If true, the AST reader will suppress most
+  /// of its regular consistency checking, allowing the use of precompiled
+  /// headers that cannot be determined to be compatible.
+      ASTReader(SourceManager &SourceMgr, FileManager &FileMgr,
+            Diagnostic &Diags, const char *isysroot = 0,
+            bool DisableValidation = false);
+  ~ASTReader();
+
+  /// \brief Load the precompiled header designated by the given file
+  /// name.
+  ASTReadResult ReadAST(const std::string &FileName);
+
+  /// \brief Set the AST callbacks listener.
+  void setListener(ASTReaderListener *listener) {
+    Listener.reset(listener);
+  }
+
+  /// \brief Set the AST deserialization listener.
+  void setDeserializationListener(ASTDeserializationListener *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 named (primary) AST file
+  const std::string &getFileName() const { return Chain[0]->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 AST file, without actually loading the AST file.
+  static std::string getOriginalSourceFile(const std::string &ASTFileName,
+                                           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 Returns the number of source locations found in the chain.
+  unsigned getTotalNumSLocs() const {
+    return TotalNumSLocEntries;
+  }
+
+  /// \brief Returns the number of identifiers found in the chain.
+  unsigned getTotalNumIdentifiers() const {
+    return static_cast<unsigned>(IdentifiersLoaded.size());
+  }
+
+  /// \brief Returns the number of types found in the chain.
+  unsigned getTotalNumTypes() const {
+    return static_cast<unsigned>(TypesLoaded.size());
+  }
+
+  /// \brief Returns the number of declarations found in the chain.
+  unsigned getTotalNumDecls() const {
+    return static_cast<unsigned>(DeclsLoaded.size());
+  }
+
+  /// \brief Returns the number of selectors found in the chain.
+  unsigned getTotalNumSelectors() const {
+    return static_cast<unsigned>(SelectorsLoaded.size());
+  }
+
+  /// \brief Reads a TemplateArgumentLocInfo appropriate for the
+  /// given TemplateArgument kind.
+  TemplateArgumentLocInfo
+  GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
+                             llvm::BitstreamCursor &DeclsCursor,
+                             const RecordData &Record, unsigned &Idx);
+
+  /// \brief Reads a TemplateArgumentLoc.
+  TemplateArgumentLoc
+  ReadTemplateArgumentLoc(llvm::BitstreamCursor &DeclsCursor,
+                          const RecordData &Record, unsigned &Idx);
+
+  /// \brief Reads a declarator info from the given record.
+  TypeSourceInfo *GetTypeSourceInfo(llvm::BitstreamCursor &DeclsCursor,
+                                    const RecordData &Record, unsigned &Idx);
+
+  /// \brief Resolve and return the translation unit declaration.
+  TranslationUnitDecl *GetTranslationUnitDecl();
+
+  /// \brief Resolve a type ID into a type, potentially building a new
+  /// type.
+  QualType GetType(serialization::TypeID ID);
+
+  /// \brief Returns the type ID associated with the given type.
+  /// If the type didn't come from the AST file the ID that is returned is
+  /// marked as "doesn't exist in AST".
+  serialization::TypeID GetTypeID(QualType T) const;
+
+  /// \brief Returns the type index associated with the given type.
+  /// If the type didn't come from the AST file the index that is returned is
+  /// marked as "doesn't exist in AST".
+  serialization::TypeIdx GetTypeIdx(QualType T) const;
+
+  /// \brief Resolve a declaration ID into a declaration, potentially
+  /// building a new declaration.
+  Decl *GetDecl(serialization::DeclID ID);
+  virtual Decl *GetExternalDecl(uint32_t 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 *GetExternalDeclStmt(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 Finds all the visible declarations with a given name.
+  /// The current implementation of this method just loads the entire
+  /// lookup table as unmaterialized references.
+  virtual DeclContext::lookup_result
+  FindExternalVisibleDeclsByName(const DeclContext *DC,
+                                 DeclarationName Name);
+
+  virtual void MaterializeVisibleDecls(const DeclContext *DC);
+
+  /// \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 FindExternalLexicalDecls(const DeclContext *DC,
+                                        llvm::SmallVectorImpl<Decl*> &Decls);
+
+  /// \brief Notify ASTReader that we started deserialization of
+  /// a decl or type so until FinishedDeserializing is called there may be
+  /// decls that are initializing. Must be paired with FinishedDeserializing.
+  virtual void StartedDeserializing() { ++NumCurrentElementsDeserializing; }
+
+  /// \brief Notify ASTReader that we finished the deserialization of
+  /// a decl or type. Must be paired with StartedDeserializing.
+  virtual void FinishedDeserializing();
+
+  /// \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 AST 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);
+
+  /// \brief Load a selector from disk, registering its ID if it exists.
+  void LoadSelector(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 GetExternalSelector(uint32_t ID);
+  uint32_t GetNumExternalSelectors();
+
+  Selector GetSelector(const RecordData &Record, unsigned &Idx) {
+    return DecodeSelector(Record[Idx++]);
+  }
+
+  /// \brief Read a declaration name.
+  DeclarationName ReadDeclarationName(const RecordData &Record, unsigned &Idx);
+
+  NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record,
+                                               unsigned &Idx);
+
+  /// \brief Read a template name.
+  TemplateName ReadTemplateName(const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read a template argument.
+  TemplateArgument ReadTemplateArgument(llvm::BitstreamCursor &DeclsCursor,
+                                        const RecordData &Record,unsigned &Idx);
+  
+  /// \brief Read a template parameter list.
+  TemplateParameterList *ReadTemplateParameterList(const RecordData &Record,
+                                                   unsigned &Idx);
+  
+  /// \brief Read a template argument array.
+  void
+  ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs,
+                           llvm::BitstreamCursor &DeclsCursor,
+                           const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read a UnresolvedSet structure.
+  void ReadUnresolvedSet(UnresolvedSetImpl &Set,
+                         const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read a C++ base specifier.
+  CXXBaseSpecifier ReadCXXBaseSpecifier(llvm::BitstreamCursor &DeclsCursor,
+                                        const RecordData &Record,unsigned &Idx);
+
+  /// \brief Read a CXXBaseOrMemberInitializer array.
+  std::pair<CXXBaseOrMemberInitializer **, unsigned>
+  ReadCXXBaseOrMemberInitializers(llvm::BitstreamCursor &DeclsCursor,
+                                  const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read a source location.
+  SourceLocation ReadSourceLocation(const RecordData &Record, unsigned& Idx) {
+    return SourceLocation::getFromRawEncoding(Record[Idx++]);
+  }
+
+  /// \brief Read a source range.
+  SourceRange ReadSourceRange(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);
+
+  CXXTemporary *ReadCXXTemporary(const RecordData &Record, unsigned &Idx);
+      
+  /// \brief Reads attributes from the current stream position.
+  void ReadAttributes(llvm::BitstreamCursor &DeclsCursor, AttrVec &Attrs);
+
+  /// \brief Reads a statement.
+  Stmt *ReadStmt(llvm::BitstreamCursor &Cursor);
+
+  /// \brief Reads an expression.
+  Expr *ReadExpr(llvm::BitstreamCursor &Cursor);
+
+  /// \brief Reads a sub-statement operand during statement reading.
+  Stmt *ReadSubStmt() {
+    assert(ReadingKind == Read_Stmt &&
+           "Should be called only during statement reading!");
+    // Subexpressions are stored from last to first, so the next Stmt we need
+    // is at the back of the stack.
+    assert(!StmtStack.empty() && "Read too many sub statements!");
+    return StmtStack.pop_back_val();
+  }
+
+  /// \brief Reads a sub-expression operand during statement reading.
+  Expr *ReadSubExpr();
+
+  /// \brief Reads the macro record located at the given offset.
+  void ReadMacroRecord(llvm::BitstreamCursor &Stream, 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(serialization::IdentID ID);
+
+  /// \brief Retrieve the AST context that this AST 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 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/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
new file mode 100644
index 0000000..b8bff27
--- /dev/null
+++ b/include/clang/Serialization/ASTWriter.h
@@ -0,0 +1,513 @@
+//===--- ASTWriter.h - AST File 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 ASTWriter class, which writes an AST file
+//  containing a serialized representation of a translation unit.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_FRONTEND_AST_WRITER_H
+#define LLVM_CLANG_FRONTEND_AST_WRITER_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/Serialization/ASTBitCodes.h"
+#include "clang/Serialization/ASTDeserializationListener.h"
+#include "clang/Sema/SemaConsumer.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include <map>
+#include <queue>
+#include <vector>
+
+namespace llvm {
+  class APFloat;
+  class APInt;
+  class BitstreamWriter;
+}
+
+namespace clang {
+
+class ASTContext;
+class NestedNameSpecifier;
+class CXXBaseSpecifier;
+class CXXBaseOrMemberInitializer;
+class LabelStmt;
+class MacroDefinition;
+class MemorizeStatCalls;
+class ASTReader;
+class Preprocessor;
+class Sema;
+class SourceManager;
+class SwitchCase;
+class TargetInfo;
+
+/// \brief Writes an AST file containing the contents of a translation unit.
+///
+/// The ASTWriter 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 ASTReader class.
+class ASTWriter : public ASTDeserializationListener {
+public:
+  typedef llvm::SmallVector<uint64_t, 64> RecordData;
+
+  friend class ASTDeclWriter;
+private:
+  /// \brief The bitstream writer used to emit this precompiled header.
+  llvm::BitstreamWriter &Stream;
+
+  /// \brief The reader of existing AST files, if we're chaining.
+  ASTReader *Chain;
+
+  /// \brief Stores a declaration or a type to be written to the AST 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 The first ID number we can use for our own declarations.
+  serialization::DeclID FirstDeclID;
+
+  /// \brief The decl ID that will be assigned to the next new decl.
+  serialization::DeclID NextDeclID;
+
+  /// \brief Map that provides the ID numbers of each declaration within
+  /// the output stream, as well as those deserialized from a chained PCH.
+  ///
+  /// 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 *, serialization::DeclID> DeclIDs;
+
+  /// \brief Offset of each declaration in the bitstream, indexed by
+  /// the declaration's ID.
+  std::vector<uint32_t> DeclOffsets;
+
+  /// \brief The first ID number we can use for our own types.
+  serialization::TypeID FirstTypeID;
+
+  /// \brief The type ID that will be assigned to the next new type.
+  serialization::TypeID NextTypeID;
+
+  /// \brief Map that provides the ID numbers of each type within the
+  /// output stream, plus those deserialized from a chained PCH.
+  ///
+  /// 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.
+  serialization::TypeIdxMap TypeIdxs;
+
+  /// \brief Offset of each type in the bitstream, indexed by
+  /// the type's ID.
+  std::vector<uint32_t> TypeOffsets;
+
+  /// \brief The first ID number we can use for our own identifiers.
+  serialization::IdentID FirstIdentID;
+
+  /// \brief The identifier ID that will be assigned to the next new identifier.
+  serialization::IdentID NextIdentID;
+
+  /// \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 *, serialization::IdentID> IdentifierIDs;
+
+  /// \brief Offsets of each of the identifier IDs into the identifier
+  /// table.
+  std::vector<uint32_t> IdentifierOffsets;
+
+  /// \brief The first ID number we can use for our own selectors.
+  serialization::SelectorID FirstSelectorID;
+
+  /// \brief The selector ID that will be assigned to the next new identifier.
+  serialization::SelectorID NextSelectorID;
+
+  /// \brief Map that provides the ID numbers of each Selector.
+  llvm::DenseMap<Selector, serialization::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 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 *, serialization::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;
+
+  typedef llvm::DenseMap<Decl *, Decl *> FirstLatestDeclMap;
+  /// \brief Map of first declarations from a chained PCH that point to the
+  /// most recent declarations in another PCH.
+  FirstLatestDeclMap FirstLatestDecls;
+  
+  /// \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 AST
+  /// file. The AST file contains a separate record for these external
+  /// definitions, which are provided to the AST consumer by the AST
+  /// 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 Namespaces that have received extensions since their serialized
+  /// form.
+  ///
+  /// Basically, when we're chaining and encountering a namespace, we check if
+  /// its primary namespace comes from the chain. If it does, we add the primary
+  /// to this set, so that we can write out lexical content updates for it.
+  llvm::SmallPtrSet<const NamespaceDecl *, 16> UpdatedNamespaces;
+
+  /// \brief Decls that have been replaced in the current dependent AST file.
+  ///
+  /// When a decl changes fundamentally after being deserialized (this shouldn't
+  /// happen, but the ObjC AST nodes are designed this way), it will be
+  /// serialized again. In this case, it is registered here, so that the reader
+  /// knows to read the updated version.
+  llvm::SmallVector<std::pair<serialization::DeclID, uint64_t>, 16>
+      ReplacedDecls;
+
+  typedef llvm::SmallVector<serialization::DeclID, 4>
+      AdditionalTemplateSpecializationsList;
+  typedef llvm::DenseMap<serialization::DeclID,
+                         AdditionalTemplateSpecializationsList>
+      AdditionalTemplateSpecializationsMap;
+
+  /// \brief Additional specializations (including partial) of templates that
+  /// were introduced after the template was serialized.
+  AdditionalTemplateSpecializationsMap AdditionalTemplateSpecializations;
+
+  /// \brief Statements that we've encountered while serializing a
+  /// declaration or type.
+  llvm::SmallVector<Stmt *, 16> StmtsToEmit;
+
+  /// \brief Statements collection to use for ASTWriter::AddStmt().
+  /// It will point to StmtsToEmit unless it is overriden. 
+  llvm::SmallVector<Stmt *, 16> *CollectedStmts;
+
+  /// \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 AST file.
+  unsigned NumStatements;
+
+  /// \brief The number of macros written to the AST file.
+  unsigned NumMacros;
+
+  /// \brief The number of lexical declcontexts written to the AST
+  /// file.
+  unsigned NumLexicalDeclContexts;
+
+  /// \brief The number of visible declcontexts written to the AST
+  /// file.
+  unsigned NumVisibleDeclContexts;
+
+  /// \brief Write the given subexpression to the bitstream.
+  void WriteSubStmt(Stmt *S);
+
+  void WriteBlockInfoBlock();
+  void WriteMetadata(ASTContext &Context, const char *isysroot);
+  void WriteLanguageOptions(const LangOptions &LangOpts);
+  void WriteStatCache(MemorizeStatCalls &StatCalls);
+  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 WriteTypeDeclOffsets();
+  void WriteSelectors(Sema &SemaRef);
+  void WriteReferencedSelectorsPool(Sema &SemaRef);
+  void WriteIdentifierTable(Preprocessor &PP);
+  void WriteAttributeRecord(const AttrVec &Attrs);
+  void WriteDeclUpdateBlock();
+  void WriteDeclContextVisibleUpdate(const DeclContext *DC);
+  void WriteAdditionalTemplateSpecializations();
+
+  unsigned ParmVarDeclAbbrev;
+  unsigned DeclContextLexicalAbbrev;
+  unsigned DeclContextVisibleLookupAbbrev;
+  unsigned UpdateVisibleAbbrev;
+  void WriteDeclsBlockAbbrevs();
+  void WriteDecl(ASTContext &Context, Decl *D);
+
+  void WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+                    const char* isysroot);
+  void WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+                     const char* isysroot);
+  
+public:
+  /// \brief Create a new precompiled header writer that outputs to
+  /// the given bitstream.
+  ASTWriter(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 WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+                const char* isysroot);
+
+  /// \brief Emit a source location.
+  void AddSourceLocation(SourceLocation Loc, RecordData &Record);
+
+  /// \brief Emit a source range.
+  void AddSourceRange(SourceRange Range, 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(Selector, RecordData &Record);
+
+  /// \brief Emit a CXXTemporary.
+  void AddCXXTemporary(const CXXTemporary *Temp, RecordData &Record);
+
+  /// \brief Get the unique number used to refer to the given selector.
+  serialization::SelectorID getSelectorRef(Selector Sel);
+  
+  /// \brief Get the unique number used to refer to the given identifier.
+  serialization::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.
+  serialization::IdentID getMacroDefinitionID(MacroDefinition *MD);
+  
+  /// \brief Emit a reference to a type.
+  void AddTypeRef(QualType T, RecordData &Record);
+
+  /// \brief Force a type to be emitted and get its ID.
+  serialization::TypeID GetOrCreateTypeID(QualType T);
+
+  /// \brief Determine the type ID of an already-emitted type.
+  serialization::TypeID getTypeID(QualType T) const;
+
+  /// \brief Force a type to be emitted and get its index.
+  serialization::TypeIdx GetOrCreateTypeIdx(QualType T);
+
+  /// \brief Determine the type index of an already-emitted type.
+  serialization::TypeIdx getTypeIdx(QualType T) const;
+
+  /// \brief Emits a reference to a declarator info.
+  void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordData &Record);
+
+  /// \brief Emits a template argument location info.
+  void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
+                                  const TemplateArgumentLocInfo &Arg,
+                                  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 Force a declaration to be emitted and get its ID.
+  serialization::DeclID GetDeclRef(const Decl *D);
+
+  /// \brief Determine the declaration ID of an already-emitted
+  /// declaration.
+  serialization::DeclID getDeclID(const Decl *D);
+
+  /// \brief Emit a declaration name.
+  void AddDeclarationName(DeclarationName Name, RecordData &Record);
+
+  /// \brief Emit a nested name specifier.
+  void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordData &Record);
+  
+  /// \brief Emit a template name.
+  void AddTemplateName(TemplateName Name, RecordData &Record);
+
+  /// \brief Emit a template argument.
+  void AddTemplateArgument(const TemplateArgument &Arg, RecordData &Record);
+
+  /// \brief Emit a template parameter list.
+  void AddTemplateParameterList(const TemplateParameterList *TemplateParams,
+                                RecordData &Record);
+
+  /// \brief Emit a template argument list.
+  void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs,
+                                RecordData &Record);
+
+  /// \brief Emit a UnresolvedSet structure.
+  void AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordData &Record);
+
+  /// \brief Emit a C++ base specifier.
+  void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, RecordData &Record);
+
+  /// \brief Emit a CXXBaseOrMemberInitializer array.
+  void AddCXXBaseOrMemberInitializers(
+                        const CXXBaseOrMemberInitializer * const *BaseOrMembers,
+                        unsigned NumBaseOrMembers, RecordData &Record);
+
+  /// \brief Add a string to the given record.
+  void AddString(const std::string &Str, RecordData &Record);
+
+  /// \brief Mark a namespace as needing an update.
+  void AddUpdatedNamespace(const NamespaceDecl *NS) {
+    UpdatedNamespaces.insert(NS);
+  }
+
+  /// \brief Record a template specialization or partial specialization of
+  /// a template from a previous PCH file.
+  void AddAdditionalTemplateSpecialization(serialization::DeclID Templ,
+                                           serialization::DeclID Spec) {
+    AdditionalTemplateSpecializations[Templ].push_back(Spec);
+  }
+
+  /// \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) {
+      CollectedStmts->push_back(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; }
+
+  bool hasChain() const { return Chain; }
+
+  // ASTDeserializationListener implementation
+  void SetReader(ASTReader *Reader);
+  void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II);
+  void TypeRead(serialization::TypeIdx Idx, QualType T);
+  void DeclRead(serialization::DeclID ID, const Decl *D);
+  void SelectorRead(serialization::SelectorID iD, Selector Sel);
+};
+
+/// \brief AST and semantic-analysis consumer that generates a
+/// precompiled header from the parsed source code.
+class PCHGenerator : public SemaConsumer {
+  const Preprocessor &PP;
+  const char *isysroot;
+  llvm::raw_ostream *Out;
+  Sema *SemaPtr;
+  MemorizeStatCalls *StatCalls; // owned by the FileManager
+  std::vector<unsigned char> Buffer;
+  llvm::BitstreamWriter Stream;
+  ASTWriter Writer;
+
+protected:
+  ASTWriter &getWriter() { return Writer; }
+  const ASTWriter &getWriter() const { return Writer; }
+
+public:
+  PCHGenerator(const Preprocessor &PP, bool Chaining,
+               const char *isysroot, llvm::raw_ostream *Out);
+  virtual void InitializeSema(Sema &S) { SemaPtr = &S; }
+  virtual void HandleTranslationUnit(ASTContext &Ctx);
+  virtual ASTDeserializationListener *GetASTDeserializationListener();
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Serialization/CMakeLists.txt b/include/clang/Serialization/CMakeLists.txt
new file mode 100644
index 0000000..3712009
--- /dev/null
+++ b/include/clang/Serialization/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(LLVM_TARGET_DEFINITIONS ../Basic/Attr.td)
+tablegen(AttrPCHRead.inc
+         -gen-clang-attr-pch-read
+         -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrPCHRead
+  DEPENDS AttrPCHRead.inc)
+
+tablegen(AttrPCHWrite.inc
+         -gen-clang-attr-pch-write
+         -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrPCHWrite
+  DEPENDS AttrPCHWrite.inc)
diff --git a/include/clang/Serialization/Makefile b/include/clang/Serialization/Makefile
new file mode 100644
index 0000000..79486b1
--- /dev/null
+++ b/include/clang/Serialization/Makefile
@@ -0,0 +1,19 @@
+CLANG_LEVEL := ../../..
+TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
+BUILT_SOURCES = AttrPCHRead.inc AttrPCHWrite.inc
+
+TABLEGEN_INC_FILES_COMMON = 1
+
+include $(CLANG_LEVEL)/Makefile
+
+$(ObjDir)/AttrPCHRead.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \
+                              $(ObjDir)/.dir
+	$(Echo) "Building Clang PCH reader with tblgen"
+	$(Verb) $(TableGen) -gen-clang-attr-pch-read -o $(call SYSPATH, $@) \
+		-I $(PROJ_SRC_DIR)/../../ $<
+
+$(ObjDir)/AttrPCHWrite.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \
+                              $(ObjDir)/.dir
+	$(Echo) "Building Clang PCH writer with tblgen"
+	$(Verb) $(TableGen) -gen-clang-attr-pch-write -o $(call SYSPATH, $@) \
+		-I $(PROJ_SRC_DIR)/../../ $<
diff --git a/lib/AST/ASTConsumer.cpp b/lib/AST/ASTConsumer.cpp
index f37cbde..04a084a 100644
--- a/lib/AST/ASTConsumer.cpp
+++ b/lib/AST/ASTConsumer.cpp
@@ -17,3 +17,6 @@
 
 void ASTConsumer::HandleTopLevelDecl(DeclGroupRef D) {}
 
+void ASTConsumer::HandleInterestingDecl(DeclGroupRef D) {
+  HandleTopLevelDecl(D);
+}
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 165105b..749c9db 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExternalASTSource.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/Basic/Builtins.h"
@@ -27,30 +28,149 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
-#include "RecordLayoutBuilder.h"
+#include "CXXABI.h"
 
 using namespace clang;
 
+unsigned ASTContext::NumImplicitDefaultConstructors;
+unsigned ASTContext::NumImplicitDefaultConstructorsDeclared;
+unsigned ASTContext::NumImplicitCopyConstructors;
+unsigned ASTContext::NumImplicitCopyConstructorsDeclared;
+unsigned ASTContext::NumImplicitCopyAssignmentOperators;
+unsigned ASTContext::NumImplicitCopyAssignmentOperatorsDeclared;
+unsigned ASTContext::NumImplicitDestructors;
+unsigned ASTContext::NumImplicitDestructorsDeclared;
+
 enum FloatingRank {
   FloatRank, DoubleRank, LongDoubleRank
 };
 
+void 
+ASTContext::CanonicalTemplateTemplateParm::Profile(llvm::FoldingSetNodeID &ID, 
+                                               TemplateTemplateParmDecl *Parm) {
+  ID.AddInteger(Parm->getDepth());
+  ID.AddInteger(Parm->getPosition());
+  // FIXME: Parameter pack
+
+  TemplateParameterList *Params = Parm->getTemplateParameters();
+  ID.AddInteger(Params->size());
+  for (TemplateParameterList::const_iterator P = Params->begin(), 
+                                          PEnd = Params->end();
+       P != PEnd; ++P) {
+    if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
+      ID.AddInteger(0);
+      ID.AddBoolean(TTP->isParameterPack());
+      continue;
+    }
+    
+    if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
+      ID.AddInteger(1);
+      // FIXME: Parameter pack
+      ID.AddPointer(NTTP->getType().getAsOpaquePtr());
+      continue;
+    }
+    
+    TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
+    ID.AddInteger(2);
+    Profile(ID, TTP);
+  }
+}
+
+TemplateTemplateParmDecl *
+ASTContext::getCanonicalTemplateTemplateParmDecl(
+                                                 TemplateTemplateParmDecl *TTP) {
+  // Check if we already have a canonical template template parameter.
+  llvm::FoldingSetNodeID ID;
+  CanonicalTemplateTemplateParm::Profile(ID, TTP);
+  void *InsertPos = 0;
+  CanonicalTemplateTemplateParm *Canonical
+    = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos);
+  if (Canonical)
+    return Canonical->getParam();
+  
+  // Build a canonical template parameter list.
+  TemplateParameterList *Params = TTP->getTemplateParameters();
+  llvm::SmallVector<NamedDecl *, 4> CanonParams;
+  CanonParams.reserve(Params->size());
+  for (TemplateParameterList::const_iterator P = Params->begin(), 
+                                          PEnd = Params->end();
+       P != PEnd; ++P) {
+    if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P))
+      CanonParams.push_back(
+                  TemplateTypeParmDecl::Create(*this, getTranslationUnitDecl(), 
+                                               SourceLocation(), TTP->getDepth(),
+                                               TTP->getIndex(), 0, false,
+                                               TTP->isParameterPack()));
+    else if (NonTypeTemplateParmDecl *NTTP
+             = dyn_cast<NonTypeTemplateParmDecl>(*P))
+      CanonParams.push_back(
+            NonTypeTemplateParmDecl::Create(*this, getTranslationUnitDecl(),
+                                            SourceLocation(), NTTP->getDepth(),
+                                            NTTP->getPosition(), 0, 
+                                            getCanonicalType(NTTP->getType()),
+                                            0));
+    else
+      CanonParams.push_back(getCanonicalTemplateTemplateParmDecl(
+                                           cast<TemplateTemplateParmDecl>(*P)));
+  }
+
+  TemplateTemplateParmDecl *CanonTTP
+    = TemplateTemplateParmDecl::Create(*this, getTranslationUnitDecl(), 
+                                       SourceLocation(), TTP->getDepth(),
+                                       TTP->getPosition(), 0,
+                         TemplateParameterList::Create(*this, SourceLocation(),
+                                                       SourceLocation(),
+                                                       CanonParams.data(),
+                                                       CanonParams.size(),
+                                                       SourceLocation()));
+
+  // Get the new insert position for the node we care about.
+  Canonical = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos);
+  assert(Canonical == 0 && "Shouldn't be in the map!");
+  (void)Canonical;
+
+  // Create the canonical template template parameter entry.
+  Canonical = new (*this) CanonicalTemplateTemplateParm(CanonTTP);
+  CanonTemplateTemplateParms.InsertNode(Canonical, InsertPos);
+  return CanonTTP;
+}
+
+CXXABI *ASTContext::createCXXABI(const TargetInfo &T) {
+  if (!LangOpts.CPlusPlus) return 0;
+
+  switch (T.getCXXABI()) {
+  case CXXABI_ARM:
+    return CreateARMCXXABI(*this);
+  case CXXABI_Itanium:
+    return CreateItaniumCXXABI(*this);
+  case CXXABI_Microsoft:
+    return CreateMicrosoftCXXABI(*this);
+  }
+  return 0;
+}
+
 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),
+                       unsigned size_reserve) :
+  TemplateSpecializationTypes(this_()),
+  DependentTemplateSpecializationTypes(this_()),
+  GlobalNestedNameSpecifier(0), IsInt128Installed(false),
+  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),
+  NullTypeSourceInfo(QualType()),
+  SourceMgr(SM), LangOpts(LOpts), ABI(createCXXABI(t)), Target(t),
   Idents(idents), Selectors(sels),
-  BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts),
-  LastSDM(0, 0) {
+  BuiltinInfo(builtins),
+  DeclarationNames(*this),
+  ExternalSource(0), PrintingPolicy(LOpts),
+  LastSDM(0, 0),
+  UniqueBlockByRefTypeID(0), UniqueBlockParmTypeID(0) {
   ObjCIdRedefinitionType = QualType();
   ObjCClassRedefinitionType = QualType();
-  ObjCSelRedefinitionType = QualType();
+  ObjCSelRedefinitionType = QualType();    
   if (size_reserve > 0) Types.reserve(size_reserve);
   TUDecl = TranslationUnitDecl::Create(*this);
   InitBuiltinTypes();
@@ -61,54 +181,35 @@
   // FIXME: Is this the ideal solution?
   ReleaseDeclContextMaps();
 
+  // Call all of the deallocation functions.
+  for (unsigned I = 0, N = Deallocations.size(); I != N; ++I)
+    Deallocations[I].first(Deallocations[I].second);
+  
   // 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; ) {
+  // ASTRecordLayout objects in ASTRecordLayouts must always be destroyed
+  // because they can contain DenseMaps.
+  for (llvm::DenseMap<const ObjCContainerDecl*,
+       const ASTRecordLayout*>::iterator
+       I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; )
     // Increment in loop to prevent using deallocated memory.
-    (*NNS++).Destroy(*this);
+    if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second))
+      R->Destroy(*this);
+
+  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);
+  }
   }
 
-  if (GlobalNestedNameSpecifier)
-    GlobalNestedNameSpecifier->Destroy(*this);
-
-  TUDecl->Destroy(*this);
+void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
+  Deallocations.push_back(std::make_pair(Callback, Data));
 }
 
 void
@@ -143,11 +244,26 @@
 #include "clang/AST/TypeNodes.def"
 
   fprintf(stderr, "Total bytes = %d\n", int(TotalBytes));
-
+  
+  // Implicit special member functions.
+  fprintf(stderr, "  %u/%u implicit default constructors created\n",
+          NumImplicitDefaultConstructorsDeclared, 
+          NumImplicitDefaultConstructors);
+  fprintf(stderr, "  %u/%u implicit copy constructors created\n",
+          NumImplicitCopyConstructorsDeclared, 
+          NumImplicitCopyConstructors);
+  fprintf(stderr, "  %u/%u implicit copy assignment operators created\n",
+          NumImplicitCopyAssignmentOperatorsDeclared, 
+          NumImplicitCopyAssignmentOperators);
+  fprintf(stderr, "  %u/%u implicit destructors created\n",
+          NumImplicitDestructorsDeclared, NumImplicitDestructors);
+  
   if (ExternalSource.get()) {
     fprintf(stderr, "\n");
     ExternalSource->PrintStats();
   }
+  
+  BumpAlloc.PrintStats();
 }
 
 
@@ -261,13 +377,14 @@
 
 void
 ASTContext::setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
-                                                TemplateSpecializationKind TSK) {
+                                                TemplateSpecializationKind TSK,
+                                          SourceLocation PointOfInstantiation) {
   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);
+    = new (*this) MemberSpecializationInfo(Tmpl, TSK, PointOfInstantiation);
 }
 
 NamedDecl *
@@ -346,25 +463,21 @@
   return Pos->second.end();
 }
 
+unsigned
+ASTContext::overridden_methods_size(const CXXMethodDecl *Method) const {
+  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos
+    = OverriddenMethods.find(Method);
+  if (Pos == OverriddenMethods.end())
+    return 0;
+
+  return Pos->second.size();
+}
+
 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
 //===----------------------------------------------------------------------===//
@@ -390,8 +503,7 @@
 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());
+  Align = std::max(Align, D->getMaxAlignment());
 
   if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
     QualType T = VD->getType();
@@ -402,6 +514,15 @@
         T = getPointerType(RT->getPointeeType());
     }
     if (!T->isIncompleteType() && !T->isFunctionType()) {
+      unsigned MinWidth = Target.getLargeArrayMinWidth();
+      unsigned ArrayAlign = Target.getLargeArrayAlign();
+      if (isa<VariableArrayType>(T) && MinWidth != 0)
+        Align = std::max(Align, ArrayAlign);
+      if (ConstantArrayType *CT = dyn_cast<ConstantArrayType>(T)) {
+        unsigned Size = getTypeSize(CT);
+        if (MinWidth != 0 && MinWidth <= Size)
+          Align = std::max(Align, ArrayAlign);
+      }
       // Incomplete or function types default to 1.
       while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T))
         T = cast<ArrayType>(T)->getElementType();
@@ -419,6 +540,18 @@
   return CharUnits::fromQuantity(Align / Target.getCharWidth());
 }
 
+std::pair<CharUnits, CharUnits>
+ASTContext::getTypeInfoInChars(const Type *T) {
+  std::pair<uint64_t, unsigned> Info = getTypeInfo(T);
+  return std::make_pair(CharUnits::fromQuantity(Info.first / getCharWidth()),
+                        CharUnits::fromQuantity(Info.second / getCharWidth()));
+}
+
+std::pair<CharUnits, CharUnits>
+ASTContext::getTypeInfoInChars(QualType T) {
+  return getTypeInfoInChars(T.getTypePtr());
+}
+
 /// getTypeSize - Return the size of the specified type, in bits.  This method
 /// does not work on incomplete types.
 ///
@@ -547,6 +680,12 @@
       Width = Target.getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t)
       Align = Target.getPointerAlign(0); //   == sizeof(void*)
       break;
+    case BuiltinType::ObjCId:
+    case BuiltinType::ObjCClass:
+    case BuiltinType::ObjCSel:
+      Width = Target.getPointerWidth(0); 
+      Align = Target.getPointerAlign(0);
+      break;
     }
     break;
   case Type::ObjCObjectPointer:
@@ -575,12 +714,10 @@
     break;
   }
   case Type::MemberPointer: {
-    QualType Pointee = cast<MemberPointerType>(T)->getPointeeType();
+    const MemberPointerType *MPT = cast<MemberPointerType>(T);
     std::pair<uint64_t, unsigned> PtrDiffInfo =
       getTypeInfo(getPointerDiffType());
-    Width = PtrDiffInfo.first;
-    if (Pointee->isFunctionType())
-      Width *= 2;
+    Width = PtrDiffInfo.first * ABI->getMemberPointerSize(MPT);
     Align = PtrDiffInfo.second;
     break;
   }
@@ -593,6 +730,8 @@
     Align = EltInfo.second;
     break;
   }
+  case Type::ObjCObject:
+    return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr());
   case Type::ObjCInterface: {
     const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
     const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
@@ -624,18 +763,12 @@
     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());
+    std::pair<uint64_t, unsigned> Info
+      = getTypeInfo(Typedef->getUnderlyingType().getTypePtr());
+    Align = std::max(Typedef->getMaxAlignment(), Info.second);
+    Width = Info.first;
     break;
   }
 
@@ -650,8 +783,8 @@
     return getTypeInfo(cast<DecltypeType>(T)->getUnderlyingExpr()->getType()
                         .getTypePtr());
 
-  case Type::QualifiedName:
-    return getTypeInfo(cast<QualifiedNameType>(T)->getNamedType().getTypePtr());
+  case Type::Elaborated:
+    return getTypeInfo(cast<ElaboratedType>(T)->getNamedType().getTypePtr());
 
   case Type::TemplateSpecialization:
     assert(getCanonicalType(T) != T &&
@@ -701,59 +834,37 @@
   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);
+  // FIXME. This need be removed but there are two many places which
+  // assume const-ness of ObjCInterfaceDecl
+  ObjCInterfaceDecl *IDecl = const_cast<ObjCInterfaceDecl *>(OI);
+  for (ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv; 
+        Iv= Iv->getNextIvar())
+    Ivars.push_back(Iv);
 }
 
-/// 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.
+/// DeepCollectObjCIvars -
+/// This routine first collects all declared, but not synthesized, ivars in
+/// super class and then collects all ivars, including those synthesized for
+/// current class. This routine is used for implementation of current class
+/// when all ivars, declared and synthesized are known.
 ///
-void ASTContext::CollectNonClassIvars(const ObjCInterfaceDecl *OI,
+void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
+                                      bool leafClass,
                                 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)
+  if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass())
+    DeepCollectObjCIvars(SuperClass, false, Ivars);
+  if (!leafClass) {
+    for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
+         E = OI->ivar_end(); I != E; ++I)
       Ivars.push_back(*I);
   }
+  else
+    ShallowCollectObjCIvars(OI, Ivars);
 }
 
 /// CollectInheritedProtocols - Collect all protocols in current class and
@@ -781,9 +892,7 @@
         CollectInheritedProtocols(SD, Protocols);
         SD = SD->getSuperClass();
       }
-    return;
-  }
-  if (const ObjCCategoryDecl *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) {
+  } else 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);
@@ -792,9 +901,7 @@
            PE = Proto->protocol_end(); P != PE; ++P)
         CollectInheritedProtocols(*P, Protocols);
     }
-    return;
-  }
-  if (const ObjCProtocolDecl *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) {
+  } else 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);
@@ -803,75 +910,21 @@
            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;
-    }
-  }
-  
+  for (const ObjCCategoryDecl *CDecl = OI->getFirstClassExtension(); CDecl;
+       CDecl = CDecl->getNextClassExtension())
+    count += CDecl->ivar_size();
+
   // 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;
+    count += ImplDecl->ivar_size();
+
   return count;
 }
 
@@ -934,40 +987,6 @@
   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);
@@ -978,45 +997,6 @@
   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
 //===----------------------------------------------------------------------===//
@@ -1402,9 +1382,17 @@
                                           SourceRange Brackets) {
   // Since we don't unique expressions, it isn't possible to unique VLA's
   // that have an expression provided for their size.
-
+  QualType CanonType;
+  
+  if (!EltTy.isCanonical()) {
+    if (NumElts)
+      NumElts->Retain();
+    CanonType = getVariableArrayType(getCanonicalType(EltTy), NumElts, ASM,
+                                     EltTypeQuals, Brackets);
+  }
+  
   VariableArrayType *New = new(*this, TypeAlignment)
-    VariableArrayType(EltTy, QualType(), NumElts, ASM, EltTypeQuals, Brackets);
+    VariableArrayType(EltTy, CanonType, NumElts, ASM, EltTypeQuals, Brackets);
 
   VariableArrayTypes.push_back(New);
   Types.push_back(New);
@@ -1508,7 +1496,7 @@
 /// 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) {
+    VectorType::AltiVecSpecific AltiVecSpec) {
   BuiltinType *baseType;
 
   baseType = dyn_cast<BuiltinType>(getCanonicalType(vecType).getTypePtr());
@@ -1516,8 +1504,8 @@
 
   // Check if we've already instantiated a vector of this type.
   llvm::FoldingSetNodeID ID;
-  VectorType::Profile(ID, vecType, NumElts, Type::Vector,
-    IsAltiVec, IsPixel);
+  VectorType::Profile(ID, vecType, NumElts, Type::Vector, AltiVecSpec);
+
   void *InsertPos = 0;
   if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(VTP, 0);
@@ -1525,16 +1513,16 @@
   // 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);
+  if (!vecType.isCanonical()) {
+    Canonical = getVectorType(getCanonicalType(vecType), NumElts,
+      VectorType::NotAltiVec);
 
     // 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);
+    VectorType(vecType, NumElts, Canonical, AltiVecSpec);
   VectorTypes.InsertNode(New, InsertPos);
   Types.push_back(New);
   return QualType(New, 0);
@@ -1550,7 +1538,8 @@
 
   // Check if we've already instantiated a vector of this type.
   llvm::FoldingSetNodeID ID;
-  VectorType::Profile(ID, vecType, NumElts, Type::ExtVector, false, false);
+  VectorType::Profile(ID, vecType, NumElts, Type::ExtVector,
+                      VectorType::NotAltiVec);
   void *InsertPos = 0;
   if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(VTP, 0);
@@ -1731,8 +1720,7 @@
   assert(NeedsInjectedClassNameType(Decl));
   if (Decl->TypeForDecl) {
     assert(isa<InjectedClassNameType>(Decl->TypeForDecl));
-  } else if (CXXRecordDecl *PrevDecl
-               = cast_or_null<CXXRecordDecl>(Decl->getPreviousDeclaration())) {
+  } else if (CXXRecordDecl *PrevDecl = Decl->getPreviousDeclaration()) {
     assert(PrevDecl->TypeForDecl && "previous declaration has no type");
     Decl->TypeForDecl = PrevDecl->TypeForDecl;
     assert(isa<InjectedClassNameType>(Decl->TypeForDecl));
@@ -1753,10 +1741,6 @@
   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.");
 
@@ -1764,11 +1748,11 @@
     assert(!Record->getPreviousDeclaration() &&
            "struct/union has previous declaration");
     assert(!NeedsInjectedClassNameType(Record));
-    Decl->TypeForDecl = new (*this, TypeAlignment) RecordType(Record);
+    return getRecordType(Record);
   } else if (const EnumDecl *Enum = dyn_cast<EnumDecl>(Decl)) {
     assert(!Enum->getPreviousDeclaration() &&
            "enum has previous declaration");
-    Decl->TypeForDecl = new (*this, TypeAlignment) EnumType(Enum);
+    return getEnumType(Enum);
   } else if (const UnresolvedUsingTypenameDecl *Using =
                dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
     Decl->TypeForDecl = new (*this, TypeAlignment) UnresolvedUsingType(Using);
@@ -1781,16 +1765,42 @@
 
 /// getTypedefType - Return the unique reference to the type for the
 /// specified typename decl.
-QualType ASTContext::getTypedefType(const TypedefDecl *Decl) {
+QualType
+ASTContext::getTypedefType(const TypedefDecl *Decl, QualType Canonical) {
   if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
 
-  QualType Canonical = getCanonicalType(Decl->getUnderlyingType());
+  if (Canonical.isNull())
+    Canonical = getCanonicalType(Decl->getUnderlyingType());
   Decl->TypeForDecl = new(*this, TypeAlignment)
     TypedefType(Type::Typedef, Decl, Canonical);
   Types.push_back(Decl->TypeForDecl);
   return QualType(Decl->TypeForDecl, 0);
 }
 
+QualType ASTContext::getRecordType(const RecordDecl *Decl) {
+  if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
+
+  if (const RecordDecl *PrevDecl = Decl->getPreviousDeclaration())
+    if (PrevDecl->TypeForDecl)
+      return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0); 
+
+  Decl->TypeForDecl = new (*this, TypeAlignment) RecordType(Decl);
+  Types.push_back(Decl->TypeForDecl);
+  return QualType(Decl->TypeForDecl, 0);
+}
+
+QualType ASTContext::getEnumType(const EnumDecl *Decl) {
+  if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
+
+  if (const EnumDecl *PrevDecl = Decl->getPreviousDeclaration())
+    if (PrevDecl->TypeForDecl)
+      return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0); 
+
+  Decl->TypeForDecl = new (*this, TypeAlignment) EnumType(Decl);
+  Types.push_back(Decl->TypeForDecl);
+  return QualType(Decl->TypeForDecl, 0);
+}
+
 /// \brief Retrieve a substitution-result type.
 QualType
 ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
@@ -1869,8 +1879,7 @@
 QualType
 ASTContext::getTemplateSpecializationType(TemplateName Template,
                                           const TemplateArgumentListInfo &Args,
-                                          QualType Canon,
-                                          bool IsCurrentInstantiation) {
+                                          QualType Canon) {
   unsigned NumArgs = Args.size();
 
   llvm::SmallVector<TemplateArgument, 4> ArgVec;
@@ -1879,56 +1888,18 @@
     ArgVec.push_back(Args[i].getArgument());
 
   return getTemplateSpecializationType(Template, ArgVec.data(), NumArgs,
-                                       Canon, IsCurrentInstantiation);
+                                       Canon);
 }
 
 QualType
 ASTContext::getTemplateSpecializationType(TemplateName Template,
                                           const TemplateArgument *Args,
                                           unsigned NumArgs,
-                                          QualType Canon,
-                                          bool IsCurrentInstantiation) {
+                                          QualType Canon) {
   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");
-  }
+  else
+    Canon = getCanonicalTemplateSpecializationType(Template, Args, NumArgs);
 
   // Allocate the (non-canonical) template specialization type, but don't
   // try to unique it: these types typically have location information that
@@ -1937,8 +1908,7 @@
                         sizeof(TemplateArgument) * NumArgs),
                        TypeAlignment);
   TemplateSpecializationType *Spec
-    = new (Mem) TemplateSpecializationType(*this, Template,
-                                           IsCurrentInstantiation,
+    = new (Mem) TemplateSpecializationType(Template,
                                            Args, NumArgs,
                                            Canon);
 
@@ -1947,29 +1917,66 @@
 }
 
 QualType
-ASTContext::getQualifiedNameType(NestedNameSpecifier *NNS,
-                                 QualType NamedType) {
+ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template,
+                                                   const TemplateArgument *Args,
+                                                   unsigned NumArgs) {
+  // 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;
-  QualifiedNameType::Profile(ID, NNS, NamedType);
+  TemplateSpecializationType::Profile(ID, CanonTemplate,
+                                      CanonArgs.data(), NumArgs, *this);
 
   void *InsertPos = 0;
-  QualifiedNameType *T
-    = QualifiedNameTypes.FindNodeOrInsertPos(ID, InsertPos);
+  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(CanonTemplate,
+                                                CanonArgs.data(), NumArgs,
+                                                QualType());
+    Types.push_back(Spec);
+    TemplateSpecializationTypes.InsertNode(Spec, InsertPos);
+  }
+
+  assert(Spec->isDependentType() &&
+         "Non-dependent template-id type must have a canonical type");
+  return QualType(Spec, 0);
+}
+
+QualType
+ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
+                              NestedNameSpecifier *NNS,
+                              QualType NamedType) {
+  llvm::FoldingSetNodeID ID;
+  ElaboratedType::Profile(ID, Keyword, NNS, NamedType);
+
+  void *InsertPos = 0;
+  ElaboratedType *T = ElaboratedTypes.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");
+    ElaboratedType *CheckT = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(!CheckT && "Elaborated canonical type broken");
     (void)CheckT;
   }
 
-  T = new (*this) QualifiedNameType(NNS, NamedType, Canon);
+  T = new (*this) ElaboratedType(Keyword, NNS, NamedType, Canon);
   Types.push_back(T);
-  QualifiedNameTypes.InsertNode(T, InsertPos);
+  ElaboratedTypes.InsertNode(T, InsertPos);
   return QualType(T, 0);
 }
 
@@ -2005,68 +2012,69 @@
 }
 
 QualType
-ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
+ASTContext::getDependentTemplateSpecializationType(
+                                 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);
+                                 const IdentifierInfo *Name,
+                                 const TemplateArgumentListInfo &Args) {
+  // TODO: avoid this copy
+  llvm::SmallVector<TemplateArgument, 16> ArgCopy;
+  for (unsigned I = 0, E = Args.size(); I != E; ++I)
+    ArgCopy.push_back(Args[I].getArgument());
+  return getDependentTemplateSpecializationType(Keyword, NNS, Name,
+                                                ArgCopy.size(),
+                                                ArgCopy.data());
 }
 
 QualType
-ASTContext::getElaboratedType(QualType UnderlyingType,
-                              ElaboratedType::TagKind Tag) {
+ASTContext::getDependentTemplateSpecializationType(
+                                 ElaboratedTypeKeyword Keyword,
+                                 NestedNameSpecifier *NNS,
+                                 const IdentifierInfo *Name,
+                                 unsigned NumArgs,
+                                 const TemplateArgument *Args) {
+  assert(NNS->isDependent() && "nested-name-specifier must be dependent");
+
   llvm::FoldingSetNodeID ID;
-  ElaboratedType::Profile(ID, UnderlyingType, Tag);
+  DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS,
+                                               Name, NumArgs, Args);
 
   void *InsertPos = 0;
-  ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
+  DependentTemplateSpecializationType *T
+    = DependentTemplateSpecializationTypes.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;
+  NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
+
+  ElaboratedTypeKeyword CanonKeyword = Keyword;
+  if (Keyword == ETK_None) CanonKeyword = ETK_Typename;
+
+  bool AnyNonCanonArgs = false;
+  llvm::SmallVector<TemplateArgument, 16> CanonArgs(NumArgs);
+  for (unsigned I = 0; I != NumArgs; ++I) {
+    CanonArgs[I] = getCanonicalTemplateArgument(Args[I]);
+    if (!CanonArgs[I].structurallyEquals(Args[I]))
+      AnyNonCanonArgs = true;
   }
 
-  T = new (*this) ElaboratedType(UnderlyingType, Tag, Canon);
+  QualType Canon;
+  if (AnyNonCanonArgs || CanonNNS != NNS || CanonKeyword != Keyword) {
+    Canon = getDependentTemplateSpecializationType(CanonKeyword, CanonNNS,
+                                                   Name, NumArgs,
+                                                   CanonArgs.data());
+
+    // Find the insert position again.
+    DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
+  }
+
+  void *Mem = Allocate((sizeof(DependentTemplateSpecializationType) +
+                        sizeof(TemplateArgument) * NumArgs),
+                       TypeAlignment);
+  T = new (Mem) DependentTemplateSpecializationType(Keyword, NNS,
+                                                    Name, NumArgs, Args, Canon);
   Types.push_back(T);
-  ElaboratedTypes.InsertNode(T, InsertPos);
+  DependentTemplateSpecializationTypes.InsertNode(T, InsertPos);
   return QualType(T, 0);
 }
 
@@ -2077,7 +2085,7 @@
   return LHS->getDeclName() < RHS->getDeclName();
 }
 
-static bool areSortedAndUniqued(ObjCProtocolDecl **Protocols,
+static bool areSortedAndUniqued(ObjCProtocolDecl * const *Protocols,
                                 unsigned NumProtocols) {
   if (NumProtocols == 0) return true;
 
@@ -2099,94 +2107,96 @@
   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) {
+QualType ASTContext::getObjCObjectType(QualType BaseType,
+                                       ObjCProtocolDecl * const *Protocols,
+                                       unsigned NumProtocols) {
+  // If the base type is an interface and there aren't any protocols
+  // to add, then the interface type will do just fine.
+  if (!NumProtocols && isa<ObjCInterfaceType>(BaseType))
+    return BaseType;
+
+  // Look in the folding set for an existing type.
   llvm::FoldingSetNodeID ID;
-  ObjCObjectPointerType::Profile(ID, InterfaceT, Protocols, NumProtocols);
-  Qualifiers Qs = Qualifiers::fromCVRMask(Quals);
+  ObjCObjectTypeImpl::Profile(ID, BaseType, Protocols, NumProtocols);
+  void *InsertPos = 0;
+  if (ObjCObjectType *QT = ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(QT, 0);
+
+  // Build the canonical type, which has the canonical base type and
+  // a sorted-and-uniqued list of protocols.
+  QualType Canonical;
+  bool ProtocolsSorted = areSortedAndUniqued(Protocols, NumProtocols);
+  if (!ProtocolsSorted || !BaseType.isCanonical()) {
+    if (!ProtocolsSorted) {
+      llvm::SmallVector<ObjCProtocolDecl*, 8> Sorted(Protocols,
+                                                     Protocols + NumProtocols);
+      unsigned UniqueCount = NumProtocols;
+
+      SortAndUniqueProtocols(&Sorted[0], UniqueCount);
+      Canonical = getObjCObjectType(getCanonicalType(BaseType),
+                                    &Sorted[0], UniqueCount);
+    } else {
+      Canonical = getObjCObjectType(getCanonicalType(BaseType),
+                                    Protocols, NumProtocols);
+    }
+
+    // Regenerate InsertPos.
+    ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos);
+  }
+
+  unsigned Size = sizeof(ObjCObjectTypeImpl);
+  Size += NumProtocols * sizeof(ObjCProtocolDecl *);
+  void *Mem = Allocate(Size, TypeAlignment);
+  ObjCObjectTypeImpl *T =
+    new (Mem) ObjCObjectTypeImpl(Canonical, BaseType, Protocols, NumProtocols);
+
+  Types.push_back(T);
+  ObjCObjectTypes.InsertNode(T, InsertPos);
+  return QualType(T, 0);
+}
+
+/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for
+/// the given object type.
+QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) {
+  llvm::FoldingSetNodeID ID;
+  ObjCObjectPointerType::Profile(ID, ObjectT);
 
   void *InsertPos = 0;
   if (ObjCObjectPointerType *QT =
               ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
-    return getQualifiedType(QualType(QT, 0), Qs);
+    return QualType(QT, 0);
 
-  // Sort the protocol list alphabetically to canonicalize it.
+  // Find the canonical object type.
   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);
-    }
+  if (!ObjectT.isCanonical()) {
+    Canonical = getObjCObjectPointerType(getCanonicalType(ObjectT));
 
     // 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);
+  void *Mem = Allocate(sizeof(ObjCObjectPointerType), TypeAlignment);
+  ObjCObjectPointerType *QType =
+    new (Mem) ObjCObjectPointerType(Canonical, ObjectT);
 
   Types.push_back(QType);
   ObjCObjectPointerTypes.InsertNode(QType, InsertPos);
-  return getQualifiedType(QualType(QType, 0), Qs);
+  return QualType(QType, 0);
 }
 
 /// 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);
+QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl) {
+  if (Decl->TypeForDecl)
+    return QualType(Decl->TypeForDecl, 0);
 
-  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);
+  // FIXME: redeclarations?
+  void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment);
+  ObjCInterfaceType *T = new (Mem) ObjCInterfaceType(Decl);
+  Decl->TypeForDecl = T;
+  Types.push_back(T);
+  return QualType(T, 0);
 }
 
 /// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique
@@ -2421,53 +2431,118 @@
 QualType ASTContext::getUnqualifiedArrayType(QualType T,
                                              Qualifiers &Quals) {
   Quals = T.getQualifiers();
-  if (!isa<ArrayType>(T)) {
+  const ArrayType *AT = getAsArrayType(T);
+  if (!AT) {
     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)) {
+  if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
     return getConstantArrayType(UnqualElt, CAT->getSize(),
                                 CAT->getSizeModifier(), 0);
   }
 
-  if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(T)) {
+  if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT)) {
     return getIncompleteArrayType(UnqualElt, IAT->getSizeModifier(), 0);
   }
 
-  const DependentSizedArrayType *DSAT = cast<DependentSizedArrayType>(T);
+  if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(AT)) {
+    return getVariableArrayType(UnqualElt,
+                                VAT->getSizeExpr() ?
+                                VAT->getSizeExpr()->Retain() : 0,
+                                VAT->getSizeModifier(),
+                                VAT->getIndexTypeCVRQualifiers(),
+                                VAT->getBracketsRange());
+  }
+
+  const DependentSizedArrayType *DSAT = cast<DependentSizedArrayType>(AT);
   return getDependentSizedArrayType(UnqualElt, DSAT->getSizeExpr()->Retain(),
                                     DSAT->getSizeModifier(), 0,
                                     SourceRange());
 }
 
-DeclarationName ASTContext::getNameForTemplate(TemplateName Name) {
-  if (TemplateDecl *TD = Name.getAsTemplateDecl())
-    return TD->getDeclName();
+/// 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 ASTContext::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 && 
+      hasSameUnqualifiedType(QualType(T1MPType->getClass(), 0), 
+                             QualType(T2MPType->getClass(), 0))) {
+    T1 = T1MPType->getPointeeType();
+    T2 = T2MPType->getPointeeType();
+    return true;
+  }
+  
+  if (getLangOptions().ObjC1) {
+    const ObjCObjectPointerType *T1OPType = T1->getAs<ObjCObjectPointerType>(),
+                                *T2OPType = T2->getAs<ObjCObjectPointerType>();
+    if (T1OPType && T2OPType) {
+      T1 = T1OPType->getPointeeType();
+      T2 = T2OPType->getPointeeType();
+      return true;
+    }
+  }
+  
+  // FIXME: Block pointers, too?
+  
+  return false;
+}
+
+DeclarationNameInfo ASTContext::getNameForTemplate(TemplateName Name,
+                                                   SourceLocation NameLoc) {
+  if (TemplateDecl *TD = Name.getAsTemplateDecl())
+    // DNInfo work in progress: CHECKME: what about DNLoc?
+    return DeclarationNameInfo(TD->getDeclName(), NameLoc);
+
   if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
+    DeclarationName DName;
     if (DTN->isIdentifier()) {
-      return DeclarationNames.getIdentifier(DTN->getIdentifier());
+      DName = DeclarationNames.getIdentifier(DTN->getIdentifier());
+      return DeclarationNameInfo(DName, NameLoc);
     } else {
-      return DeclarationNames.getCXXOperatorName(DTN->getOperator());
+      DName = DeclarationNames.getCXXOperatorName(DTN->getOperator());
+      // DNInfo work in progress: FIXME: source locations?
+      DeclarationNameLoc DNLoc;
+      DNLoc.CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
+      DNLoc.CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
+      return DeclarationNameInfo(DName, NameLoc, DNLoc);
     }
   }
 
   OverloadedTemplateStorage *Storage = Name.getAsOverloadedTemplate();
   assert(Storage);
-  return (*Storage->begin())->getDeclName();
+  // DNInfo work in progress: CHECKME: what about DNLoc?
+  return DeclarationNameInfo((*Storage->begin())->getDeclName(), NameLoc);
 }
 
 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())
+  if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
+    if (TemplateTemplateParmDecl *TTP 
+                              = dyn_cast<TemplateTemplateParmDecl>(Template))
+      Template = getCanonicalTemplateTemplateParmDecl(TTP);
+  
+    // The canonical template name is the canonical template declaration.
     return TemplateName(cast<TemplateDecl>(Template->getCanonicalDecl()));
+  }
 
   assert(!Name.getAsOverloadedTemplate());
 
@@ -2645,14 +2720,9 @@
 
 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);
-    }
-  }
+  while (const ArrayType *AT = getAsArrayType(QualType(Qs.strip(QT), 0)))
+    QT = AT->getElementType();
+  return Qs.apply(QT);
 }
 
 QualType ASTContext::getBaseElementType(const ArrayType *AT) {
@@ -2780,6 +2850,9 @@
 /// \returns the type this bit-field will promote to, or NULL if no
 /// promotion occurs.
 QualType ASTContext::isPromotableBitField(Expr *E) {
+  if (E->isTypeDependent() || E->isValueDependent())
+    return QualType();
+  
   FieldDecl *Field = E->getBitField();
   if (!Field)
     return QualType();
@@ -2875,7 +2948,7 @@
 QualType ASTContext::getCFConstantStringType() {
   if (!CFConstantStringTypeDecl) {
     CFConstantStringTypeDecl =
-      CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+      CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
                        &Idents.get("NSConstantString"));
     CFConstantStringTypeDecl->startDefinition();
 
@@ -2897,6 +2970,7 @@
                                            FieldTypes[i], /*TInfo=*/0,
                                            /*BitWidth=*/0,
                                            /*Mutable=*/false);
+      Field->setAccess(AS_public);
       CFConstantStringTypeDecl->addDecl(Field);
     }
 
@@ -2916,7 +2990,7 @@
 QualType ASTContext::getNSConstantStringType() {
   if (!NSConstantStringTypeDecl) {
     NSConstantStringTypeDecl =
-    CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+    CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
                      &Idents.get("__builtin_NSString"));
     NSConstantStringTypeDecl->startDefinition();
     
@@ -2936,6 +3010,7 @@
                                            FieldTypes[i], /*TInfo=*/0,
                                            /*BitWidth=*/0,
                                            /*Mutable=*/false);
+      Field->setAccess(AS_public);
       NSConstantStringTypeDecl->addDecl(Field);
     }
     
@@ -2954,7 +3029,7 @@
 QualType ASTContext::getObjCFastEnumerationStateType() {
   if (!ObjCFastEnumerationStateTypeDecl) {
     ObjCFastEnumerationStateTypeDecl =
-      CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+      CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
                        &Idents.get("__objcFastEnumerationState"));
     ObjCFastEnumerationStateTypeDecl->startDefinition();
 
@@ -2973,8 +3048,13 @@
                                            FieldTypes[i], /*TInfo=*/0,
                                            /*BitWidth=*/0,
                                            /*Mutable=*/false);
+      Field->setAccess(AS_public);
       ObjCFastEnumerationStateTypeDecl->addDecl(Field);
     }
+    if (getLangOptions().CPlusPlus)
+      if (CXXRecordDecl *CXXRD = 
+            dyn_cast<CXXRecordDecl>(ObjCFastEnumerationStateTypeDecl))
+        CXXRD->setEmpty(false);
 
     ObjCFastEnumerationStateTypeDecl->completeDefinition();
   }
@@ -2988,7 +3068,7 @@
 
   RecordDecl *T;
   // FIXME: Needs the FlagAppleBlock bit.
-  T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+  T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
                        &Idents.get("__block_descriptor"));
   T->startDefinition();
   
@@ -3010,6 +3090,7 @@
                                          FieldTypes[i], /*TInfo=*/0,
                                          /*BitWidth=*/0,
                                          /*Mutable=*/false);
+    Field->setAccess(AS_public);
     T->addDecl(Field);
   }
 
@@ -3032,7 +3113,7 @@
 
   RecordDecl *T;
   // FIXME: Needs the FlagAppleBlock bit.
-  T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+  T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
                        &Idents.get("__block_descriptor_withcopydispose"));
   T->startDefinition();
   
@@ -3058,6 +3139,7 @@
                                          FieldTypes[i], /*TInfo=*/0,
                                          /*BitWidth=*/0,
                                          /*Mutable=*/false);
+    Field->setAccess(AS_public);
     T->addDecl(Field);
   }
 
@@ -3084,26 +3166,25 @@
   return false;
 }
 
-QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) {
+QualType ASTContext::BuildByRefType(llvm::StringRef 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
+  //    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(),
+  T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
                        &Idents.get(Name.str()));
   T->startDefinition();
   QualType Int32Ty = IntTy;
@@ -3118,7 +3199,7 @@
     Ty
   };
 
-  const char *FieldNames[] = {
+  llvm::StringRef FieldNames[] = {
     "__isa",
     "__forwarding",
     "__flags",
@@ -3135,6 +3216,7 @@
                                          &Idents.get(FieldNames[i]),
                                          FieldTypes[i], /*TInfo=*/0,
                                          /*BitWidth=*/0, /*Mutable=*/false);
+    Field->setAccess(AS_public);
     T->addDecl(Field);
   }
 
@@ -3146,14 +3228,14 @@
 
 QualType ASTContext::getBlockParmType(
   bool BlockHasCopyDispose,
-  llvm::SmallVector<const Expr *, 8> &BlockDeclRefDecls) {
+  llvm::SmallVectorImpl<const Expr *> &Layout) {
+
   // 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(),
+  T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
                        &Idents.get(Name.str()));
   T->startDefinition();
   QualType FieldTypes[] = {
@@ -3179,26 +3261,34 @@
                                          &Idents.get(FieldNames[i]),
                                          FieldTypes[i], /*TInfo=*/0,
                                          /*BitWidth=*/0, /*Mutable=*/false);
+    Field->setAccess(AS_public);
     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();
+  for (unsigned i = 0; i < Layout.size(); ++i) {
+    const Expr *E = Layout[i];
 
-    if (BDRE && BDRE->isByRef())
-      FieldType = BuildByRefType(BDRE->getDecl()->getNameAsCString(),
-                                 FieldType);
+    QualType FieldType = E->getType();
+    IdentifierInfo *FieldName = 0;
+    if (isa<CXXThisExpr>(E)) {
+      FieldName = &Idents.get("this");
+    } else if (const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E)) {
+      const ValueDecl *D = BDRE->getDecl();
+      FieldName = D->getIdentifier();
+      if (BDRE->isByRef())
+        FieldType = BuildByRefType(D->getName(), FieldType);
+    } else {
+      // Padding.
+      assert(isa<ConstantArrayType>(FieldType) &&
+             isa<DeclRefExpr>(E) &&
+             !cast<DeclRefExpr>(E)->getDecl()->getDeclName() &&
+             "doesn't match characteristics of padding decl");
+    }
 
     FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
-                                         Name, FieldType, /*TInfo=*/0,
+                                         FieldName, FieldType, /*TInfo=*/0,
                                          /*BitWidth=*/0, /*Mutable=*/false);
+    Field->setAccess(AS_public);
     T->addDecl(Field);
   }
 
@@ -3229,7 +3319,7 @@
   CharUnits sz = getTypeSizeInChars(type);
 
   // Make all integer and enum types at least as large as an int
-  if (sz.isPositive() && type->isIntegralType())
+  if (sz.isPositive() && type->isIntegralOrEnumerationType())
     sz = std::max(sz, getTypeSizeInChars(IntTy));
   // Treat arrays as pointers, since that's how they're passed in.
   else if (type->isArrayType())
@@ -3250,7 +3340,7 @@
   QualType BlockTy =
       Expr->getType()->getAs<BlockPointerType>()->getPointeeType();
   // Encode result type.
-  getObjCEncodingForType(cast<FunctionType>(BlockTy)->getResultType(), S);
+  getObjCEncodingForType(BlockTy->getAs<FunctionType>()->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!
@@ -3483,13 +3573,74 @@
                              true /* outermost type */);
 }
 
+static char ObjCEncodingForPrimitiveKind(const ASTContext *C, QualType T) {
+    switch (T->getAs<BuiltinType>()->getKind()) {
+    default: assert(0 && "Unhandled builtin type kind");
+    case BuiltinType::Void:       return 'v';
+    case BuiltinType::Bool:       return 'B';
+    case BuiltinType::Char_U:
+    case BuiltinType::UChar:      return 'C';
+    case BuiltinType::UShort:     return 'S';
+    case BuiltinType::UInt:       return 'I';
+    case BuiltinType::ULong:
+        return
+          (const_cast<ASTContext *>(C))->getIntWidth(T) == 32 ? 'L' : 'Q';
+    case BuiltinType::UInt128:    return 'T';
+    case BuiltinType::ULongLong:  return 'Q';
+    case BuiltinType::Char_S:
+    case BuiltinType::SChar:      return 'c';
+    case BuiltinType::Short:      return 's';
+    case BuiltinType::WChar:
+    case BuiltinType::Int:        return 'i';
+    case BuiltinType::Long:
+      return
+        (const_cast<ASTContext *>(C))->getIntWidth(T) == 32 ? 'l' : 'q';
+    case BuiltinType::LongLong:   return 'q';
+    case BuiltinType::Int128:     return 't';
+    case BuiltinType::Float:      return 'f';
+    case BuiltinType::Double:     return 'd';
+    case BuiltinType::LongDouble: return 'd';
+    }
+}
+
 static void EncodeBitField(const ASTContext *Context, std::string& S,
-                           const FieldDecl *FD) {
+                           QualType T, 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';
+  // The NeXT runtime encodes bit fields as b followed by the number of bits.
+  // The GNU runtime requires more information; bitfields are encoded as b,
+  // then the offset (in bits) of the first element, then the type of the
+  // bitfield, then the size in bits.  For example, in this structure:
+  //
+  // struct
+  // {
+  //    int integer;
+  //    int flags:2;
+  // };
+  // On a 32-bit system, the encoding for flags would be b2 for the NeXT
+  // runtime, but b32i2 for the GNU runtime.  The reason for this extra
+  // information is not especially sensible, but we're stuck with it for
+  // compatibility with GCC, although providing it breaks anything that
+  // actually uses runtime introspection and wants to work on both runtimes...
+  if (!Ctx->getLangOptions().NeXTRuntime) {
+    const RecordDecl *RD = FD->getParent();
+    const ASTRecordLayout &RL = Ctx->getASTRecordLayout(RD);
+    // FIXME: This same linear search is also used in ExprConstant - it might
+    // be better if the FieldDecl stored its offset.  We'd be increasing the
+    // size of the object slightly, but saving some time every time it is used.
+    unsigned i = 0;
+    for (RecordDecl::field_iterator Field = RD->field_begin(),
+                                 FieldEnd = RD->field_end();
+         Field != FieldEnd; (void)++Field, ++i) {
+      if (*Field == FD)
+        break;
+    }
+    S += llvm::utostr(RL.getFieldOffset(i));
+    S += ObjCEncodingForPrimitiveKind(Context, T);
+  }
+  unsigned N = E->EvaluateAsInt(*Ctx).getZExtValue();
   S += llvm::utostr(N);
 }
 
@@ -3500,40 +3651,10 @@
                                             const FieldDecl *FD,
                                             bool OutermostType,
                                             bool EncodingProperty) {
-  if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
+  if (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 EncodeBitField(this, S, T, FD);
+    S += ObjCEncodingForPrimitiveKind(this, T);
     return;
   }
 
@@ -3579,12 +3700,8 @@
       // 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 (llvm::StringRef(S).endswith("nr"))
+        S.replace(S.end()-2, S.end(), "rn");
     }
 
     if (PointeeTy->isCharType()) {
@@ -3653,6 +3770,17 @@
     // Anonymous structures print as '?'
     if (const IdentifierInfo *II = RDecl->getIdentifier()) {
       S += II->getName();
+      if (ClassTemplateSpecializationDecl *Spec
+          = dyn_cast<ClassTemplateSpecializationDecl>(RDecl)) {
+        const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+        std::string TemplateArgsStr
+          = TemplateSpecializationType::PrintTemplateArgumentList(
+                                            TemplateArgs.getFlatArgumentList(),
+                                            TemplateArgs.flat_size(),
+                                            (*this).PrintingPolicy);
+
+        S += TemplateArgsStr;
+      }
     } else {
       S += '?';
     }
@@ -3685,7 +3813,7 @@
 
   if (T->isEnumeralType()) {
     if (FD && FD->isBitField())
-      EncodeBitField(this, S, FD);
+      EncodeBitField(this, S, T, FD);
     else
       S += 'i';
     return;
@@ -3696,6 +3824,10 @@
     return;
   }
 
+  // Ignore protocol qualifiers when mangling at this level.
+  if (const ObjCObjectType *OT = T->getAs<ObjCObjectType>())
+    T = OT->getBaseType();
+
   if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
     // @encode(class_name)
     ObjCInterfaceDecl *OI = OIT->getDecl();
@@ -3703,15 +3835,14 @@
     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]);
+    llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
+    DeepCollectObjCIvars(OI, true, Ivars);
+    for (unsigned i = 0, e = Ivars.size(); i != e; ++i) {
+      FieldDecl *Field = cast<FieldDecl>(Ivars[i]);
+      if (Field->isBitField())
+        getObjCEncodingForTypeImpl(Field->getType(), S, false, true, Field);
       else
-        getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true,
-                                   FD);
+        getObjCEncodingForTypeImpl(Field->getType(), S, false, true, FD);
     }
     S += '}';
     return;
@@ -3778,6 +3909,11 @@
     return;
   }
 
+  // gcc just blithely ignores member pointers.
+  // TODO: maybe there should be a mangling for these
+  if (T->getAs<MemberPointerType>())
+    return;
+
   assert(0 && "@encode for type not implemented!");
 }
 
@@ -4013,6 +4149,28 @@
          LHS->getNumElements() == RHS->getNumElements();
 }
 
+bool ASTContext::areCompatibleVectorTypes(QualType FirstVec,
+                                          QualType SecondVec) {
+  assert(FirstVec->isVectorType() && "FirstVec should be a vector type");
+  assert(SecondVec->isVectorType() && "SecondVec should be a vector type");
+
+  if (hasSameUnqualifiedType(FirstVec, SecondVec))
+    return true;
+
+  // AltiVec vectors types are identical to equivalent GCC vector types
+  const VectorType *First = FirstVec->getAs<VectorType>();
+  const VectorType *Second = SecondVec->getAs<VectorType>();
+  if ((((First->getAltiVecSpecific() == VectorType::AltiVec) &&
+        (Second->getAltiVecSpecific() == VectorType::NotAltiVec)) ||
+       ((First->getAltiVecSpecific() == VectorType::NotAltiVec) &&
+        (Second->getAltiVecSpecific() == VectorType::AltiVec))) &&
+      hasSameType(First->getElementType(), Second->getElementType()) &&
+      (First->getNumElements() == Second->getNumElements()))
+    return true;
+
+  return false;
+}
+
 //===----------------------------------------------------------------------===//
 // ObjCQualifiedIdTypesAreCompatible - Compatibility testing for qualified id's.
 //===----------------------------------------------------------------------===//
@@ -4039,6 +4197,32 @@
   return false;
 }
 
+/// ObjCQualifiedClassTypesAreCompatible - compare  Class<p,...> and
+/// Class<p1, ...>.
+bool ASTContext::ObjCQualifiedClassTypesAreCompatible(QualType lhs, 
+                                                      QualType rhs) {
+  const ObjCObjectPointerType *lhsQID = lhs->getAs<ObjCObjectPointerType>();
+  const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
+  assert ((lhsQID && rhsOPT) && "ObjCQualifiedClassTypesAreCompatible");
+  
+  for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
+       E = lhsQID->qual_end(); I != E; ++I) {
+    bool match = false;
+    ObjCProtocolDecl *lhsProto = *I;
+    for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(),
+         E = rhsOPT->qual_end(); J != E; ++J) {
+      ObjCProtocolDecl *rhsProto = *J;
+      if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto)) {
+        match = true;
+        break;
+      }
+    }
+    if (!match)
+      return false;
+  }
+  return true;
+}
+
 /// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an
 /// ObjCQualifiedIDType.
 bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
@@ -4121,9 +4305,9 @@
       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.
+          // when comparing an id<P> on rhs with a static type on lhs,
+          // static class must implement all of id's protocols directly or
+          // indirectly through its super class.
           if (lhsID->ClassImplementsProtocol(*I, true)) {
             match = true;
             break;
@@ -4166,18 +4350,25 @@
 ///
 bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
                                          const ObjCObjectPointerType *RHSOPT) {
+  const ObjCObjectType* LHS = LHSOPT->getObjectType();
+  const ObjCObjectType* RHS = RHSOPT->getObjectType();
+
   // If either type represents the built-in 'id' or 'Class' types, return true.
-  if (LHSOPT->isObjCBuiltinType() || RHSOPT->isObjCBuiltinType())
+  if (LHS->isObjCUnqualifiedIdOrClass() ||
+      RHS->isObjCUnqualifiedIdOrClass())
     return true;
 
-  if (LHSOPT->isObjCQualifiedIdType() || RHSOPT->isObjCQualifiedIdType())
+  if (LHS->isObjCQualifiedId() || RHS->isObjCQualifiedId())
     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->isObjCQualifiedClass() && RHS->isObjCQualifiedClass())
+    return ObjCQualifiedClassTypesAreCompatible(QualType(LHSOPT,0),
+                                                QualType(RHSOPT,0));
+  
+  // If we have 2 user-defined types, fall into that path.
+  if (LHS->getInterface() && RHS->getInterface())
     return canAssignObjCInterfaces(LHS, RHS);
 
   return false;
@@ -4228,8 +4419,10 @@
                                 const ObjCObjectPointerType *RHSOPT,
       llvm::SmallVectorImpl<ObjCProtocolDecl *> &IntersectionOfProtocols) {
   
-  const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();
-  const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();
+  const ObjCObjectType* LHS = LHSOPT->getObjectType();
+  const ObjCObjectType* RHS = RHSOPT->getObjectType();
+  assert(LHS->getInterface() && "LHS must have an interface base");
+  assert(RHS->getInterface() && "RHS must have an interface base");
   
   llvm::SmallPtrSet<ObjCProtocolDecl *, 8> InheritedProtocolSet;
   unsigned LHSNumProtocols = LHS->getNumProtocols();
@@ -4237,7 +4430,8 @@
     InheritedProtocolSet.insert(LHS->qual_begin(), LHS->qual_end());
   else {
     llvm::SmallPtrSet<ObjCProtocolDecl *, 8> LHSInheritedProtocols;
-    Context.CollectInheritedProtocols(LHS->getDecl(), LHSInheritedProtocols);
+    Context.CollectInheritedProtocols(LHS->getInterface(),
+                                      LHSInheritedProtocols);
     InheritedProtocolSet.insert(LHSInheritedProtocols.begin(), 
                                 LHSInheritedProtocols.end());
   }
@@ -4252,7 +4446,8 @@
   }
   else {
     llvm::SmallPtrSet<ObjCProtocolDecl *, 8> RHSInheritedProtocols;
-    Context.CollectInheritedProtocols(RHS->getDecl(), RHSInheritedProtocols);
+    Context.CollectInheritedProtocols(RHS->getInterface(),
+                                      RHSInheritedProtocols);
     for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I = 
          RHSInheritedProtocols.begin(),
          E = RHSInheritedProtocols.end(); I != E; ++I) 
@@ -4266,37 +4461,40 @@
 /// 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)
+                                          const ObjCObjectPointerType *Lptr,
+                                          const ObjCObjectPointerType *Rptr) {
+  const ObjCObjectType *LHS = Lptr->getObjectType();
+  const ObjCObjectType *RHS = Rptr->getObjectType();
+  const ObjCInterfaceDecl* LDecl = LHS->getInterface();
+  const ObjCInterfaceDecl* RDecl = RHS->getInterface();
+  if (!LDecl || !RDecl)
     return QualType();
   
-  while (const ObjCInterfaceDecl *LHSIDecl = LHS->getDecl()->getSuperClass()) {
-    QualType LHSTy = getObjCInterfaceType(LHSIDecl);
-    LHS = LHSTy->getAs<ObjCInterfaceType>();
+  while ((LDecl = LDecl->getSuperClass())) {
+    LHS = cast<ObjCInterfaceType>(getObjCInterfaceType(LDecl));
     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;
+      llvm::SmallVector<ObjCProtocolDecl *, 8> Protocols;
+      getIntersectionOfProtocols(*this, Lptr, Rptr, Protocols);
+
+      QualType Result = QualType(LHS, 0);
+      if (!Protocols.empty())
+        Result = getObjCObjectType(Result, Protocols.data(), Protocols.size());
+      Result = getObjCObjectPointerType(Result);
+      return Result;
     }
   }
     
   return QualType();
 }
 
-bool ASTContext::canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
-                                         const ObjCInterfaceType *RHS) {
+bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS,
+                                         const ObjCObjectType *RHS) {
+  assert(LHS->getInterface() && "LHS is not an interface type");
+  assert(RHS->getInterface() && "RHS is not an interface type");
+
   // Verify that the base decls are compatible: the RHS must be a subclass of
   // the LHS.
-  if (!LHS->getDecl()->isSuperClassOf(RHS->getDecl()))
+  if (!LHS->getInterface()->isSuperClassOf(RHS->getInterface()))
     return false;
 
   // RHS must have a superset of the protocols in the LHS.  If the LHS is not
@@ -4309,15 +4507,15 @@
   if (RHS->getNumProtocols() == 0)
     return true;  // FIXME: should return false!
 
-  for (ObjCInterfaceType::qual_iterator LHSPI = LHS->qual_begin(),
-                                        LHSPE = LHS->qual_end();
+  for (ObjCObjectType::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();
+    for (ObjCObjectType::qual_iterator RHSPI = RHS->qual_begin(),
+                                       RHSPE = RHS->qual_end();
          RHSPI != RHSPE; RHSPI++) {
       if ((*RHSPI)->lookupProtocolNamed((*LHSPI)->getIdentifier())) {
         RHSImplementsProtocol = true;
@@ -4344,15 +4542,22 @@
          canAssignObjCInterfaces(RHSOPT, LHSOPT);
 }
 
+bool ASTContext::canBindObjCObjectType(QualType To, QualType From) {
+  return canAssignObjCInterfaces(
+                getObjCObjectPointerType(To)->getAs<ObjCObjectPointerType>(),
+                getObjCObjectPointerType(From)->getAs<ObjCObjectPointerType>());
+}
+
 /// 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) {
+bool ASTContext::typesAreCompatible(QualType LHS, QualType RHS,
+                                    bool CompareUnqualified) {
   if (getLangOptions().CPlusPlus)
     return hasSameType(LHS, RHS);
   
-  return !mergeTypes(LHS, RHS).isNull();
+  return !mergeTypes(LHS, RHS, false, CompareUnqualified).isNull();
 }
 
 bool ASTContext::typesAreBlockPointerCompatible(QualType LHS, QualType RHS) {
@@ -4360,7 +4565,8 @@
 }
 
 QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, 
-                                        bool OfBlockPointer) {
+                                        bool OfBlockPointer,
+                                        bool Unqualified) {
   const FunctionType *lbase = lhs->getAs<FunctionType>();
   const FunctionType *rbase = rhs->getAs<FunctionType>();
   const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase);
@@ -4371,13 +4577,26 @@
   // Check return type
   QualType retType;
   if (OfBlockPointer)
-    retType = mergeTypes(rbase->getResultType(), lbase->getResultType(), true);
+    retType = mergeTypes(rbase->getResultType(), lbase->getResultType(), true,
+                         Unqualified);
   else
-   retType = mergeTypes(lbase->getResultType(), rbase->getResultType());
+   retType = mergeTypes(lbase->getResultType(), rbase->getResultType(),
+                        false, Unqualified);
   if (retType.isNull()) return QualType();
-  if (getCanonicalType(retType) != getCanonicalType(lbase->getResultType()))
+  
+  if (Unqualified)
+    retType = retType.getUnqualifiedType();
+
+  CanQualType LRetType = getCanonicalType(lbase->getResultType());
+  CanQualType RRetType = getCanonicalType(rbase->getResultType());
+  if (Unqualified) {
+    LRetType = LRetType.getUnqualifiedType();
+    RRetType = RRetType.getUnqualifiedType();
+  }
+  
+  if (getCanonicalType(retType) != LRetType)
     allLTypes = false;
-  if (getCanonicalType(retType) != getCanonicalType(rbase->getResultType()))
+  if (getCanonicalType(retType) != RRetType)
     allRTypes = false;
   // FIXME: double check this
   // FIXME: should we error if lbase->getRegParmAttr() != 0 &&
@@ -4422,9 +4641,19 @@
     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);
+      QualType argtype = mergeTypes(largtype, rargtype, OfBlockPointer,
+                                    Unqualified);
       if (argtype.isNull()) return QualType();
+      
+      if (Unqualified)
+        argtype = argtype.getUnqualifiedType();
+      
       types.push_back(argtype);
+      if (Unqualified) {
+        largtype = largtype.getUnqualifiedType();
+        rargtype = rargtype.getUnqualifiedType();
+      }
+      
       if (getCanonicalType(argtype) != getCanonicalType(largtype))
         allLTypes = false;
       if (getCanonicalType(argtype) != getCanonicalType(rargtype))
@@ -4480,7 +4709,8 @@
 }
 
 QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, 
-                                bool OfBlockPointer) {
+                                bool OfBlockPointer,
+                                bool Unqualified) {
   // 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
@@ -4488,6 +4718,11 @@
   // 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?");
+
+  if (Unqualified) {
+    LHS = LHS.getUnqualifiedType();
+    RHS = RHS.getUnqualifiedType();
+  }
   
   QualType LHSCan = getCanonicalType(LHS),
            RHSCan = getCanonicalType(RHS);
@@ -4543,6 +4778,10 @@
   if (RHSClass == Type::VariableArray || RHSClass == Type::IncompleteArray)
     RHSClass = Type::ConstantArray;
 
+  // ObjCInterfaces are just specialized ObjCObjects.
+  if (LHSClass == Type::ObjCInterface) LHSClass = Type::ObjCObject;
+  if (RHSClass == Type::ObjCInterface) RHSClass = Type::ObjCObject;
+
   // Canonicalize ExtVector -> Vector.
   if (LHSClass == Type::ExtVector) LHSClass = Type::Vector;
   if (RHSClass == Type::ExtVector) RHSClass = Type::Vector;
@@ -4582,6 +4821,7 @@
     assert(false && "C++ should never be in mergeTypes");
     return QualType();
 
+  case Type::ObjCInterface:
   case Type::IncompleteArray:
   case Type::VariableArray:
   case Type::FunctionProto:
@@ -4594,7 +4834,12 @@
     // 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 (Unqualified) {
+      LHSPointee = LHSPointee.getUnqualifiedType();
+      RHSPointee = RHSPointee.getUnqualifiedType();
+    }
+    QualType ResultType = mergeTypes(LHSPointee, RHSPointee, false, 
+                                     Unqualified);
     if (ResultType.isNull()) return QualType();
     if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))
       return LHS;
@@ -4607,7 +4852,12 @@
     // 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 (Unqualified) {
+      LHSPointee = LHSPointee.getUnqualifiedType();
+      RHSPointee = RHSPointee.getUnqualifiedType();
+    }
+    QualType ResultType = mergeTypes(LHSPointee, RHSPointee, OfBlockPointer,
+                                     Unqualified);
     if (ResultType.isNull()) return QualType();
     if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))
       return LHS;
@@ -4624,7 +4874,12 @@
 
     QualType LHSElem = getAsArrayType(LHS)->getElementType();
     QualType RHSElem = getAsArrayType(RHS)->getElementType();
-    QualType ResultType = mergeTypes(LHSElem, RHSElem);
+    if (Unqualified) {
+      LHSElem = LHSElem.getUnqualifiedType();
+      RHSElem = RHSElem.getUnqualifiedType();
+    }
+    
+    QualType ResultType = mergeTypes(LHSElem, RHSElem, false, Unqualified);
     if (ResultType.isNull()) return QualType();
     if (LCAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))
       return LHS;
@@ -4658,7 +4913,7 @@
                                   ArrayType::ArraySizeModifier(), 0);
   }
   case Type::FunctionNoProto:
-    return mergeFunctionTypes(LHS, RHS, OfBlockPointer);
+    return mergeFunctionTypes(LHS, RHS, OfBlockPointer, Unqualified);
   case Type::Record:
   case Type::Enum:
     return QualType();
@@ -4674,14 +4929,13 @@
                              RHSCan->getAs<VectorType>()))
       return LHS;
     return QualType();
-  case Type::ObjCInterface: {
-    // Check if the interfaces are assignment compatible.
+  case Type::ObjCObject: {
+    // Check if the types 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))
+    const ObjCObjectType* LHSIface = LHS->getAs<ObjCObjectType>();
+    const ObjCObjectType* RHSIface = RHS->getAs<ObjCObjectType>();
+    if (canAssignObjCInterfaces(LHSIface, RHSIface))
       return LHS;
 
     return QualType();
@@ -4705,6 +4959,87 @@
   return QualType();
 }
 
+/// mergeObjCGCQualifiers - This routine merges ObjC's GC attribute of 'LHS' and
+/// 'RHS' attributes and returns the merged version; including for function
+/// return types.
+QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
+  QualType LHSCan = getCanonicalType(LHS),
+  RHSCan = getCanonicalType(RHS);
+  // If two types are identical, they are compatible.
+  if (LHSCan == RHSCan)
+    return LHS;
+  if (RHSCan->isFunctionType()) {
+    if (!LHSCan->isFunctionType())
+      return QualType();
+    QualType OldReturnType = 
+      cast<FunctionType>(RHSCan.getTypePtr())->getResultType();
+    QualType NewReturnType =
+      cast<FunctionType>(LHSCan.getTypePtr())->getResultType();
+    QualType ResReturnType = 
+      mergeObjCGCQualifiers(NewReturnType, OldReturnType);
+    if (ResReturnType.isNull())
+      return QualType();
+    if (ResReturnType == NewReturnType || ResReturnType == OldReturnType) {
+      // id foo(); ... __strong id foo(); or: __strong id foo(); ... id foo();
+      // In either case, use OldReturnType to build the new function type.
+      const FunctionType *F = LHS->getAs<FunctionType>();
+      if (const FunctionProtoType *FPT = cast<FunctionProtoType>(F)) {
+        FunctionType::ExtInfo Info = getFunctionExtInfo(LHS);
+        QualType ResultType
+          = getFunctionType(OldReturnType, FPT->arg_type_begin(),
+                                  FPT->getNumArgs(), FPT->isVariadic(),
+                                  FPT->getTypeQuals(),
+                                  FPT->hasExceptionSpec(),
+                                  FPT->hasAnyExceptionSpec(),
+                                  FPT->getNumExceptions(),
+                                  FPT->exception_begin(),
+                                  Info);
+        return ResultType;
+      }
+    }
+    return QualType();
+  }
+  
+  // If the qualifiers are different, the types can still be merged.
+  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)
+      return LHS;
+    if (GC_R == Qualifiers::Strong)
+      return RHS;
+    return QualType();
+  }
+  
+  if (LHSCan->isObjCObjectPointerType() && RHSCan->isObjCObjectPointerType()) {
+    QualType LHSBaseQT = LHS->getAs<ObjCObjectPointerType>()->getPointeeType();
+    QualType RHSBaseQT = RHS->getAs<ObjCObjectPointerType>()->getPointeeType();
+    QualType ResQT = mergeObjCGCQualifiers(LHSBaseQT, RHSBaseQT);
+    if (ResQT == LHSBaseQT)
+      return LHS;
+    if (ResQT == RHSBaseQT)
+      return RHS;
+  }
+  return QualType();
+}
+
 //===----------------------------------------------------------------------===//
 //                         Integer Predicates
 //===----------------------------------------------------------------------===//
@@ -4719,12 +5054,12 @@
 }
 
 QualType ASTContext::getCorrespondingUnsignedType(QualType T) {
-  assert(T->isSignedIntegerType() && "Unexpected type");
+  assert(T->hasSignedIntegerRepresentation() && "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());
+             VTy->getNumElements(), VTy->getAltiVecSpecific());
 
   // For enums, we return the unsigned version of the base type.
   if (const EnumType *ETy = T->getAs<EnumType>())
@@ -4882,7 +5217,8 @@
 
     QualType ElementType = DecodeTypeFromStr(Str, Context, Error, false);
     // FIXME: Don't know what to do about AltiVec.
-    Type = Context.getVectorType(ElementType, NumElements, false, false);
+    Type = Context.getVectorType(ElementType, NumElements,
+                                 VectorType::NotAltiVec);
     break;
   }
   case 'X': {
@@ -5098,8 +5434,8 @@
   // 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();
+  bool lhsSigned = lhs->hasSignedIntegerRepresentation(),
+       rhsSigned = rhs->hasSignedIntegerRepresentation();
   QualType destType;
   if (lhsSigned == rhsSigned) {
     // Same signedness; use the higher-ranked type
@@ -5122,3 +5458,173 @@
   }
   return destType;
 }
+
+GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) {
+  GVALinkage External = GVA_StrongExternal;
+
+  Linkage L = FD->getLinkage();
+  if (L == ExternalLinkage && getLangOptions().CPlusPlus &&
+      FD->getType()->getLinkage() == UniqueExternalLinkage)
+    L = UniqueExternalLinkage;
+  
+  switch (L) {
+  case NoLinkage:
+  case InternalLinkage:
+  case UniqueExternalLinkage:
+    return GVA_Internal;
+    
+  case ExternalLinkage:
+    switch (FD->getTemplateSpecializationKind()) {
+    case TSK_Undeclared:
+    case TSK_ExplicitSpecialization:
+      External = GVA_StrongExternal;
+      break;
+
+    case TSK_ExplicitInstantiationDefinition:
+      return GVA_ExplicitTemplateInstantiation;
+
+    case TSK_ExplicitInstantiationDeclaration:
+    case TSK_ImplicitInstantiation:
+      External = GVA_TemplateInstantiation;
+      break;
+    }
+  }
+
+  if (!FD->isInlined())
+    return External;
+    
+  if (!getLangOptions().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 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 GVA_C99Inline;
+
+  return GVA_CXXInline;
+}
+
+GVALinkage ASTContext::GetGVALinkageForVariable(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 && getLangOptions().CPlusPlus &&
+      VD->getType()->getLinkage() == UniqueExternalLinkage)
+    L = UniqueExternalLinkage;
+
+  switch (L) {
+  case NoLinkage:
+  case InternalLinkage:
+  case UniqueExternalLinkage:
+    return GVA_Internal;
+
+  case ExternalLinkage:
+    switch (TSK) {
+    case TSK_Undeclared:
+    case TSK_ExplicitSpecialization:
+      return 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 GVA_ExplicitTemplateInstantiation;
+
+    case TSK_ImplicitInstantiation:
+      return GVA_TemplateInstantiation;      
+    }
+  }
+
+  return GVA_StrongExternal;
+}
+
+bool ASTContext::DeclMustBeEmitted(const Decl *D) {
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (!VD->isFileVarDecl())
+      return false;
+  } else if (!isa<FunctionDecl>(D))
+    return false;
+
+  // Weak references don't produce any output by themselves.
+  if (D->hasAttr<WeakRefAttr>())
+    return false;
+
+  // Aliases and used decls are required.
+  if (D->hasAttr<AliasAttr>() || D->hasAttr<UsedAttr>())
+    return true;
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    // Forward declarations aren't required.
+    if (!FD->isThisDeclarationADefinition())
+      return false;
+
+    // Constructors and destructors are required.
+    if (FD->hasAttr<ConstructorAttr>() || FD->hasAttr<DestructorAttr>())
+      return true;
+    
+    // The key function for a class is required.
+    if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+      const CXXRecordDecl *RD = MD->getParent();
+      if (MD->isOutOfLine() && RD->isDynamicClass()) {
+        const CXXMethodDecl *KeyFunc = getKeyFunction(RD);
+        if (KeyFunc && KeyFunc->getCanonicalDecl() == MD->getCanonicalDecl())
+          return true;
+      }
+    }
+
+    GVALinkage Linkage = GetGVALinkageForFunction(FD);
+
+    // 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 false;
+    return true;
+  }
+
+  const VarDecl *VD = cast<VarDecl>(D);
+  assert(VD->isFileVarDecl() && "Expected file scoped var");
+
+  if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly)
+    return false;
+
+  // Structs that have non-trivial constructors or destructors are required.
+
+  // FIXME: Handle references.
+  if (const RecordType *RT = VD->getType()->getAs<RecordType>()) {
+    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+      if (RD->hasDefinition() &&
+          (!RD->hasTrivialConstructor() || !RD->hasTrivialDestructor()))
+        return true;
+    }
+  }
+
+  GVALinkage L = GetGVALinkageForVariable(VD);
+  if (L == GVA_Internal || L == GVA_TemplateInstantiation) {
+    if (!(VD->getInit() && VD->getInit()->HasSideEffects(*this)))
+      return false;
+  }
+
+  return true;
+}
+
+CXXABI::~CXXABI() {}
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index e4cd2a9..23f323d 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -19,65 +19,41 @@
 
 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;
-  
+// Returns a desugared version of the QualType, and marks ShouldAKA as true
+// whenever we remove significant sugar from the type.
+static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
+  QualifierCollector QC;
+
   while (true) {
-    const Type *Ty = Qc.strip(QT);
-    
+    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;
@@ -94,50 +70,56 @@
 }
 #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;
+
+    // Record that we actually looked through an opaque type here.
+    ShouldAKA = 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;
-    }
+
+  // If we have a pointer-like type, desugar the pointee as well.
+  // FIXME: Handle other pointer-like types.
+  if (const PointerType *Ty = QT->getAs<PointerType>()) {
+      QT = Context.getPointerType(Desugar(Context, Ty->getPointeeType(),
+                                          ShouldAKA));
+  } else if (const LValueReferenceType *Ty = QT->getAs<LValueReferenceType>()) {
+      QT = Context.getLValueReferenceType(Desugar(Context, Ty->getPointeeType(),
+                                                  ShouldAKA));
   }
-  
-  DesugaredQT = Qc.apply(QT);
-  return true;
+
+  return QC.apply(QT);
 }
 
 /// \brief Convert the given type to a string suitable for printing as part of 
-/// a diagnostic. 
+/// a diagnostic.
+///
+/// There are three main criteria when determining whether we should have an
+/// a.k.a. clause when pretty-printing a type:
+///
+/// 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.
 ///
 /// \param Context the context in which the type was allocated
 /// \param Ty the type to print
@@ -147,18 +129,38 @@
                               unsigned NumPrevArgs) {
   // FIXME: Playing with std::string is really slow.
   std::string S = Ty.getAsString(Context.PrintingPolicy);
-  
+
+  // Check to see if we already desugared this type in this
+  // diagnostic.  If so, don't do it again.
+  bool Repeated = false;
+  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 == Ty) {
+        Repeated = true;
+        break;
+      }
+    }
+  }
+
   // 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;
+  if (!Repeated) {
+    bool ShouldAKA = false;
+    QualType DesugaredTy = Desugar(Context, Ty, ShouldAKA);
+    if (ShouldAKA) {
+      std::string D = DesugaredTy.getAsString(Context.PrintingPolicy);
+      if (D != S) {
+        S = "'" + S + "' (aka '";
+        S += D;
+        S += "')";
+        return S;
+      }
+    }
   }
-  
+
   S = "'" + S + "'";
   return S;
 }
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index ae09d79..eee41a6 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -19,7 +19,6 @@
 #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"
@@ -68,19 +67,22 @@
     // FIXME: DependentDecltypeType
     QualType VisitRecordType(RecordType *T);
     QualType VisitEnumType(EnumType *T);
-    QualType VisitElaboratedType(ElaboratedType *T);
     // FIXME: TemplateTypeParmType
     // FIXME: SubstTemplateTypeParmType
     // FIXME: TemplateSpecializationType
-    QualType VisitQualifiedNameType(QualifiedNameType *T);
+    QualType VisitElaboratedType(ElaboratedType *T);
     // FIXME: DependentNameType
+    // FIXME: DependentTemplateSpecializationType
     QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
+    QualType VisitObjCObjectType(ObjCObjectType *T);
     QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
                             
     // Importing declarations
     bool ImportDeclParts(NamedDecl *D, DeclContext *&DC, 
                          DeclContext *&LexicalDC, DeclarationName &Name, 
                          SourceLocation &Loc);
+    void ImportDeclarationNameLoc(const DeclarationNameInfo &From,
+                                  DeclarationNameInfo& To);
     void ImportDeclContext(DeclContext *FromDC);
     bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord);
     bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
@@ -439,9 +441,7 @@
       return false;
     if (Vec1->getNumElements() != Vec2->getNumElements())
       return false;
-    if (Vec1->isAltiVec() != Vec2->isAltiVec())
-      return false;
-    if (Vec1->isPixel() != Vec2->isPixel())
+    if (Vec1->getAltiVecSpecific() != Vec2->getAltiVecSpecific())
       return false;
     break;
   }
@@ -532,19 +532,7 @@
                                   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);
@@ -594,16 +582,19 @@
     break;
   }
       
-  case Type::QualifiedName: {
-    const QualifiedNameType *Qual1 = cast<QualifiedNameType>(T1);
-    const QualifiedNameType *Qual2 = cast<QualifiedNameType>(T2);
+  case Type::Elaborated: {
+    const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
+    const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
+    // CHECKME: what if a keyword is ETK_None or ETK_typename ?
+    if (Elab1->getKeyword() != Elab2->getKeyword())
+      return false;
     if (!IsStructurallyEquivalent(Context, 
-                                  Qual1->getQualifier(), 
-                                  Qual2->getQualifier()))
+                                  Elab1->getQualifier(), 
+                                  Elab2->getQualifier()))
       return false;
     if (!IsStructurallyEquivalent(Context,
-                                  Qual1->getNamedType(),
-                                  Qual2->getNamedType()))
+                                  Elab1->getNamedType(),
+                                  Elab2->getNamedType()))
       return false;
     break;
   }
@@ -628,26 +619,54 @@
     if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
                                   Typename2->getIdentifier()))
       return false;
-    if (!IsStructurallyEquivalent(Context,
-                                  QualType(Typename1->getTemplateId(), 0),
-                                  QualType(Typename2->getTemplateId(), 0)))
-      return false;
     
     break;
   }
   
+  case Type::DependentTemplateSpecialization: {
+    const DependentTemplateSpecializationType *Spec1 =
+      cast<DependentTemplateSpecializationType>(T1);
+    const DependentTemplateSpecializationType *Spec2 =
+      cast<DependentTemplateSpecializationType>(T2);
+    if (!IsStructurallyEquivalent(Context, 
+                                  Spec1->getQualifier(),
+                                  Spec2->getQualifier()))
+      return false;
+    if (!IsStructurallyEquivalent(Spec1->getIdentifier(),
+                                  Spec2->getIdentifier()))
+      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::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())
+    break;
+  }
+
+  case Type::ObjCObject: {
+    const ObjCObjectType *Obj1 = cast<ObjCObjectType>(T1);
+    const ObjCObjectType *Obj2 = cast<ObjCObjectType>(T2);
+    if (!IsStructurallyEquivalent(Context,
+                                  Obj1->getBaseType(),
+                                  Obj2->getBaseType()))
       return false;
-    for (unsigned I = 0, N = Iface1->getNumProtocols(); I != N; ++I) {
+    if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
+      return false;
+    for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
       if (!IsStructurallyEquivalent(Context,
-                                    Iface1->getProtocol(I),
-                                    Iface2->getProtocol(I)))
+                                    Obj1->getProtocol(I),
+                                    Obj2->getProtocol(I)))
         return false;
     }
     break;
@@ -660,14 +679,6 @@
                                   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;
   }
       
@@ -1179,8 +1190,7 @@
   
   return Importer.getToContext().getVectorType(ToElementType, 
                                                T->getNumElements(),
-                                               T->isAltiVec(),
-                                               T->isPixel());
+                                               T->getAltiVecSpecific());
 }
 
 QualType ASTNodeImporter::VisitExtVectorType(ExtVectorType *T) {
@@ -1293,24 +1303,20 @@
 }
 
 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();
+  NestedNameSpecifier *ToQualifier = 0;
+  // Note: the qualifier in an ElaboratedType is optional.
+  if (T->getQualifier()) {
+    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);
+  return Importer.getToContext().getElaboratedType(T->getKeyword(),
+                                                   ToQualifier, ToNamedType);
 }
 
 QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {
@@ -1319,8 +1325,16 @@
   if (!Class)
     return QualType();
 
+  return Importer.getToContext().getObjCInterfaceType(Class);
+}
+
+QualType ASTNodeImporter::VisitObjCObjectType(ObjCObjectType *T) {
+  QualType ToBaseType = Importer.Import(T->getBaseType());
+  if (ToBaseType.isNull())
+    return QualType();
+
   llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
-  for (ObjCInterfaceType::qual_iterator P = T->qual_begin(), 
+  for (ObjCObjectType::qual_iterator P = T->qual_begin(), 
                                      PEnd = T->qual_end();
        P != PEnd; ++P) {
     ObjCProtocolDecl *Protocol
@@ -1330,9 +1344,9 @@
     Protocols.push_back(Protocol);
   }
 
-  return Importer.getToContext().getObjCInterfaceType(Class,
-                                                      Protocols.data(),
-                                                      Protocols.size());
+  return Importer.getToContext().getObjCObjectType(ToBaseType,
+                                                   Protocols.data(),
+                                                   Protocols.size());
 }
 
 QualType ASTNodeImporter::VisitObjCObjectPointerType(ObjCObjectPointerType *T) {
@@ -1340,20 +1354,7 @@
   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());
+  return Importer.getToContext().getObjCObjectPointerType(ToPointeeType);
 }
 
 //----------------------------------------------------------------------------
@@ -1385,6 +1386,40 @@
   return false;
 }
 
+void
+ASTNodeImporter::ImportDeclarationNameLoc(const DeclarationNameInfo &From,
+                                          DeclarationNameInfo& To) {
+  // NOTE: To.Name and To.Loc are already imported.
+  // We only have to import To.LocInfo.
+  switch (To.getName().getNameKind()) {
+  case DeclarationName::Identifier:
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+  case DeclarationName::CXXUsingDirective:
+    return;
+
+  case DeclarationName::CXXOperatorName: {
+    SourceRange Range = From.getCXXOperatorNameRange();
+    To.setCXXOperatorNameRange(Importer.Import(Range));
+    return;
+  }
+  case DeclarationName::CXXLiteralOperatorName: {
+    SourceLocation Loc = From.getCXXLiteralOperatorNameLoc();
+    To.setCXXLiteralOperatorNameLoc(Importer.Import(Loc));
+    return;
+  }
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName: {
+    TypeSourceInfo *FromTInfo = From.getNamedTypeInfo();
+    To.setNamedTypeInfo(Importer.Import(FromTInfo));
+    return;
+  }
+    assert(0 && "Unknown name kind.");
+  }
+}
+
 void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC) {
   for (DeclContext::decl_iterator From = FromDC->decls_begin(),
                                FromEnd = FromDC->decls_end();
@@ -1617,7 +1652,12 @@
     
     D2->startDefinition();
     ImportDeclContext(D);
-    D2->completeDefinition(T, ToPromotionType);
+
+    // FIXME: we might need to merge the number of positive or negative bits
+    // if the enumerator lists don't match.
+    D2->completeDefinition(T, ToPromotionType,
+                           D->getNumPositiveBits(),
+                           D->getNumNegativeBits());
   }
   
   return D2;
@@ -1698,7 +1738,7 @@
   // Create the record declaration.
   RecordDecl *D2 = AdoptDecl;
   if (!D2) {
-    if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D)) {
+    if (isa<CXXRecordDecl>(D)) {
       CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(), 
                                                    D->getTagKind(),
                                                    DC, Loc,
@@ -1706,30 +1746,6 @@
                                         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,
@@ -1750,6 +1766,33 @@
 
   if (D->isDefinition()) {
     D2->startDefinition();
+
+    // Add base classes.
+    if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
+      CXXRecordDecl *D1CXX = cast<CXXRecordDecl>(D);
+
+      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(),
+                                 Importer.Import(Base1->getTypeSourceInfo())));
+      }
+      if (!Bases.empty())
+        D2CXX->setBases(Bases.data(), Bases.size());
+    }
+
     ImportDeclContext(D);
     D2->completeDefinition();
   }
@@ -1814,7 +1857,7 @@
   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()) {
@@ -1863,6 +1906,10 @@
     }    
   }
 
+  DeclarationNameInfo NameInfo(Name, Loc);
+  // Import additional name location/type info.
+  ImportDeclarationNameLoc(D->getNameInfo(), NameInfo);
+
   // Import the type.
   QualType T = Importer.Import(D->getType());
   if (T.isNull())
@@ -1885,26 +1932,26 @@
   if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
     ToFunction = CXXConstructorDecl::Create(Importer.getToContext(),
                                             cast<CXXRecordDecl>(DC),
-                                            Loc, Name, T, TInfo, 
+                                            NameInfo, T, TInfo, 
                                             FromConstructor->isExplicit(),
                                             D->isInlineSpecified(), 
                                             D->isImplicit());
   } else if (isa<CXXDestructorDecl>(D)) {
     ToFunction = CXXDestructorDecl::Create(Importer.getToContext(),
                                            cast<CXXRecordDecl>(DC),
-                                           Loc, Name, T, 
+                                           NameInfo, 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,
+                                           NameInfo, T, TInfo,
                                            D->isInlineSpecified(),
                                            FromConversion->isExplicit());
   } else {
-    ToFunction = FunctionDecl::Create(Importer.getToContext(), DC, Loc, 
-                                      Name, T, TInfo, D->getStorageClass(), 
+    ToFunction = FunctionDecl::Create(Importer.getToContext(), DC,
+                                      NameInfo, T, TInfo, D->getStorageClass(),
                                       D->getStorageClassAsWritten(),
                                       D->isInlineSpecified(),
                                       D->hasWrittenPrototype());
@@ -2018,7 +2065,7 @@
                                               cast<ObjCContainerDecl>(DC),
                                               Loc, Name.getAsIdentifierInfo(),
                                               T, TInfo, D->getAccessControl(),
-                                              BitWidth);
+                                              BitWidth, D->getSynthesize());
   ToIvar->setLexicalDeclContext(LexicalDC);
   Importer.Imported(D, ToIvar);
   LexicalDC->addDecl(ToIvar);
@@ -2291,6 +2338,7 @@
                              D->isInstanceMethod(),
                              D->isVariadic(),
                              D->isSynthesized(),
+                             D->isDefined(),
                              D->getImplementationControl());
 
   // FIXME: When we decide to merge method definitions, we'll need to
@@ -2609,8 +2657,8 @@
   }
 
   // Import the type.
-  QualType T = Importer.Import(D->getType());
-  if (T.isNull())
+  TypeSourceInfo *T = Importer.Import(D->getTypeSourceInfo());
+  if (!T)
     return 0;
 
   // Create the new property.
@@ -2625,6 +2673,8 @@
   LexicalDC->addDecl(ToProperty);
 
   ToProperty->setPropertyAttributes(D->getPropertyAttributes());
+  ToProperty->setPropertyAttributesAsWritten(
+                                      D->getPropertyAttributesAsWritten());
   ToProperty->setGetterName(Importer.Import(D->getGetterName()));
   ToProperty->setSetterName(Importer.Import(D->getSetterName()));
   ToProperty->setGetterMethodDecl(
@@ -2768,8 +2818,9 @@
   if (T.isNull())
     return 0;
 
-  return new (Importer.getToContext()) 
-    IntegerLiteral(E->getValue(), T, Importer.Import(E->getLocation()));
+  return IntegerLiteral::Create(Importer.getToContext(), 
+                                E->getValue(), T,
+                                Importer.Import(E->getLocation()));
 }
 
 Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
@@ -2876,6 +2927,13 @@
                                           Importer.Import(E->getOperatorLoc()));
 }
 
+bool ImportCastPath(CastExpr *E, CXXCastPath &Path) {
+  if (E->path_empty()) return false;
+
+  // TODO: import cast paths
+  return true;
+}
+
 Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
@@ -2884,13 +2942,13 @@
   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());
+
+  CXXCastPath BasePath;
+  if (ImportCastPath(E, BasePath))
+    return 0;
+
+  return ImplicitCastExpr::Create(Importer.getToContext(), T, E->getCastKind(),
+                                  SubExpr, &BasePath, E->getValueKind());
 }
 
 Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
@@ -2906,13 +2964,14 @@
   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()));
+  CXXCastPath BasePath;
+  if (ImportCastPath(E, BasePath))
+    return 0;
+
+  return CStyleCastExpr::Create(Importer.getToContext(), T, E->getCastKind(),
+                                SubExpr, &BasePath, TInfo,
+                                Importer.Import(E->getLParenLoc()),
+                                Importer.Import(E->getRParenLoc()));
 }
 
 ASTImporter::ASTImporter(Diagnostic &Diags,
@@ -2954,14 +3013,13 @@
     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.
+  // on the type and a single 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());
+                        FromTSI->getTypeLoc().getSourceRange().getBegin());
 }
 
 Decl *ASTImporter::Import(Decl *FromD) {
diff --git a/lib/AST/Android.mk b/lib/AST/Android.mk
index 5d05735..733dcb6 100644
--- a/lib/AST/Android.mk
+++ b/lib/AST/Android.mk
@@ -6,8 +6,13 @@
 include $(CLEAR_TBLGEN_VARS)
 
 TBLGEN_TABLES :=    \
+	AttrImpl.inc	\
+	AttrList.inc	\
+	Attrs.inc	\
+	DeclNodes.inc	\
 	DiagnosticASTKinds.inc	\
-    DiagnosticCommonKinds.inc
+    DiagnosticCommonKinds.inc	\
+	StmtNodes.inc
 
 clang_ast_SRC_FILES :=	\
 	APValue.cpp	\
@@ -28,9 +33,12 @@
 	DeclarationName.cpp	\
 	Expr.cpp	\
 	ExprCXX.cpp	\
+	ExprClassification.cpp	\
 	ExprConstant.cpp	\
 	FullExpr.cpp	\
+	ItaniumCXXABI.cpp	\
 	InheritViz.cpp	\
+	MicrosoftCXXABI.cpp	\
 	NestedNameSpecifier.cpp	\
 	ParentMap.cpp	\
 	RecordLayout.cpp	\
diff --git a/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp
index 423aa06..3ca7d4d 100644
--- a/lib/AST/AttrImpl.cpp
+++ b/lib/AST/AttrImpl.cpp
@@ -13,187 +13,10 @@
 
 #include "clang/AST/Attr.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/Expr.h"
 using namespace clang;
 
-void Attr::Destroy(ASTContext &C) {
-  if (Next) {
-    Next->Destroy(C);
-    Next = 0;
-  }
-  this->~Attr();
-  C.Deallocate((void*)this);
-}
+Attr::~Attr() { }
 
-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);
-}
+#include "clang/AST/AttrImpl.inc"
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index 91aaddc..82a81ec 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -18,10 +18,13 @@
   DeclPrinter.cpp
   DeclTemplate.cpp
   Expr.cpp
+  ExprClassification.cpp
   ExprConstant.cpp
   ExprCXX.cpp
   FullExpr.cpp
   InheritViz.cpp
+  ItaniumCXXABI.cpp
+  MicrosoftCXXABI.cpp
   NestedNameSpecifier.cpp
   ParentMap.cpp
   RecordLayout.cpp
@@ -39,4 +42,5 @@
   TypePrinter.cpp
   )
 
-add_dependencies(clangAST ClangDiagnosticAST)
+add_dependencies(clangAST ClangARMNeon ClangAttrClasses ClangAttrList 
+                 ClangAttrImpl ClangDiagnosticAST ClangDeclNodes ClangStmtNodes)
diff --git a/lib/AST/CXXABI.h b/lib/AST/CXXABI.h
new file mode 100644
index 0000000..4b38d7a
--- /dev/null
+++ b/lib/AST/CXXABI.h
@@ -0,0 +1,39 @@
+//===----- CXXABI.h - Interface to C++ ABIs ---------------------*- 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 C++ AST support. Concrete
+// subclasses of this implement AST support for specific C++ ABIs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_CXXABI_H
+#define LLVM_CLANG_AST_CXXABI_H
+
+namespace clang {
+
+class ASTContext;
+class MemberPointerType;
+
+/// Implements C++ ABI-specific semantic analysis functions.
+class CXXABI {
+public:
+  virtual ~CXXABI();
+
+  /// Returns the size of a member pointer in multiples of the target
+  /// pointer size.
+  virtual unsigned getMemberPointerSize(const MemberPointerType *MPT) const = 0;
+};
+
+/// Creates an instance of a C++ ABI class.
+CXXABI *CreateARMCXXABI(ASTContext &Ctx);
+CXXABI *CreateItaniumCXXABI(ASTContext &Ctx);
+CXXABI *CreateMicrosoftCXXABI(ASTContext &Ctx);
+}
+
+#endif
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index a9f2230..c563c37 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -49,9 +49,8 @@
 /// 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");
+bool CXXBasePaths::isAmbiguous(CanQualType BaseType) {
+  BaseType = BaseType.getUnqualifiedType();
   std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
   return Subobjects.second + (Subobjects.first? 1 : 0) > 1;
 }
@@ -91,6 +90,9 @@
 }
 
 bool CXXRecordDecl::isVirtuallyDerivedFrom(CXXRecordDecl *Base) const {
+  if (!getNumVBases())
+    return false;
+
   CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
                      /*DetectVirtual=*/false);
 
@@ -560,22 +562,23 @@
       for (; OverMethods.first != OverMethods.second; ++OverMethods.first) {
         const CXXMethodDecl *CanonOM
           = cast<CXXMethodDecl>((*OverMethods.first)->getCanonicalDecl());
+
+        // 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));
+
         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));
+                                       == CanonOM->end_overridden_methods())
           continue;
-        } 
 
         // Continue recursion to the methods that this virtual method
         // overrides.
@@ -583,6 +586,12 @@
                                        CanonOM->end_overridden_methods()));
       }
     }
+
+    // C++ [class.virtual]p2:
+    //   For convenience we say that any virtual function overrides itself.
+    Overriders[CanonM].add(SubobjectNumber,
+                           UniqueVirtualMethod(CanonM, SubobjectNumber,
+                                               InVirtualSubobject));
   }
 }
 
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 1d94c20..bef6194 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -23,17 +23,11 @@
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/IdentifierTable.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Basic/Specifiers.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
 //===----------------------------------------------------------------------===//
@@ -103,6 +97,12 @@
   return L;
 }
 
+static Linkage
+getLinkageForTemplateArgumentList(const TemplateArgumentList &TArgs) {
+  return getLinkageForTemplateArgumentList(TArgs.getFlatArgumentList(), 
+                                           TArgs.flat_size());
+}
+
 static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
   assert(D->getDeclContext()->getLookupContext()->isFileContext() &&
          "Not a name having namespace scope");
@@ -116,7 +116,7 @@
   // (This bullet corresponds to C99 6.2.2p3.)
   if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
     // Explicitly declared static.
-    if (Var->getStorageClass() == VarDecl::Static)
+    if (Var->getStorageClass() == SC_Static)
       return InternalLinkage;
 
     // - an object or reference that is explicitly declared const
@@ -125,8 +125,8 @@
     // (there is no equivalent in C99)
     if (Context.getLangOptions().CPlusPlus &&
         Var->getType().isConstant(Context) && 
-        Var->getStorageClass() != VarDecl::Extern &&
-        Var->getStorageClass() != VarDecl::PrivateExtern) {
+        Var->getStorageClass() != SC_Extern &&
+        Var->getStorageClass() != SC_PrivateExtern) {
       bool FoundExtern = false;
       for (const VarDecl *PrevVar = Var->getPreviousDeclaration();
            PrevVar && !FoundExtern; 
@@ -149,7 +149,7 @@
       Function = cast<FunctionDecl>(D);
 
     // Explicitly declared static.
-    if (Function->getStorageClass() == FunctionDecl::Static)
+    if (Function->getStorageClass() == SC_Static)
       return InternalLinkage;
   } else if (const FieldDecl *Field = dyn_cast<FieldDecl>(D)) {
     //   - a data member of an anonymous union.
@@ -165,8 +165,8 @@
   //     - 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)) {
+        (Var->getStorageClass() == SC_Extern ||
+         Var->getStorageClass() == SC_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
@@ -200,9 +200,9 @@
     //   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)) {
+        (Function->getStorageClass() == SC_Extern ||
+         Function->getStorageClass() == SC_PrivateExtern ||
+         Function->getStorageClass() == SC_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
@@ -225,10 +225,7 @@
                                = Function->getTemplateSpecializationInfo()) {
       Linkage L = SpecInfo->getTemplate()->getLinkage();
       const TemplateArgumentList &TemplateArgs = *SpecInfo->TemplateArguments;
-      L = minLinkage(L, 
-                     getLinkageForTemplateArgumentList(
-                                          TemplateArgs.getFlatArgumentList(), 
-                                          TemplateArgs.flat_size()));
+      L = minLinkage(L, getLinkageForTemplateArgumentList(TemplateArgs));
       return L;
     }
 
@@ -251,9 +248,7 @@
       if (const ClassTemplateSpecializationDecl *Spec
             = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) {
         const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
-        Linkage L = getLinkageForTemplateArgumentList(
-                                          TemplateArgs.getFlatArgumentList(),
-                                                 TemplateArgs.flat_size());
+        Linkage L = getLinkageForTemplateArgumentList(TemplateArgs);
         return minLinkage(L, Spec->getSpecializedTemplate()->getLinkage());
       }
 
@@ -285,6 +280,47 @@
   return NoLinkage;
 }
 
+static Linkage getLinkageForClassMember(const NamedDecl *D) {
+  if (!(isa<CXXMethodDecl>(D) ||
+        isa<VarDecl>(D) ||
+        (isa<TagDecl>(D) &&
+         (D->getDeclName() || cast<TagDecl>(D)->getTypedefForAnonDecl()))))
+    return NoLinkage;
+
+  // Class members only have linkage if their class has external linkage.
+  Linkage L = cast<RecordDecl>(D->getDeclContext())->getLinkage();
+  if (!isExternalLinkage(L)) return NoLinkage;
+
+  // If the class already has unique-external linkage, we can't improve.
+  if (L == UniqueExternalLinkage) return UniqueExternalLinkage;
+
+  // If this is a method template specialization, use the linkage for
+  // the template parameters and arguments.
+  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+    if (FunctionTemplateSpecializationInfo *SpecInfo
+           = MD->getTemplateSpecializationInfo()) {
+      Linkage ArgLinkage =
+        getLinkageForTemplateArgumentList(*SpecInfo->TemplateArguments);
+      Linkage ParamLinkage =
+        getLinkageForTemplateParameterList(
+                           SpecInfo->getTemplate()->getTemplateParameters());
+      return minLinkage(ArgLinkage, ParamLinkage);
+    }
+
+  // Similarly for member class template specializations.
+  } else if (const ClassTemplateSpecializationDecl *Spec
+               = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+    Linkage ArgLinkage =
+      getLinkageForTemplateArgumentList(Spec->getTemplateArgs());
+    Linkage ParamLinkage =
+      getLinkageForTemplateParameterList(
+                    Spec->getSpecializedTemplate()->getTemplateParameters());
+    return minLinkage(ArgLinkage, ParamLinkage);
+  }
+
+  return ExternalLinkage;
+}
+
 Linkage NamedDecl::getLinkage() const {
 
   // Objective-C: treat all Objective-C declarations as having external
@@ -320,14 +356,8 @@
   //   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;
-  }
+  if (getDeclContext()->isRecord())
+    return getLinkageForClassMember(this);
 
   // C++ [basic.link]p6:
   //   The name of a function declared in block scope and the name of
@@ -353,8 +383,8 @@
     }
 
     if (const VarDecl *Var = dyn_cast<VarDecl>(this))
-      if (Var->getStorageClass() == VarDecl::Extern ||
-          Var->getStorageClass() == VarDecl::PrivateExtern) {
+      if (Var->getStorageClass() == SC_Extern ||
+          Var->getStorageClass() == SC_PrivateExtern) {
         if (Var->getPreviousDeclaration())
           if (Linkage L = Var->getPreviousDeclaration()->getLinkage())
             return L;
@@ -376,88 +406,79 @@
 }
 
 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) {
+  typedef llvm::SmallVector<const DeclContext *, 8> ContextsTy;
+  ContextsTy Contexts;
+
+  // Collect contexts.
+  while (Ctx && isa<NamedDecl>(Ctx)) {
+    Contexts.push_back(Ctx);
+    Ctx = Ctx->getParent();
+  };
+
+  std::string QualName;
+  llvm::raw_string_ostream OS(QualName);
+
+  for (ContextsTy::reverse_iterator I = Contexts.rbegin(), E = Contexts.rend();
+       I != E; ++I) {
     if (const ClassTemplateSpecializationDecl *Spec
-          = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
+          = dyn_cast<ClassTemplateSpecializationDecl>(*I)) {
       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)) {
+      OS << Spec->getName() << TemplateArgsStr;
+    } else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) {
       if (ND->isAnonymousNamespace())
-        Names.push_back("<anonymous namespace>");
+        OS << "<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();
-
+        OS << ND;
+    } else if (const RecordDecl *RD = dyn_cast<RecordDecl>(*I)) {
+      if (!RD->getIdentifier())
+        OS << "<anonymous " << RD->getKindName() << '>';
+      else
+        OS << RD;
+    } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
       const FunctionProtoType *FT = 0;
       if (FD->hasWrittenPrototype())
         FT = dyn_cast<FunctionProtoType>(FD->getType()->getAs<FunctionType>());
 
-      Proto += "(";
+      OS << FD << '(';
       if (FT) {
-        llvm::raw_string_ostream POut(Proto);
         unsigned NumParams = FD->getNumParams();
         for (unsigned i = 0; i < NumParams; ++i) {
           if (i)
-            POut << ", ";
+            OS << ", ";
           std::string Param;
           FD->getParamDecl(i)->getType().getAsStringInternal(Param, P);
-          POut << Param;
+          OS << Param;
         }
 
         if (FT->isVariadic()) {
           if (NumParams > 0)
-            POut << ", ";
-          POut << "...";
+            OS << ", ";
+          OS << "...";
         }
       }
-      Proto += ")";
-
-      Names.push_back(Proto);
-    } else if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx))
-      Names.push_back(ND->getNameAsString());
-    else
-      break;
-
-    Ctx = Ctx->getParent();
+      OS << ')';
+    } else {
+      OS << cast<NamedDecl>(*I);
+    }
+    OS << "::";
   }
 
-  std::vector<std::string>::reverse_iterator
-    I = Names.rbegin(),
-    End = Names.rend();
-
-  for (; I!=End; ++I)
-    QualName += *I + "::";
-
   if (getDeclName())
-    QualName += getNameAsString();
+    OS << this;
   else
-    QualName += "<anonymous>";
+    OS << "<anonymous>";
 
-  return QualName;
+  return OS.str();
 }
 
 bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
@@ -538,23 +559,17 @@
 // DeclaratorDecl Implementation
 //===----------------------------------------------------------------------===//
 
-DeclaratorDecl::~DeclaratorDecl() {}
-void DeclaratorDecl::Destroy(ASTContext &C) {
-  if (hasExtInfo())
-    C.Deallocate(getExtInfo());
-  ValueDecl::Destroy(C);
+template <typename DeclT>
+static SourceLocation getTemplateOrInnerLocStart(const DeclT *decl) {
+  if (decl->getNumTemplateParameterLists() > 0)
+    return decl->getTemplateParameterList(0)->getTemplateLoc();
+  else
+    return decl->getInnerLocStart();
 }
 
 SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const {
-  if (DeclInfo) {
-    TypeLoc TL = getTypeSourceInfo()->getTypeLoc();
-    while (true) {
-      TypeLoc NextTL = TL.getNextTypeLoc();
-      if (!NextTL)
-        return TL.getSourceRange().getBegin();
-      TL = NextTL;
-    }
-  }
+  TypeSourceInfo *TSI = getTypeSourceInfo();
+  if (TSI) return TSI->getTypeLoc().getBeginLoc();
   return SourceLocation();
 }
 
@@ -588,18 +603,46 @@
   }
 }
 
+SourceLocation DeclaratorDecl::getOuterLocStart() const {
+  return getTemplateOrInnerLocStart(this);
+}
+
+void
+QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context,
+                                             unsigned NumTPLists,
+                                             TemplateParameterList **TPLists) {
+  assert((NumTPLists == 0 || TPLists != 0) &&
+         "Empty array of template parameters with positive size!");
+  assert((NumTPLists == 0 || NNS) &&
+         "Nonempty array of template parameters with no qualifier!");
+
+  // Free previous template parameters (if any).
+  if (NumTemplParamLists > 0) {
+    Context.Deallocate(TemplParamLists);
+    TemplParamLists = 0;
+    NumTemplParamLists = 0;
+  }
+  // Set info on matched template parameter lists (if any).
+  if (NumTPLists > 0) {
+    TemplParamLists = new (Context) TemplateParameterList*[NumTPLists];
+    NumTemplParamLists = NumTPLists;
+    for (unsigned i = NumTPLists; i-- > 0; )
+      TemplParamLists[i] = TPLists[i];
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // 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;
+  case SC_None:          break;
+  case SC_Auto:          return "auto"; break;
+  case SC_Extern:        return "extern"; break;
+  case SC_PrivateExtern: return "__private_extern__"; break;
+  case SC_Register:      return "register"; break;
+  case SC_Static:        return "static"; break;
   }
 
   assert(0 && "Invalid storage class");
@@ -612,44 +655,31 @@
   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 VarDecl::getInnerLocStart() const {
   SourceLocation Start = getTypeSpecStartLoc();
   if (Start.isInvalid())
     Start = getLocation();
-  
+  return Start;
+}
+
+SourceRange VarDecl::getSourceRange() const {
   if (getInit())
-    return SourceRange(Start, getInit()->getLocEnd());
-  return SourceRange(Start, getLocation());
+    return SourceRange(getOuterLocStart(), getInit()->getLocEnd());
+  return SourceRange(getOuterLocStart(), getLocation());
 }
 
 bool VarDecl::isExternC() const {
   ASTContext &Context = getASTContext();
   if (!Context.getLangOptions().CPlusPlus)
     return (getDeclContext()->isTranslationUnit() &&
-            getStorageClass() != Static) ||
+            getStorageClass() != SC_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;
+        return getStorageClass() != SC_Static;
 
       break;
     }
@@ -693,7 +723,15 @@
   // AST for 'extern "C" int foo;' is annotated with 'extern'.
   if (hasExternalStorage())
     return DeclarationOnly;
-
+  
+  if (getStorageClassAsWritten() == SC_Extern ||
+       getStorageClassAsWritten() == SC_PrivateExtern) {
+    for (const VarDecl *PrevVar = getPreviousDeclaration();
+         PrevVar; PrevVar = PrevVar->getPreviousDeclaration()) {
+      if (PrevVar->getLinkage() == InternalLinkage && PrevVar->hasInit())
+        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
@@ -712,7 +750,7 @@
   if (Kind != TentativeDefinition)
     return 0;
 
-  VarDecl *LastTentative = false;
+  VarDecl *LastTentative = 0;
   VarDecl *First = getFirstDeclaration();
   for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
        I != E; ++I) {
@@ -881,28 +919,6 @@
 // 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 {
@@ -916,6 +932,23 @@
     
 }
 
+bool FunctionDecl::isVariadic() const {
+  if (const FunctionProtoType *FT = getType()->getAs<FunctionProtoType>())
+    return FT->isVariadic();
+  return false;
+}
+
+bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const {
+  for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+    if (I->Body) {
+      Definition = *I;
+      return true;
+    }
+  }
+
+  return false;
+}
+
 Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
   for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
     if (I->Body) {
@@ -945,17 +978,20 @@
   // In C, any non-static, non-overloadable function has external
   // linkage.
   if (!Context.getLangOptions().CPlusPlus)
-    return getStorageClass() != Static && !getAttr<OverloadableAttr>();
+    return getStorageClass() != SC_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 &&
+        return getStorageClass() != SC_Static &&
                !getAttr<OverloadableAttr>();
 
       break;
     }
+    
+    if (DC->isRecord())
+      break;
   }
 
   return false;
@@ -965,7 +1001,7 @@
   if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this))
     return Method->isStatic();
 
-  if (getStorageClass() == Static)
+  if (getStorageClass() == SC_Static)
     return false;
 
   for (const DeclContext *DC = getDeclContext();
@@ -1024,7 +1060,7 @@
   // function or whether it just has the same name.
 
   // If this is a static function, it's not a builtin.
-  if (getStorageClass() == Static)
+  if (getStorageClass() == SC_Static)
     return 0;
 
   // If this function is at translation-unit scope and we're not in
@@ -1116,11 +1152,11 @@
   }
 
   const FunctionDecl *PatternDecl = getTemplateInstantiationPattern();
-  Stmt *Pattern = 0;
+  bool HasPattern = false;
   if (PatternDecl)
-    Pattern = PatternDecl->getBody(PatternDecl);
+    HasPattern = PatternDecl->hasBody(PatternDecl);
   
-  if (Pattern && PatternDecl)
+  if (HasPattern && PatternDecl)
     return PatternDecl->isInlined();
   
   return false;
@@ -1158,7 +1194,7 @@
     for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end();
          Redecl != RedeclEnd;
          ++Redecl) {
-      if (Redecl->isInlineSpecified() && Redecl->getStorageClass() != Extern)
+      if (Redecl->isInlineSpecified() && Redecl->getStorageClass() != SC_Extern)
         return true;
     }
     
@@ -1177,7 +1213,7 @@
     if (!Redecl->getLexicalDeclContext()->isTranslationUnit())
       continue;
     
-    if (!Redecl->isInlineSpecified() || Redecl->getStorageClass() == Extern) 
+    if (!Redecl->isInlineSpecified() || Redecl->getStorageClass() == SC_Extern) 
       return true; // Not an inline definition
   }
   
@@ -1206,6 +1242,23 @@
     return 0;
 }
 
+FunctionDecl::TemplatedKind FunctionDecl::getTemplatedKind() const {
+  if (TemplateOrSpecialization.isNull())
+    return TK_NonTemplate;
+  if (TemplateOrSpecialization.is<FunctionTemplateDecl *>())
+    return TK_FunctionTemplate;
+  if (TemplateOrSpecialization.is<MemberSpecializationInfo *>())
+    return TK_MemberSpecialization;
+  if (TemplateOrSpecialization.is<FunctionTemplateSpecializationInfo *>())
+    return TK_FunctionTemplateSpecialization;
+  if (TemplateOrSpecialization.is
+                               <DependentFunctionTemplateSpecializationInfo*>())
+    return TK_DependentFunctionTemplateSpecialization;
+
+  assert(false && "Did we miss a TemplateOrSpecialization type?");
+  return TK_NonTemplate;
+}
+
 FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const {
   if (MemberSpecializationInfo *Info = getMemberSpecializationInfo())
     return cast<FunctionDecl>(Info->getInstantiatedFrom());
@@ -1228,9 +1281,8 @@
 }
 
 bool FunctionDecl::isImplicitlyInstantiable() const {
-  // If this function already has a definition or is invalid, it can't be
-  // implicitly instantiated.
-  if (isInvalidDecl() || getBody())
+  // If the function is invalid, it can't be implicitly instantiated.
+  if (isInvalidDecl())
     return false;
   
   switch (getTemplateSpecializationKind()) {
@@ -1249,15 +1301,15 @@
 
   // Find the actual template from which we will instantiate.
   const FunctionDecl *PatternDecl = getTemplateInstantiationPattern();
-  Stmt *Pattern = 0;
+  bool HasPattern = false;
   if (PatternDecl)
-    Pattern = PatternDecl->getBody(PatternDecl);
+    HasPattern = PatternDecl->hasBody(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)
+  if (!HasPattern || !PatternDecl) 
     return true;
 
   return PatternDecl->isInlined();
@@ -1299,11 +1351,23 @@
   return 0;
 }
 
+const TemplateArgumentListInfo *
+FunctionDecl::getTemplateSpecializationArgsAsWritten() const {
+  if (FunctionTemplateSpecializationInfo *Info
+        = TemplateOrSpecialization
+            .dyn_cast<FunctionTemplateSpecializationInfo*>()) {
+    return Info->TemplateArgumentsAsWritten;
+  }
+  return 0;
+}
+
 void
 FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
                                      const TemplateArgumentList *TemplateArgs,
                                                 void *InsertPos,
-                                              TemplateSpecializationKind TSK) {
+                                                TemplateSpecializationKind TSK,
+                        const TemplateArgumentListInfo *TemplateArgsAsWritten,
+                                          SourceLocation PointOfInstantiation) {
   assert(TSK != TSK_Undeclared && 
          "Must specify the type of function template specialization");
   FunctionTemplateSpecializationInfo *Info
@@ -1315,6 +1379,8 @@
   Info->Template.setPointer(Template);
   Info->Template.setInt(TSK - 1);
   Info->TemplateArguments = TemplateArgs;
+  Info->TemplateArgumentsAsWritten = TemplateArgsAsWritten;
+  Info->PointOfInstantiation = PointOfInstantiation;
   TemplateOrSpecialization = Info;
 
   // Insert this function template specialization into the set of known
@@ -1322,18 +1388,41 @@
   if (InsertPos)
     Template->getSpecializations().InsertNode(Info, InsertPos);
   else {
-    // Try to insert the new node. If there is an existing node, remove it 
-    // first.
+    // Try to insert the new node. If there is an existing node, leave it, the
+    // set will contain the canonical decls while
+    // FunctionTemplateDecl::findSpecialization will return
+    // the most recent redeclarations.
     FunctionTemplateSpecializationInfo *Existing
       = Template->getSpecializations().GetOrInsertNode(Info);
-    if (Existing) {
-      Template->getSpecializations().RemoveNode(Existing);
-      Template->getSpecializations().GetOrInsertNode(Info);
-    }
+    (void)Existing;
+    assert((!Existing || Existing->Function->isCanonicalDecl()) &&
+           "Set is supposed to only contain canonical decls");
   }
 }
 
 void
+FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
+                                                unsigned NumTemplateArgs,
+                                           const TemplateArgument *TemplateArgs,
+                                                 TemplateSpecializationKind TSK,
+                                              unsigned NumTemplateArgsAsWritten,
+                                   TemplateArgumentLoc *TemplateArgsAsWritten,
+                                                SourceLocation LAngleLoc,
+                                                SourceLocation RAngleLoc,
+                                          SourceLocation PointOfInstantiation) {
+  ASTContext &Ctx = getASTContext();
+  TemplateArgumentList *TemplArgs
+    = new (Ctx) TemplateArgumentList(Ctx, TemplateArgs, NumTemplateArgs);
+  TemplateArgumentListInfo *TemplArgsInfo
+    = new (Ctx) TemplateArgumentListInfo(LAngleLoc, RAngleLoc);
+  for (unsigned i=0; i != NumTemplateArgsAsWritten; ++i)
+    TemplArgsInfo->addArgument(TemplateArgsAsWritten[i]);
+
+  setFunctionTemplateSpecialization(Template, TemplArgs, /*InsertPos=*/0, TSK,
+                                    TemplArgsInfo, PointOfInstantiation);
+}
+
+void
 FunctionDecl::setDependentTemplateSpecialization(ASTContext &Context,
                                     const UnresolvedSetImpl &Templates,
                              const TemplateArgumentListInfo &TemplateArgs) {
@@ -1425,7 +1514,7 @@
   // class template, check whether that member function was defined out-of-line.
   if (FunctionDecl *FD = getInstantiatedFromMemberFunction()) {
     const FunctionDecl *Definition;
-    if (FD->getBody(Definition))
+    if (FD->hasBody(Definition))
       return Definition->isOutOfLine();
   }
   
@@ -1433,7 +1522,7 @@
   // check whether that function template was defined out-of-line.
   if (FunctionTemplateDecl *FunTmpl = getPrimaryTemplate()) {
     const FunctionDecl *Definition;
-    if (FunTmpl->getTemplatedDecl()->getBody(Definition))
+    if (FunTmpl->getTemplatedDecl()->hasBody(Definition))
       return Definition->isOutOfLine();
   }
   
@@ -1464,26 +1553,27 @@
 // TagDecl Implementation
 //===----------------------------------------------------------------------===//
 
-void TagDecl::Destroy(ASTContext &C) {
-  if (hasExtInfo())
-    C.Deallocate(getExtInfo());
-  TypeDecl::Destroy(C);
+SourceLocation TagDecl::getOuterLocStart() const {
+  return getTemplateOrInnerLocStart(this);
 }
 
 SourceRange TagDecl::getSourceRange() const {
   SourceLocation E = RBraceLoc.isValid() ? RBraceLoc : getLocation();
-  return SourceRange(TagKeywordLoc, E);
+  return SourceRange(getOuterLocStart(), E);
 }
 
 TagDecl* TagDecl::getCanonicalDecl() {
   return getFirstDeclaration();
 }
 
+void TagDecl::setTypedefForAnonDecl(TypedefDecl *TDD) { 
+  TypedefDeclOrQualifier = TDD; 
+  if (TypeForDecl)
+    TypeForDecl->ClearLinkageCache();
+}
+
 void TagDecl::startDefinition() {
-  if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) {
-    TagT->decl.setPointer(this);
-    TagT->decl.setInt(1);
-  }
+  IsBeingDefined = true;
 
   if (isa<CXXRecordDecl>(this)) {
     CXXRecordDecl *D = cast<CXXRecordDecl>(this);
@@ -1500,11 +1590,7 @@
          "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);
-  }
+  IsBeingDefined = false;
 }
 
 TagDecl* TagDecl::getDefinition() const {
@@ -1519,16 +1605,6 @@
   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) {
@@ -1561,15 +1637,19 @@
   return Enum;
 }
 
-void EnumDecl::Destroy(ASTContext& C) {
-  TagDecl::Destroy(C);
+EnumDecl *EnumDecl::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) EnumDecl(0, SourceLocation(), 0, 0, SourceLocation());
 }
 
 void EnumDecl::completeDefinition(QualType NewType,
-                                  QualType NewPromotionType) {
+                                  QualType NewPromotionType,
+                                  unsigned NumPositiveBits,
+                                  unsigned NumNegativeBits) {
   assert(!isDefinition() && "Cannot redefine enums!");
   IntegerType = NewType;
   PromotionType = NewPromotionType;
+  setNumPositiveBits(NumPositiveBits);
+  setNumNegativeBits(NumNegativeBits);
   TagDecl::completeDefinition();
 }
 
@@ -1596,11 +1676,9 @@
   return R;
 }
 
-RecordDecl::~RecordDecl() {
-}
-
-void RecordDecl::Destroy(ASTContext& C) {
-  TagDecl::Destroy(C);
+RecordDecl *RecordDecl::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) RecordDecl(Record, TTK_Struct, 0, SourceLocation(), 0, 0,
+                            SourceLocation());
 }
 
 bool RecordDecl::isInjectedClassName() const {
@@ -1615,24 +1693,21 @@
   TagDecl::completeDefinition();
 }
 
+ValueDecl *RecordDecl::getAnonymousStructOrUnionObject() {
+  // Force the decl chain to come into existence properly.
+  if (!getNextDeclInContext()) getParent()->decls_begin();
+
+  assert(isAnonymousStructOrUnion());
+  ValueDecl *D = cast<ValueDecl>(getNextDeclInContext());
+  assert(D->getType()->isRecordType());
+  assert(D->getType()->getAs<RecordType>()->getDecl() == this);
+  return D;
+}
+
 //===----------------------------------------------------------------------===//
 // 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!");
@@ -1664,27 +1739,17 @@
   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,
+                                   const DeclarationNameInfo &NameInfo,
+                                   QualType T, TypeSourceInfo *TInfo,
                                    StorageClass S, StorageClass SCAsWritten,
                                    bool isInline, bool hasWrittenPrototype) {
-  FunctionDecl *New = new (C) FunctionDecl(Function, DC, L, N, T, TInfo,
+  FunctionDecl *New = new (C) FunctionDecl(Function, DC, NameInfo, T, TInfo,
                                            S, SCAsWritten, isInline);
   New->HasWrittenPrototype = hasWrittenPrototype;
   return New;
@@ -1701,20 +1766,12 @@
   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) {
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index b5aec0c..3dd7aba 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -35,16 +35,18 @@
 //  Statistics
 //===----------------------------------------------------------------------===//
 
-#define DECL(Derived, Base) static int n##Derived##s = 0;
-#include "clang/AST/DeclNodes.def"
+#define DECL(DERIVED, BASE) static int n##DERIVED##s = 0;
+#define ABSTRACT_DECL(DECL)
+#include "clang/AST/DeclNodes.inc"
 
 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"
+  default: assert(0 && "Declaration not in DeclNodes.inc!");
+#define DECL(DERIVED, BASE) case DERIVED: return #DERIVED;
+#define ABSTRACT_DECL(DECL)
+#include "clang/AST/DeclNodes.inc"
   }
 }
 
@@ -60,9 +62,10 @@
 
 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"
+  default: assert(0 && "Declaration context not in DeclNodes.inc!");
+#define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED;
+#define ABSTRACT_DECL(DECL)
+#include "clang/AST/DeclNodes.inc"
   }
 }
 
@@ -75,28 +78,31 @@
   fprintf(stderr, "*** Decl Stats:\n");
 
   int totalDecls = 0;
-#define DECL(Derived, Base) totalDecls += n##Derived##s;
-#include "clang/AST/DeclNodes.def"
+#define DECL(DERIVED, BASE) totalDecls += n##DERIVED##s;
+#define ABSTRACT_DECL(DECL)
+#include "clang/AST/DeclNodes.inc"
   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)));              \
+#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"
+#define ABSTRACT_DECL(DECL)
+#include "clang/AST/DeclNodes.inc"
 
   fprintf(stderr, "Total bytes = %d\n", totalBytes);
 }
 
-void Decl::addDeclKind(Kind k) {
+void Decl::add(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"
+  default: assert(0 && "Declaration not in DeclNodes.inc!");
+#define DECL(DERIVED, BASE) case DERIVED: ++n##DERIVED##s; break;
+#define ABSTRACT_DECL(DECL)
+#include "clang/AST/DeclNodes.inc"
   }
 }
 
@@ -151,9 +157,7 @@
 //===----------------------------------------------------------------------===//
 
 // Out-of-line virtual method providing a home for Decl.
-Decl::~Decl() {
-  assert(!HasAttrs && "attributes should have been freed by Destroy");
-}
+Decl::~Decl() { }
 
 void Decl::setDeclContext(DeclContext *DC) {
   if (isOutOfSemaDC())
@@ -206,17 +210,17 @@
   return getTranslationUnitDecl()->getASTContext();
 }
 
-bool Decl::isUsed() const { 
+bool Decl::isUsed(bool CheckUsedAttr) const { 
   if (Used)
     return true;
   
   // Check for used attribute.
-  if (hasAttr<UsedAttr>())
+  if (CheckUsedAttr && 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)
+    if ((CheckUsedAttr && I->hasAttr<UsedAttr>()) || I->Used)
       return true;
   }
   
@@ -285,6 +289,7 @@
     // Never have names.
     case Friend:
     case FriendTemplate:
+    case AccessSpec:
     case LinkageSpec:
     case FileScopeAsm:
     case StaticAssert:
@@ -307,24 +312,25 @@
   return 0;
 }
 
-void Decl::addAttr(Attr *NewAttr) {
-  Attr *&ExistingAttr = getASTContext().getDeclAttrs(this);
+void Decl::setAttrs(const AttrVec &attrs) {
+  assert(!HasAttrs && "Decl already contains attrs.");
 
-  NewAttr->setNext(ExistingAttr);
-  ExistingAttr = NewAttr;
+  AttrVec &AttrBlank = getASTContext().getDeclAttrs(this);
+  assert(AttrBlank.empty() && "HasAttrs was wrong?");
 
+  AttrBlank = attrs;
   HasAttrs = true;
 }
 
-void Decl::invalidateAttrs() {
+void Decl::dropAttrs() {
   if (!HasAttrs) return;
 
   HasAttrs = false;
   getASTContext().eraseDeclAttrs(this);
 }
 
-const Attr *Decl::getAttrsImpl() const {
-  assert(HasAttrs && "getAttrs() should verify this!");
+const AttrVec &Decl::getAttrs() const {
+  assert(HasAttrs && "No attrs to get!");
   return getASTContext().getDeclAttrs(this);
 }
 
@@ -354,54 +360,21 @@
   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"
+#define DECL(NAME, BASE)
+#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.inc"
     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"
+#define DECL(NAME, BASE)
+#define DECL_CONTEXT_BASE(NAME)                  \
+      if (DK >= first##NAME && DK <= last##NAME) \
+        return static_cast<NAME##Decl*>(const_cast<DeclContext*>(D));
+#include "clang/AST/DeclNodes.inc"
       assert(false && "a decl that inherits DeclContext isn't handled");
       return 0;
   }
@@ -410,46 +383,51 @@
 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"
+#define DECL(NAME, BASE)
+#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.inc"
     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"
+#define DECL(NAME, BASE)
+#define DECL_CONTEXT_BASE(NAME)                                   \
+      if (DK >= first##NAME && DK <= last##NAME)                  \
+        return static_cast<NAME##Decl*>(const_cast<Decl*>(D));
+#include "clang/AST/DeclNodes.inc"
       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)
+  // Special handling of FunctionDecl to avoid de-serializing the body from PCH.
+  // FunctionDecl stores EndRangeLoc for this purpose.
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) {
+    const FunctionDecl *Definition;
+    if (FD->hasBody(Definition))
+      return Definition->getSourceRange().getEnd();
     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();
+  }
+
+  if (Stmt *Body = getBody())
+    return Body->getSourceRange().getEnd();
+
+  return SourceLocation();
 }
 
 #ifndef NDEBUG
 void Decl::CheckAccessDeclContext() const {
+  // FIXME: Disable this until rdar://8146294 "access specifier for inner class
+  // templates is not set or checked" is fixed.
+  return;
   // 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
+  // 3. the context is not a record
+  // 4. it's invalid
   if (isa<TranslationUnitDecl>(this) ||
+      isa<TemplateTypeParmDecl>(this) ||
       !isa<CXXRecordDecl>(getDeclContext()) ||
       isInvalidDecl())
     return;
@@ -466,31 +444,23 @@
 
 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"
+#define DECL(NAME, BASE)
+#define DECL_CONTEXT(NAME) case Decl::NAME:
+#define DECL_CONTEXT_BASE(NAME)
+#include "clang/AST/DeclNodes.inc"
       return true;
     default:
-#define DECL_CONTEXT_BASE(Name)                   \
-      if (D->getKind() >= Decl::Name##First &&  \
-          D->getKind() <= Decl::Name##Last)     \
+#define DECL(NAME, BASE)
+#define DECL_CONTEXT_BASE(NAME)                 \
+      if (D->getKind() >= Decl::first##NAME &&  \
+          D->getKind() <= Decl::last##NAME)     \
         return true;
-#include "clang/AST/DeclNodes.def"
+#include "clang/AST/DeclNodes.inc"
       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);
-}
+DeclContext::~DeclContext() { }
 
 /// \brief Find the parent context of this context that will be
 /// used for unqualified name lookup.
@@ -537,7 +507,7 @@
     return true; // FIXME: Check for C++0x scoped enums
   else if (DeclKind == Decl::LinkageSpec)
     return true;
-  else if (DeclKind >= Decl::RecordFirst && DeclKind <= Decl::RecordLast)
+  else if (DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord)
     return cast<RecordDecl>(this)->isAnonymousStructOrUnion();
   else if (DeclKind == Decl::Namespace)
     return false; // FIXME: Check for C++0x inline namespaces
@@ -581,7 +551,7 @@
     return this;
 
   default:
-    if (DeclKind >= Decl::TagFirst && DeclKind <= Decl::TagLast) {
+    if (DeclKind >= Decl::firstTag && DeclKind <= Decl::lastTag) {
       // 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);
@@ -602,7 +572,7 @@
       return Tag;
     }
 
-    assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
+    assert(DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction &&
           "Unknown DeclContext kind");
     return this;
   }
@@ -626,9 +596,11 @@
   ExternalASTSource *Source = getParentASTContext().getExternalSource();
   assert(hasExternalLexicalStorage() && Source && "No external storage?");
 
-  llvm::SmallVector<uint32_t, 64> Decls;
-  if (Source->ReadDeclsLexicallyInContext(const_cast<DeclContext *>(this),
-                                          Decls))
+  // Notify that we have a DeclContext that is initializing.
+  ExternalASTSource::Deserializing ADeclContext(Source);
+
+  llvm::SmallVector<Decl*, 64> Decls;
+  if (Source->FindExternalLexicalDecls(this, Decls))
     return;
 
   // There is no longer any lexical storage in this context
@@ -642,7 +614,7 @@
   Decl *FirstNewDecl = 0;
   Decl *PrevDecl = 0;
   for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
-    Decl *D = Source->GetDecl(Decls[I]);
+    Decl *D = Decls[I];
     if (PrevDecl)
       PrevDecl->NextDeclInContext = D;
     else
@@ -659,26 +631,67 @@
     LastDecl = PrevDecl;
 }
 
-void
-DeclContext::LoadVisibleDeclsFromExternalStorage() const {
-  DeclContext *This = const_cast<DeclContext *>(this);
-  ExternalASTSource *Source = getParentASTContext().getExternalSource();
-  assert(hasExternalVisibleStorage() && Source && "No external storage?");
+DeclContext::lookup_result
+ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC,
+                                                    DeclarationName Name) {
+  ASTContext &Context = DC->getParentASTContext();
+  StoredDeclsMap *Map;
+  if (!(Map = DC->LookupPtr))
+    Map = DC->CreateStoredDeclsMap(Context);
 
-  llvm::SmallVector<VisibleDeclaration, 64> Decls;
-  if (Source->ReadDeclsVisibleInContext(This, Decls))
-    return;
+  StoredDeclsList &List = (*Map)[Name];
+  assert(List.isNull());
+  (void) List;
 
-  // There is no longer any visible storage in this context
-  ExternalVisibleStorage = false;
+  return DeclContext::lookup_result();
+}
 
-  // 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());
+DeclContext::lookup_result
+ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
+                                                  DeclarationName Name,
+                                    llvm::SmallVectorImpl<NamedDecl*> &Decls) {
+  ASTContext &Context = DC->getParentASTContext();;
+
+  StoredDeclsMap *Map;
+  if (!(Map = DC->LookupPtr))
+    Map = DC->CreateStoredDeclsMap(Context);
+
+  StoredDeclsList &List = (*Map)[Name];
   for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
-    (*Map)[Decls[I].Name].setFromDeclIDs(Decls[I].Declarations);
+    if (List.isNull())
+      List.setOnlyValue(Decls[I]);
+    else
+      List.AddSubsequentDecl(Decls[I]);
   }
+
+  return List.getLookupResult();
+}
+
+void ExternalASTSource::MaterializeVisibleDeclsForName(const DeclContext *DC,
+                                                       DeclarationName Name,
+                                     llvm::SmallVectorImpl<NamedDecl*> &Decls) {
+  assert(DC->LookupPtr);
+  StoredDeclsMap &Map = *DC->LookupPtr;
+
+  // If there's an entry in the table the visible decls for this name have
+  // already been deserialized.
+  if (Map.find(Name) == Map.end()) {
+    StoredDeclsList &List = Map[Name];
+    for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
+      if (List.isNull())
+        List.setOnlyValue(Decls[I]);
+      else
+        List.AddSubsequentDecl(Decls[I]);
+    }
+  }
+}
+
+DeclContext::decl_iterator DeclContext::noload_decls_begin() const {
+  return decl_iterator(FirstDecl);
+}
+
+DeclContext::decl_iterator DeclContext::noload_decls_end() const {
+  return decl_iterator();
 }
 
 DeclContext::decl_iterator DeclContext::decls_begin() const {
@@ -801,8 +814,17 @@
   if (PrimaryContext != this)
     return PrimaryContext->lookup(Name);
 
-  if (hasExternalVisibleStorage())
-    LoadVisibleDeclsFromExternalStorage();
+  if (hasExternalVisibleStorage()) {
+    // Check to see if we've already cached the lookup results.
+    if (LookupPtr) {
+      StoredDeclsMap::iterator I = LookupPtr->find(Name);
+      if (I != LookupPtr->end())
+        return I->second.getLookupResult();
+    }
+
+    ExternalASTSource *Source = getParentASTContext().getExternalSource();
+    return Source->FindExternalVisibleDeclsByName(this, Name);
+  }
 
   /// If there is no lookup data structure, build one now by walking
   /// all of the linked DeclContexts (in declaration order!) and
@@ -811,13 +833,13 @@
     buildLookup(this);
 
     if (!LookupPtr)
-      return lookup_result(0, 0);
+      return lookup_result(lookup_iterator(0), lookup_iterator(0));
   }
 
   StoredDeclsMap::iterator Pos = LookupPtr->find(Name);
   if (Pos == LookupPtr->end())
-    return lookup_result(0, 0);
-  return Pos->second.getLookupResult(getParentASTContext());
+    return lookup_result(lookup_iterator(0), lookup_iterator(0));
+  return Pos->second.getLookupResult();
 }
 
 DeclContext::lookup_const_result
@@ -858,9 +880,10 @@
   }
 
   // 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)
+  // into it. If we haven't deserialized externally stored decls, deserialize
+  // them so we can add the decl. Otherwise, be lazy and don't build that
+  // structure until someone asks for it.
+  if (LookupPtr || !Recoverable || hasExternalVisibleStorage())
     makeDeclVisibleInContextImpl(D);
 
   // If we are a transparent context, insert into our parent context,
@@ -886,6 +909,15 @@
     CreateStoredDeclsMap(*C);
   }
 
+  // If there is an external AST source, load any declarations it knows about
+  // with this declaration's name.
+  // If the lookup table contains an entry about this name it means that we
+  // have already checked the external source.
+  if (ExternalASTSource *Source = getParentASTContext().getExternalSource())
+    if (hasExternalVisibleStorage() &&
+        LookupPtr->find(D->getDeclName()) == LookupPtr->end())
+      Source->FindExternalVisibleDeclsByName(this, D->getDeclName());
+
   // Insert this declaration into the map.
   StoredDeclsList &DeclNameEntries = (*LookupPtr)[D->getDeclName()];
   if (DeclNameEntries.isNull()) {
@@ -896,16 +928,22 @@
   // 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))
+  if (DeclNameEntries.HandleRedeclaration(D))
     return;
 
   // Put this declaration into the appropriate slot.
   DeclNameEntries.AddSubsequentDecl(D);
 }
 
+void DeclContext::MaterializeVisibleDeclsFromExternalStorage() {
+  ExternalASTSource *Source = getParentASTContext().getExternalSource();
+  assert(hasExternalVisibleStorage() && Source && "No external storage?");
+
+  if (!LookupPtr)
+    CreateStoredDeclsMap(getParentASTContext());
+  Source->MaterializeVisibleDecls(this);
+}
+
 /// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
 /// this context.
 DeclContext::udir_iterator_range
@@ -915,43 +953,6 @@
                              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.                               //
 //===----------------------------------------------------------------------===//
@@ -977,7 +978,6 @@
   // 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());
 }
 
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index e6e9ee6..eed3702 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -32,6 +32,8 @@
     Abstract(false), HasTrivialConstructor(true),
     HasTrivialCopyConstructor(true), HasTrivialCopyAssignment(true),
     HasTrivialDestructor(true), ComputedVisibleConversions(false),
+    DeclaredDefaultConstructor(false), DeclaredCopyConstructor(false), 
+    DeclaredCopyAssignment(false), DeclaredDestructor(false),
     Bases(0), NumBases(0), VBases(0), NumVBases(0),
     Definition(D), FirstFriend(0) {
 }
@@ -58,16 +60,9 @@
   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);
+CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) CXXRecordDecl(CXXRecord, TTK_Struct, 0, SourceLocation(), 0, 0,
+                               SourceLocation());
 }
 
 void
@@ -126,19 +121,19 @@
   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();
-    
+    TypeSourceInfo *VBaseTypeInfo = VBases[I]->getTypeSourceInfo();
+
     // Skip dependent types; we can't do any checking on them now.
-    if (VBaseType->isDependentType())
+    if (VBaseTypeInfo->getType()->isDependentType())
       continue;
 
-    CXXRecordDecl *VBaseClassDecl
-      = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl());
+    CXXRecordDecl *VBaseClassDecl = cast<CXXRecordDecl>(
+      VBaseTypeInfo->getType()->getAs<RecordType>()->getDecl());
 
     data().VBases[I] =
       CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true,
-                       VBaseClassDecl->getTagKind() == RecordDecl::TK_class,
-                       VBases[I]->getAccessSpecifier(), VBaseType);
+                       VBaseClassDecl->getTagKind() == TTK_Class,
+                       VBases[I]->getAccessSpecifier(), VBaseTypeInfo);
   }
 }
 
@@ -159,6 +154,29 @@
   return getCopyConstructor(Context, Qualifiers::Const) != 0;
 }
 
+/// \brief Perform a simplistic form of overload resolution that only considers
+/// cv-qualifiers on a single parameter, and return the best overload candidate
+/// (if there is one).
+static CXXMethodDecl *
+GetBestOverloadCandidateSimple(
+  const llvm::SmallVectorImpl<std::pair<CXXMethodDecl *, Qualifiers> > &Cands) {
+  if (Cands.empty())
+    return 0;
+  if (Cands.size() == 1)
+    return Cands[0].first;
+  
+  unsigned Best = 0, N = Cands.size();
+  for (unsigned I = 1; I != N; ++I)
+    if (Cands[Best].second.isSupersetOf(Cands[I].second))
+      Best = I;
+  
+  for (unsigned I = 1; I != N; ++I)
+    if (Cands[Best].second.isSupersetOf(Cands[I].second))
+      return 0;
+  
+  return Cands[Best].first;
+}
+
 CXXConstructorDecl *CXXRecordDecl::getCopyConstructor(ASTContext &Context,
                                                       unsigned TypeQuals) const{
   QualType ClassType
@@ -167,6 +185,7 @@
     = Context.DeclarationNames.getCXXConstructorName(
                                           Context.getCanonicalType(ClassType));
   unsigned FoundTQs;
+  llvm::SmallVector<std::pair<CXXMethodDecl *, Qualifiers>, 4> Found;
   DeclContext::lookup_const_iterator Con, ConEnd;
   for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName);
        Con != ConEnd; ++Con) {
@@ -175,61 +194,68 @@
     if (isa<FunctionTemplateDecl>(*Con))
       continue;
 
-    if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(FoundTQs)) {
+    CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
+    if (Constructor->isCopyConstructor(FoundTQs)) {
       if (((TypeQuals & Qualifiers::Const) == (FoundTQs & Qualifiers::Const)) ||
           (!(TypeQuals & Qualifiers::Const) && (FoundTQs & Qualifiers::Const)))
-        return cast<CXXConstructorDecl>(*Con);
-
+        Found.push_back(std::make_pair(
+                                 const_cast<CXXConstructorDecl *>(Constructor), 
+                                       Qualifiers::fromCVRMask(FoundTQs)));
     }
   }
-  return 0;
+  
+  return cast_or_null<CXXConstructorDecl>(
+                                        GetBestOverloadCandidateSimple(Found));
 }
 
-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);
-
+CXXMethodDecl *CXXRecordDecl::getCopyAssignmentOperator(bool ArgIsConst) const {
+  ASTContext &Context = getASTContext();
+  QualType Class = Context.getTypeDeclType(const_cast<CXXRecordDecl *>(this));
+  DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal);
+  
+  llvm::SmallVector<std::pair<CXXMethodDecl *, Qualifiers>, 4> Found;
   DeclContext::lookup_const_iterator Op, OpEnd;
-  for (llvm::tie(Op, OpEnd) = this->lookup(OpName);
-       Op != OpEnd; ++Op) {
+  for (llvm::tie(Op, OpEnd) = this->lookup(Name); 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)
+    if (!Method || Method->isStatic() || Method->getPrimaryTemplate())
       continue;
-
-    if (Method->isStatic())
-      continue;
-    if (Method->getPrimaryTemplate())
-      continue;
-    const FunctionProtoType *FnType =
-      Method->getType()->getAs<FunctionProtoType>();
+    
+    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);
+    Qualifiers Quals;
     if (const LValueReferenceType *Ref = ArgType->getAs<LValueReferenceType>()) {
       ArgType = Ref->getPointeeType();
-      // Is it a non-const lvalue reference?
-      if (!ArgType.isConstQualified())
-        AcceptsConst = false;
+      // If we have a const argument and we have a reference to a non-const,
+      // this function does not match.
+      if (ArgIsConst && !ArgType.isConstQualified())
+        continue;
+      
+      Quals = ArgType.getQualifiers();
+    } else {
+      // By-value copy-assignment operators are treated like const X&
+      // copy-assignment operators.
+      Quals = Qualifiers::fromCVRMask(Qualifiers::Const);
     }
-    if (!Context.hasSameUnqualifiedType(ArgType, ClassType))
+    
+    if (!Context.hasSameUnqualifiedType(ArgType, Class))
       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;
+
+    // Save this copy-assignment operator. It might be "the one".
+    Found.push_back(std::make_pair(const_cast<CXXMethodDecl *>(Method), Quals));
   }
-  assert(isInvalidDecl() &&
-         "No copy assignment operator declared in valid code.");
-  return false;
+  
+  // Use a simplistic form of overload resolution to find the candidate.
+  return GetBestOverloadCandidateSimple(Found);
 }
 
 void
@@ -239,6 +265,9 @@
   // Note that we have a user-declared constructor.
   data().UserDeclaredConstructor = true;
 
+  // Note that we have no need of an implicitly-declared default constructor.
+  data().DeclaredDefaultConstructor = true;
+  
   // C++ [dcl.init.aggr]p1:
   //   An aggregate is an array or a class (clause 9) with no
   //   user-declared constructors (12.1) [...].
@@ -258,11 +287,13 @@
   // suppress the implicit declaration of a copy constructor.
   if (ConDecl->isCopyConstructor()) {
     data().UserDeclaredCopyConstructor = true;
-
+    data().DeclaredCopyConstructor = 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;
+    
   }
 }
 
@@ -294,7 +325,8 @@
 
   // Suppress the implicit declaration of a copy constructor.
   data().UserDeclaredCopyAssignment = true;
-
+  data().DeclaredCopyAssignment = 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.
@@ -546,7 +578,8 @@
 }
 
 CXXConstructorDecl *
-CXXRecordDecl::getDefaultConstructor(ASTContext &Context) {
+CXXRecordDecl::getDefaultConstructor() {
+  ASTContext &Context = getASTContext();
   QualType ClassType = Context.getTypeDeclType(this);
   DeclarationName ConstructorName
     = Context.DeclarationNames.getCXXConstructorName(
@@ -566,7 +599,8 @@
   return 0;
 }
 
-CXXDestructorDecl *CXXRecordDecl::getDestructor(ASTContext &Context) const {
+CXXDestructorDecl *CXXRecordDecl::getDestructor() const {
+  ASTContext &Context = getASTContext();
   QualType ClassType = Context.getTypeDeclType(this);
 
   DeclarationName Name
@@ -585,10 +619,10 @@
 
 CXXMethodDecl *
 CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
-                      SourceLocation L, DeclarationName N,
+                      const DeclarationNameInfo &NameInfo,
                       QualType T, TypeSourceInfo *TInfo,
                       bool isStatic, StorageClass SCAsWritten, bool isInline) {
-  return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, TInfo,
+  return new (C) CXXMethodDecl(CXXMethod, RD, NameInfo, T, TInfo,
                                isStatic, SCAsWritten, isInline);
 }
 
@@ -633,6 +667,27 @@
   return true;
 }
 
+bool CXXMethodDecl::isCopyAssignmentOperator() const {
+  // C++0x [class.copy]p19:
+  //  A user-declared copy assignment operator X::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&.
+  if (/*operator=*/getOverloadedOperator() != OO_Equal ||
+      /*non-static*/ isStatic() || 
+      /*non-template*/getPrimaryTemplate() || getDescribedFunctionTemplate() ||
+      /*exactly one parameter*/getNumParams() != 1)
+    return false;
+      
+  QualType ParamType = getParamDecl(0)->getType();
+  if (const LValueReferenceType *Ref = ParamType->getAs<LValueReferenceType>())
+    ParamType = Ref->getPointeeType();
+  
+  ASTContext &Context = getASTContext();
+  QualType ClassType
+    = Context.getCanonicalType(Context.getTypeDeclType(getParent()));
+  return Context.hasSameUnqualifiedType(ClassType, ParamType);
+}
+
 void CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) {
   assert(MD->isCanonicalDecl() && "Method is not canonical!");
   assert(!MD->getParent()->isDependentContext() &&
@@ -649,6 +704,10 @@
   return getASTContext().overridden_methods_end(this);
 }
 
+unsigned CXXMethodDecl::size_overridden_methods() const {
+  return getASTContext().overridden_methods_size(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*,
@@ -672,15 +731,16 @@
     CheckFn = this;
   
   const FunctionDecl *fn;
-  return CheckFn->getBody(fn) && !fn->isOutOfLine();
+  return CheckFn->hasBody(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) 
+  : BaseOrMember(TInfo), Init(Init), AnonUnionMember(0),
+    LParenLoc(L), RParenLoc(R), IsVirtual(IsVirtual), IsWritten(false),
+    SourceOrderOrNumArrayIndices(0)
 {
 }
 
@@ -688,15 +748,40 @@
 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) 
+  : BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init),
+    AnonUnionMember(0), LParenLoc(L), RParenLoc(R), IsVirtual(false),
+    IsWritten(false), SourceOrderOrNumArrayIndices(0)
 {
 }
 
-void CXXBaseOrMemberInitializer::Destroy(ASTContext &Context) {
-  if (Init)
-    Init->Destroy(Context);
-  this->~CXXBaseOrMemberInitializer();
+CXXBaseOrMemberInitializer::
+CXXBaseOrMemberInitializer(ASTContext &Context,
+                           FieldDecl *Member, SourceLocation MemberLoc,
+                           SourceLocation L, Expr *Init, SourceLocation R,
+                           VarDecl **Indices,
+                           unsigned NumIndices)
+  : BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init), 
+    AnonUnionMember(0), LParenLoc(L), RParenLoc(R), IsVirtual(false),
+    IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices)
+{
+  VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1);
+  memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *));
+}
+
+CXXBaseOrMemberInitializer *
+CXXBaseOrMemberInitializer::Create(ASTContext &Context,
+                                   FieldDecl *Member, 
+                                   SourceLocation MemberLoc,
+                                   SourceLocation L,
+                                   Expr *Init,
+                                   SourceLocation R,
+                                   VarDecl **Indices,
+                                   unsigned NumIndices) {
+  void *Mem = Context.Allocate(sizeof(CXXBaseOrMemberInitializer) +
+                               sizeof(VarDecl *) * NumIndices,
+                               llvm::alignof<CXXBaseOrMemberInitializer>());
+  return new (Mem) CXXBaseOrMemberInitializer(Context, Member, MemberLoc,
+                                              L, Init, R, Indices, NumIndices);
 }
 
 TypeLoc CXXBaseOrMemberInitializer::getBaseClassLoc() const {
@@ -724,7 +809,7 @@
   if (isMemberInitializer())
     return getMemberLocation();
   
-  return getBaseClassLoc().getSourceRange().getBegin();
+  return getBaseClassLoc().getLocalSourceRange().getBegin();
 }
 
 SourceRange CXXBaseOrMemberInitializer::getSourceRange() const {
@@ -732,15 +817,22 @@
 }
 
 CXXConstructorDecl *
+CXXConstructorDecl::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) CXXConstructorDecl(0, DeclarationNameInfo(),
+                                    QualType(), 0, false, false, false);
+}
+
+CXXConstructorDecl *
 CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
-                           SourceLocation L, DeclarationName N,
+                           const DeclarationNameInfo &NameInfo,
                            QualType T, TypeSourceInfo *TInfo,
                            bool isExplicit,
                            bool isInline,
                            bool isImplicitlyDeclared) {
-  assert(N.getNameKind() == DeclarationName::CXXConstructorName &&
+  assert(NameInfo.getName().getNameKind()
+         == DeclarationName::CXXConstructorName &&
          "Name must refer to a constructor");
-  return new (C) CXXConstructorDecl(RD, L, N, T, TInfo, isExplicit,
+  return new (C) CXXConstructorDecl(RD, NameInfo, T, TInfo, isExplicit,
                                     isInline, isImplicitlyDeclared);
 }
 
@@ -834,29 +926,39 @@
 }
 
 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);
+CXXDestructorDecl::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) CXXDestructorDecl(0, DeclarationNameInfo(),
+                                   QualType(), false, false);
 }
 
-void
-CXXConstructorDecl::Destroy(ASTContext& C) {
-  C.Deallocate(BaseOrMemberInitializers);
-  CXXMethodDecl::Destroy(C);
+CXXDestructorDecl *
+CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
+                          const DeclarationNameInfo &NameInfo,
+                          QualType T, bool isInline,
+                          bool isImplicitlyDeclared) {
+  assert(NameInfo.getName().getNameKind()
+         == DeclarationName::CXXDestructorName &&
+         "Name must refer to a destructor");
+  return new (C) CXXDestructorDecl(RD, NameInfo, T, isInline,
+                                   isImplicitlyDeclared);
+}
+
+CXXConversionDecl *
+CXXConversionDecl::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) CXXConversionDecl(0, DeclarationNameInfo(),
+                                   QualType(), 0, false, false);
 }
 
 CXXConversionDecl *
 CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
-                          SourceLocation L, DeclarationName N,
+                          const DeclarationNameInfo &NameInfo,
                           QualType T, TypeSourceInfo *TInfo,
                           bool isInline, bool isExplicit) {
-  assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName &&
+  assert(NameInfo.getName().getNameKind()
+         == DeclarationName::CXXConversionFunctionName &&
          "Name must refer to a conversion function");
-  return new (C) CXXConversionDecl(RD, L, N, T, TInfo, isInline, isExplicit);
+  return new (C) CXXConversionDecl(RD, NameInfo, T, TInfo,
+                                   isInline, isExplicit);
 }
 
 LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
@@ -887,6 +989,12 @@
   return cast_or_null<NamespaceDecl>(NominatedNamespace);
 }
 
+void UsingDirectiveDecl::setNominatedNamespace(NamedDecl* ND) {
+  assert((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
+    "expected a NamespaceDecl or NamespaceAliasDecl");
+  NominatedNamespace = ND;
+}
+
 NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
                                                SourceLocation L,
                                                SourceLocation AliasLoc,
@@ -902,10 +1010,11 @@
 }
 
 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);
+                             SourceRange NNR, SourceLocation UL,
+                             NestedNameSpecifier* TargetNNS,
+                             const DeclarationNameInfo &NameInfo,
+                             bool IsTypeNameArg) {
+  return new (C) UsingDecl(DC, NNR, UL, TargetNNS, NameInfo, IsTypeNameArg);
 }
 
 UnresolvedUsingValueDecl *
@@ -913,11 +1022,9 @@
                                  SourceLocation UsingLoc,
                                  SourceRange TargetNNR,
                                  NestedNameSpecifier *TargetNNS,
-                                 SourceLocation TargetNameLoc,
-                                 DeclarationName TargetName) {
+                                 const DeclarationNameInfo &NameInfo) {
   return new (C) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
-                                          TargetNNR, TargetNNS,
-                                          TargetNameLoc, TargetName);
+                                          TargetNNR, TargetNNS, NameInfo);
 }
 
 UnresolvedUsingTypenameDecl *
@@ -940,15 +1047,6 @@
   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:
@@ -968,5 +1066,3 @@
                                            AccessSpecifier AS) {
   return DB << getAccessName(AS);
 }
-
-
diff --git a/lib/AST/DeclFriend.cpp b/lib/AST/DeclFriend.cpp
index ab3552d..99bfe40 100644
--- a/lib/AST/DeclFriend.cpp
+++ b/lib/AST/DeclFriend.cpp
@@ -39,3 +39,7 @@
   cast<CXXRecordDecl>(DC)->pushFriendDecl(FD);
   return FD;
 }
+
+FriendDecl *FriendDecl::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) FriendDecl(Empty);
+}
diff --git a/lib/AST/DeclGroup.cpp b/lib/AST/DeclGroup.cpp
index 434bf00..036acc2 100644
--- a/lib/AST/DeclGroup.cpp
+++ b/lib/AST/DeclGroup.cpp
@@ -30,9 +30,3 @@
   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
index dc4aacd..28c7a49 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -21,14 +21,8 @@
 // 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!");
+  List = 0;
   if (Elts == 0) return;  // Setting to an empty list is a noop.
 
 
@@ -47,12 +41,6 @@
   set(InList, Elts, Ctx);
 }
 
-void ObjCProtocolList::Destroy(ASTContext &Ctx) {
-  Ctx.Deallocate(Locations);
-  Locations = 0;
-  ObjCList<ObjCProtocolDecl>::Destroy(Ctx);
-}
-
 //===----------------------------------------------------------------------===//
 // ObjCInterfaceDecl
 //===----------------------------------------------------------------------===//
@@ -218,22 +206,28 @@
     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;
+/// getFirstClassExtension - Find first class extension of the given class.
+ObjCCategoryDecl* ObjCInterfaceDecl::getFirstClassExtension() const {
+  for (ObjCCategoryDecl *CDecl = getCategoryList(); CDecl;
        CDecl = CDecl->getNextClassCategory())
     if (CDecl->IsClassExtension())
       return CDecl;
   return 0;
 }
 
+/// getNextClassCategory - Find next class extension in list of categories.
+const ObjCCategoryDecl* ObjCCategoryDecl::getNextClassExtension() const {
+  for (const ObjCCategoryDecl *CDecl = getNextClassCategory(); CDecl; 
+        CDecl = CDecl->getNextClassCategory())
+    if (CDecl->IsClassExtension())
+      return CDecl;
+  return 0;
+}
+
 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
                                               ObjCInterfaceDecl *&clsDeclared) {
   ObjCInterfaceDecl* ClassDecl = this;
@@ -242,11 +236,13 @@
       clsDeclared = ClassDecl;
       return I;
     }
-    if (const ObjCCategoryDecl *CDecl = ClassDecl->getClassExtension())
+    for (const ObjCCategoryDecl *CDecl = ClassDecl->getFirstClassExtension();
+         CDecl; CDecl = CDecl->getNextClassExtension()) {
       if (ObjCIvarDecl *I = CDecl->getIvarDecl(ID)) {
         clsDeclared = ClassDecl;
         return I;
       }
+    }
       
     ClassDecl = ClassDecl->getSuperClass();
   }
@@ -330,27 +326,17 @@
                                        bool isInstance,
                                        bool isVariadic,
                                        bool isSynthesized,
+                                       bool isDefined,
                                        ImplementationControl impControl,
                                        unsigned numSelectorArgs) {
   return new (C) ObjCMethodDecl(beginLoc, endLoc,
                                 SelInfo, T, ResultTInfo, contextDecl,
                                 isInstance,
-                                isVariadic, isSynthesized, impControl,
+                                isVariadic, isSynthesized, isDefined,
+                                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.
@@ -456,22 +442,11 @@
                   SourceLocation CLoc, bool FD, bool isInternal)
   : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
     TypeForDecl(0), SuperClass(0),
-    CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
+    CategoryList(0), IvarList(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));
@@ -481,6 +456,49 @@
   getASTContext().setObjCImplementation(this, ImplD);
 }
 
+/// all_declared_ivar_begin - return first ivar declared in this class,
+/// its extensions and its implementation. Lazily build the list on first
+/// access.
+ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
+  if (IvarList)
+    return IvarList;
+  
+  ObjCIvarDecl *curIvar = 0;
+  if (!ivar_empty()) {
+    ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
+    IvarList = (*I); ++I;
+    for (curIvar = IvarList; I != E; curIvar = *I, ++I)
+      curIvar->setNextIvar(*I);
+  }
+  
+  for (const ObjCCategoryDecl *CDecl = getFirstClassExtension(); CDecl;
+       CDecl = CDecl->getNextClassExtension()) {
+    if (!CDecl->ivar_empty()) {
+      ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
+                                          E = CDecl->ivar_end();
+      if (!IvarList) {
+        IvarList = (*I); ++I;
+        curIvar = IvarList;
+      }
+      for ( ;I != E; curIvar = *I, ++I)
+        curIvar->setNextIvar(*I);
+    }
+  }
+  
+  if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
+    if (!ImplDecl->ivar_empty()) {
+      ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
+                                            E = ImplDecl->ivar_end();
+      if (!IvarList) {
+        IvarList = (*I); ++I;
+        curIvar = IvarList;
+      }
+      for ( ;I != E; curIvar = *I, ++I)
+        curIvar->setNextIvar(*I);
+    }
+  }
+  return IvarList;
+}
 
 /// FindCategoryDeclaration - Finds category declaration in the list of
 /// categories for this class and returns it. Name of the category is passed
@@ -566,7 +584,8 @@
 ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
                                    SourceLocation L, IdentifierInfo *Id,
                                    QualType T, TypeSourceInfo *TInfo,
-                                   AccessControl ac, Expr *BW) {
+                                   AccessControl ac, Expr *BW,
+                                   bool synthesized) {
   if (DC) {
     // Ivar's can only appear in interfaces, implementations (via synthesized
     // properties), and class extensions (via direct declaration, or synthesized
@@ -581,9 +600,26 @@
     assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
             isa<ObjCCategoryDecl>(DC)) &&
            "Invalid ivar decl context!");
+    // Once a new ivar is created in any of class/class-extension/implementation
+    // decl contexts, the previously built IvarList must be rebuilt.
+    ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(DC);
+    if (!ID) {
+      if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC)) {
+        ID = IM->getClassInterface();
+        if (BW)
+          IM->setHasSynthBitfield(true);
+      }
+      else {
+        ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
+        ID = CD->getClassInterface();
+        if (BW)
+          CD->setHasSynthBitfield(true);
+      }
+    }
+    ID->setIvarList(0);
   }
 
-  return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW);
+  return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW, synthesized);
 }
 
 const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
@@ -621,11 +657,6 @@
   return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
 }
 
-void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
-  this->~ObjCAtDefsFieldDecl();
-  C.Deallocate((void *)this);
-}
-
 //===----------------------------------------------------------------------===//
 // ObjCProtocolDecl
 //===----------------------------------------------------------------------===//
@@ -636,11 +667,6 @@
   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;
 
@@ -700,23 +726,6 @@
   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);
@@ -745,11 +754,6 @@
   return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, Locs, C);
 }
 
-void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
-  ReferencedProtocols.Destroy(C);
-  Decl::Destroy(C);
-}
-
 //===----------------------------------------------------------------------===//
 // ObjCCategoryDecl
 //===----------------------------------------------------------------------===//
@@ -887,7 +891,7 @@
                                            SourceLocation L,
                                            IdentifierInfo *Id,
                                            SourceLocation AtLoc,
-                                           QualType T,
+                                           TypeSourceInfo *T,
                                            PropertyControl propControl) {
   return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, T);
 }
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 5394924..f18d2f0 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -183,7 +183,7 @@
   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;
+  case AS_private:   Out << "private"; break;
   }
 }
 
@@ -195,31 +195,27 @@
   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) {
+
+    // Don't print ObjCIvarDecls, as they are printed when visiting the
+    // containing ObjCInterfaceDecl.
+    if (isa<ObjCIvarDecl>(*D))
+      continue;
+
     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;
+      // of __builtin_va_list or __[u]int128_t.  There should be some other way
+      // to check that.
+      if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) {
+        if (IdentifierInfo *II = ND->getIdentifier()) {
+          if (II->isStr("__builtin_va_list") ||
+              II->isStr("__int128_t") || II->isStr("__uint128_t"))
+            continue;
+        }
       }
     }
 
@@ -251,6 +247,16 @@
       Decls.push_back(*D);
       continue;
     }
+
+    if (isa<AccessSpecDecl>(*D)) {
+      Indentation -= Policy.Indentation;
+      this->Indent();
+      Print(D->getAccess());
+      Out << ":\n";
+      Indentation += Policy.Indentation;
+      continue;
+    }
+
     this->Indent();
     Visit(*D);
 
@@ -329,10 +335,11 @@
 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;
+    case SC_None: break;
+    case SC_Extern: Out << "extern "; break;
+    case SC_Static: Out << "static "; break;
+    case SC_PrivateExtern: Out << "__private_extern__ "; break;
+    case SC_Auto: case SC_Register: llvm_unreachable("invalid for functions");
     }
 
     if (D->isInlineSpecified())           Out << "inline ";
@@ -341,7 +348,7 @@
 
   PrintingPolicy SubPolicy(Policy);
   SubPolicy.SuppressSpecifiers = false;
-  std::string Proto = D->getNameAsString();
+  std::string Proto = D->getNameInfo().getAsString();
   if (isa<FunctionType>(D->getType().getTypePtr())) {
     const FunctionType *AFT = D->getType()->getAs<FunctionType>();
 
@@ -406,7 +413,8 @@
             FieldDecl *FD = BMInitializer->getMember();
             Out << FD;
           } else {
-            Out << QualType(BMInitializer->getBaseClass(), 0).getAsString();
+            Out << QualType(BMInitializer->getBaseClass(),
+                            0).getAsString(Policy);
           }
           
           Out << "(";
@@ -498,7 +506,7 @@
 }
 
 void DeclPrinter::VisitVarDecl(VarDecl *D) {
-  if (!Policy.SuppressSpecifiers && D->getStorageClass() != VarDecl::None)
+  if (!Policy.SuppressSpecifiers && D->getStorageClass() != SC_None)
     Out << VarDecl::getStorageClassSpecifierString(D->getStorageClass()) << " ";
 
   if (!Policy.SuppressSpecifiers && D->isThreadSpecified())
@@ -653,7 +661,11 @@
 
   Out << "> ";
 
-  Visit(D->getTemplatedDecl());
+  if (isa<TemplateTemplateParmDecl>(D)) {
+    Out << "class " << D->getName();
+  } else {
+    Visit(D->getTemplatedDecl());
+  }
 }
 
 //----------------------------------------------------------------------------
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index e3d30a0..e69338a 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -84,16 +84,69 @@
 }
 
 //===----------------------------------------------------------------------===//
-// TemplateDecl Implementation
+// RedeclarableTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
 
-TemplateDecl::~TemplateDecl() {
+RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() {
+  // Find the first declaration of this function template.
+  RedeclarableTemplateDecl *First = getCanonicalDecl();
+
+  if (First->CommonOrPrev.isNull()) {
+    CommonBase *CommonPtr = First->newCommon();
+    First->CommonOrPrev = CommonPtr;
+    CommonPtr->Latest = First;
+  }
+  return First->CommonOrPrev.get<CommonBase*>();
+}
+
+
+RedeclarableTemplateDecl *RedeclarableTemplateDecl::getCanonicalDeclImpl() {
+  RedeclarableTemplateDecl *Tmpl = this;
+  while (Tmpl->getPreviousDeclaration())
+    Tmpl = Tmpl->getPreviousDeclaration();
+  return Tmpl;
+}
+
+void RedeclarableTemplateDecl::setPreviousDeclarationImpl(
+                                               RedeclarableTemplateDecl *Prev) {
+  if (Prev) {
+    CommonBase *Common = Prev->getCommonPtr();
+    Prev = Common->Latest;
+    Common->Latest = this;
+    CommonOrPrev = Prev;
+  } else {
+    assert(CommonOrPrev.is<CommonBase*>() && "Cannot reset TemplateDecl Prev");
+  }
+}
+
+RedeclarableTemplateDecl *RedeclarableTemplateDecl::getNextRedeclaration() {
+  if (CommonOrPrev.is<RedeclarableTemplateDecl*>())
+    return CommonOrPrev.get<RedeclarableTemplateDecl*>();
+  CommonBase *Common = CommonOrPrev.get<CommonBase*>();
+  return Common ? Common->Latest : this;
+}
+
+template <class EntryType>
+typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
+RedeclarableTemplateDecl::findSpecializationImpl(
+                                 llvm::FoldingSet<EntryType> &Specs,
+                                 const TemplateArgument *Args, unsigned NumArgs,
+                                 void *&InsertPos) {
+  typedef SpecEntryTraits<EntryType> SETraits;
+  llvm::FoldingSetNodeID ID;
+  EntryType::Profile(ID,Args,NumArgs, getASTContext());
+  EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
+  return Entry ? SETraits::getMostRecentDeclaration(Entry) : 0;
 }
 
 //===----------------------------------------------------------------------===//
 // FunctionTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
 
+void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
+  static_cast<Common *>(Ptr)->~Common();
+}
+
 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
                                                    DeclContext *DC,
                                                    SourceLocation L,
@@ -103,47 +156,24 @@
   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);
+RedeclarableTemplateDecl::CommonBase *FunctionTemplateDecl::newCommon() {
+  Common *CommonPtr = new (getASTContext()) Common;
+  getASTContext().AddDeallocation(DeallocateCommon, CommonPtr);
+  return CommonPtr;
 }
 
-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*>();
+FunctionDecl *
+FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
+                                         unsigned NumArgs, void *&InsertPos) {
+  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
 }
 
 //===----------------------------------------------------------------------===//
 // ClassTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
 
-ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() {
-  ClassTemplateDecl *Template = this;
-  while (Template->getPreviousDeclaration())
-    Template = Template->getPreviousDeclaration();
-  return Template;
+void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
+  static_cast<Common *>(Ptr)->~Common();
 }
 
 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
@@ -153,29 +183,43 @@
                                              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 *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
+  New->setPreviousDeclaration(PrevDecl);
+  return New;
 }
 
-ClassTemplateDecl::~ClassTemplateDecl() {
-  assert(CommonPtr == 0 && "ClassTemplateDecl must be explicitly destroyed");
+RedeclarableTemplateDecl::CommonBase *ClassTemplateDecl::newCommon() {
+  Common *CommonPtr = new (getASTContext()) Common;
+  getASTContext().AddDeallocation(DeallocateCommon, CommonPtr);
+  return CommonPtr;
 }
 
-void ClassTemplateDecl::Destroy(ASTContext& C) {
-  if (!PreviousDeclaration) {
-    CommonPtr->~Common();
-    C.Deallocate((void*)CommonPtr);
+ClassTemplateSpecializationDecl *
+ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
+                                      unsigned NumArgs, void *&InsertPos) {
+  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
+}
+
+ClassTemplatePartialSpecializationDecl *
+ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
+                                             unsigned NumArgs,
+                                             void *&InsertPos) {
+  return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
+                                InsertPos);
+}
+
+void ClassTemplateDecl::getPartialSpecializations(
+          llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
+  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &PartialSpecs
+    = getPartialSpecializations();
+  PS.clear();
+  PS.resize(PartialSpecs.size());
+  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
+       P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
+       P != PEnd; ++P) {
+    assert(!PS[P->getSequenceNumber()]);
+    PS[P->getSequenceNumber()] = P->getMostRecentDeclaration();
   }
-  CommonPtr = 0;
-
-  this->~ClassTemplateDecl();
-  C.Deallocate((void*)this);
 }
 
 ClassTemplatePartialSpecializationDecl *
@@ -187,14 +231,30 @@
                           PEnd = getPartialSpecializations().end();
        P != PEnd; ++P) {
     if (Context.hasSameType(P->getInjectedSpecializationType(), T))
-      return &*P;
+      return P->getMostRecentDeclaration();
+  }
+
+  return 0;
+}
+
+ClassTemplatePartialSpecializationDecl *
+ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
+                                    ClassTemplatePartialSpecializationDecl *D) {
+  Decl *DCanon = D->getCanonicalDecl();
+  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
+            P = getPartialSpecializations().begin(),
+         PEnd = getPartialSpecializations().end();
+       P != PEnd; ++P) {
+    if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
+      return P->getMostRecentDeclaration();
   }
 
   return 0;
 }
 
 QualType
-ClassTemplateDecl::getInjectedClassNameSpecialization(ASTContext &Context) {
+ClassTemplateDecl::getInjectedClassNameSpecialization() {
+  Common *CommonPtr = getCommonPtr();
   if (!CommonPtr->InjectedClassNameType.isNull())
     return CommonPtr->InjectedClassNameType;
 
@@ -202,7 +262,7 @@
   // 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.
-
+  ASTContext &Context = getASTContext();
   TemplateParameterList *Params = getTemplateParameters();
   llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
   TemplateArgs.reserve(Params->size());
@@ -215,7 +275,7 @@
     } else if (NonTypeTemplateParmDecl *NTTP =
                  dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
       Expr *E = new (Context) DeclRefExpr(NTTP,
-                                          NTTP->getType().getNonReferenceType(),
+                                  NTTP->getType().getNonLValueExprType(Context),
                                           NTTP->getLocation());
       TemplateArgs.push_back(TemplateArgument(E));
     } else {
@@ -244,8 +304,14 @@
   return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack);
 }
 
+TemplateTypeParmDecl *
+TemplateTypeParmDecl::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) TemplateTypeParmDecl(0, SourceLocation(), 0, false,
+                                      QualType(), false);
+}
+
 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
-  return DefaultArgument->getTypeLoc().getFullSourceRange().getBegin();
+  return DefaultArgument->getTypeLoc().getSourceRange().getBegin();
 }
 
 unsigned TemplateTypeParmDecl::getDepth() const {
@@ -269,8 +335,9 @@
 }
 
 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
-  return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
-                        : SourceLocation();
+  return hasDefaultArgument()
+    ? getDefaultArgument()->getSourceRange().getBegin()
+    : SourceLocation();
 }
 
 //===----------------------------------------------------------------------===//
@@ -289,22 +356,14 @@
 // 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!");
+void TemplateArgumentListBuilder::Append(const TemplateArgument &Arg) {
+  assert((Arg.getKind() != TemplateArgument::Type ||
+          Arg.getAsType().isCanonical()) && "Type must be canonical!");
+  assert(FlatArgs.size() < 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;
+  FlatArgs.push_back(Arg);
 }
 
 void TemplateArgumentListBuilder::BeginPack() {
@@ -312,7 +371,7 @@
   assert(!StructuredArgs && "Argument list already contains a pack!");
 
   AddingToPack = true;
-  PackBeginIndex = NumFlatArgs;
+  PackBeginIndex = FlatArgs.size();
 }
 
 void TemplateArgumentListBuilder::EndPack() {
@@ -321,6 +380,7 @@
 
   AddingToPack = false;
 
+  // FIXME: This is a memory leak!
   StructuredArgs = new TemplateArgument[MaxStructuredArgs];
 
   // First copy the flat entries over to the list  (if any)
@@ -332,22 +392,14 @@
   // Next, set the pack.
   TemplateArgument *PackArgs = 0;
   unsigned NumPackArgs = NumFlatArgs - PackBeginIndex;
+  // FIXME: NumPackArgs shouldn't be negative here???
   if (NumPackArgs)
-    PackArgs = &FlatArgs[PackBeginIndex];
+    PackArgs = FlatArgs.data()+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
 //===----------------------------------------------------------------------===//
@@ -362,45 +414,87 @@
   if (!TakeArgs)
     return;
 
-  if (Builder.getStructuredArguments() == Builder.getFlatArguments())
+  // If this does take ownership of the arguments, then we have to new them
+  // and copy over.
+  TemplateArgument *NewArgs =
+    new (Context) TemplateArgument[Builder.flatSize()];
+  std::copy(Builder.getFlatArguments(),
+            Builder.getFlatArguments()+Builder.flatSize(), NewArgs);
+  FlatArguments.setPointer(NewArgs);
+      
+  // Just reuse the structured and flat arguments array if possible.
+  if (Builder.getStructuredArguments() == Builder.getFlatArguments()) {
+    StructuredArguments.setPointer(NewArgs);    
     StructuredArguments.setInt(0);
-  Builder.ReleaseArgs();
+  } else {
+    TemplateArgument *NewSArgs =
+      new (Context) TemplateArgument[Builder.flatSize()];
+    std::copy(Builder.getFlatArguments(),
+              Builder.getFlatArguments()+Builder.flatSize(), NewSArgs);
+    StructuredArguments.setPointer(NewSArgs);
+  }
 }
 
-TemplateArgumentList::TemplateArgumentList(const TemplateArgumentList &Other)
-  : FlatArguments(Other.FlatArguments.getPointer(), 1),
-    NumFlatArguments(Other.flat_size()),
-    StructuredArguments(Other.StructuredArguments.getPointer(), 1),
-    NumStructuredArguments(Other.NumStructuredArguments) { }
+TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
+                                           const TemplateArgument *Args,
+                                           unsigned NumArgs)
+  : NumFlatArguments(0), NumStructuredArguments(0) {
+  init(Context, Args, NumArgs);
+}
 
-TemplateArgumentList::~TemplateArgumentList() {
-  // FIXME: Deallocate template arguments
+/// Produces a shallow copy of the given template argument list.  This
+/// assumes that the input argument list outlives it.  This takes the list as
+/// a pointer to avoid looking like a copy constructor, since this really
+/// really isn't safe to use that way.
+TemplateArgumentList::TemplateArgumentList(const TemplateArgumentList *Other)
+  : FlatArguments(Other->FlatArguments.getPointer(), false),
+    NumFlatArguments(Other->flat_size()),
+    StructuredArguments(Other->StructuredArguments.getPointer(), false),
+    NumStructuredArguments(Other->NumStructuredArguments) { }
+
+void TemplateArgumentList::init(ASTContext &Context,
+                           const TemplateArgument *Args,
+                           unsigned NumArgs) {
+assert(NumFlatArguments == 0 && NumStructuredArguments == 0 &&
+       "Already initialized!");
+
+NumFlatArguments = NumStructuredArguments = NumArgs;
+TemplateArgument *NewArgs = new (Context) TemplateArgument[NumArgs];
+std::copy(Args, Args+NumArgs, NewArgs);
+FlatArguments.setPointer(NewArgs);
+FlatArguments.setInt(1); // Owns the pointer.
+
+// Just reuse the flat arguments array.
+StructuredArguments.setPointer(NewArgs);    
+StructuredArguments.setInt(0); // Doesn't own the pointer.
 }
 
 //===----------------------------------------------------------------------===//
 // ClassTemplateSpecializationDecl Implementation
 //===----------------------------------------------------------------------===//
 ClassTemplateSpecializationDecl::
-ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
+ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
                                 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?
+  : CXXRecordDecl(DK, TK, DC, L,
                   SpecializedTemplate->getIdentifier(),
                   PrevDecl),
     SpecializedTemplate(SpecializedTemplate),
-    TypeAsWritten(0),
+    ExplicitInfo(0),
     TemplateArgs(Context, Builder, /*TakeArgs=*/true),
     SpecializationKind(TSK_Undeclared) {
 }
 
+ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
+  : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), 0, 0),
+    ExplicitInfo(0),
+    SpecializationKind(TSK_Undeclared) {
+}
+
 ClassTemplateSpecializationDecl *
-ClassTemplateSpecializationDecl::Create(ASTContext &Context,
+ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
                                         DeclContext *DC, SourceLocation L,
                                         ClassTemplateDecl *SpecializedTemplate,
                                         TemplateArgumentListBuilder &Builder,
@@ -408,7 +502,7 @@
   ClassTemplateSpecializationDecl *Result
     = new (Context)ClassTemplateSpecializationDecl(Context,
                                                    ClassTemplateSpecialization,
-                                                   DC, L,
+                                                   TK, DC, L,
                                                    SpecializedTemplate,
                                                    Builder,
                                                    PrevDecl);
@@ -416,12 +510,10 @@
   return Result;
 }
 
-void ClassTemplateSpecializationDecl::Destroy(ASTContext &C) {
-  if (SpecializedPartialSpecialization *PartialSpec
-        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
-    C.Deallocate(PartialSpec);
-
-  CXXRecordDecl::Destroy(C);
+ClassTemplateSpecializationDecl *
+ClassTemplateSpecializationDecl::Create(ASTContext &Context, EmptyShell Empty) {
+  return
+    new (Context)ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
 }
 
 void
@@ -450,31 +542,52 @@
 //===----------------------------------------------------------------------===//
 ClassTemplatePartialSpecializationDecl *
 ClassTemplatePartialSpecializationDecl::
-Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
+Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
        TemplateParameterList *Params,
        ClassTemplateDecl *SpecializedTemplate,
        TemplateArgumentListBuilder &Builder,
        const TemplateArgumentListInfo &ArgInfos,
        QualType CanonInjectedType,
-       ClassTemplatePartialSpecializationDecl *PrevDecl) {
+       ClassTemplatePartialSpecializationDecl *PrevDecl,
+       unsigned SequenceNumber) {
   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,
+    = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK,
                                                           DC, L, Params,
                                                           SpecializedTemplate,
                                                           Builder,
                                                           ClonedArgs, N,
-                                                          PrevDecl);
+                                                          PrevDecl,
+                                                          SequenceNumber);
   Result->setSpecializationKind(TSK_ExplicitSpecialization);
 
   Context.getInjectedClassNameType(Result, CanonInjectedType);
   return Result;
 }
 
+ClassTemplatePartialSpecializationDecl *
+ClassTemplatePartialSpecializationDecl::Create(ASTContext &Context,
+                                               EmptyShell Empty) {
+  return new (Context)ClassTemplatePartialSpecializationDecl();
+}
+
+void ClassTemplatePartialSpecializationDecl::
+initTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgInfos) {
+  assert(ArgsAsWritten == 0 && "ArgsAsWritten already set");
+  unsigned N = ArgInfos.size();
+  TemplateArgumentLoc *ClonedArgs
+    = new (getASTContext()) TemplateArgumentLoc[N];
+  for (unsigned I = 0; I != N; ++I)
+    ClonedArgs[I] = ArgInfos[I];
+  
+  ArgsAsWritten = ClonedArgs;
+  NumArgsAsWritten = N;
+}
+
 //===----------------------------------------------------------------------===//
 // FriendTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
@@ -490,3 +603,8 @@
     = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
   return Result;
 }
+
+FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
+                                               EmptyShell Empty) {
+  return new (Context) FriendTemplateDecl(Empty);
+}
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index 4f85fca..860a0b2 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -11,10 +11,12 @@
 // classes.
 //
 //===----------------------------------------------------------------------===//
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.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"
@@ -383,12 +385,12 @@
   llvm::errs() << '\n';
 }
 
-DeclarationNameTable::DeclarationNameTable() {
+DeclarationNameTable::DeclarationNameTable(ASTContext &C) : Ctx(C) {
   CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
   CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
 
   // Initialize the overloaded operator names.
-  CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
+  CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
     CXXOperatorNames[Op].ExtraKindOrNumArgs
       = Op + DeclarationNameExtra::CXXConversionFunction;
@@ -399,29 +401,12 @@
 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;
-  }
+        (CXXLiteralOperatorNames);
 
   delete SpecialNames;
   delete LiteralNames;
-  delete [] CXXOperatorNames;
 }
 
 DeclarationName
@@ -459,7 +444,7 @@
   if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
     return DeclarationName(Name);
 
-  CXXSpecialName *SpecialName = new CXXSpecialName;
+  CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
   SpecialName->ExtraKindOrNumArgs = EKind;
   SpecialName->Type = Ty;
   SpecialName->FETokenInfo = 0;
@@ -487,7 +472,7 @@
                                LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
     return DeclarationName (Name);
   
-  CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName;
+  CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
   LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
   LiteralName->ID = II;
 
@@ -501,3 +486,98 @@
   return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
 }
 
+DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
+  switch (Name.getNameKind()) {
+  case DeclarationName::Identifier:
+    break;
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName:
+    NamedType.TInfo = 0;
+    break;
+  case DeclarationName::CXXOperatorName:
+    CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
+    CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
+    break;
+  case DeclarationName::CXXLiteralOperatorName:
+    CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
+    break;
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+    // FIXME: ?
+    break;
+  case DeclarationName::CXXUsingDirective:
+    break;
+  }
+}
+
+std::string DeclarationNameInfo::getAsString() const {
+  std::string Result;
+  llvm::raw_string_ostream OS(Result);
+  printName(OS);
+  return OS.str();
+}
+
+void DeclarationNameInfo::printName(llvm::raw_ostream &OS) const {
+  switch (Name.getNameKind()) {
+  case DeclarationName::Identifier:
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+  case DeclarationName::CXXOperatorName:
+  case DeclarationName::CXXLiteralOperatorName:
+  case DeclarationName::CXXUsingDirective:
+    Name.printName(OS);
+    return;
+
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName:
+    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
+      if (Name.getNameKind() == DeclarationName::CXXDestructorName)
+        OS << '~';
+      else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
+        OS << "operator ";
+      OS << TInfo->getType().getAsString();
+    }
+    else
+      Name.printName(OS);
+    return;
+  }
+  assert(false && "Unexpected declaration name kind");
+}
+
+SourceLocation DeclarationNameInfo::getEndLoc() const {
+  switch (Name.getNameKind()) {
+  case DeclarationName::Identifier:
+    return NameLoc;
+
+  case DeclarationName::CXXOperatorName: {
+    unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
+    return SourceLocation::getFromRawEncoding(raw);
+  }
+
+  case DeclarationName::CXXLiteralOperatorName: {
+    unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
+    return SourceLocation::getFromRawEncoding(raw);
+  }
+
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName:
+    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
+      return TInfo->getTypeLoc().getEndLoc();
+    else
+      return NameLoc;
+
+    // DNInfo work in progress: FIXME.
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+  case DeclarationName::CXXUsingDirective:
+    return NameLoc;
+  }
+  assert(false && "Unexpected declaration name kind");
+  return SourceLocation();
+}
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 72ffe00..5feef1c 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -27,6 +27,8 @@
 #include <algorithm>
 using namespace clang;
 
+void Expr::ANCHOR() {} // key function for Expr class.
+
 /// 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
@@ -35,46 +37,48 @@
   // 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 (!getType()->isIntegralOrEnumerationType()) 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:
+    case UO_Plus:
+    case UO_Extension:
       return UO->getSubExpr()->isKnownToHaveBooleanValue();
     default:
       return false;
     }
   }
   
-  if (const CastExpr *CE = dyn_cast<CastExpr>(this))
+  // Only look through implicit casts.  If the user writes
+  // '(int) (a && b)' treat it as an arbitrary int.
+  if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(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.
+    case BO_LT:   // Relational operators.
+    case BO_GT:
+    case BO_LE:
+    case BO_GE:
+    case BO_EQ:   // Equality operators.
+    case BO_NE:
+    case BO_LAnd: // AND operator.
+    case BO_LOr:  // Logical OR operator.
       return true;
         
-    case BinaryOperator::And:  // Bitwise AND operator.
-    case BinaryOperator::Xor:  // Bitwise XOR operator.
-    case BinaryOperator::Or:   // Bitwise OR operator.
+    case BO_And:  // Bitwise AND operator.
+    case BO_Xor:  // Bitwise XOR operator.
+    case BO_Or:   // Bitwise OR operator.
       // Handle things like (x==2)|(y==12).
       return BO->getLHS()->isKnownToHaveBooleanValue() &&
              BO->getRHS()->isKnownToHaveBooleanValue();
         
-    case BinaryOperator::Comma:
-    case BinaryOperator::Assign:
+    case BO_Comma:
+    case BO_Assign:
       return BO->getRHS()->isKnownToHaveBooleanValue();
     }
   }
@@ -109,10 +113,14 @@
     Info.addArgument(getTemplateArgs()[I]);
 }
 
+std::size_t ExplicitTemplateArgumentList::sizeFor(unsigned NumTemplateArgs) {
+  return sizeof(ExplicitTemplateArgumentList) +
+         sizeof(TemplateArgumentLoc) * NumTemplateArgs;
+}
+
 std::size_t ExplicitTemplateArgumentList::sizeFor(
                                       const TemplateArgumentListInfo &Info) {
-  return sizeof(ExplicitTemplateArgumentList) +
-         sizeof(TemplateArgumentLoc) * Info.size();
+  return sizeFor(Info.size());
 }
 
 void DeclRefExpr::computeDependence() {
@@ -143,7 +151,7 @@
     ValueDependent = true;
   }
   //  (TD)  - a template-id that is dependent,
-  else if (hasExplicitTemplateArgumentList() && 
+  else if (hasExplicitTemplateArgs() && 
            TemplateSpecializationType::anyDependentTemplateArguments(
                                                        getTemplateArgs(), 
                                                        getNumTemplateArgs())) {
@@ -156,13 +164,24 @@
   //  (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() &&
+    if (Var->getType()->isIntegralOrEnumerationType() &&
         Var->getType().getCVRQualifiers() == Qualifiers::Const) {
       if (const Expr *Init = Var->getAnyInitializer())
         if (Init->isValueDependent())
           ValueDependent = true;
-    }
-  }
+    } 
+    // (VD) - FIXME: Missing from the standard: 
+    //      -  a member function or a static data member of the current 
+    //         instantiation
+    else if (Var->isStaticDataMember() && 
+             Var->getDeclContext()->isDependentContext())
+      ValueDependent = true;
+  } 
+  // (VD) - FIXME: Missing from the standard: 
+  //      -  a member function or a static data member of the current 
+  //         instantiation
+  else if (isa<CXXMethodDecl>(D) && D->getDeclContext()->isDependentContext())
+    ValueDependent = true;
   //  (TD)  - a nested-name-specifier or a qualified-id that names a
   //          member of an unknown specialization.
   //        (handled by DependentScopeDeclRefExpr)
@@ -185,7 +204,29 @@
   }
       
   if (TemplateArgs)
-    getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
+    getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
+
+  computeDependence();
+}
+
+DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
+                         SourceRange QualifierRange,
+                         ValueDecl *D, const DeclarationNameInfo &NameInfo,
+                         const TemplateArgumentListInfo *TemplateArgs,
+                         QualType T)
+  : Expr(DeclRefExprClass, T, false, false),
+    DecoratedD(D,
+               (Qualifier? HasQualifierFlag : 0) |
+               (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)),
+    Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) {
+  if (Qualifier) {
+    NameQualifier *NQ = getNameQualifier();
+    NQ->NNS = Qualifier;
+    NQ->Range = QualifierRange;
+  }
+
+  if (TemplateArgs)
+    getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
 
   computeDependence();
 }
@@ -197,6 +238,18 @@
                                  SourceLocation NameLoc,
                                  QualType T,
                                  const TemplateArgumentListInfo *TemplateArgs) {
+  return Create(Context, Qualifier, QualifierRange, D,
+                DeclarationNameInfo(D->getDeclName(), NameLoc),
+                T, TemplateArgs);
+}
+
+DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
+                                 NestedNameSpecifier *Qualifier,
+                                 SourceRange QualifierRange,
+                                 ValueDecl *D,
+                                 const DeclarationNameInfo &NameInfo,
+                                 QualType T,
+                                 const TemplateArgumentListInfo *TemplateArgs) {
   std::size_t Size = sizeof(DeclRefExpr);
   if (Qualifier != 0)
     Size += sizeof(NameQualifier);
@@ -205,17 +258,28 @@
     Size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
   
   void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>());
-  return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc,
+  return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameInfo,
                                TemplateArgs, T);
 }
 
-SourceRange DeclRefExpr::getSourceRange() const {
-  // FIXME: Does not handle multi-token names well, e.g., operator[].
-  SourceRange R(Loc);
+DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context, bool HasQualifier,
+                                      unsigned NumTemplateArgs) {
+  std::size_t Size = sizeof(DeclRefExpr);
+  if (HasQualifier)
+    Size += sizeof(NameQualifier);
   
+  if (NumTemplateArgs)
+    Size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
+  
+  void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>());
+  return new (Mem) DeclRefExpr(EmptyShell());
+}
+
+SourceRange DeclRefExpr::getSourceRange() const {
+  SourceRange R = getNameInfo().getSourceRange();
   if (hasQualifier())
     R.setBegin(getQualifierRange().getBegin());
-  if (hasExplicitTemplateArgumentList())
+  if (hasExplicitTemplateArgs())
     R.setEnd(getRAngleLoc());
   return R;
 }
@@ -310,6 +374,44 @@
   return "";
 }
 
+void APNumericStorage::setIntValue(ASTContext &C, const llvm::APInt &Val) {
+  if (hasAllocation())
+    C.Deallocate(pVal);
+
+  BitWidth = Val.getBitWidth();
+  unsigned NumWords = Val.getNumWords();
+  const uint64_t* Words = Val.getRawData();
+  if (NumWords > 1) {
+    pVal = new (C) uint64_t[NumWords];
+    std::copy(Words, Words + NumWords, pVal);
+  } else if (NumWords == 1)
+    VAL = Words[0];
+  else
+    VAL = 0;
+}
+
+IntegerLiteral *
+IntegerLiteral::Create(ASTContext &C, const llvm::APInt &V,
+                       QualType type, SourceLocation l) {
+  return new (C) IntegerLiteral(C, V, type, l);
+}
+
+IntegerLiteral *
+IntegerLiteral::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) IntegerLiteral(Empty);
+}
+
+FloatingLiteral *
+FloatingLiteral::Create(ASTContext &C, const llvm::APFloat &V,
+                        bool isexact, QualType Type, SourceLocation L) {
+  return new (C) FloatingLiteral(C, V, isexact, Type, L);
+}
+
+FloatingLiteral *
+FloatingLiteral::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) FloatingLiteral(Empty);
+}
+
 /// getValueAsApproximateDouble - This returns the value as an inaccurate
 /// double.  Note that this may cause loss of precision, but is useful for
 /// debugging dumps, etc.
@@ -358,15 +460,7 @@
   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;
@@ -378,48 +472,47 @@
 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";
+  case UO_PostInc: return "++";
+  case UO_PostDec: return "--";
+  case UO_PreInc:  return "++";
+  case UO_PreDec:  return "--";
+  case UO_AddrOf:  return "&";
+  case UO_Deref:   return "*";
+  case UO_Plus:    return "+";
+  case UO_Minus:   return "-";
+  case UO_Not:     return "~";
+  case UO_LNot:    return "!";
+  case UO_Real:    return "__real";
+  case UO_Imag:    return "__imag";
+  case UO_Extension: return "__extension__";
   }
 }
 
-UnaryOperator::Opcode
+UnaryOperatorKind
 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;
+  case OO_PlusPlus:   return Postfix ? UO_PostInc : UO_PreInc;
+  case OO_MinusMinus: return Postfix ? UO_PostDec : UO_PreDec;
+  case OO_Amp:        return UO_AddrOf;
+  case OO_Star:       return UO_Deref;
+  case OO_Plus:       return UO_Plus;
+  case OO_Minus:      return UO_Minus;
+  case OO_Tilde:      return UO_Not;
+  case OO_Exclaim:    return UO_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;
+  case UO_PostInc: case UO_PreInc: return OO_PlusPlus;
+  case UO_PostDec: case UO_PreDec: return OO_MinusMinus;
+  case UO_AddrOf: return OO_Amp;
+  case UO_Deref: return OO_Star;
+  case UO_Plus: return OO_Plus;
+  case UO_Minus: return OO_Minus;
+  case UO_Not: return OO_Tilde;
+  case UO_LNot: return OO_Exclaim;
   default: return OO_None;
   }
 }
@@ -464,13 +557,6 @@
   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))
@@ -494,8 +580,6 @@
 
   // 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;
   }
@@ -544,17 +628,71 @@
     CalleeType = FnTypePtr->getPointeeType();
   else if (const BlockPointerType *BPT = CalleeType->getAs<BlockPointerType>())
     CalleeType = BPT->getPointeeType();
-
+  else if (const MemberPointerType *MPT
+                                      = CalleeType->getAs<MemberPointerType>())
+    CalleeType = MPT->getPointeeType();
+    
   const FunctionType *FnType = CalleeType->getAs<FunctionType>();
   return FnType->getResultType();
 }
 
+OffsetOfExpr *OffsetOfExpr::Create(ASTContext &C, QualType type, 
+                                   SourceLocation OperatorLoc,
+                                   TypeSourceInfo *tsi, 
+                                   OffsetOfNode* compsPtr, unsigned numComps, 
+                                   Expr** exprsPtr, unsigned numExprs,
+                                   SourceLocation RParenLoc) {
+  void *Mem = C.Allocate(sizeof(OffsetOfExpr) +
+                         sizeof(OffsetOfNode) * numComps + 
+                         sizeof(Expr*) * numExprs);
+
+  return new (Mem) OffsetOfExpr(C, type, OperatorLoc, tsi, compsPtr, numComps,
+                                exprsPtr, numExprs, RParenLoc);
+}
+
+OffsetOfExpr *OffsetOfExpr::CreateEmpty(ASTContext &C,
+                                        unsigned numComps, unsigned numExprs) {
+  void *Mem = C.Allocate(sizeof(OffsetOfExpr) +
+                         sizeof(OffsetOfNode) * numComps +
+                         sizeof(Expr*) * numExprs);
+  return new (Mem) OffsetOfExpr(numComps, numExprs);
+}
+
+OffsetOfExpr::OffsetOfExpr(ASTContext &C, QualType type, 
+                           SourceLocation OperatorLoc, TypeSourceInfo *tsi,
+                           OffsetOfNode* compsPtr, unsigned numComps, 
+                           Expr** exprsPtr, unsigned numExprs,
+                           SourceLocation RParenLoc)
+  : Expr(OffsetOfExprClass, type, /*TypeDependent=*/false, 
+         /*ValueDependent=*/tsi->getType()->isDependentType() ||
+         hasAnyTypeDependentArguments(exprsPtr, numExprs) ||
+         hasAnyValueDependentArguments(exprsPtr, numExprs)),
+    OperatorLoc(OperatorLoc), RParenLoc(RParenLoc), TSInfo(tsi), 
+    NumComps(numComps), NumExprs(numExprs) 
+{
+  for(unsigned i = 0; i < numComps; ++i) {
+    setComponent(i, compsPtr[i]);
+  }
+  
+  for(unsigned i = 0; i < numExprs; ++i) {
+    setIndexExpr(i, exprsPtr[i]);
+  }
+}
+
+IdentifierInfo *OffsetOfExpr::OffsetOfNode::getFieldName() const {
+  assert(getKind() == Field || getKind() == Identifier);
+  if (getKind() == Field)
+    return getField()->getIdentifier();
+  
+  return reinterpret_cast<IdentifierInfo *> (Data & ~(uintptr_t)Mask);
+}
+
 MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow,
                                NestedNameSpecifier *qual,
                                SourceRange qualrange,
                                ValueDecl *memberdecl,
                                DeclAccessPair founddecl,
-                               SourceLocation l,
+                               DeclarationNameInfo nameinfo,
                                const TemplateArgumentListInfo *targs,
                                QualType ty) {
   std::size_t Size = sizeof(MemberExpr);
@@ -569,7 +707,7 @@
     Size += ExplicitTemplateArgumentList::sizeFor(*targs);
 
   void *Mem = C.Allocate(Size, llvm::alignof<MemberExpr>());
-  MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, l, ty);
+  MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, nameinfo, ty);
 
   if (hasQualOrFound) {
     if (qual && qual->isDependent()) {
@@ -586,7 +724,7 @@
 
   if (targs) {
     E->HasExplicitTemplateArgumentList = true;
-    E->getExplicitTemplateArgumentList()->initializeFrom(*targs);
+    E->getExplicitTemplateArgs().initializeFrom(*targs);
   }
 
   return E;
@@ -594,70 +732,68 @@
 
 const char *CastExpr::getCastKindName() const {
   switch (getCastKind()) {
-  case CastExpr::CK_Unknown:
+  case CK_Unknown:
     return "Unknown";
-  case CastExpr::CK_BitCast:
+  case CK_BitCast:
     return "BitCast";
-  case CastExpr::CK_NoOp:
+  case CK_LValueBitCast:
+    return "LValueBitCast";
+  case CK_NoOp:
     return "NoOp";
-  case CastExpr::CK_BaseToDerived:
+  case CK_BaseToDerived:
     return "BaseToDerived";
-  case CastExpr::CK_DerivedToBase:
+  case CK_DerivedToBase:
     return "DerivedToBase";
-  case CastExpr::CK_UncheckedDerivedToBase:
+  case CK_UncheckedDerivedToBase:
     return "UncheckedDerivedToBase";
-  case CastExpr::CK_Dynamic:
+  case CK_Dynamic:
     return "Dynamic";
-  case CastExpr::CK_ToUnion:
+  case CK_ToUnion:
     return "ToUnion";
-  case CastExpr::CK_ArrayToPointerDecay:
+  case CK_ArrayToPointerDecay:
     return "ArrayToPointerDecay";
-  case CastExpr::CK_FunctionToPointerDecay:
+  case CK_FunctionToPointerDecay:
     return "FunctionToPointerDecay";
-  case CastExpr::CK_NullToMemberPointer:
+  case CK_NullToMemberPointer:
     return "NullToMemberPointer";
-  case CastExpr::CK_BaseToDerivedMemberPointer:
+  case CK_BaseToDerivedMemberPointer:
     return "BaseToDerivedMemberPointer";
-  case CastExpr::CK_DerivedToBaseMemberPointer:
+  case CK_DerivedToBaseMemberPointer:
     return "DerivedToBaseMemberPointer";
-  case CastExpr::CK_UserDefinedConversion:
+  case CK_UserDefinedConversion:
     return "UserDefinedConversion";
-  case CastExpr::CK_ConstructorConversion:
+  case CK_ConstructorConversion:
     return "ConstructorConversion";
-  case CastExpr::CK_IntegralToPointer:
+  case CK_IntegralToPointer:
     return "IntegralToPointer";
-  case CastExpr::CK_PointerToIntegral:
+  case CK_PointerToIntegral:
     return "PointerToIntegral";
-  case CastExpr::CK_ToVoid:
+  case CK_ToVoid:
     return "ToVoid";
-  case CastExpr::CK_VectorSplat:
+  case CK_VectorSplat:
     return "VectorSplat";
-  case CastExpr::CK_IntegralCast:
+  case CK_IntegralCast:
     return "IntegralCast";
-  case CastExpr::CK_IntegralToFloating:
+  case CK_IntegralToFloating:
     return "IntegralToFloating";
-  case CastExpr::CK_FloatingToIntegral:
+  case CK_FloatingToIntegral:
     return "FloatingToIntegral";
-  case CastExpr::CK_FloatingCast:
+  case CK_FloatingCast:
     return "FloatingCast";
-  case CastExpr::CK_MemberPointerToBoolean:
+  case CK_MemberPointerToBoolean:
     return "MemberPointerToBoolean";
-  case CastExpr::CK_AnyPointerToObjCPointerCast:
+  case CK_AnyPointerToObjCPointerCast:
     return "AnyPointerToObjCPointerCast";
-  case CastExpr::CK_AnyPointerToBlockPointerCast:
+  case CK_AnyPointerToBlockPointerCast:
     return "AnyPointerToBlockPointerCast";
+  case CK_ObjCObjectLValueCast:
+    return "ObjCObjectLValueCast";
   }
 
   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;
@@ -670,9 +806,9 @@
     
     // Conversions by constructor and conversion functions have a
     // subexpression describing the call; strip it off.
-    if (E->getCastKind() == CastExpr::CK_ConstructorConversion)
+    if (E->getCastKind() == CK_ConstructorConversion)
       SubExpr = cast<CXXConstructExpr>(SubExpr)->getArg(0);
-    else if (E->getCastKind() == CastExpr::CK_UserDefinedConversion)
+    else if (E->getCastKind() == CK_UserDefinedConversion)
       SubExpr = cast<CXXMemberCallExpr>(SubExpr)->getImplicitObjectArgument();
     
     // If the subexpression we're left with is an implicit cast, look
@@ -682,82 +818,142 @@
   return SubExpr;
 }
 
+CXXBaseSpecifier **CastExpr::path_buffer() {
+  switch (getStmtClass()) {
+#define ABSTRACT_STMT(x)
+#define CASTEXPR(Type, Base) \
+  case Stmt::Type##Class: \
+    return reinterpret_cast<CXXBaseSpecifier**>(static_cast<Type*>(this)+1);
+#define STMT(Type, Base)
+#include "clang/AST/StmtNodes.inc"
+  default:
+    llvm_unreachable("non-cast expressions not possible here");
+    return 0;
+  }
+}
+
+void CastExpr::setCastPath(const CXXCastPath &Path) {
+  assert(Path.size() == path_size());
+  memcpy(path_buffer(), Path.data(), Path.size() * sizeof(CXXBaseSpecifier*));
+}
+
+ImplicitCastExpr *ImplicitCastExpr::Create(ASTContext &C, QualType T,
+                                           CastKind Kind, Expr *Operand,
+                                           const CXXCastPath *BasePath,
+                                           ExprValueKind VK) {
+  unsigned PathSize = (BasePath ? BasePath->size() : 0);
+  void *Buffer =
+    C.Allocate(sizeof(ImplicitCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+  ImplicitCastExpr *E =
+    new (Buffer) ImplicitCastExpr(T, Kind, Operand, PathSize, VK);
+  if (PathSize) E->setCastPath(*BasePath);
+  return E;
+}
+
+ImplicitCastExpr *ImplicitCastExpr::CreateEmpty(ASTContext &C,
+                                                unsigned PathSize) {
+  void *Buffer =
+    C.Allocate(sizeof(ImplicitCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+  return new (Buffer) ImplicitCastExpr(EmptyShell(), PathSize);
+}
+
+
+CStyleCastExpr *CStyleCastExpr::Create(ASTContext &C, QualType T,
+                                       CastKind K, Expr *Op,
+                                       const CXXCastPath *BasePath,
+                                       TypeSourceInfo *WrittenTy,
+                                       SourceLocation L, SourceLocation R) {
+  unsigned PathSize = (BasePath ? BasePath->size() : 0);
+  void *Buffer =
+    C.Allocate(sizeof(CStyleCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+  CStyleCastExpr *E =
+    new (Buffer) CStyleCastExpr(T, K, Op, PathSize, WrittenTy, L, R);
+  if (PathSize) E->setCastPath(*BasePath);
+  return E;
+}
+
+CStyleCastExpr *CStyleCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
+  void *Buffer =
+    C.Allocate(sizeof(CStyleCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+  return new (Buffer) CStyleCastExpr(EmptyShell(), PathSize);
+}
+
 /// 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 ",";
+  case BO_PtrMemD:   return ".*";
+  case BO_PtrMemI:   return "->*";
+  case BO_Mul:       return "*";
+  case BO_Div:       return "/";
+  case BO_Rem:       return "%";
+  case BO_Add:       return "+";
+  case BO_Sub:       return "-";
+  case BO_Shl:       return "<<";
+  case BO_Shr:       return ">>";
+  case BO_LT:        return "<";
+  case BO_GT:        return ">";
+  case BO_LE:        return "<=";
+  case BO_GE:        return ">=";
+  case BO_EQ:        return "==";
+  case BO_NE:        return "!=";
+  case BO_And:       return "&";
+  case BO_Xor:       return "^";
+  case BO_Or:        return "|";
+  case BO_LAnd:      return "&&";
+  case BO_LOr:       return "||";
+  case BO_Assign:    return "=";
+  case BO_MulAssign: return "*=";
+  case BO_DivAssign: return "/=";
+  case BO_RemAssign: return "%=";
+  case BO_AddAssign: return "+=";
+  case BO_SubAssign: return "-=";
+  case BO_ShlAssign: return "<<=";
+  case BO_ShrAssign: return ">>=";
+  case BO_AndAssign: return "&=";
+  case BO_XorAssign: return "^=";
+  case BO_OrAssign:  return "|=";
+  case BO_Comma:     return ",";
   }
 
   return "";
 }
 
-BinaryOperator::Opcode
+BinaryOperatorKind
 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;
+  case OO_Plus: return BO_Add;
+  case OO_Minus: return BO_Sub;
+  case OO_Star: return BO_Mul;
+  case OO_Slash: return BO_Div;
+  case OO_Percent: return BO_Rem;
+  case OO_Caret: return BO_Xor;
+  case OO_Amp: return BO_And;
+  case OO_Pipe: return BO_Or;
+  case OO_Equal: return BO_Assign;
+  case OO_Less: return BO_LT;
+  case OO_Greater: return BO_GT;
+  case OO_PlusEqual: return BO_AddAssign;
+  case OO_MinusEqual: return BO_SubAssign;
+  case OO_StarEqual: return BO_MulAssign;
+  case OO_SlashEqual: return BO_DivAssign;
+  case OO_PercentEqual: return BO_RemAssign;
+  case OO_CaretEqual: return BO_XorAssign;
+  case OO_AmpEqual: return BO_AndAssign;
+  case OO_PipeEqual: return BO_OrAssign;
+  case OO_LessLess: return BO_Shl;
+  case OO_GreaterGreater: return BO_Shr;
+  case OO_LessLessEqual: return BO_ShlAssign;
+  case OO_GreaterGreaterEqual: return BO_ShrAssign;
+  case OO_EqualEqual: return BO_EQ;
+  case OO_ExclaimEqual: return BO_NE;
+  case OO_LessEqual: return BO_LE;
+  case OO_GreaterEqual: return BO_GE;
+  case OO_AmpAmp: return BO_LAnd;
+  case OO_PipePipe: return BO_LOr;
+  case OO_Comma: return BO_Comma;
+  case OO_ArrowStar: return BO_PtrMemI;
   }
 }
 
@@ -809,9 +1005,6 @@
 }
 
 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);
 }
 
@@ -875,24 +1068,24 @@
 
     switch (UO->getOpcode()) {
     default: break;
-    case UnaryOperator::PostInc:
-    case UnaryOperator::PostDec:
-    case UnaryOperator::PreInc:
-    case UnaryOperator::PreDec:                 // ++/--
+    case UO_PostInc:
+    case UO_PostDec:
+    case UO_PreInc:
+    case UO_PreDec:                 // ++/--
       return false;  // Not a warning.
-    case UnaryOperator::Deref:
+    case UO_Deref:
       // Dereferencing a volatile pointer is a side-effect.
       if (Ctx.getCanonicalType(getType()).isVolatileQualified())
         return false;
       break;
-    case UnaryOperator::Real:
-    case UnaryOperator::Imag:
+    case UO_Real:
+    case UO_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:
+    case UO_Extension:
       return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx);
     }
     Loc = UO->getOperatorLoc();
@@ -904,18 +1097,23 @@
     switch (BO->getOpcode()) {
       default:
         break;
-      // Consider ',', '||', '&&' to have side effects if the LHS or RHS does.
-      case BinaryOperator::Comma:
+      // Consider the RHS of comma for side effects. LHS was checked by
+      // Sema::CheckCommaOperands.
+      case BO_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));
+        return BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx);
+      // Consider '||', '&&' to have side effects if the LHS or RHS does.
+      case BO_LAnd:
+      case BO_LOr:
+        if (!BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx) ||
+            !BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx))
+          return false;
+        break;
     }
     if (BO->isAssignmentOp())
       return false;
@@ -925,6 +1123,7 @@
     return true;
   }
   case CompoundAssignOperatorClass:
+  case VAArgExprClass:
     return false;
 
   case ConditionalOperatorClass: {
@@ -1043,8 +1242,8 @@
     
     // 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)
+    if (CE->getCastKind() == CK_ToVoid ||
+        CE->getCastKind() == CK_ConstructorConversion)
       return (cast<CastExpr>(this)->getSubExpr()
               ->isUnusedResultAWarning(Loc, R1, R2, Ctx));
     Loc = cast<CXXFunctionalCastExpr>(this)->getTypeBeginLoc();
@@ -1075,376 +1274,6 @@
   }
 }
 
-/// 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 {
@@ -1504,6 +1333,18 @@
   }
 }
 
+Expr *Expr::IgnoreParenImpCasts() {
+  Expr *E = this;
+  while (true) {
+    if (ParenExpr *P = dyn_cast<ParenExpr>(E))
+      E = P->getSubExpr();
+    else if (ImplicitCastExpr *P = dyn_cast<ImplicitCastExpr>(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.
@@ -1517,7 +1358,7 @@
 
     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.
+      // ptr<->int casts of the same width.  We also ignore all identity casts.
       Expr *SE = P->getSubExpr();
 
       if (Ctx.hasSameUnqualifiedType(E->getType(), SE->getType())) {
@@ -1525,8 +1366,10 @@
         continue;
       }
 
-      if ((E->getType()->isPointerType() || E->getType()->isIntegralType()) &&
-          (SE->getType()->isPointerType() || SE->getType()->isIntegralType()) &&
+      if ((E->getType()->isPointerType() || 
+           E->getType()->isIntegralType(Ctx)) &&
+          (SE->getType()->isPointerType() || 
+           SE->getType()->isIntegralType(Ctx)) &&
           Ctx.getTypeSize(E->getType()) == Ctx.getTypeSize(SE->getType())) {
         E = SE;
         continue;
@@ -1549,7 +1392,7 @@
 /// expressions.
 static const Expr *skipTemporaryBindingsAndNoOpCasts(const Expr *E) {
   while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
-    if (ICE->getCastKind() == CastExpr::CK_NoOp)
+    if (ICE->getCastKind() == CK_NoOp)
       E = ICE->getSubExpr();
     else
       break;
@@ -1559,7 +1402,7 @@
     E = BE->getSubExpr();
 
   while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
-    if (ICE->getCastKind() == CastExpr::CK_NoOp)
+    if (ICE->getCastKind() == CK_NoOp)
       E = ICE->getSubExpr();
     else
       break;
@@ -1576,8 +1419,8 @@
   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)
+    if (Cast->getCastKind() != CK_ConstructorConversion &&
+        Cast->getCastKind() != CK_UserDefinedConversion)
       return 0;
 
     // Strip off temporary bindings and no-op casts.
@@ -1585,12 +1428,12 @@
 
     // If this is a constructor conversion, see if we have an object
     // construction.
-    if (Cast->getCastKind() == CastExpr::CK_ConstructorConversion)
+    if (Cast->getCastKind() == 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 (Cast->getCastKind() == CK_UserDefinedConversion)
       if (const CallExpr *CE = dyn_cast<CallExpr>(Sub))
         if (CE->getCallReturnType()->isRecordType())
           return CE;
@@ -1630,15 +1473,20 @@
   return false;
 }
 
-bool Expr::isConstantInitializer(ASTContext &Ctx) const {
+bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef) 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!
+  // If we ever capture reference-binding directly in the AST, we can
+  // kill the second parameter.
+
+  if (IsForRef) {
+    EvalResult Result;
+    return EvaluateAsLValue(Result, Ctx) && !Result.HasSideEffects;
+  }
 
   switch (getStmtClass()) {
   default: break;
@@ -1646,12 +1494,27 @@
   case ObjCStringLiteralClass:
   case ObjCEncodeExprClass:
     return true;
+  case CXXTemporaryObjectExprClass:
+  case CXXConstructExprClass: {
+    const CXXConstructExpr *CE = cast<CXXConstructExpr>(this);
+
+    // Only if it's
+    // 1) an application of the trivial default constructor or
+    if (!CE->getConstructor()->isTrivial()) return false;
+    if (!CE->getNumArgs()) return true;
+
+    // 2) an elidable trivial copy construction of an operand which is
+    //    itself a constant initializer.  Note that we consider the
+    //    operand on its own, *not* as a reference binding.
+    return CE->isElidable() &&
+           CE->getArg(0)->isConstantInitializer(Ctx, false);
+  }
   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);
+    return Exp->isConstantInitializer(Ctx, false);
   }
   case InitListExprClass: {
     // FIXME: This doesn't deal with fields with reference types correctly.
@@ -1660,7 +1523,7 @@
     const InitListExpr *Exp = cast<InitListExpr>(this);
     unsigned numInits = Exp->getNumInits();
     for (unsigned i = 0; i < numInits; i++) {
-      if (!Exp->getInit(i)->isConstantInitializer(Ctx))
+      if (!Exp->getInit(i)->isConstantInitializer(Ctx, false))
         return false;
     }
     return true;
@@ -1668,416 +1531,47 @@
   case ImplicitValueInitExprClass:
     return true;
   case ParenExprClass:
-    return cast<ParenExpr>(this)->getSubExpr()->isConstantInitializer(Ctx);
+    return cast<ParenExpr>(this)->getSubExpr()
+      ->isConstantInitializer(Ctx, IsForRef);
   case UnaryOperatorClass: {
     const UnaryOperator* Exp = cast<UnaryOperator>(this);
-    if (Exp->getOpcode() == UnaryOperator::Extension)
-      return Exp->getSubExpr()->isConstantInitializer(Ctx);
+    if (Exp->getOpcode() == UO_Extension)
+      return Exp->getSubExpr()->isConstantInitializer(Ctx, false);
     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 &&
+    if (Exp->getOpcode() == BO_Sub &&
         isa<AddrLabelExpr>(Exp->getLHS()->IgnoreParenNoopCasts(Ctx)) &&
         isa<AddrLabelExpr>(Exp->getRHS()->IgnoreParenNoopCasts(Ctx)))
       return true;
     break;
   }
+  case CXXFunctionalCastExprClass:
+  case CXXStaticCastExprClass:
   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);
+      return cast<CastExpr>(this)->getSubExpr()
+        ->isConstantInitializer(Ctx, false);
       
     // 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);
+      return cast<CastExpr>(this)->getSubExpr()
+        ->isConstantInitializer(Ctx, false);
       
     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*.
@@ -2090,7 +1584,7 @@
       // If the unthinkable happens, fall through to the safest alternative.
         
     case NPC_ValueDependentIsNull:
-      return isTypeDependent() || getType()->isIntegralType();
+      return isTypeDependent() || getType()->isIntegralType(Ctx);
         
     case NPC_ValueDependentIsNotNull:
       return false;
@@ -2144,7 +1638,8 @@
   Expr *E = this->IgnoreParens();
 
   while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
-    if (ICE->isLvalueCast() && ICE->getCastKind() == CastExpr::CK_NoOp)
+    if (ICE->getValueKind() != VK_RValue &&
+        ICE->getCastKind() == CK_NoOp)
       E = ICE->getSubExpr()->IgnoreParens();
     else
       break;
@@ -2166,7 +1661,8 @@
   const Expr *E = this->IgnoreParens();
   
   while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
-    if (ICE->isLvalueCast() && ICE->getCastKind() == CastExpr::CK_NoOp)
+    if (ICE->getValueKind() != VK_RValue &&
+        ICE->getCastKind() == CK_NoOp)
       E = ICE->getSubExpr()->IgnoreParens();
     else
       break;
@@ -2375,9 +1871,9 @@
     break;
 
   case Class:
-    if (const ObjCInterfaceType *Iface
-                       = getClassReceiver()->getAs<ObjCInterfaceType>())
-      return Iface->getDecl();
+    if (const ObjCObjectType *Ty
+          = getClassReceiver()->getAs<ObjCObjectType>())
+      return Ty->getInterface();
     break;
 
   case SuperInstance:
@@ -2409,27 +1905,6 @@
   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
 //===----------------------------------------------------------------------===//
@@ -2514,8 +1989,6 @@
 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)
@@ -2586,23 +2059,10 @@
   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)
@@ -2616,13 +2076,6 @@
     Exprs[i] = exprs[i];
 }
 
-void ParenListExpr::DoDestroy(ASTContext& C) {
-  DestroyChildren(C);
-  if (Exprs) C.Deallocate(Exprs);
-  this->~ParenListExpr();
-  C.Deallocate(this);
-}
-
 //===----------------------------------------------------------------------===//
 //  ExprIterator.
 //===----------------------------------------------------------------------===//
@@ -2654,7 +2107,9 @@
 
 // ObjCImplicitSetterGetterRefExpr
 Stmt::child_iterator ObjCImplicitSetterGetterRefExpr::child_begin() {
-  return &Base;
+  // If this is accessing a class member, skip that entry.
+  if (Base) return &Base;
+  return &Base+1;
 }
 Stmt::child_iterator ObjCImplicitSetterGetterRefExpr::child_end() {
   return &Base+1;
@@ -2700,6 +2155,15 @@
 Stmt::child_iterator UnaryOperator::child_begin() { return &Val; }
 Stmt::child_iterator UnaryOperator::child_end() { return &Val+1; }
 
+// OffsetOfExpr
+Stmt::child_iterator OffsetOfExpr::child_begin() {
+  return reinterpret_cast<Stmt **> (reinterpret_cast<OffsetOfNode *> (this + 1)
+                                      + NumComps);
+}
+Stmt::child_iterator OffsetOfExpr::child_end() {
+  return child_iterator(&*child_begin() + NumExprs);
+}
+
 // 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
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 5f90809..9161c1c 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -74,30 +74,29 @@
   return child_iterator();
 }
 
-// CXXZeroInitValueExpr
-Stmt::child_iterator CXXZeroInitValueExpr::child_begin() {
+// CXXScalarValueInitExpr
+Stmt::child_iterator CXXScalarValueInitExpr::child_begin() {
   return child_iterator();
 }
-Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
+Stmt::child_iterator CXXScalarValueInitExpr::child_end() {
   return child_iterator();
 }
 
 // CXXNewExpr
 CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
                        Expr **placementArgs, unsigned numPlaceArgs,
-                       bool parenTypeId, Expr *arraySize,
+                       SourceRange TypeIdParens, 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),
+    GlobalNew(globalNew),
+    Initializer(initializer), SubExprs(0), OperatorNew(operatorNew),
     OperatorDelete(operatorDelete), Constructor(constructor),
-    StartLoc(startLoc), EndLoc(endLoc) {
-  unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
-  SubExprs = new (C) Stmt*[TotalSize];
+    TypeIdParens(TypeIdParens), StartLoc(startLoc), EndLoc(endLoc) {
+      
+  AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs);
   unsigned i = 0;
   if (Array)
     SubExprs[i++] = arraySize;
@@ -105,17 +104,20 @@
     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);
+void CXXNewExpr::AllocateArgsArray(ASTContext &C, bool isArray,
+                                   unsigned numPlaceArgs, unsigned numConsArgs){
+  assert(SubExprs == 0 && "SubExprs already allocated");
+  Array = isArray;
+  NumPlacementArgs = numPlaceArgs;
+  NumConstructorArgs = numConsArgs; 
+  
+  unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
+  SubExprs = new (C) Stmt*[TotalSize];
 }
 
+
 Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; }
 Stmt::child_iterator CXXNewExpr::child_end() {
   return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs();
@@ -134,7 +136,7 @@
 PseudoDestructorTypeStorage::PseudoDestructorTypeStorage(TypeSourceInfo *Info)
  : Type(Info) 
 {
-  Location = Info->getTypeLoc().getSourceRange().getBegin();
+  Location = Info->getTypeLoc().getLocalSourceRange().getBegin();
 }
 
 QualType CXXPseudoDestructorExpr::getDestroyedType() const {
@@ -147,7 +149,7 @@
 SourceRange CXXPseudoDestructorExpr::getSourceRange() const {
   SourceLocation End = DestroyedType.getLocation();
   if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
-    End = TInfo->getTypeLoc().getSourceRange().getEnd();
+    End = TInfo->getTypeLoc().getLocalSourceRange().getEnd();
   return SourceRange(Base->getLocStart(), End);
 }
 
@@ -157,25 +159,71 @@
 UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
                              CXXRecordDecl *NamingClass,
                              NestedNameSpecifier *Qualifier,
-                             SourceRange QualifierRange, DeclarationName Name,
-                             SourceLocation NameLoc, bool ADL,
-                             const TemplateArgumentListInfo &Args) 
+                             SourceRange QualifierRange,
+                             const DeclarationNameInfo &NameInfo,
+                             bool ADL,
+                             const TemplateArgumentListInfo &Args,
+                             UnresolvedSetIterator Begin, 
+                             UnresolvedSetIterator End) 
 {
   void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) + 
                          ExplicitTemplateArgumentList::sizeFor(Args));
   UnresolvedLookupExpr *ULE
-    = new (Mem) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
+    = new (Mem) UnresolvedLookupExpr(C, 
+                                     Dependent ? C.DependentTy : C.OverloadTy,
                                      Dependent, NamingClass,
-                                     Qualifier, QualifierRange,
-                                     Name, NameLoc, ADL,
+                                     Qualifier, QualifierRange, NameInfo,
+                                     ADL,
                                      /*Overload*/ true,
-                                     /*ExplicitTemplateArgs*/ true);
+                                     /*ExplicitTemplateArgs*/ true,
+                                     Begin, End);
 
   reinterpret_cast<ExplicitTemplateArgumentList*>(ULE+1)->initializeFrom(Args);
 
   return ULE;
 }
 
+UnresolvedLookupExpr *
+UnresolvedLookupExpr::CreateEmpty(ASTContext &C, unsigned NumTemplateArgs) {
+  std::size_t size = sizeof(UnresolvedLookupExpr);
+  if (NumTemplateArgs != 0)
+    size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
+
+  void *Mem = C.Allocate(size, llvm::alignof<UnresolvedLookupExpr>());
+  UnresolvedLookupExpr *E = new (Mem) UnresolvedLookupExpr(EmptyShell());
+  E->HasExplicitTemplateArgs = NumTemplateArgs != 0;
+  return E;
+}
+
+OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, QualType T, 
+                           bool Dependent, NestedNameSpecifier *Qualifier, 
+                           SourceRange QRange,
+                           const DeclarationNameInfo &NameInfo,
+                           bool HasTemplateArgs,
+                           UnresolvedSetIterator Begin, 
+                           UnresolvedSetIterator End)
+  : Expr(K, T, Dependent, Dependent),
+  Results(0), NumResults(0), NameInfo(NameInfo), Qualifier(Qualifier), 
+  QualifierRange(QRange), HasExplicitTemplateArgs(HasTemplateArgs)
+{
+  initializeResults(C, Begin, End);
+}
+
+void OverloadExpr::initializeResults(ASTContext &C,
+                                     UnresolvedSetIterator Begin,
+                                     UnresolvedSetIterator End) {
+  assert(Results == 0 && "Results already initialized!");
+  NumResults = End - Begin;
+  if (NumResults) {
+    Results = static_cast<DeclAccessPair *>(
+                                C.Allocate(sizeof(DeclAccessPair) * NumResults, 
+                                           llvm::alignof<DeclAccessPair>()));
+    memcpy(Results, &*Begin.getIterator(), 
+           NumResults * sizeof(DeclAccessPair));
+  }
+}
+
+
 bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin,
                                      UnresolvedSetIterator End,
                                      const TemplateArgumentListInfo *Args) {
@@ -215,8 +263,7 @@
 DependentScopeDeclRefExpr::Create(ASTContext &C,
                                   NestedNameSpecifier *Qualifier,
                                   SourceRange QualifierRange,
-                                  DeclarationName Name,
-                                  SourceLocation NameLoc,
+                                  const DeclarationNameInfo &NameInfo,
                                   const TemplateArgumentListInfo *Args) {
   std::size_t size = sizeof(DependentScopeDeclRefExpr);
   if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args);
@@ -225,8 +272,7 @@
   DependentScopeDeclRefExpr *DRE
     = new (Mem) DependentScopeDeclRefExpr(C.DependentTy,
                                           Qualifier, QualifierRange,
-                                          Name, NameLoc,
-                                          Args != 0);
+                                          NameInfo, Args != 0);
 
   if (Args)
     reinterpret_cast<ExplicitTemplateArgumentList*>(DRE+1)
@@ -235,6 +281,19 @@
   return DRE;
 }
 
+DependentScopeDeclRefExpr *
+DependentScopeDeclRefExpr::CreateEmpty(ASTContext &C,
+                                       unsigned NumTemplateArgs) {
+  std::size_t size = sizeof(DependentScopeDeclRefExpr);
+  if (NumTemplateArgs)
+    size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
+  void *Mem = C.Allocate(size);
+
+  return new (Mem) DependentScopeDeclRefExpr(QualType(), 0, SourceRange(),
+                                             DeclarationNameInfo(),
+                                             NumTemplateArgs != 0);
+}
+
 StmtIterator DependentScopeDeclRefExpr::child_begin() {
   return child_iterator();
 }
@@ -400,6 +459,100 @@
   }
 }
 
+CXXStaticCastExpr *CXXStaticCastExpr::Create(ASTContext &C, QualType T,
+                                             CastKind K, Expr *Op,
+                                             const CXXCastPath *BasePath,
+                                             TypeSourceInfo *WrittenTy,
+                                             SourceLocation L) {
+  unsigned PathSize = (BasePath ? BasePath->size() : 0);
+  void *Buffer = C.Allocate(sizeof(CXXStaticCastExpr)
+                            + PathSize * sizeof(CXXBaseSpecifier*));
+  CXXStaticCastExpr *E =
+    new (Buffer) CXXStaticCastExpr(T, K, Op, PathSize, WrittenTy, L);
+  if (PathSize) E->setCastPath(*BasePath);
+  return E;
+}
+
+CXXStaticCastExpr *CXXStaticCastExpr::CreateEmpty(ASTContext &C,
+                                                  unsigned PathSize) {
+  void *Buffer =
+    C.Allocate(sizeof(CXXStaticCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+  return new (Buffer) CXXStaticCastExpr(EmptyShell(), PathSize);
+}
+
+CXXDynamicCastExpr *CXXDynamicCastExpr::Create(ASTContext &C, QualType T,
+                                               CastKind K, Expr *Op,
+                                               const CXXCastPath *BasePath,
+                                               TypeSourceInfo *WrittenTy,
+                                               SourceLocation L) {
+  unsigned PathSize = (BasePath ? BasePath->size() : 0);
+  void *Buffer = C.Allocate(sizeof(CXXDynamicCastExpr)
+                            + PathSize * sizeof(CXXBaseSpecifier*));
+  CXXDynamicCastExpr *E =
+    new (Buffer) CXXDynamicCastExpr(T, K, Op, PathSize, WrittenTy, L);
+  if (PathSize) E->setCastPath(*BasePath);
+  return E;
+}
+
+CXXDynamicCastExpr *CXXDynamicCastExpr::CreateEmpty(ASTContext &C,
+                                                    unsigned PathSize) {
+  void *Buffer =
+    C.Allocate(sizeof(CXXDynamicCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+  return new (Buffer) CXXDynamicCastExpr(EmptyShell(), PathSize);
+}
+
+CXXReinterpretCastExpr *
+CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, CastKind K, Expr *Op,
+                               const CXXCastPath *BasePath,
+                               TypeSourceInfo *WrittenTy, SourceLocation L) {
+  unsigned PathSize = (BasePath ? BasePath->size() : 0);
+  void *Buffer =
+    C.Allocate(sizeof(CXXReinterpretCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+  CXXReinterpretCastExpr *E =
+    new (Buffer) CXXReinterpretCastExpr(T, K, Op, PathSize, WrittenTy, L);
+  if (PathSize) E->setCastPath(*BasePath);
+  return E;
+}
+
+CXXReinterpretCastExpr *
+CXXReinterpretCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
+  void *Buffer = C.Allocate(sizeof(CXXReinterpretCastExpr)
+                            + PathSize * sizeof(CXXBaseSpecifier*));
+  return new (Buffer) CXXReinterpretCastExpr(EmptyShell(), PathSize);
+}
+
+CXXConstCastExpr *CXXConstCastExpr::Create(ASTContext &C, QualType T, Expr *Op,
+                                           TypeSourceInfo *WrittenTy,
+                                           SourceLocation L) {
+  return new (C) CXXConstCastExpr(T, Op, WrittenTy, L);
+}
+
+CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) {
+  return new (C) CXXConstCastExpr(EmptyShell());
+}
+
+CXXFunctionalCastExpr *
+CXXFunctionalCastExpr::Create(ASTContext &C, QualType T,
+                              TypeSourceInfo *Written, SourceLocation L,
+                              CastKind K, Expr *Op, const CXXCastPath *BasePath,
+                               SourceLocation R) {
+  unsigned PathSize = (BasePath ? BasePath->size() : 0);
+  void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
+                            + PathSize * sizeof(CXXBaseSpecifier*));
+  CXXFunctionalCastExpr *E =
+    new (Buffer) CXXFunctionalCastExpr(T, Written, L, K, Op, PathSize, R);
+  if (PathSize) E->setCastPath(*BasePath);
+  return E;
+}
+
+CXXFunctionalCastExpr *
+CXXFunctionalCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
+  void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
+                            + PathSize * sizeof(CXXBaseSpecifier*));
+  return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize);
+}
+
+
 CXXDefaultArgExpr *
 CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc, 
                           ParmVarDecl *Param, Expr *SubExpr) {
@@ -408,23 +561,11 @@
                                      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) {
@@ -434,12 +575,6 @@
   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) {
@@ -448,20 +583,16 @@
                                       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)
+                                               SourceLocation rParenLoc,
+                                               bool ZeroInitialization)
   : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, tyBeginLoc,
-                     Cons, false, Args, NumArgs),
+                     Cons, false, Args, NumArgs, ZeroInitialization),
   TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {
 }
 
@@ -470,25 +601,25 @@
                                            CXXConstructorDecl *D, bool Elidable,
                                            Expr **Args, unsigned NumArgs,
                                            bool ZeroInitialization,
-                                           bool BaseInitialization) {
+                                           ConstructionKind ConstructKind) {
   return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D, 
                                   Elidable, Args, NumArgs, ZeroInitialization,
-                                  BaseInitialization);
+                                  ConstructKind);
 }
 
 CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
                                    SourceLocation Loc,
                                    CXXConstructorDecl *D, bool elidable,
                                    Expr **args, unsigned numargs,
-                                   bool ZeroInitialization,
-                                   bool BaseInitialization)
+                                   bool ZeroInitialization, 
+                                   ConstructionKind ConstructKind)
 : 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) 
+  ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind),
+  Args(0), NumArgs(numargs) 
 {
   if (NumArgs) {
     Args = new (C) Stmt*[NumArgs];
@@ -500,50 +631,32 @@
   }
 }
 
-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,
+CXXExprWithTemporaries::CXXExprWithTemporaries(ASTContext &C,
+                                               Expr *subexpr,
                                                CXXTemporary **temps,
                                                unsigned numtemps)
-: Expr(CXXExprWithTemporariesClass, subexpr->getType(),
+  : 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)
+    SubExpr(subexpr), Temps(0), NumTemps(0) {
+  if (numtemps) {
+    setNumTemporaries(C, numtemps);
+    for (unsigned i = 0; i != numtemps; ++i)
       Temps[i] = temps[i];
   }
 }
 
+void CXXExprWithTemporaries::setNumTemporaries(ASTContext &C, unsigned N) {
+  assert(Temps == 0 && "Cannot resize with this");
+  NumTemps = N;
+  Temps = new (C) CXXTemporary*[NumTemps];
+}
+
+
 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;
+  return new (C) CXXExprWithTemporaries(C, SubExpr, Temps, NumTemps);
 }
 
 // CXXBindTemporaryExpr
@@ -613,6 +726,14 @@
                                               Args, NumArgs, RParenLoc);
 }
 
+CXXUnresolvedConstructExpr *
+CXXUnresolvedConstructExpr::CreateEmpty(ASTContext &C, unsigned NumArgs) {
+  Stmt::EmptyShell Empty;
+  void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
+                         sizeof(Expr *) * NumArgs);
+  return new (Mem) CXXUnresolvedConstructExpr(Empty, NumArgs);
+}
+
 Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() {
   return child_iterator(reinterpret_cast<Stmt **>(this + 1));
 }
@@ -628,8 +749,7 @@
                                                  NestedNameSpecifier *Qualifier,
                                                  SourceRange QualifierRange,
                                           NamedDecl *FirstQualifierFoundInScope,
-                                                 DeclarationName Member,
-                                                 SourceLocation MemberLoc,
+                                          DeclarationNameInfo MemberNameInfo,
                                    const TemplateArgumentListInfo *TemplateArgs)
   : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
     Base(Base), BaseType(BaseType), IsArrow(IsArrow),
@@ -637,9 +757,9 @@
     OperatorLoc(OperatorLoc),
     Qualifier(Qualifier), QualifierRange(QualifierRange),
     FirstQualifierFoundInScope(FirstQualifierFoundInScope),
-    Member(Member), MemberLoc(MemberLoc) {
+    MemberNameInfo(MemberNameInfo) {
   if (TemplateArgs)
-    getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
+    getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
 }
 
 CXXDependentScopeMemberExpr *
@@ -649,15 +769,14 @@
                                 NestedNameSpecifier *Qualifier,
                                 SourceRange QualifierRange,
                                 NamedDecl *FirstQualifierFoundInScope,
-                                DeclarationName Member,
-                                SourceLocation MemberLoc,
+                                DeclarationNameInfo MemberNameInfo,
                                 const TemplateArgumentListInfo *TemplateArgs) {
   if (!TemplateArgs)
     return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType,
                                                IsArrow, OperatorLoc,
                                                Qualifier, QualifierRange,
                                                FirstQualifierFoundInScope,
-                                               Member, MemberLoc);
+                                               MemberNameInfo);
 
   std::size_t size = sizeof(CXXDependentScopeMemberExpr);
   if (TemplateArgs)
@@ -668,7 +787,28 @@
                                                IsArrow, OperatorLoc,
                                                Qualifier, QualifierRange,
                                                FirstQualifierFoundInScope,
-                                               Member, MemberLoc, TemplateArgs);
+                                               MemberNameInfo, TemplateArgs);
+}
+
+CXXDependentScopeMemberExpr *
+CXXDependentScopeMemberExpr::CreateEmpty(ASTContext &C,
+                                         unsigned NumTemplateArgs) {
+  if (NumTemplateArgs == 0)
+    return new (C) CXXDependentScopeMemberExpr(C, 0, QualType(),
+                                               0, SourceLocation(), 0,
+                                               SourceRange(), 0,
+                                               DeclarationNameInfo());
+
+  std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
+                     ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
+  void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
+  CXXDependentScopeMemberExpr *E
+    =  new (Mem) CXXDependentScopeMemberExpr(C, 0, QualType(),
+                                             0, SourceLocation(), 0,
+                                             SourceRange(), 0,
+                                             DeclarationNameInfo(), 0);
+  E->HasExplicitTemplateArgs = true;
+  return E;
 }
 
 Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() {
@@ -681,19 +821,21 @@
   return child_iterator(&Base + 1);
 }
 
-UnresolvedMemberExpr::UnresolvedMemberExpr(QualType T, bool Dependent,
+UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, 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),
+                                   const DeclarationNameInfo &MemberNameInfo,
+                                   const TemplateArgumentListInfo *TemplateArgs,
+                                           UnresolvedSetIterator Begin, 
+                                           UnresolvedSetIterator End)
+  : OverloadExpr(UnresolvedMemberExprClass, C, T, Dependent,
+                 Qualifier, QualifierRange, MemberNameInfo,
+                 TemplateArgs != 0, Begin, End),
     IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
     Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
   if (TemplateArgs)
@@ -707,19 +849,32 @@
                              SourceLocation OperatorLoc,
                              NestedNameSpecifier *Qualifier,
                              SourceRange QualifierRange,
-                             DeclarationName Member,
-                             SourceLocation MemberLoc,
-                             const TemplateArgumentListInfo *TemplateArgs) {
+                             const DeclarationNameInfo &MemberNameInfo,
+                             const TemplateArgumentListInfo *TemplateArgs,
+                             UnresolvedSetIterator Begin, 
+                             UnresolvedSetIterator End) {
   std::size_t size = sizeof(UnresolvedMemberExpr);
   if (TemplateArgs)
     size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
 
   void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
-  return new (Mem) UnresolvedMemberExpr(
+  return new (Mem) UnresolvedMemberExpr(C, 
                              Dependent ? C.DependentTy : C.OverloadTy,
                              Dependent, HasUnresolvedUsing, Base, BaseType,
                              IsArrow, OperatorLoc, Qualifier, QualifierRange,
-                             Member, MemberLoc, TemplateArgs);
+                             MemberNameInfo, TemplateArgs, Begin, End);
+}
+
+UnresolvedMemberExpr *
+UnresolvedMemberExpr::CreateEmpty(ASTContext &C, unsigned NumTemplateArgs) {
+  std::size_t size = sizeof(UnresolvedMemberExpr);
+  if (NumTemplateArgs != 0)
+    size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
+
+  void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
+  UnresolvedMemberExpr *E = new (Mem) UnresolvedMemberExpr(EmptyShell());
+  E->HasExplicitTemplateArgs = NumTemplateArgs != 0;
+  return E;
 }
 
 CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
@@ -728,15 +883,15 @@
   // 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;
+  CXXRecordDecl *Record = 0;
   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");
-
+    Record = T->getAsCXXRecordDecl();
+    assert(Record && "qualifier in member expression does not name record");
+  }
   // Otherwise the naming class must have been the base class.
-  } else {
+  else {
     QualType BaseType = getBaseType().getNonReferenceType();
     if (isArrow()) {
       const PointerType *PT = BaseType->getAs<PointerType>();
@@ -744,11 +899,11 @@
       BaseType = PT->getPointeeType();
     }
     
-    RT = BaseType->getAs<RecordType>();
-    assert(RT && "base of member expression does not name record");
+    Record = BaseType->getAsCXXRecordDecl();
+    assert(Record && "base of member expression does not name record");
   }
   
-  return cast<CXXRecordDecl>(RT->getDecl());
+  return Record;
 }
 
 Stmt::child_iterator UnresolvedMemberExpr::child_begin() {
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
new file mode 100644
index 0000000..d7e38eb
--- /dev/null
+++ b/lib/AST/ExprClassification.cpp
@@ -0,0 +1,481 @@
+//===--- ExprClassification.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 Expr::classify.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ErrorHandling.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+using namespace clang;
+
+typedef Expr::Classification Cl;
+
+static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E);
+static Cl::Kinds ClassifyDecl(ASTContext &Ctx, const Decl *D);
+static Cl::Kinds ClassifyUnnamed(ASTContext &Ctx, QualType T);
+static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E);
+static Cl::Kinds ClassifyBinaryOp(ASTContext &Ctx, const BinaryOperator *E);
+static Cl::Kinds ClassifyConditional(ASTContext &Ctx,
+                                    const ConditionalOperator *E);
+static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E,
+                                       Cl::Kinds Kind, SourceLocation &Loc);
+
+Cl Expr::ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const {
+  assert(!TR->isReferenceType() && "Expressions can't have reference type.");
+
+  Cl::Kinds kind = ClassifyInternal(Ctx, this);
+  // C99 6.3.2.1: An lvalue is an expression with an object type or an
+  //   incomplete type other than void.
+  if (!Ctx.getLangOptions().CPlusPlus) {
+    // Thus, no functions.
+    if (TR->isFunctionType() || TR == Ctx.OverloadTy)
+      kind = Cl::CL_Function;
+    // No void either, but qualified void is OK because it is "other than void".
+    else if (TR->isVoidType() && !Ctx.getCanonicalType(TR).hasQualifiers())
+      kind = Cl::CL_Void;
+  }
+
+  Cl::ModifiableType modifiable = Cl::CM_Untested;
+  if (Loc)
+    modifiable = IsModifiable(Ctx, this, kind, *Loc);
+  return Classification(kind, modifiable);
+}
+
+static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
+  // This function takes the first stab at classifying expressions.
+  const LangOptions &Lang = Ctx.getLangOptions();
+
+  switch (E->getStmtClass()) {
+    // First come the expressions that are always lvalues, unconditionally.
+
+  case Expr::ObjCIsaExprClass:
+    // C++ [expr.prim.general]p1: A string literal is an lvalue.
+  case Expr::StringLiteralClass:
+    // @encode is equivalent to its string
+  case Expr::ObjCEncodeExprClass:
+    // __func__ and friends are too.
+  case Expr::PredefinedExprClass:
+    // Property references are lvalues
+  case Expr::ObjCPropertyRefExprClass:
+  case Expr::ObjCImplicitSetterGetterRefExprClass:
+    // C++ [expr.typeid]p1: The result of a typeid expression is an lvalue of...
+  case Expr::CXXTypeidExprClass:
+    // Unresolved lookups get classified as lvalues.
+    // FIXME: Is this wise? Should they get their own kind?
+  case Expr::UnresolvedLookupExprClass:
+  case Expr::UnresolvedMemberExprClass:
+    // ObjC instance variables are lvalues
+    // FIXME: ObjC++0x might have different rules
+  case Expr::ObjCIvarRefExprClass:
+    // C99 6.5.2.5p5 says that compound literals are lvalues.
+    // FIXME: C++ might have a different opinion.
+  case Expr::CompoundLiteralExprClass:
+    return Cl::CL_LValue;
+
+    // Next come the complicated cases.
+
+    // C++ [expr.sub]p1: The result is an lvalue of type "T".
+    // However, subscripting vector types is more like member access.
+  case Expr::ArraySubscriptExprClass:
+    if (cast<ArraySubscriptExpr>(E)->getBase()->getType()->isVectorType())
+      return ClassifyInternal(Ctx, cast<ArraySubscriptExpr>(E)->getBase());
+    return Cl::CL_LValue;
+
+    // C++ [expr.prim.general]p3: The result is an lvalue if the entity is a
+    //   function or variable and a prvalue otherwise.
+  case Expr::DeclRefExprClass:
+    return ClassifyDecl(Ctx, cast<DeclRefExpr>(E)->getDecl());
+    // We deal with names referenced from blocks the same way.
+  case Expr::BlockDeclRefExprClass:
+    return ClassifyDecl(Ctx, cast<BlockDeclRefExpr>(E)->getDecl());
+
+    // Member access is complex.
+  case Expr::MemberExprClass:
+    return ClassifyMemberExpr(Ctx, cast<MemberExpr>(E));
+
+  case Expr::UnaryOperatorClass:
+    switch (cast<UnaryOperator>(E)->getOpcode()) {
+      // C++ [expr.unary.op]p1: The unary * operator performs indirection:
+      //   [...] the result is an lvalue referring to the object or function
+      //   to which the expression points.
+    case UO_Deref:
+      return Cl::CL_LValue;
+
+      // GNU extensions, simply look through them.
+    case UO_Real:
+    case UO_Imag:
+    case UO_Extension:
+      return ClassifyInternal(Ctx, cast<UnaryOperator>(E)->getSubExpr());
+
+      // C++ [expr.pre.incr]p1: The result is the updated operand; it is an
+      //   lvalue, [...]
+      // Not so in C.
+    case UO_PreInc:
+    case UO_PreDec:
+      return Lang.CPlusPlus ? Cl::CL_LValue : Cl::CL_PRValue;
+
+    default:
+      return Cl::CL_PRValue;
+    }
+
+    // Implicit casts are lvalues if they're lvalue casts. Other than that, we
+    // only specifically record class temporaries.
+  case Expr::ImplicitCastExprClass:
+    switch (cast<ImplicitCastExpr>(E)->getValueKind()) {
+    case VK_RValue:
+      return Lang.CPlusPlus && E->getType()->isRecordType() ?
+        Cl::CL_ClassTemporary : Cl::CL_PRValue;
+    case VK_LValue:
+      return Cl::CL_LValue;
+    case VK_XValue:
+      return Cl::CL_XValue;
+    }
+    llvm_unreachable("Invalid value category of implicit cast.");
+
+    // C++ [expr.prim.general]p4: The presence of parentheses does not affect
+    //   whether the expression is an lvalue.
+  case Expr::ParenExprClass:
+    return ClassifyInternal(Ctx, cast<ParenExpr>(E)->getSubExpr());
+
+  case Expr::BinaryOperatorClass:
+  case Expr::CompoundAssignOperatorClass:
+    // C doesn't have any binary expressions that are lvalues.
+    if (Lang.CPlusPlus)
+      return ClassifyBinaryOp(Ctx, cast<BinaryOperator>(E));
+    return Cl::CL_PRValue;
+
+  case Expr::CallExprClass:
+  case Expr::CXXOperatorCallExprClass:
+  case Expr::CXXMemberCallExprClass:
+    return ClassifyUnnamed(Ctx, cast<CallExpr>(E)->getCallReturnType());
+
+    // __builtin_choose_expr is equivalent to the chosen expression.
+  case Expr::ChooseExprClass:
+    return ClassifyInternal(Ctx, cast<ChooseExpr>(E)->getChosenSubExpr(Ctx));
+
+    // Extended vector element access is an lvalue unless there are duplicates
+    // in the shuffle expression.
+  case Expr::ExtVectorElementExprClass:
+    return cast<ExtVectorElementExpr>(E)->containsDuplicateElements() ?
+      Cl::CL_DuplicateVectorComponents : Cl::CL_LValue;
+
+    // Simply look at the actual default argument.
+  case Expr::CXXDefaultArgExprClass:
+    return ClassifyInternal(Ctx, cast<CXXDefaultArgExpr>(E)->getExpr());
+
+    // Same idea for temporary binding.
+  case Expr::CXXBindTemporaryExprClass:
+    return ClassifyInternal(Ctx, cast<CXXBindTemporaryExpr>(E)->getSubExpr());
+
+    // And the temporary lifetime guard.
+  case Expr::CXXExprWithTemporariesClass:
+    return ClassifyInternal(Ctx, cast<CXXExprWithTemporaries>(E)->getSubExpr());
+
+    // Casts depend completely on the target type. All casts work the same.
+  case Expr::CStyleCastExprClass:
+  case Expr::CXXFunctionalCastExprClass:
+  case Expr::CXXStaticCastExprClass:
+  case Expr::CXXDynamicCastExprClass:
+  case Expr::CXXReinterpretCastExprClass:
+  case Expr::CXXConstCastExprClass:
+    // Only in C++ can casts be interesting at all.
+    if (!Lang.CPlusPlus) return Cl::CL_PRValue;
+    return ClassifyUnnamed(Ctx, cast<ExplicitCastExpr>(E)->getTypeAsWritten());
+
+  case Expr::ConditionalOperatorClass:
+    // Once again, only C++ is interesting.
+    if (!Lang.CPlusPlus) return Cl::CL_PRValue;
+    return ClassifyConditional(Ctx, cast<ConditionalOperator>(E));
+
+    // ObjC message sends are effectively function calls, if the target function
+    // is known.
+  case Expr::ObjCMessageExprClass:
+    if (const ObjCMethodDecl *Method =
+          cast<ObjCMessageExpr>(E)->getMethodDecl()) {
+      return ClassifyUnnamed(Ctx, Method->getResultType());
+    }
+
+    // Some C++ expressions are always class temporaries.
+  case Expr::CXXConstructExprClass:
+  case Expr::CXXTemporaryObjectExprClass:
+  case Expr::CXXScalarValueInitExprClass:
+    return Cl::CL_ClassTemporary;
+
+    // Everything we haven't handled is a prvalue.
+  default:
+    return Cl::CL_PRValue;
+  }
+}
+
+/// ClassifyDecl - Return the classification of an expression referencing the
+/// given declaration.
+static Cl::Kinds ClassifyDecl(ASTContext &Ctx, const Decl *D) {
+  // C++ [expr.prim.general]p6: The result is an lvalue if the entity is a
+  //   function, variable, or data member and a prvalue otherwise.
+  // In C, functions are not lvalues.
+  // In addition, NonTypeTemplateParmDecl derives from VarDecl but isn't an
+  // lvalue unless it's a reference type (C++ [temp.param]p6), so we need to
+  // special-case this.
+
+  if (isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance())
+    return Cl::CL_MemberFunction;
+
+  bool islvalue;
+  if (const NonTypeTemplateParmDecl *NTTParm =
+        dyn_cast<NonTypeTemplateParmDecl>(D))
+    islvalue = NTTParm->getType()->isReferenceType();
+  else
+    islvalue = isa<VarDecl>(D) || isa<FieldDecl>(D) ||
+      (Ctx.getLangOptions().CPlusPlus &&
+        (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)));
+
+  return islvalue ? Cl::CL_LValue : Cl::CL_PRValue;
+}
+
+/// ClassifyUnnamed - Return the classification of an expression yielding an
+/// unnamed value of the given type. This applies in particular to function
+/// calls and casts.
+static Cl::Kinds ClassifyUnnamed(ASTContext &Ctx, QualType T) {
+  // In C, function calls are always rvalues.
+  if (!Ctx.getLangOptions().CPlusPlus) return Cl::CL_PRValue;
+
+  // C++ [expr.call]p10: A function call is an lvalue if the result type is an
+  //   lvalue reference type or an rvalue reference to function type, an xvalue
+  //   if the result type is an rvalue refernence to object type, and a prvalue
+  //   otherwise.
+  if (T->isLValueReferenceType())
+    return Cl::CL_LValue;
+  const RValueReferenceType *RV = T->getAs<RValueReferenceType>();
+  if (!RV) // Could still be a class temporary, though.
+    return T->isRecordType() ? Cl::CL_ClassTemporary : Cl::CL_PRValue;
+
+  return RV->getPointeeType()->isFunctionType() ? Cl::CL_LValue : Cl::CL_XValue;
+}
+
+static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E) {
+  // Handle C first, it's easier.
+  if (!Ctx.getLangOptions().CPlusPlus) {
+    // C99 6.5.2.3p3
+    // For dot access, the expression is an lvalue if the first part is. For
+    // arrow access, it always is an lvalue.
+    if (E->isArrow())
+      return Cl::CL_LValue;
+    // ObjC property accesses are not lvalues, but get special treatment.
+    Expr *Base = E->getBase();
+    if (isa<ObjCPropertyRefExpr>(Base) ||
+        isa<ObjCImplicitSetterGetterRefExpr>(Base))
+      return Cl::CL_SubObjCPropertySetting;
+    return ClassifyInternal(Ctx, Base);
+  }
+
+  NamedDecl *Member = E->getMemberDecl();
+  // C++ [expr.ref]p3: E1->E2 is converted to the equivalent form (*(E1)).E2.
+  // 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 Cl::CL_LValue;
+
+  //   Otherwise, one of the following rules applies.
+  //   -- If E2 is a static member [...] then E1.E2 is an lvalue.
+  if (isa<VarDecl>(Member) && Member->getDeclContext()->isRecord())
+    return Cl::CL_LValue;
+
+  //   -- If E2 is a non-static data member [...]. If E1 is an lvalue, then
+  //      E1.E2 is an lvalue; if E1 is an xvalue, then E1.E2 is an xvalue;
+  //      otherwise, it is a prvalue.
+  if (isa<FieldDecl>(Member)) {
+    // *E1 is an lvalue
+    if (E->isArrow())
+      return Cl::CL_LValue;
+    return ClassifyInternal(Ctx, E->getBase());
+  }
+
+  //   -- If E2 is a [...] member function, [...]
+  //      -- If it refers to a static member function [...], then E1.E2 is an
+  //         lvalue; [...]
+  //      -- Otherwise [...] E1.E2 is a prvalue.
+  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Member))
+    return Method->isStatic() ? Cl::CL_LValue : Cl::CL_MemberFunction;
+
+  //   -- If E2 is a member enumerator [...], the expression E1.E2 is a prvalue.
+  // So is everything else we haven't handled yet.
+  return Cl::CL_PRValue;
+}
+
+static Cl::Kinds ClassifyBinaryOp(ASTContext &Ctx, const BinaryOperator *E) {
+  assert(Ctx.getLangOptions().CPlusPlus &&
+         "This is only relevant for C++.");
+  // C++ [expr.ass]p1: All [...] return an lvalue referring to the left operand.
+  if (E->isAssignmentOp())
+    return Cl::CL_LValue;
+
+  // C++ [expr.comma]p1: the result is of the same value category as its right
+  //   operand, [...].
+  if (E->getOpcode() == BO_Comma)
+    return ClassifyInternal(Ctx, E->getRHS());
+
+  // C++ [expr.mptr.oper]p6: The result of a .* expression whose second operand
+  //   is a pointer to a data member is of the same value category as its first
+  //   operand.
+  if (E->getOpcode() == BO_PtrMemD)
+    return E->getType()->isFunctionType() ? Cl::CL_MemberFunction :
+      ClassifyInternal(Ctx, E->getLHS());
+
+  // C++ [expr.mptr.oper]p6: The result of an ->* expression is an lvalue if its
+  //   second operand is a pointer to data member and a prvalue otherwise.
+  if (E->getOpcode() == BO_PtrMemI)
+    return E->getType()->isFunctionType() ?
+      Cl::CL_MemberFunction : Cl::CL_LValue;
+
+  // All other binary operations are prvalues.
+  return Cl::CL_PRValue;
+}
+
+static Cl::Kinds ClassifyConditional(ASTContext &Ctx,
+                                     const ConditionalOperator *E) {
+  assert(Ctx.getLangOptions().CPlusPlus &&
+         "This is only relevant for C++.");
+
+  Expr *True = E->getTrueExpr();
+  Expr *False = E->getFalseExpr();
+  // C++ [expr.cond]p2
+  //   If either the second or the third operand has type (cv) void, [...]
+  //   the result [...] is a prvalue.
+  if (True->getType()->isVoidType() || False->getType()->isVoidType())
+    return Cl::CL_PRValue;
+
+  // Note that at this point, we have already performed all conversions
+  // according to [expr.cond]p3.
+  // C++ [expr.cond]p4: If the second and third operands are glvalues of the
+  //   same value category [...], the result is of that [...] value category.
+  // C++ [expr.cond]p5: Otherwise, the result is a prvalue.
+  Cl::Kinds LCl = ClassifyInternal(Ctx, True),
+            RCl = ClassifyInternal(Ctx, False);
+  return LCl == RCl ? LCl : Cl::CL_PRValue;
+}
+
+static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E,
+                                       Cl::Kinds Kind, SourceLocation &Loc) {
+  // As a general rule, we only care about lvalues. But there are some rvalues
+  // for which we want to generate special results.
+  if (Kind == Cl::CL_PRValue) {
+    // For the sake of better diagnostics, we want to specifically recognize
+    // use of the GCC cast-as-lvalue extension.
+    if (const CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(E->IgnoreParens())){
+      if (CE->getSubExpr()->Classify(Ctx).isLValue()) {
+        Loc = CE->getLParenLoc();
+        return Cl::CM_LValueCast;
+      }
+    }
+  }
+  if (Kind != Cl::CL_LValue)
+    return Cl::CM_RValue;
+
+  // This is the lvalue case.
+  // Functions are lvalues in C++, but not modifiable. (C++ [basic.lval]p6)
+  if (Ctx.getLangOptions().CPlusPlus && E->getType()->isFunctionType())
+    return Cl::CM_Function;
+
+  // You cannot assign to a variable outside a block from within the block if
+  // it is not marked __block, e.g.
+  //   void takeclosure(void (^C)(void));
+  //   void func() { int x = 1; takeclosure(^{ x = 7; }); }
+  if (const BlockDeclRefExpr *BDR = dyn_cast<BlockDeclRefExpr>(E)) {
+    if (!BDR->isByRef() && isa<VarDecl>(BDR->getDecl()))
+      return Cl::CM_NotBlockQualified;
+  }
+
+  // Assignment to a property in ObjC is an implicit setter access. But a
+  // setter might not exist.
+  if (const ObjCImplicitSetterGetterRefExpr *Expr =
+        dyn_cast<ObjCImplicitSetterGetterRefExpr>(E)) {
+    if (Expr->getSetterMethod() == 0)
+      return Cl::CM_NoSetterProperty;
+  }
+
+  CanQualType CT = Ctx.getCanonicalType(E->getType());
+  // Const stuff is obviously not modifiable.
+  if (CT.isConstQualified())
+    return Cl::CM_ConstQualified;
+  // Arrays are not modifiable, only their elements are.
+  if (CT->isArrayType())
+    return Cl::CM_ArrayType;
+  // Incomplete types are not modifiable.
+  if (CT->isIncompleteType())
+    return Cl::CM_IncompleteType;
+
+  // Records with any const fields (recursively) are not modifiable.
+  if (const RecordType *R = CT->getAs<RecordType>()) {
+    assert(!Ctx.getLangOptions().CPlusPlus &&
+           "C++ struct assignment should be resolved by the "
+           "copy assignment operator.");
+    if (R->hasConstFields())
+      return Cl::CM_ConstQualified;
+  }
+
+  return Cl::CM_Modifiable;
+}
+
+Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
+  Classification VC = Classify(Ctx);
+  switch (VC.getKind()) {
+  case Cl::CL_LValue: return LV_Valid;
+  case Cl::CL_XValue: return LV_InvalidExpression;
+  case Cl::CL_Function: return LV_NotObjectType;
+  case Cl::CL_Void: return LV_IncompleteVoidType;
+  case Cl::CL_DuplicateVectorComponents: return LV_DuplicateVectorComponents;
+  case Cl::CL_MemberFunction: return LV_MemberFunction;
+  case Cl::CL_SubObjCPropertySetting: return LV_SubObjCPropertySetting;
+  case Cl::CL_ClassTemporary: return LV_ClassTemporary;
+  case Cl::CL_PRValue: return LV_InvalidExpression;
+  }
+  llvm_unreachable("Unhandled kind");
+}
+
+Expr::isModifiableLvalueResult
+Expr::isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc) const {
+  SourceLocation dummy;
+  Classification VC = ClassifyModifiable(Ctx, Loc ? *Loc : dummy);
+  switch (VC.getKind()) {
+  case Cl::CL_LValue: break;
+  case Cl::CL_XValue: return MLV_InvalidExpression;
+  case Cl::CL_Function: return MLV_NotObjectType;
+  case Cl::CL_Void: return MLV_IncompleteVoidType;
+  case Cl::CL_DuplicateVectorComponents: return MLV_DuplicateVectorComponents;
+  case Cl::CL_MemberFunction: return MLV_MemberFunction;
+  case Cl::CL_SubObjCPropertySetting: return MLV_SubObjCPropertySetting;
+  case Cl::CL_ClassTemporary: return MLV_ClassTemporary;
+  case Cl::CL_PRValue:
+    return VC.getModifiable() == Cl::CM_LValueCast ?
+      MLV_LValueCast : MLV_InvalidExpression;
+  }
+  assert(VC.getKind() == Cl::CL_LValue && "Unhandled kind");
+  switch (VC.getModifiable()) {
+  case Cl::CM_Untested: llvm_unreachable("Did not test modifiability");
+  case Cl::CM_Modifiable: return MLV_Valid;
+  case Cl::CM_RValue: llvm_unreachable("CM_RValue and CL_LValue don't match");
+  case Cl::CM_Function: return MLV_NotObjectType;
+  case Cl::CM_LValueCast:
+    llvm_unreachable("CM_LValueCast and CL_LValue don't match");
+  case Cl::CM_NotBlockQualified: return MLV_NotBlockQualified;
+  case Cl::CM_NoSetterProperty: return MLV_NoSetterProperty;
+  case Cl::CM_ConstQualified: return MLV_ConstQualified;
+  case Cl::CM_ArrayType: return MLV_ArrayType;
+  case Cl::CM_IncompleteType: return MLV_IncompleteType;
+  }
+  llvm_unreachable("Unhandled modifiable type");
+}
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index a52cf6f..14cbbaf 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -16,7 +16,9 @@
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/Expr.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/SmallString.h"
@@ -46,37 +48,116 @@
   /// 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) {}
+  EvalInfo(ASTContext &ctx, Expr::EvalResult& evalresult)
+    : Ctx(ctx), EvalResult(evalresult) {}
 };
 
+namespace {
+  struct ComplexValue {
+  private:
+    bool IsInt;
 
-static bool EvaluateLValue(const Expr *E, APValue &Result, EvalInfo &Info);
-static bool EvaluatePointer(const Expr *E, APValue &Result, EvalInfo &Info);
+  public:
+    APSInt IntReal, IntImag;
+    APFloat FloatReal, FloatImag;
+
+    ComplexValue() : FloatReal(APFloat::Bogus), FloatImag(APFloat::Bogus) {}
+
+    void makeComplexFloat() { IsInt = false; }
+    bool isComplexFloat() const { return !IsInt; }
+    APFloat &getComplexFloatReal() { return FloatReal; }
+    APFloat &getComplexFloatImag() { return FloatImag; }
+
+    void makeComplexInt() { IsInt = true; }
+    bool isComplexInt() const { return IsInt; }
+    APSInt &getComplexIntReal() { return IntReal; }
+    APSInt &getComplexIntImag() { return IntImag; }
+
+    void moveInto(APValue &v) {
+      if (isComplexFloat())
+        v = APValue(FloatReal, FloatImag);
+      else
+        v = APValue(IntReal, IntImag);
+    }
+  };
+
+  struct LValue {
+    Expr *Base;
+    CharUnits Offset;
+
+    Expr *getLValueBase() { return Base; }
+    CharUnits getLValueOffset() { return Offset; }
+
+    void moveInto(APValue &v) {
+      v = APValue(Base, Offset);
+    }
+  };
+}
+
+static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info);
+static bool EvaluatePointer(const Expr *E, LValue &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);
+static bool EvaluateComplex(const Expr *E, ComplexValue &Res, 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();
+static bool IsGlobalLValue(const Expr* E) {
+  if (!E) return true;
+
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+    if (isa<FunctionDecl>(DRE->getDecl()))
+      return true;
+    if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
+      return VD->hasGlobalStorage();
+    return false;
+  }
+
+  if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(E))
+    return CLE->isFileScope();
+
+  return true;
+}
+
+static bool EvalPointerValueAsBool(LValue& Value, bool& Result) {
+  const Expr* Base = Value.Base;
+
+  // A null base expression indicates a null pointer.  These are always
+  // evaluatable, and they are false unless the offset is zero.
+  if (!Base) {
+    Result = !Value.Offset.isZero();
+    return true;
+  }
+
+  // Require the base expression to be a global l-value.
+  if (!IsGlobalLValue(Base)) return false;
+
+  // We have a non-null base expression.  These are generally known to
+  // be true, but if it'a decl-ref to a weak symbol it can be null at
+  // runtime.
+  Result = true;
+
+  const DeclRefExpr* DeclRef = dyn_cast<DeclRefExpr>(Base);
+  if (!DeclRef)
+    return true;
+
+  // If it's a weak symbol, it isn't constant-evaluable.
+  const ValueDecl* Decl = DeclRef->getDecl();
+  if (Decl->hasAttr<WeakAttr>() ||
+      Decl->hasAttr<WeakRefAttr>() ||
+      Decl->hasAttr<WeakImportAttr>())
+    return false;
+
   return true;
 }
 
 static bool HandleConversionToBool(const Expr* E, bool& Result,
                                    EvalInfo &Info) {
-  if (E->getType()->isIntegralType()) {
+  if (E->getType()->isIntegralOrEnumerationType()) {
     APSInt IntResult;
     if (!EvaluateInteger(E, IntResult, Info))
       return false;
@@ -89,12 +170,12 @@
     Result = !FloatResult.isZero();
     return true;
   } else if (E->getType()->hasPointerRepresentation()) {
-    APValue PointerResult;
+    LValue PointerResult;
     if (!EvaluatePointer(E, PointerResult, Info))
       return false;
     return EvalPointerValueAsBool(PointerResult, Result);
   } else if (E->getType()->isAnyComplexType()) {
-    APValue ComplexResult;
+    ComplexValue ComplexResult;
     if (!EvaluateComplex(E, ComplexResult, Info))
       return false;
     if (ComplexResult.isComplexFloat()) {
@@ -219,36 +300,44 @@
 //===----------------------------------------------------------------------===//
 namespace {
 class LValueExprEvaluator
-  : public StmtVisitor<LValueExprEvaluator, APValue> {
+  : public StmtVisitor<LValueExprEvaluator, bool> {
   EvalInfo &Info;
+  LValue &Result;
+
+  bool Success(Expr *E) {
+    Result.Base = E;
+    Result.Offset = CharUnits::Zero();
+    return true;
+  }
 public:
 
-  LValueExprEvaluator(EvalInfo &info) : Info(info) {}
+  LValueExprEvaluator(EvalInfo &info, LValue &Result) :
+    Info(info), Result(Result) {}
 
-  APValue VisitStmt(Stmt *S) {
-    return APValue();
+  bool VisitStmt(Stmt *S) {
+    return false;
   }
-
-  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)
+  
+  bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
+  bool VisitDeclRefExpr(DeclRefExpr *E);
+  bool VisitPredefinedExpr(PredefinedExpr *E) { return Success(E); }
+  bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
+  bool VisitMemberExpr(MemberExpr *E);
+  bool VisitStringLiteral(StringLiteral *E) { return Success(E); }
+  bool VisitObjCEncodeExpr(ObjCEncodeExpr *E) { return Success(E); }
+  bool VisitArraySubscriptExpr(ArraySubscriptExpr *E);
+  bool VisitUnaryDeref(UnaryOperator *E);
+  bool VisitUnaryExtension(const UnaryOperator *E)
     { return Visit(E->getSubExpr()); }
-  APValue VisitChooseExpr(const ChooseExpr *E)
+  bool VisitChooseExpr(const ChooseExpr *E)
     { return Visit(E->getChosenSubExpr(Info.Ctx)); }
 
-  APValue VisitCastExpr(CastExpr *E) {
+  bool VisitCastExpr(CastExpr *E) {
     switch (E->getCastKind()) {
     default:
-      return APValue();
+      return false;
 
-    case CastExpr::CK_NoOp:
+    case CK_NoOp:
       return Visit(E->getSubExpr());
     }
   }
@@ -256,44 +345,41 @@
 };
 } // end anonymous namespace
 
-static bool EvaluateLValue(const Expr* E, APValue& Result, EvalInfo &Info) {
-  Result = LValueExprEvaluator(Info).Visit(const_cast<Expr*>(E));
-  return Result.isLValue();
+static bool EvaluateLValue(const Expr* E, LValue& Result, EvalInfo &Info) {
+  return LValueExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
 }
 
-APValue LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E) {
+bool LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E) {
   if (isa<FunctionDecl>(E->getDecl())) {
-    return APValue(E);
+    return Success(E);
   } else if (VarDecl* VD = dyn_cast<VarDecl>(E->getDecl())) {
-    if (!Info.AnyLValue && !VD->hasGlobalStorage())
-      return APValue();
     if (!VD->getType()->isReferenceType())
-      return APValue(E);
+      return Success(E);
+    // Reference parameters can refer to anything even if they have an
+    // "initializer" in the form of a default argument.
+    if (isa<ParmVarDecl>(VD))
+      return false;
     // FIXME: Check whether VD might be overridden!
     if (const Expr *Init = VD->getAnyInitializer())
       return Visit(const_cast<Expr *>(Init));
   }
 
-  return APValue();
+  return false;
 }
 
-APValue LValueExprEvaluator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
-  if (!Info.AnyLValue && !E->isFileScope())
-    return APValue();
-  return APValue(E);
+bool LValueExprEvaluator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+  return Success(E);
 }
 
-APValue LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) {
-  APValue result;
+bool LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) {
   QualType Ty;
   if (E->isArrow()) {
-    if (!EvaluatePointer(E->getBase(), result, Info))
-      return APValue();
+    if (!EvaluatePointer(E->getBase(), Result, Info))
+      return false;
     Ty = E->getBase()->getType()->getAs<PointerType>()->getPointeeType();
   } else {
-    result = Visit(E->getBase());
-    if (result.isUninit())
-      return APValue();
+    if (!Visit(E->getBase()))
+      return false;
     Ty = E->getBase()->getType();
   }
 
@@ -302,10 +388,10 @@
 
   FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
   if (!FD) // FIXME: deal with other kinds of member expressions
-    return APValue();
+    return false;
 
   if (FD->getType()->isReferenceType())
-    return APValue();
+    return false;
 
   // FIXME: This is linear time.
   unsigned i = 0;
@@ -316,36 +402,25 @@
       break;
   }
 
-  result.setLValue(result.getLValueBase(),
-                   result.getLValueOffset() + 
-                       CharUnits::fromQuantity(RL.getFieldOffset(i) / 8));
-
-  return result;
+  Result.Offset += CharUnits::fromQuantity(RL.getFieldOffset(i) / 8);
+  return true;
 }
 
-APValue LValueExprEvaluator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
-  APValue Result;
-
+bool LValueExprEvaluator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
   if (!EvaluatePointer(E->getBase(), Result, Info))
-    return APValue();
+    return false;
 
   APSInt Index;
   if (!EvaluateInteger(E->getIdx(), Index, Info))
-    return APValue();
+    return false;
 
   CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(E->getType());
-
-  CharUnits Offset = Index.getSExtValue() * ElementSize;
-  Result.setLValue(Result.getLValueBase(),
-                   Result.getLValueOffset() + Offset);
-  return Result;
+  Result.Offset += Index.getSExtValue() * ElementSize;
+  return true;
 }
 
-APValue LValueExprEvaluator::VisitUnaryDeref(UnaryOperator *E) {
-  APValue Result;
-  if (!EvaluatePointer(E->getSubExpr(), Result, Info))
-    return APValue();
-  return Result;
+bool LValueExprEvaluator::VisitUnaryDeref(UnaryOperator *E) {
+  return EvaluatePointer(E->getSubExpr(), Result, Info);
 }
 
 //===----------------------------------------------------------------------===//
@@ -354,111 +429,110 @@
 
 namespace {
 class PointerExprEvaluator
-  : public StmtVisitor<PointerExprEvaluator, APValue> {
+  : public StmtVisitor<PointerExprEvaluator, bool> {
   EvalInfo &Info;
+  LValue &Result;
+
+  bool Success(Expr *E) {
+    Result.Base = E;
+    Result.Offset = CharUnits::Zero();
+    return true;
+  }
 public:
 
-  PointerExprEvaluator(EvalInfo &info) : Info(info) {}
+  PointerExprEvaluator(EvalInfo &info, LValue &Result)
+    : Info(info), Result(Result) {}
 
-  APValue VisitStmt(Stmt *S) {
-    return APValue();
+  bool VisitStmt(Stmt *S) {
+    return false;
   }
 
-  APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
+  bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
 
-  APValue VisitBinaryOperator(const BinaryOperator *E);
-  APValue VisitCastExpr(CastExpr* E);
-  APValue VisitUnaryExtension(const UnaryOperator *E)
+  bool VisitBinaryOperator(const BinaryOperator *E);
+  bool VisitCastExpr(CastExpr* E);
+  bool 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) {
+  bool VisitUnaryAddrOf(const UnaryOperator *E);
+  bool VisitObjCStringLiteral(ObjCStringLiteral *E)
+      { return Success(E); }
+  bool VisitAddrLabelExpr(AddrLabelExpr *E)
+      { return Success(E); }
+  bool VisitCallExpr(CallExpr *E);
+  bool VisitBlockExpr(BlockExpr *E) {
     if (!E->hasBlockDeclRefExprs())
-      return APValue(E);
-    return APValue();
+      return Success(E);
+    return false;
   }
-  APValue VisitImplicitValueInitExpr(ImplicitValueInitExpr *E)
-      { return APValue((Expr*)0); }
-  APValue VisitConditionalOperator(ConditionalOperator *E);
-  APValue VisitChooseExpr(ChooseExpr *E)
+  bool VisitImplicitValueInitExpr(ImplicitValueInitExpr *E)
+      { return Success((Expr*)0); }
+  bool VisitConditionalOperator(ConditionalOperator *E);
+  bool VisitChooseExpr(ChooseExpr *E)
       { return Visit(E->getChosenSubExpr(Info.Ctx)); }
-  APValue VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E)
-      { return APValue((Expr*)0); }
+  bool VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E)
+      { return Success((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();
+static bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo &Info) {
+  assert(E->getType()->hasPointerRepresentation());
+  return PointerExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
 }
 
-APValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
-  if (E->getOpcode() != BinaryOperator::Add &&
-      E->getOpcode() != BinaryOperator::Sub)
-    return APValue();
+bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+  if (E->getOpcode() != BO_Add &&
+      E->getOpcode() != BO_Sub)
+    return false;
 
   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();
+  if (!EvaluatePointer(PExp, Result, Info))
+    return false;
 
-  llvm::APSInt AdditionalOffset;
-  if (!EvaluateInteger(IExp, AdditionalOffset, Info))
-    return APValue();
+  llvm::APSInt Offset;
+  if (!EvaluateInteger(IExp, Offset, Info))
+    return false;
+  int64_t AdditionalOffset
+    = Offset.isSigned() ? Offset.getSExtValue()
+                        : static_cast<int64_t>(Offset.getZExtValue());
 
   // Compute the new offset in the appropriate width.
 
   QualType PointeeType =
     PExp->getType()->getAs<PointerType>()->getPointeeType();
-  llvm::APSInt SizeOfPointee(AdditionalOffset);
+  CharUnits SizeOfPointee;
 
   // Explicitly handle GNU void* and function pointer arithmetic extensions.
   if (PointeeType->isVoidType() || PointeeType->isFunctionType())
-    SizeOfPointee = 1;
+    SizeOfPointee = CharUnits::One();
   else
-    SizeOfPointee = Info.Ctx.getTypeSizeInChars(PointeeType).getQuantity();
+    SizeOfPointee = Info.Ctx.getTypeSizeInChars(PointeeType);
 
-  llvm::APSInt Offset(AdditionalOffset);
-  Offset = ResultLValue.getLValueOffset().getQuantity();
-  if (E->getOpcode() == BinaryOperator::Add)
-    Offset += AdditionalOffset * SizeOfPointee;
+  if (E->getOpcode() == BO_Add)
+    Result.Offset += AdditionalOffset * SizeOfPointee;
   else
-    Offset -= AdditionalOffset * SizeOfPointee;
+    Result.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()));
+  return true;
 }
 
-APValue PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) {
-  APValue result;
-  if (EvaluateLValue(E->getSubExpr(), result, Info))
-    return result;
-  return APValue();
+bool PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) {
+  return EvaluateLValue(E->getSubExpr(), Result, Info);
 }
 
 
-APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) {
+bool PointerExprEvaluator::VisitCastExpr(CastExpr* E) {
   Expr* SubExpr = E->getSubExpr();
 
   switch (E->getCastKind()) {
   default:
     break;
 
-  case CastExpr::CK_Unknown: {
+  case CK_Unknown: {
     // FIXME: The handling for CK_Unknown is ugly/shouldn't be necessary!
 
     // Check for pointer->pointer cast
@@ -468,75 +542,73 @@
         SubExpr->getType()->isBlockPointerType())
       return Visit(SubExpr);
 
-    if (SubExpr->getType()->isIntegralType()) {
-      APValue Result;
-      if (!EvaluateIntegerOrLValue(SubExpr, Result, Info))
+    if (SubExpr->getType()->isIntegralOrEnumerationType()) {
+      APValue Value;
+      if (!EvaluateIntegerOrLValue(SubExpr, Value, Info))
         break;
 
-      if (Result.isInt()) {
-        Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
-        return APValue(0, 
-                       CharUnits::fromQuantity(Result.getInt().getZExtValue()));
+      if (Value.isInt()) {
+        Value.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
+        Result.Base = 0;
+        Result.Offset = CharUnits::fromQuantity(Value.getInt().getZExtValue());
+        return true;
+      } else {
+        Result.Base = Value.getLValueBase();
+        Result.Offset = Value.getLValueOffset();
+        return true;
       }
-
-      // 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:
+  case CK_NoOp:
+  case CK_BitCast:
+  case CK_LValueBitCast:
+  case CK_AnyPointerToObjCPointerCast:
+  case CK_AnyPointerToBlockPointerCast:
     return Visit(SubExpr);
 
-  case CastExpr::CK_IntegralToPointer: {
-    APValue Result;
-    if (!EvaluateIntegerOrLValue(SubExpr, Result, Info))
+  case CK_IntegralToPointer: {
+    APValue Value;
+    if (!EvaluateIntegerOrLValue(SubExpr, Value, Info))
       break;
 
-    if (Result.isInt()) {
-      Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
-      return APValue(0, 
-                     CharUnits::fromQuantity(Result.getInt().getZExtValue()));
+    if (Value.isInt()) {
+      Value.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
+      Result.Base = 0;
+      Result.Offset = CharUnits::fromQuantity(Value.getInt().getZExtValue());
+      return true;
+    } else {
+      // Cast is of an lvalue, no need to change value.
+      Result.Base = Value.getLValueBase();
+      Result.Offset = Value.getLValueOffset();
+      return true;
     }
-
-    // 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;
-  }
+  case CK_ArrayToPointerDecay:
+  case CK_FunctionToPointerDecay:
+    return EvaluateLValue(SubExpr, Result, Info);
   }
 
-  return APValue();
+  return false;
 }
 
-APValue PointerExprEvaluator::VisitCallExpr(CallExpr *E) {
+bool 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();
+    return Success(E);
+  return false;
 }
 
-APValue PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) {
+bool PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) {
   bool BoolResult;
   if (!HandleConversionToBool(E->getCond(), BoolResult, Info))
-    return APValue();
+    return false;
 
   Expr* EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr();
-
-  APValue Result;
-  if (EvaluatePointer(EvalExpr, Result, Info))
-    return Result;
-  return APValue();
+  return Visit(EvalExpr);
 }
 
 //===----------------------------------------------------------------------===//
@@ -675,25 +747,46 @@
   QualType EltTy = VT->getElementType();
   llvm::SmallVector<APValue, 4> Elements;
 
-  for (unsigned i = 0; i < NumElements; i++) {
+  // If a vector is initialized with a single element, that value
+  // becomes every element of the vector, not just the first.
+  // This is the behavior described in the IBM AltiVec documentation.
+  if (NumInits == 1) {
+    APValue InitValue;
     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));
+      if (!EvaluateInteger(E->getInit(0), sInt, Info))
+        return APValue();
+      InitValue = APValue(sInt);
     } else {
       llvm::APFloat f(0.0);
-      if (i < NumInits) {
-        if (!EvaluateFloat(E->getInit(i), f, Info))
-          return APValue();
+      if (!EvaluateFloat(E->getInit(0), f, Info))
+        return APValue();
+      InitValue = APValue(f);
+    }
+    for (unsigned i = 0; i < NumElements; i++) {
+      Elements.push_back(InitValue);
+    }
+  } else {
+    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 {
-        f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
+        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));
       }
-      Elements.push_back(APValue(f));
     }
   }
   return APValue(&Elements[0], Elements.size());
@@ -747,7 +840,8 @@
     : Info(info), Result(result) {}
 
   bool Success(const llvm::APSInt &SI, const Expr *E) {
-    assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
+    assert(E->getType()->isIntegralOrEnumerationType() && 
+           "Invalid evaluation result.");
     assert(SI.isSigned() == E->getType()->isSignedIntegerType() &&
            "Invalid evaluation result.");
     assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
@@ -757,7 +851,8 @@
   }
 
   bool Success(const llvm::APInt &I, const Expr *E) {
-    assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
+    assert(E->getType()->isIntegralOrEnumerationType() && 
+           "Invalid evaluation result.");
     assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
            "Invalid evaluation result.");
     Result = APValue(APSInt(I));
@@ -766,7 +861,8 @@
   }
 
   bool Success(uint64_t Value, const Expr *E) {
-    assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
+    assert(E->getType()->isIntegralOrEnumerationType() && 
+           "Invalid evaluation result.");
     Result = APValue(Info.Ctx.MakeIntValue(Value, E->getType()));
     return true;
   }
@@ -828,6 +924,7 @@
 
   bool VisitCallExpr(CallExpr *E);
   bool VisitBinaryOperator(const BinaryOperator *E);
+  bool VisitOffsetOfExpr(const OffsetOfExpr *E);
   bool VisitUnaryOperator(const UnaryOperator *E);
   bool VisitConditionalOperator(const ConditionalOperator *E);
 
@@ -842,7 +939,7 @@
     return Success(0, E);
   }
 
-  bool VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
+  bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
     return Success(0, E);
   }
 
@@ -864,18 +961,20 @@
 private:
   CharUnits GetAlignOfExpr(const Expr *E);
   CharUnits GetAlignOfType(QualType T);
+  static QualType GetObjectType(const Expr *E);
+  bool TryEvaluateBuiltinObjectSize(CallExpr *E);
   // 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;
-
+  assert(E->getType()->isIntegralOrEnumerationType());
   return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
 }
 
 static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {
+  assert(E->getType()->isIntegralOrEnumerationType());
+
   APValue Val;
   if (!EvaluateIntegerOrLValue(E, Val, Info) || !Val.isInt())
     return false;
@@ -981,36 +1080,55 @@
   return -1;
 }
 
+/// Retrieves the "underlying object type" of the given expression,
+/// as used by __builtin_object_size.
+QualType IntExprEvaluator::GetObjectType(const Expr *E) {
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+    if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
+      return VD->getType();
+  } else if (isa<CompoundLiteralExpr>(E)) {
+    return E->getType();
+  }
+
+  return QualType();
+}
+
+bool IntExprEvaluator::TryEvaluateBuiltinObjectSize(CallExpr *E) {
+  // TODO: Perhaps we should let LLVM lower this?
+  LValue Base;
+  if (!EvaluatePointer(E->getArg(0), Base, Info))
+    return false;
+
+  // If we can prove the base is null, lower to zero now.
+  const Expr *LVBase = Base.getLValueBase();
+  if (!LVBase) return Success(0, E);
+
+  QualType T = GetObjectType(LVBase);
+  if (T.isNull() ||
+      T->isIncompleteType() ||
+      T->isFunctionType() ||
+      T->isVariablyModifiedType() ||
+      T->isDependentType())
+    return false;
+
+  CharUnits Size = Info.Ctx.getTypeSizeInChars(T);
+  CharUnits Offset = Base.getLValueOffset();
+
+  if (!Offset.isNegative() && Offset <= Size)
+    Size -= Offset;
+  else
+    Size = CharUnits::Zero();
+  return Success(Size.getQuantity(), E);
+}
+
 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 (TryEvaluateBuiltinObjectSize(E))
+      return true;
 
     // If evaluating the argument has side-effects we can't determine
     // the size of the object and lower it to unknown now.
@@ -1043,7 +1161,7 @@
 }
 
 bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
-  if (E->getOpcode() == BinaryOperator::Comma) {
+  if (E->getOpcode() == BO_Comma) {
     if (!Visit(E->getRHS()))
       return false;
 
@@ -1063,11 +1181,11 @@
     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))
+      if (lhsResult == (E->getOpcode() == BO_LOr))
         return Success(lhsResult, E);
 
       if (HandleConversionToBool(E->getRHS(), rhsResult, Info)) {
-        if (E->getOpcode() == BinaryOperator::LOr)
+        if (E->getOpcode() == BO_LOr)
           return Success(lhsResult || rhsResult, E);
         else
           return Success(lhsResult && rhsResult, E);
@@ -1076,8 +1194,8 @@
       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)) {
+        if (rhsResult == (E->getOpcode() == BO_LOr) ||
+            !rhsResult == (E->getOpcode() == BO_LAnd)) {
           // Since we weren't able to evaluate the left hand side, it
           // must have had side effects.
           Info.EvalResult.HasSideEffects = true;
@@ -1095,7 +1213,7 @@
 
   if (LHSTy->isAnyComplexType()) {
     assert(RHSTy->isAnyComplexType() && "Invalid comparison");
-    APValue LHS, RHS;
+    ComplexValue LHS, RHS;
 
     if (!EvaluateComplex(E->getLHS(), LHS, Info))
       return false;
@@ -1109,23 +1227,25 @@
       APFloat::cmpResult CR_i =
         LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
 
-      if (E->getOpcode() == BinaryOperator::EQ)
+      if (E->getOpcode() == BO_EQ)
         return Success((CR_r == APFloat::cmpEqual &&
                         CR_i == APFloat::cmpEqual), E);
       else {
-        assert(E->getOpcode() == BinaryOperator::NE &&
+        assert(E->getOpcode() == BO_NE &&
                "Invalid complex comparison.");
         return Success(((CR_r == APFloat::cmpGreaterThan ||
-                         CR_r == APFloat::cmpLessThan) &&
+                         CR_r == APFloat::cmpLessThan ||
+                         CR_r == APFloat::cmpUnordered) ||
                         (CR_i == APFloat::cmpGreaterThan ||
-                         CR_i == APFloat::cmpLessThan)), E);
+                         CR_i == APFloat::cmpLessThan ||
+                         CR_i == APFloat::cmpUnordered)), E);
       }
     } else {
-      if (E->getOpcode() == BinaryOperator::EQ)
+      if (E->getOpcode() == BO_EQ)
         return Success((LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
                         LHS.getComplexIntImag() == RHS.getComplexIntImag()), E);
       else {
-        assert(E->getOpcode() == BinaryOperator::NE &&
+        assert(E->getOpcode() == BO_NE &&
                "Invalid compex comparison.");
         return Success((LHS.getComplexIntReal() != RHS.getComplexIntReal() ||
                         LHS.getComplexIntImag() != RHS.getComplexIntImag()), E);
@@ -1148,30 +1268,31 @@
     switch (E->getOpcode()) {
     default:
       assert(0 && "Invalid binary operator!");
-    case BinaryOperator::LT:
+    case BO_LT:
       return Success(CR == APFloat::cmpLessThan, E);
-    case BinaryOperator::GT:
+    case BO_GT:
       return Success(CR == APFloat::cmpGreaterThan, E);
-    case BinaryOperator::LE:
+    case BO_LE:
       return Success(CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual, E);
-    case BinaryOperator::GE:
+    case BO_GE:
       return Success(CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual,
                      E);
-    case BinaryOperator::EQ:
+    case BO_EQ:
       return Success(CR == APFloat::cmpEqual, E);
-    case BinaryOperator::NE:
+    case BO_NE:
       return Success(CR == APFloat::cmpGreaterThan
-                     || CR == APFloat::cmpLessThan, E);
+                     || CR == APFloat::cmpLessThan
+                     || CR == APFloat::cmpUnordered, E);
     }
   }
 
   if (LHSTy->isPointerType() && RHSTy->isPointerType()) {
-    if (E->getOpcode() == BinaryOperator::Sub || E->isEqualityOp()) {
-      APValue LHSValue;
+    if (E->getOpcode() == BO_Sub || E->isEqualityOp()) {
+      LValue LHSValue;
       if (!EvaluatePointer(E->getLHS(), LHSValue, Info))
         return false;
 
-      APValue RHSValue;
+      LValue RHSValue;
       if (!EvaluatePointer(E->getRHS(), RHSValue, Info))
         return false;
 
@@ -1185,7 +1306,7 @@
         bool bres;
         if (!EvalPointerValueAsBool(LHSValue, bres))
           return false;
-        return Success(bres ^ (E->getOpcode() == BinaryOperator::EQ), E);
+        return Success(bres ^ (E->getOpcode() == BO_EQ), E);
       } else if (RHSValue.getLValueBase()) {
         if (!E->isEqualityOp())
           return false;
@@ -1194,10 +1315,10 @@
         bool bres;
         if (!EvalPointerValueAsBool(RHSValue, bres))
           return false;
-        return Success(bres ^ (E->getOpcode() == BinaryOperator::EQ), E);
+        return Success(bres ^ (E->getOpcode() == BO_EQ), E);
       }
 
-      if (E->getOpcode() == BinaryOperator::Sub) {
+      if (E->getOpcode() == BO_Sub) {
         QualType Type = E->getLHS()->getType();
         QualType ElementType = Type->getAs<PointerType>()->getPointeeType();
 
@@ -1210,7 +1331,7 @@
         return Success(Diff / ElementSize, E);
       }
       bool Result;
-      if (E->getOpcode() == BinaryOperator::EQ) {
+      if (E->getOpcode() == BO_EQ) {
         Result = LHSValue.getLValueOffset() == RHSValue.getLValueOffset();
       } else {
         Result = LHSValue.getLValueOffset() != RHSValue.getLValueOffset();
@@ -1218,8 +1339,8 @@
       return Success(Result, E);
     }
   }
-  if (!LHSTy->isIntegralType() ||
-      !RHSTy->isIntegralType()) {
+  if (!LHSTy->isIntegralOrEnumerationType() ||
+      !RHSTy->isIntegralOrEnumerationType()) {
     // We can't continue from here for non-integral types, and they
     // could potentially confuse the following operations.
     return false;
@@ -1238,7 +1359,7 @@
     CharUnits Offset = Result.getLValueOffset();
     CharUnits AdditionalOffset = CharUnits::fromQuantity(
                                      RHSVal.getInt().getZExtValue());
-    if (E->getOpcode() == BinaryOperator::Add)
+    if (E->getOpcode() == BO_Add)
       Offset += AdditionalOffset;
     else
       Offset -= AdditionalOffset;
@@ -1247,7 +1368,7 @@
   }
 
   // Handle cases like 4 + (unsigned long)&a
-  if (E->getOpcode() == BinaryOperator::Add &&
+  if (E->getOpcode() == BO_Add &&
         RHSVal.isLValue() && Result.isInt()) {
     CharUnits Offset = RHSVal.getLValueOffset();
     Offset += CharUnits::fromQuantity(Result.getInt().getZExtValue());
@@ -1264,38 +1385,38 @@
   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:
+  case BO_Mul: return Success(Result.getInt() * RHS, E);
+  case BO_Add: return Success(Result.getInt() + RHS, E);
+  case BO_Sub: return Success(Result.getInt() - RHS, E);
+  case BO_And: return Success(Result.getInt() & RHS, E);
+  case BO_Xor: return Success(Result.getInt() ^ RHS, E);
+  case BO_Or:  return Success(Result.getInt() | RHS, E);
+  case BO_Div:
     if (RHS == 0)
       return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E);
     return Success(Result.getInt() / RHS, E);
-  case BinaryOperator::Rem:
+  case BO_Rem:
     if (RHS == 0)
       return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E);
     return Success(Result.getInt() % RHS, E);
-  case BinaryOperator::Shl: {
+  case BO_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: {
+  case BO_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);
+  case BO_LT: return Success(Result.getInt() < RHS, E);
+  case BO_GT: return Success(Result.getInt() > RHS, E);
+  case BO_LE: return Success(Result.getInt() <= RHS, E);
+  case BO_GE: return Success(Result.getInt() >= RHS, E);
+  case BO_EQ: return Success(Result.getInt() == RHS, E);
+  case BO_NE: return Success(Result.getInt() != RHS, E);
   }
 }
 
@@ -1372,21 +1493,87 @@
   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))
+bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *E) {
+  CharUnits Result;
+  unsigned n = E->getNumComponents();
+  OffsetOfExpr* OOE = const_cast<OffsetOfExpr*>(E);
+  if (n == 0)
+    return false;
+  QualType CurrentType = E->getTypeSourceInfo()->getType();
+  for (unsigned i = 0; i != n; ++i) {
+    OffsetOfExpr::OffsetOfNode ON = OOE->getComponent(i);
+    switch (ON.getKind()) {
+    case OffsetOfExpr::OffsetOfNode::Array: {
+      Expr *Idx = OOE->getIndexExpr(ON.getArrayExprIndex());
+      APSInt IdxResult;
+      if (!EvaluateInteger(Idx, IdxResult, Info))
+        return false;
+      const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
+      if (!AT)
+        return false;
+      CurrentType = AT->getElementType();
+      CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
+      Result += IdxResult.getSExtValue() * ElementSize;
+        break;
+    }
+        
+    case OffsetOfExpr::OffsetOfNode::Field: {
+      FieldDecl *MemberDecl = ON.getField();
+      const RecordType *RT = CurrentType->getAs<RecordType>();
+      if (!RT) 
+        return false;
+      RecordDecl *RD = RT->getDecl();
+      const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
+      unsigned i = 0;
+      // FIXME: It would be nice if we didn't have to loop here!
+      for (RecordDecl::field_iterator Field = RD->field_begin(),
+                                      FieldEnd = RD->field_end();
+           Field != FieldEnd; (void)++Field, ++i) {
+        if (*Field == MemberDecl)
+          break;
+      }
+      assert(i < RL.getFieldCount() && "offsetof field in wrong type");
+      Result += CharUnits::fromQuantity(
+                           RL.getFieldOffset(i) / Info.Ctx.getCharWidth());
+      CurrentType = MemberDecl->getType().getNonReferenceType();
+      break;
+    }
+        
+    case OffsetOfExpr::OffsetOfNode::Identifier:
+      llvm_unreachable("dependent __builtin_offsetof");
       return false;
-    if (LV.getLValueBase())
-      return false;
-    return Success(LV.getLValueOffset().getQuantity(), E);
-  }
+        
+    case OffsetOfExpr::OffsetOfNode::Base: {
+      CXXBaseSpecifier *BaseSpec = ON.getBase();
+      if (BaseSpec->isVirtual())
+        return false;
 
-  if (E->getOpcode() == UnaryOperator::LNot) {
+      // Find the layout of the class whose base we are looking into.
+      const RecordType *RT = CurrentType->getAs<RecordType>();
+      if (!RT) 
+        return false;
+      RecordDecl *RD = RT->getDecl();
+      const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
+
+      // Find the base class itself.
+      CurrentType = BaseSpec->getType();
+      const RecordType *BaseRT = CurrentType->getAs<RecordType>();
+      if (!BaseRT)
+        return false;
+      
+      // Add the offset to the base.
+      Result += CharUnits::fromQuantity(
+                RL.getBaseClassOffset(cast<CXXRecordDecl>(BaseRT->getDecl()))
+                                        / Info.Ctx.getCharWidth());
+      break;
+    }
+    }
+  }
+  return Success(Result.getQuantity(), E);
+}
+
+bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
+  if (E->getOpcode() == UO_LNot) {
     // LNot's operand isn't necessarily an integer, so we handle it specially.
     bool bres;
     if (!HandleConversionToBool(E->getSubExpr(), bres, Info))
@@ -1395,7 +1582,7 @@
   }
 
   // Only handle integral operations...
-  if (!E->getSubExpr()->getType()->isIntegralType())
+  if (!E->getSubExpr()->getType()->isIntegralOrEnumerationType())
     return false;
 
   // Get the operand value into 'Result'.
@@ -1407,17 +1594,17 @@
     // 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:
+  case UO_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:
+  case UO_Plus:
     // The result is always just the subexpr.
     return true;
-  case UnaryOperator::Minus:
+  case UO_Minus:
     if (!Result.isInt()) return false;
     return Success(-Result.getInt(), E);
-  case UnaryOperator::Not:
+  case UO_Not:
     if (!Result.isInt()) return false;
     return Success(~Result.getInt(), E);
   }
@@ -1438,7 +1625,7 @@
   }
 
   // Handle simple integer->integer casts.
-  if (SrcType->isIntegralType()) {
+  if (SrcType->isIntegralOrEnumerationType()) {
     if (!Visit(SubExpr))
       return false;
 
@@ -1453,7 +1640,7 @@
 
   // FIXME: Clean this up!
   if (SrcType->isPointerType()) {
-    APValue LV;
+    LValue LV;
     if (!EvaluatePointer(SubExpr, LV, Info))
       return false;
 
@@ -1462,7 +1649,7 @@
       if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
         return false;
 
-      Result = LV;
+      LV.moveInto(Result);
       return true;
     }
 
@@ -1474,19 +1661,19 @@
   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;
+    LValue LV;
     if (!EvaluateLValue(SubExpr, LV, Info))
       return false;
 
     if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(Info.Ctx.VoidPtrTy))
       return false;
 
-    Result = LV;
+    LV.moveInto(Result);
     return true;
   }
 
   if (SrcType->isAnyComplexType()) {
-    APValue C;
+    ComplexValue C;
     if (!EvaluateComplex(SubExpr, C, Info))
       return false;
     if (C.isComplexFloat())
@@ -1511,7 +1698,7 @@
 
 bool IntExprEvaluator::VisitUnaryReal(const UnaryOperator *E) {
   if (E->getSubExpr()->getType()->isAnyComplexType()) {
-    APValue LV;
+    ComplexValue 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);
@@ -1522,7 +1709,7 @@
 
 bool IntExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
   if (E->getSubExpr()->getType()->isComplexIntegerType()) {
-    APValue LV;
+    ComplexValue 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);
@@ -1557,20 +1744,23 @@
   bool VisitBinaryOperator(const BinaryOperator *E);
   bool VisitFloatingLiteral(const FloatingLiteral *E);
   bool VisitCastExpr(CastExpr *E);
-  bool VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
+  bool VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *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()); }
+  bool VisitUnaryReal(const UnaryOperator *E);
+  bool VisitUnaryImag(const UnaryOperator *E);
 
-  // FIXME: Missing: __real__/__imag__, array subscript of vector,
-  //                 member of vector, ImplicitValueInitExpr
+  // FIXME: Missing: array subscript of vector, member of vector,
+  //                 ImplicitValueInitExpr
 };
 } // end anonymous namespace
 
 static bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) {
+  assert(E->getType()->isRealFloatingType());
   return FloatExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
 }
 
@@ -1651,8 +1841,36 @@
   }
 }
 
+bool FloatExprEvaluator::VisitUnaryReal(const UnaryOperator *E) {
+  if (E->getSubExpr()->getType()->isAnyComplexType()) {
+    ComplexValue CV;
+    if (!EvaluateComplex(E->getSubExpr(), CV, Info))
+      return false;
+    Result = CV.FloatReal;
+    return true;
+  }
+
+  return Visit(E->getSubExpr());
+}
+
+bool FloatExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
+  if (E->getSubExpr()->getType()->isAnyComplexType()) {
+    ComplexValue CV;
+    if (!EvaluateComplex(E->getSubExpr(), CV, Info))
+      return false;
+    Result = CV.FloatImag;
+    return true;
+  }
+
+  if (!E->getSubExpr()->isEvaluatable(Info.Ctx))
+    Info.EvalResult.HasSideEffects = true;
+  const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->getType());
+  Result = llvm::APFloat::getZero(Sem);
+  return true;
+}
+
 bool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
-  if (E->getOpcode() == UnaryOperator::Deref)
+  if (E->getOpcode() == UO_Deref)
     return false;
 
   if (!EvaluateFloat(E->getSubExpr(), Result, Info))
@@ -1660,16 +1878,16 @@
 
   switch (E->getOpcode()) {
   default: return false;
-  case UnaryOperator::Plus:
+  case UO_Plus:
     return true;
-  case UnaryOperator::Minus:
+  case UO_Minus:
     Result.changeSign();
     return true;
   }
 }
 
 bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
-  if (E->getOpcode() == BinaryOperator::Comma) {
+  if (E->getOpcode() == BO_Comma) {
     if (!EvaluateFloat(E->getRHS(), Result, Info))
       return false;
 
@@ -1691,16 +1909,16 @@
 
   switch (E->getOpcode()) {
   default: return false;
-  case BinaryOperator::Mul:
+  case BO_Mul:
     Result.multiply(RHS, APFloat::rmNearestTiesToEven);
     return true;
-  case BinaryOperator::Add:
+  case BO_Add:
     Result.add(RHS, APFloat::rmNearestTiesToEven);
     return true;
-  case BinaryOperator::Sub:
+  case BO_Sub:
     Result.subtract(RHS, APFloat::rmNearestTiesToEven);
     return true;
-  case BinaryOperator::Div:
+  case BO_Div:
     Result.divide(RHS, APFloat::rmNearestTiesToEven);
     return true;
   }
@@ -1714,7 +1932,7 @@
 bool FloatExprEvaluator::VisitCastExpr(CastExpr *E) {
   Expr* SubExpr = E->getSubExpr();
 
-  if (SubExpr->getType()->isIntegralType()) {
+  if (SubExpr->getType()->isIntegralOrEnumerationType()) {
     APSInt IntResult;
     if (!EvaluateInteger(SubExpr, IntResult, Info))
       return false;
@@ -1734,7 +1952,7 @@
   return false;
 }
 
-bool FloatExprEvaluator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+bool FloatExprEvaluator::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
   Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->getType()));
   return true;
 }
@@ -1753,167 +1971,175 @@
 
 namespace {
 class ComplexExprEvaluator
-  : public StmtVisitor<ComplexExprEvaluator, APValue> {
+  : public StmtVisitor<ComplexExprEvaluator, bool> {
   EvalInfo &Info;
+  ComplexValue &Result;
 
 public:
-  ComplexExprEvaluator(EvalInfo &info) : Info(info) {}
+  ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
+    : Info(info), Result(Result) {}
 
   //===--------------------------------------------------------------------===//
   //                            Visitor Methods
   //===--------------------------------------------------------------------===//
 
-  APValue VisitStmt(Stmt *S) {
-    return APValue();
+  bool VisitStmt(Stmt *S) {
+    return false;
   }
 
-  APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
+  bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
 
-  APValue VisitImaginaryLiteral(ImaginaryLiteral *E) {
-    Expr* SubExpr = E->getSubExpr();
+  bool VisitImaginaryLiteral(ImaginaryLiteral *E);
 
-    if (SubExpr->getType()->isRealFloatingType()) {
-      APFloat Result(0.0);
+  bool VisitCastExpr(CastExpr *E);
 
-      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)
+  bool VisitBinaryOperator(const BinaryOperator *E);
+  bool VisitChooseExpr(const ChooseExpr *E)
     { return Visit(E->getChosenSubExpr(Info.Ctx)); }
-  APValue VisitUnaryExtension(const UnaryOperator *E)
+  bool 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();
+static bool EvaluateComplex(const Expr *E, ComplexValue &Result,
+                            EvalInfo &Info) {
+  assert(E->getType()->isAnyComplexType());
+  return ComplexExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
 }
 
-APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
-  APValue Result, RHS;
+bool ComplexExprEvaluator::VisitImaginaryLiteral(ImaginaryLiteral *E) {
+  Expr* SubExpr = E->getSubExpr();
 
-  if (!EvaluateComplex(E->getLHS(), Result, Info))
-    return APValue();
+  if (SubExpr->getType()->isRealFloatingType()) {
+    Result.makeComplexFloat();
+    APFloat &Imag = Result.FloatImag;
+    if (!EvaluateFloat(SubExpr, Imag, Info))
+      return false;
 
+    Result.FloatReal = APFloat(Imag.getSemantics());
+    return true;
+  } else {
+    assert(SubExpr->getType()->isIntegerType() &&
+           "Unexpected imaginary literal.");
+
+    Result.makeComplexInt();
+    APSInt &Imag = Result.IntImag;
+    if (!EvaluateInteger(SubExpr, Imag, Info))
+      return false;
+
+    Result.IntReal = APSInt(Imag.getBitWidth(), !Imag.isSigned());
+    return true;
+  }
+}
+
+bool ComplexExprEvaluator::VisitCastExpr(CastExpr *E) {
+  Expr* SubExpr = E->getSubExpr();
+  QualType EltType = E->getType()->getAs<ComplexType>()->getElementType();
+  QualType SubType = SubExpr->getType();
+
+  if (SubType->isRealFloatingType()) {
+    APFloat &Real = Result.FloatReal;
+    if (!EvaluateFloat(SubExpr, Real, Info))
+      return false;
+
+    if (EltType->isRealFloatingType()) {
+      Result.makeComplexFloat();
+      Real = HandleFloatToFloatCast(EltType, SubType, Real, Info.Ctx);
+      Result.FloatImag = APFloat(Real.getSemantics());
+      return true;
+    } else {
+      Result.makeComplexInt();
+      Result.IntReal = HandleFloatToIntCast(EltType, SubType, Real, Info.Ctx);
+      Result.IntImag = APSInt(Result.IntReal.getBitWidth(),
+                              !Result.IntReal.isSigned());
+      return true;
+    }
+  } else if (SubType->isIntegerType()) {
+    APSInt &Real = Result.IntReal;
+    if (!EvaluateInteger(SubExpr, Real, Info))
+      return false;
+
+    if (EltType->isRealFloatingType()) {
+      Result.makeComplexFloat();
+      Result.FloatReal
+        = HandleIntToFloatCast(EltType, SubType, Real, Info.Ctx);
+      Result.FloatImag = APFloat(Result.FloatReal.getSemantics());
+      return true;
+    } else {
+      Result.makeComplexInt();
+      Real = HandleIntToIntCast(EltType, SubType, Real, Info.Ctx);
+      Result.IntImag = APSInt(Real.getBitWidth(), !Real.isSigned());
+      return true;
+    }
+  } else if (const ComplexType *CT = SubType->getAs<ComplexType>()) {
+    if (!Visit(SubExpr))
+      return false;
+
+    QualType SrcType = CT->getElementType();
+
+    if (Result.isComplexFloat()) {
+      if (EltType->isRealFloatingType()) {
+        Result.makeComplexFloat();
+        Result.FloatReal = HandleFloatToFloatCast(EltType, SrcType,
+                                                  Result.FloatReal,
+                                                  Info.Ctx);
+        Result.FloatImag = HandleFloatToFloatCast(EltType, SrcType,
+                                                  Result.FloatImag,
+                                                  Info.Ctx);
+        return true;
+      } else {
+        Result.makeComplexInt();
+        Result.IntReal = HandleFloatToIntCast(EltType, SrcType,
+                                              Result.FloatReal,
+                                              Info.Ctx);
+        Result.IntImag = HandleFloatToIntCast(EltType, SrcType,
+                                              Result.FloatImag,
+                                              Info.Ctx);
+        return true;
+      }
+    } else {
+      assert(Result.isComplexInt() && "Invalid evaluate result.");
+      if (EltType->isRealFloatingType()) {
+        Result.makeComplexFloat();
+        Result.FloatReal = HandleIntToFloatCast(EltType, SrcType,
+                                                Result.IntReal,
+                                                Info.Ctx);
+        Result.FloatImag = HandleIntToFloatCast(EltType, SrcType,
+                                                Result.IntImag,
+                                                Info.Ctx);
+        return true;
+      } else {
+        Result.makeComplexInt();
+        Result.IntReal = HandleIntToIntCast(EltType, SrcType,
+                                            Result.IntReal,
+                                            Info.Ctx);
+        Result.IntImag = HandleIntToIntCast(EltType, SrcType,
+                                            Result.IntImag,
+                                            Info.Ctx);
+        return true;
+      }
+    }
+  }
+
+  // FIXME: Handle more casts.
+  return false;
+}
+
+bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+  if (!Visit(E->getLHS()))
+    return false;
+
+  ComplexValue RHS;
   if (!EvaluateComplex(E->getRHS(), RHS, Info))
-    return APValue();
+    return false;
 
   assert(Result.isComplexFloat() == RHS.isComplexFloat() &&
          "Invalid operands to binary operator.");
   switch (E->getOpcode()) {
-  default: return APValue();
-  case BinaryOperator::Add:
+  default: return false;
+  case BO_Add:
     if (Result.isComplexFloat()) {
       Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
                                        APFloat::rmNearestTiesToEven);
@@ -1924,7 +2150,7 @@
       Result.getComplexIntImag() += RHS.getComplexIntImag();
     }
     break;
-  case BinaryOperator::Sub:
+  case BO_Sub:
     if (Result.isComplexFloat()) {
       Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
                                             APFloat::rmNearestTiesToEven);
@@ -1935,9 +2161,9 @@
       Result.getComplexIntImag() -= RHS.getComplexIntImag();
     }
     break;
-  case BinaryOperator::Mul:
+  case BO_Mul:
     if (Result.isComplexFloat()) {
-      APValue LHS = Result;
+      ComplexValue LHS = Result;
       APFloat &LHS_r = LHS.getComplexFloatReal();
       APFloat &LHS_i = LHS.getComplexFloatImag();
       APFloat &RHS_r = RHS.getComplexFloatReal();
@@ -1957,7 +2183,7 @@
       Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven);
       Result.getComplexFloatImag().add(Tmp, APFloat::rmNearestTiesToEven);
     } else {
-      APValue LHS = Result;
+      ComplexValue LHS = Result;
       Result.getComplexIntReal() =
         (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
          LHS.getComplexIntImag() * RHS.getComplexIntImag());
@@ -1968,7 +2194,7 @@
     break;
   }
 
-  return Result;
+  return true;
 }
 
 //===----------------------------------------------------------------------===//
@@ -1980,53 +2206,34 @@
 /// we want to.  If this function returns true, it returns the folded constant
 /// in Result.
 bool Expr::Evaluate(EvalResult &Result, ASTContext &Ctx) const {
+  const Expr *E = this;
   EvalInfo Info(Ctx, Result);
-
-  if (getType()->isVectorType()) {
-    if (!EvaluateVector(this, Result.Val, Info))
+  if (E->getType()->isVectorType()) {
+    if (!EvaluateVector(E, Info.EvalResult.Val, Info))
       return false;
-  } else if (getType()->isIntegerType()) {
-    if (!IntExprEvaluator(Info, Result.Val).Visit(const_cast<Expr*>(this)))
+  } else if (E->getType()->isIntegerType()) {
+    if (!IntExprEvaluator(Info, Info.EvalResult.Val).Visit(const_cast<Expr*>(E)))
       return false;
-  } else if (getType()->hasPointerRepresentation()) {
-    if (!EvaluatePointer(this, Result.Val, Info))
+    if (Result.Val.isLValue() && !IsGlobalLValue(Result.Val.getLValueBase()))
       return false;
-  } else if (getType()->isRealFloatingType()) {
-    llvm::APFloat f(0.0);
-    if (!EvaluateFloat(this, f, Info))
+  } else if (E->getType()->hasPointerRepresentation()) {
+    LValue LV;
+    if (!EvaluatePointer(E, LV, Info))
+      return false;
+    if (!IsGlobalLValue(LV.Base))
+      return false;
+    LV.moveInto(Info.EvalResult.Val);
+  } else if (E->getType()->isRealFloatingType()) {
+    llvm::APFloat F(0.0);
+    if (!EvaluateFloat(E, F, Info))
       return false;
 
-    Result.Val = APValue(f);
-  } else if (getType()->isAnyComplexType()) {
-    if (!EvaluateComplex(this, Result.Val, Info))
+    Info.EvalResult.Val = APValue(F);
+  } else if (E->getType()->isAnyComplexType()) {
+    ComplexValue C;
+    if (!EvaluateComplex(E, C, 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;
+    C.moveInto(Info.EvalResult.Val);
   } else
     return false;
 
@@ -2043,13 +2250,25 @@
 bool Expr::EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const {
   EvalInfo Info(Ctx, Result);
 
-  return EvaluateLValue(this, Result.Val, Info) && !Result.HasSideEffects;
+  LValue LV;
+  if (EvaluateLValue(this, LV, Info) &&
+      !Result.HasSideEffects &&
+      IsGlobalLValue(LV.Base)) {
+    LV.moveInto(Result.Val);
+    return true;
+  }
+  return false;
 }
 
 bool Expr::EvaluateAsAnyLValue(EvalResult &Result, ASTContext &Ctx) const {
-  EvalInfo Info(Ctx, Result, true);
+  EvalInfo Info(Ctx, Result);
 
-  return EvaluateLValue(this, Result.Val, Info) && !Result.HasSideEffects;
+  LValue LV;
+  if (EvaluateLValue(this, LV, Info)) {
+    LV.moveInto(Result.Val);
+    return true;
+  }
+  return false;
 }
 
 /// isEvaluatable - Call Evaluate to see if this expression can be constant
@@ -2074,3 +2293,390 @@
 
   return EvalResult.Val.getInt();
 }
+
+ bool Expr::EvalResult::isGlobalLValue() const {
+   assert(Val.isLValue());
+   return IsGlobalLValue(Val.getLValueBase());
+ }
+
+
+/// 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.
+
+namespace {
+
+struct ICEDiag {
+  unsigned Val;
+  SourceLocation Loc;
+
+  public:
+  ICEDiag(unsigned v, SourceLocation l) : Val(v), Loc(l) {}
+  ICEDiag() : Val(0) {}
+};
+
+}
+
+static 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()->isIntegralOrEnumerationType()) {
+    return ICEDiag(2, E->getLocStart());
+  }
+
+  switch (E->getStmtClass()) {
+#define STMT(Node, Base) case Expr::Node##Class:
+#define EXPR(Node, Base)
+#include "clang/AST/StmtNodes.inc"
+  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::CXXScalarValueInitExprClass:
+  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 UO_PostInc:
+    case UO_PostDec:
+    case UO_PreInc:
+    case UO_PreDec:
+    case UO_AddrOf:
+    case UO_Deref:
+      return ICEDiag(2, E->getLocStart());
+    case UO_Extension:
+    case UO_LNot:
+    case UO_Plus:
+    case UO_Minus:
+    case UO_Not:
+    case UO_Real:
+    case UO_Imag:
+      return CheckICE(Exp->getSubExpr(), Ctx);
+    }
+    
+    // OffsetOf falls through here.
+  }
+  case Expr::OffsetOfExprClass: {
+      // 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 BO_PtrMemD:
+    case BO_PtrMemI:
+    case BO_Assign:
+    case BO_MulAssign:
+    case BO_DivAssign:
+    case BO_RemAssign:
+    case BO_AddAssign:
+    case BO_SubAssign:
+    case BO_ShlAssign:
+    case BO_ShrAssign:
+    case BO_AndAssign:
+    case BO_XorAssign:
+    case BO_OrAssign:
+      return ICEDiag(2, E->getLocStart());
+
+    case BO_Mul:
+    case BO_Div:
+    case BO_Rem:
+    case BO_Add:
+    case BO_Sub:
+    case BO_Shl:
+    case BO_Shr:
+    case BO_LT:
+    case BO_GT:
+    case BO_LE:
+    case BO_GE:
+    case BO_EQ:
+    case BO_NE:
+    case BO_And:
+    case BO_Xor:
+    case BO_Or:
+    case BO_Comma: {
+      ICEDiag LHSResult = CheckICE(Exp->getLHS(), Ctx);
+      ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx);
+      if (Exp->getOpcode() == BO_Div ||
+          Exp->getOpcode() == BO_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() == BO_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 BO_LAnd:
+    case BO_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() == BO_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()->isIntegralOrEnumerationType())
+      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;
+}
diff --git a/lib/AST/FullExpr.cpp b/lib/AST/FullExpr.cpp
index f47284f..93ee8d1 100644
--- a/lib/AST/FullExpr.cpp
+++ b/lib/AST/FullExpr.cpp
@@ -43,16 +43,3 @@
   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/ItaniumCXXABI.cpp b/lib/AST/ItaniumCXXABI.cpp
new file mode 100644
index 0000000..c3fa466
--- /dev/null
+++ b/lib/AST/ItaniumCXXABI.cpp
@@ -0,0 +1,52 @@
+//===------- ItaniumCXXABI.cpp - AST support for the Itanium C++ ABI ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This provides C++ AST support targetting the Itanium C++ ABI, which is
+// documented at:
+//  http://www.codesourcery.com/public/cxx-abi/abi.html
+//  http://www.codesourcery.com/public/cxx-abi/abi-eh.html
+//
+// It also supports the closely-related ARM C++ ABI, documented at:
+// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
+//
+//===----------------------------------------------------------------------===//
+
+#include "CXXABI.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+
+using namespace clang;
+
+namespace {
+class ItaniumCXXABI : public CXXABI {
+protected:
+  ASTContext &Context;
+public:
+  ItaniumCXXABI(ASTContext &Ctx) : Context(Ctx) { }
+
+  unsigned getMemberPointerSize(const MemberPointerType *MPT) const {
+    QualType Pointee = MPT->getPointeeType();
+    if (Pointee->isFunctionType()) return 2;
+    return 1;
+  }
+};
+
+class ARMCXXABI : public ItaniumCXXABI {
+public:
+  ARMCXXABI(ASTContext &Ctx) : ItaniumCXXABI(Ctx) { }
+};
+}
+
+CXXABI *clang::CreateItaniumCXXABI(ASTContext &Ctx) {
+  return new ItaniumCXXABI(Ctx);
+}
+
+CXXABI *clang::CreateARMCXXABI(ASTContext &Ctx) {
+  return new ARMCXXABI(Ctx);
+}
diff --git a/lib/AST/Makefile b/lib/AST/Makefile
index ede2577..65383c5 100644
--- a/lib/AST/Makefile
+++ b/lib/AST/Makefile
@@ -11,11 +11,8 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
+CLANG_LEVEL := ../..
 LIBRARYNAME := clangAST
-BUILD_ARCHIVE = 1
 
-CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
 
diff --git a/lib/AST/MicrosoftCXXABI.cpp b/lib/AST/MicrosoftCXXABI.cpp
new file mode 100644
index 0000000..87b7767
--- /dev/null
+++ b/lib/AST/MicrosoftCXXABI.cpp
@@ -0,0 +1,48 @@
+//===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This provides C++ AST support targetting the Microsoft Visual C++
+// ABI.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CXXABI.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/DeclCXX.h"
+
+using namespace clang;
+
+namespace {
+class MicrosoftCXXABI : public CXXABI {
+  ASTContext &Context;
+public:
+  MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
+
+  unsigned getMemberPointerSize(const MemberPointerType *MPT) const;
+};
+}
+
+unsigned MicrosoftCXXABI::getMemberPointerSize(const MemberPointerType *MPT) const {
+  QualType Pointee = MPT->getPointeeType();
+  CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+  if (RD->getNumVBases() > 0) {
+    if (Pointee->isFunctionType())
+      return 3;
+    else
+      return 2;
+  } else if (RD->getNumBases() > 1 && Pointee->isFunctionType())
+    return 2;
+  return 1;
+}
+
+CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
+  return new MicrosoftCXXABI(Ctx);
+}
+
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index 45518e9..212def8 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -145,14 +145,14 @@
     InnerPolicy.SuppressScope = true;
 
     // Nested-name-specifiers are intended to contain minimally-qualified
-    // types. An actual QualifiedNameType will not occur, since we'll store
+    // types. An actual ElaboratedType 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");
+    assert(!isa<ElaboratedType>(T) &&
+           "Elaborated type in nested-name-specifier");
     if (const TemplateSpecializationType *SpecType
           = dyn_cast<TemplateSpecializationType>(T)) {
       // Print the template name without its corresponding
@@ -176,11 +176,6 @@
   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
index 48251d5..5fe873a 100644
--- a/lib/AST/ParentMap.cpp
+++ b/lib/AST/ParentMap.cpp
@@ -73,7 +73,7 @@
       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();
+      return BE->getOpcode()!=BO_Comma ||DirectChild==BE->getRHS();
     }
     case Stmt::ForStmtClass:
       return DirectChild == cast<ForStmt>(P)->getCond();
diff --git a/lib/AST/RecordLayout.cpp b/lib/AST/RecordLayout.cpp
index ade2483..4d9c516 100644
--- a/lib/AST/RecordLayout.cpp
+++ b/lib/AST/RecordLayout.cpp
@@ -19,8 +19,10 @@
 void ASTRecordLayout::Destroy(ASTContext &Ctx) {
   if (FieldOffsets)
     Ctx.Deallocate(FieldOffsets);
-  if (CXXInfo)
+  if (CXXInfo) {
     Ctx.Deallocate(CXXInfo);
+    CXXInfo->~CXXRecordLayoutInfo();
+  }
   this->~ASTRecordLayout();
   Ctx.Deallocate(this);
 }
@@ -44,7 +46,9 @@
                                  unsigned fieldcount,
                                  uint64_t nonvirtualsize,
                                  unsigned nonvirtualalign,
-                                 const PrimaryBaseInfo &PrimaryBase,
+                                 uint64_t SizeOfLargestEmptySubobject,
+                                 const CXXRecordDecl *PrimaryBase,
+                                 bool PrimaryBaseIsVirtual,
                                  const BaseOffsetsMapTy& BaseOffsets,
                                  const BaseOffsetsMapTy& VBaseOffsets)
   : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
@@ -55,9 +59,10 @@
     memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
   }
 
-  CXXInfo->PrimaryBase = PrimaryBase;
+  CXXInfo->PrimaryBase = PrimaryBaseInfo(PrimaryBase, PrimaryBaseIsVirtual);
   CXXInfo->NonVirtualSize = nonvirtualsize;
   CXXInfo->NonVirtualAlign = nonvirtualalign;
+  CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
   CXXInfo->BaseOffsets = BaseOffsets;
   CXXInfo->VBaseOffsets = VBaseOffsets;
 
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 3782985..13fae29 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -1,4 +1,4 @@
-//=== ASTRecordLayoutBuilder.cpp - Helper class for building record layouts ==//
+//=== RecordLayoutBuilder.cpp - Helper class for building record layouts ---==//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,28 +7,676 @@
 //
 //===----------------------------------------------------------------------===//
 
-#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/AST/RecordLayout.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/Support/Format.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/Support/MathExtras.h"
+#include <map>
 
 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) { }
+namespace {
+
+/// BaseSubobjectInfo - Represents a single base subobject in a complete class.
+/// For a class hierarchy like
+///
+/// class A { };
+/// class B : A { };
+/// class C : A, B { };
+///
+/// The BaseSubobjectInfo graph for C will have three BaseSubobjectInfo
+/// instances, one for B and two for A.
+///
+/// If a base is virtual, it will only have one BaseSubobjectInfo allocated.
+struct BaseSubobjectInfo {
+  /// Class - The class for this base info.
+  const CXXRecordDecl *Class;
+
+  /// IsVirtual - Whether the BaseInfo represents a virtual base or not.
+  bool IsVirtual;
+
+  /// Bases - Information about the base subobjects.
+  llvm::SmallVector<BaseSubobjectInfo*, 4> Bases;
+
+  /// PrimaryVirtualBaseInfo - Holds the base info for the primary virtual base
+  /// of this base info (if one exists).
+  BaseSubobjectInfo *PrimaryVirtualBaseInfo;
+
+  // FIXME: Document.
+  const BaseSubobjectInfo *Derived;
+};
+
+/// EmptySubobjectMap - Keeps track of which empty subobjects exist at different
+/// offsets while laying out a C++ class.
+class EmptySubobjectMap {
+  ASTContext &Context;
+
+  /// Class - The class whose empty entries we're keeping track of.
+  const CXXRecordDecl *Class;
+
+  /// EmptyClassOffsets - A map from offsets to empty record decls.
+  typedef llvm::SmallVector<const CXXRecordDecl *, 1> ClassVectorTy;
+  typedef llvm::DenseMap<uint64_t, ClassVectorTy> EmptyClassOffsetsMapTy;
+  EmptyClassOffsetsMapTy EmptyClassOffsets;
+  
+  /// MaxEmptyClassOffset - The highest offset known to contain an empty
+  /// base subobject.
+  uint64_t MaxEmptyClassOffset;
+  
+  /// ComputeEmptySubobjectSizes - Compute the size of the largest base or
+  /// member subobject that is empty.
+  void ComputeEmptySubobjectSizes();
+  
+  void AddSubobjectAtOffset(const CXXRecordDecl *RD, uint64_t Offset);
+  
+  void UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info,
+                                 uint64_t Offset, bool PlacingEmptyBase);
+  
+  void UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, 
+                                  const CXXRecordDecl *Class,
+                                  uint64_t Offset);
+  void UpdateEmptyFieldSubobjects(const FieldDecl *FD, uint64_t Offset);
+  
+  /// AnyEmptySubobjectsBeyondOffset - Returns whether there are any empty
+  /// subobjects beyond the given offset.
+  bool AnyEmptySubobjectsBeyondOffset(uint64_t Offset) const {
+    return Offset <= MaxEmptyClassOffset;
+  }
+
+protected:
+  bool CanPlaceSubobjectAtOffset(const CXXRecordDecl *RD, 
+                                 uint64_t Offset) const;
+
+  bool CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info,
+                                     uint64_t Offset);
+
+  bool CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, 
+                                      const CXXRecordDecl *Class,
+                                      uint64_t Offset) const;
+  bool CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD,
+                                      uint64_t Offset) const;
+
+public:
+  /// This holds the size of the largest empty subobject (either a base
+  /// or a member). Will be zero if the record being built doesn't contain
+  /// any empty classes.
+  uint64_t SizeOfLargestEmptySubobject;
+
+  EmptySubobjectMap(ASTContext &Context, const CXXRecordDecl *Class)
+    : Context(Context), Class(Class), MaxEmptyClassOffset(0),
+    SizeOfLargestEmptySubobject(0) {
+      ComputeEmptySubobjectSizes();
+  }
+
+  /// CanPlaceBaseAtOffset - Return whether the given base class 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 CanPlaceBaseAtOffset(const BaseSubobjectInfo *Info,
+                            uint64_t Offset);
+
+  /// CanPlaceFieldAtOffset - Return whether a field can be placed at the given
+  /// offset.
+  bool CanPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset);
+};
+
+void EmptySubobjectMap::ComputeEmptySubobjectSizes() {
+  // Check the bases.
+  for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
+       E = Class->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    uint64_t EmptySize = 0;
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
+    if (BaseDecl->isEmpty()) {
+      // If the class decl is empty, get its size.
+      EmptySize = Layout.getSize();
+    } else {
+      // Otherwise, we get the largest empty subobject for the decl.
+      EmptySize = Layout.getSizeOfLargestEmptySubobject();
+    }
+
+    SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject,
+                                           EmptySize);
+  }
+
+  // Check the fields.
+  for (CXXRecordDecl::field_iterator I = Class->field_begin(),
+       E = Class->field_end(); I != E; ++I) {
+    const FieldDecl *FD = *I;
+
+    const RecordType *RT =
+      Context.getBaseElementType(FD->getType())->getAs<RecordType>();
+
+    // We only care about record types.
+    if (!RT)
+      continue;
+
+    uint64_t EmptySize = 0;
+    const CXXRecordDecl *MemberDecl = cast<CXXRecordDecl>(RT->getDecl());
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(MemberDecl);
+    if (MemberDecl->isEmpty()) {
+      // If the class decl is empty, get its size.
+      EmptySize = Layout.getSize();
+    } else {
+      // Otherwise, we get the largest empty subobject for the decl.
+      EmptySize = Layout.getSizeOfLargestEmptySubobject();
+    }
+
+   SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject,
+                                          EmptySize);
+  }
+}
+
+bool
+EmptySubobjectMap::CanPlaceSubobjectAtOffset(const CXXRecordDecl *RD, 
+                                             uint64_t Offset) const {
+  // We only need to check empty bases.
+  if (!RD->isEmpty())
+    return true;
+
+  EmptyClassOffsetsMapTy::const_iterator I = EmptyClassOffsets.find(Offset);
+  if (I == EmptyClassOffsets.end())
+    return true;
+  
+  const ClassVectorTy& Classes = I->second;
+  if (std::find(Classes.begin(), Classes.end(), RD) == Classes.end())
+    return true;
+
+  // There is already an empty class of the same type at this offset.
+  return false;
+}
+  
+void EmptySubobjectMap::AddSubobjectAtOffset(const CXXRecordDecl *RD, 
+                                             uint64_t Offset) {
+  // We only care about empty bases.
+  if (!RD->isEmpty())
+    return;
+
+  ClassVectorTy& Classes = EmptyClassOffsets[Offset];
+  assert(std::find(Classes.begin(), Classes.end(), RD) == Classes.end() &&
+         "Duplicate empty class detected!");
+
+  Classes.push_back(RD);
+  
+  // Update the empty class offset.
+  MaxEmptyClassOffset = std::max(MaxEmptyClassOffset, Offset);
+}
+
+bool
+EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info, 
+                                                 uint64_t Offset) {
+  // We don't have to keep looking past the maximum offset that's known to
+  // contain an empty class.
+  if (!AnyEmptySubobjectsBeyondOffset(Offset))
+    return true;
+
+  if (!CanPlaceSubobjectAtOffset(Info->Class, Offset))
+    return false;
+
+  // Traverse all non-virtual bases.
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class);
+  for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) {
+    BaseSubobjectInfo* Base = Info->Bases[I];
+    if (Base->IsVirtual)
+      continue;
+
+    uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class);
+
+    if (!CanPlaceBaseSubobjectAtOffset(Base, BaseOffset))
+      return false;
+  }
+
+  if (Info->PrimaryVirtualBaseInfo) {
+    BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo;
+
+    if (Info == PrimaryVirtualBaseInfo->Derived) {
+      if (!CanPlaceBaseSubobjectAtOffset(PrimaryVirtualBaseInfo, Offset))
+        return false;
+    }
+  }
+  
+  // Traverse all member variables.
+  unsigned FieldNo = 0;
+  for (CXXRecordDecl::field_iterator I = Info->Class->field_begin(), 
+       E = Info->Class->field_end(); I != E; ++I, ++FieldNo) {
+    const FieldDecl *FD = *I;
+
+    uint64_t FieldOffset = Offset + Layout.getFieldOffset(FieldNo);
+    if (!CanPlaceFieldSubobjectAtOffset(FD, FieldOffset))
+      return false;
+  }
+  
+  return true;
+}
+
+void EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info, 
+                                                  uint64_t Offset,
+                                                  bool PlacingEmptyBase) {
+  if (!PlacingEmptyBase && Offset >= SizeOfLargestEmptySubobject) {
+    // We know that the only empty subobjects that can conflict with empty
+    // subobject of non-empty bases, are empty bases that can be placed at
+    // offset zero. Because of this, we only need to keep track of empty base 
+    // subobjects with offsets less than the size of the largest empty
+    // subobject for our class.    
+    return;
+  }
+
+  AddSubobjectAtOffset(Info->Class, Offset);
+
+  // Traverse all non-virtual bases.
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class);
+  for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) {
+    BaseSubobjectInfo* Base = Info->Bases[I];
+    if (Base->IsVirtual)
+      continue;
+
+    uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class);
+    UpdateEmptyBaseSubobjects(Base, BaseOffset, PlacingEmptyBase);
+  }
+
+  if (Info->PrimaryVirtualBaseInfo) {
+    BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo;
+    
+    if (Info == PrimaryVirtualBaseInfo->Derived)
+      UpdateEmptyBaseSubobjects(PrimaryVirtualBaseInfo, Offset,
+                                PlacingEmptyBase);
+  }
+
+  // Traverse all member variables.
+  unsigned FieldNo = 0;
+  for (CXXRecordDecl::field_iterator I = Info->Class->field_begin(), 
+       E = Info->Class->field_end(); I != E; ++I, ++FieldNo) {
+    const FieldDecl *FD = *I;
+
+    uint64_t FieldOffset = Offset + Layout.getFieldOffset(FieldNo);
+    UpdateEmptyFieldSubobjects(FD, FieldOffset);
+  }
+}
+
+bool EmptySubobjectMap::CanPlaceBaseAtOffset(const BaseSubobjectInfo *Info,
+                                             uint64_t Offset) {
+  // If we know this class doesn't have any empty subobjects we don't need to
+  // bother checking.
+  if (!SizeOfLargestEmptySubobject)
+    return true;
+
+  if (!CanPlaceBaseSubobjectAtOffset(Info, Offset))
+    return false;
+
+  // We are able to place the base at this offset. Make sure to update the
+  // empty base subobject map.
+  UpdateEmptyBaseSubobjects(Info, Offset, Info->Class->isEmpty());
+  return true;
+}
+
+bool
+EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, 
+                                                  const CXXRecordDecl *Class,
+                                                  uint64_t Offset) const {
+  // We don't have to keep looking past the maximum offset that's known to
+  // contain an empty class.
+  if (!AnyEmptySubobjectsBeyondOffset(Offset))
+    return true;
+
+  if (!CanPlaceSubobjectAtOffset(RD, Offset))
+    return false;
+  
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+
+  // Traverse all non-virtual 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());
+
+    uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl);
+    if (!CanPlaceFieldSubobjectAtOffset(BaseDecl, Class, BaseOffset))
+      return false;
+  }
+
+  if (RD == Class) {
+    // This is the most derived class, traverse virtual bases as well.
+    for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
+         E = RD->vbases_end(); I != E; ++I) {
+      const CXXRecordDecl *VBaseDecl =
+        cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+      
+      uint64_t VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl);
+      if (!CanPlaceFieldSubobjectAtOffset(VBaseDecl, Class, VBaseOffset))
+        return false;
+    }
+  }
+    
+  // Traverse all member variables.
+  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 = Offset + Layout.getFieldOffset(FieldNo);
+    
+    if (!CanPlaceFieldSubobjectAtOffset(FD, FieldOffset))
+      return false;
+  }
+
+  return true;
+}
+
+bool EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD,
+                                                       uint64_t Offset) const {
+  // We don't have to keep looking past the maximum offset that's known to
+  // contain an empty class.
+  if (!AnyEmptySubobjectsBeyondOffset(Offset))
+    return true;
+  
+  QualType T = FD->getType();
+  if (const RecordType *RT = T->getAs<RecordType>()) {
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+    return CanPlaceFieldSubobjectAtOffset(RD, RD, Offset);
+  }
+
+  // If we have an array type we need to look at every element.
+  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 = cast<CXXRecordDecl>(RT->getDecl());
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+
+    uint64_t NumElements = Context.getConstantArrayElementCount(AT);
+    uint64_t ElementOffset = Offset;
+    for (uint64_t I = 0; I != NumElements; ++I) {
+      // We don't have to keep looking past the maximum offset that's known to
+      // contain an empty class.
+      if (!AnyEmptySubobjectsBeyondOffset(ElementOffset))
+        return true;
+      
+      if (!CanPlaceFieldSubobjectAtOffset(RD, RD, ElementOffset))
+        return false;
+
+      ElementOffset += Layout.getSize();
+    }
+  }
+
+  return true;
+}
+
+bool
+EmptySubobjectMap::CanPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) {
+  if (!CanPlaceFieldSubobjectAtOffset(FD, Offset))
+    return false;
+  
+  // We are able to place the member variable at this offset.
+  // Make sure to update the empty base subobject map.
+  UpdateEmptyFieldSubobjects(FD, Offset);
+  return true;
+}
+
+void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, 
+                                                   const CXXRecordDecl *Class,
+                                                   uint64_t Offset) {
+  // We know that the only empty subobjects that can conflict with empty
+  // field subobjects are subobjects of empty bases that can be placed at offset
+  // zero. Because of this, we only need to keep track of empty field 
+  // subobjects with offsets less than the size of the largest empty
+  // subobject for our class.
+  if (Offset >= SizeOfLargestEmptySubobject)
+    return;
+
+  AddSubobjectAtOffset(RD, Offset);
+
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+
+  // Traverse all non-virtual 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());
+
+    uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl);
+    UpdateEmptyFieldSubobjects(BaseDecl, Class, BaseOffset);
+  }
+
+  if (RD == Class) {
+    // This is the most derived class, traverse virtual bases as well.
+    for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
+         E = RD->vbases_end(); I != E; ++I) {
+      const CXXRecordDecl *VBaseDecl =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+      
+      uint64_t VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl);
+      UpdateEmptyFieldSubobjects(VBaseDecl, Class, VBaseOffset);
+    }
+  }
+  
+  // Traverse all member variables.
+  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 = Offset + Layout.getFieldOffset(FieldNo);
+
+    UpdateEmptyFieldSubobjects(FD, FieldOffset);
+  }
+}
+  
+void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const FieldDecl *FD,
+                                                   uint64_t Offset) {
+  QualType T = FD->getType();
+  if (const RecordType *RT = T->getAs<RecordType>()) {
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+    UpdateEmptyFieldSubobjects(RD, RD, Offset);
+    return;
+  }
+
+  // If we have an array type we need to update every element.
+  if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) {
+    QualType ElemTy = Context.getBaseElementType(AT);
+    const RecordType *RT = ElemTy->getAs<RecordType>();
+    if (!RT)
+      return;
+    
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    
+    uint64_t NumElements = Context.getConstantArrayElementCount(AT);
+    uint64_t ElementOffset = Offset;
+    
+    for (uint64_t I = 0; I != NumElements; ++I) {
+      // We know that the only empty subobjects that can conflict with empty
+      // field subobjects are subobjects of empty bases that can be placed at 
+      // offset zero. Because of this, we only need to keep track of empty field
+      // subobjects with offsets less than the size of the largest empty
+      // subobject for our class.
+      if (ElementOffset >= SizeOfLargestEmptySubobject)
+        return;
+
+      UpdateEmptyFieldSubobjects(RD, RD, ElementOffset);
+      ElementOffset += Layout.getSize();
+    }
+  }
+}
+
+class RecordLayoutBuilder {
+protected:
+  // FIXME: Remove this and make the appropriate fields public.
+  friend class clang::ASTContext;
+
+  ASTContext &Context;
+
+  EmptySubobjectMap *EmptySubobjects;
+
+  /// 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.
+  unsigned Packed : 1;
+
+  unsigned IsUnion : 1;
+
+  unsigned IsMac68kAlign : 1;
+
+  /// 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;
+
+  uint64_t NonVirtualSize;
+  unsigned NonVirtualAlignment;
+
+  /// PrimaryBase - the primary base class (if one exists) of the class
+  /// we're laying out.
+  const CXXRecordDecl *PrimaryBase;
+
+  /// PrimaryBaseIsVirtual - Whether the primary base of the class we're laying
+  /// out is virtual.
+  bool PrimaryBaseIsVirtual;
+
+  typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsetsMapTy;
+
+  /// Bases - base classes and their offsets in the record.
+  BaseOffsetsMapTy Bases;
+
+  // VBases - virtual base classes and their offsets in the record.
+  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;
+
+  RecordLayoutBuilder(ASTContext &Context, EmptySubobjectMap *EmptySubobjects)
+    : Context(Context), EmptySubobjects(EmptySubobjects), Size(0), Alignment(8),
+      Packed(false), IsUnion(false), IsMac68kAlign(false),
+      UnfilledBitsInLastByte(0), MaxFieldAlignment(0), DataSize(0),
+      NonVirtualSize(0), NonVirtualAlignment(8), PrimaryBase(0),
+      PrimaryBaseIsVirtual(false), FirstNearlyEmptyVBase(0) { }
+
+  void Layout(const RecordDecl *D);
+  void Layout(const CXXRecordDecl *D);
+  void Layout(const ObjCInterfaceDecl *D);
+
+  void LayoutFields(const RecordDecl *D);
+  void LayoutField(const FieldDecl *D);
+  void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize);
+  void LayoutBitField(const FieldDecl *D);
+
+  /// BaseSubobjectInfoAllocator - Allocator for BaseSubobjectInfo objects.
+  llvm::SpecificBumpPtrAllocator<BaseSubobjectInfo> BaseSubobjectInfoAllocator;
+  
+  typedef llvm::DenseMap<const CXXRecordDecl *, BaseSubobjectInfo *>
+    BaseSubobjectInfoMapTy;
+
+  /// VirtualBaseInfo - Map from all the (direct or indirect) virtual bases
+  /// of the class we're laying out to their base subobject info.
+  BaseSubobjectInfoMapTy VirtualBaseInfo;
+  
+  /// NonVirtualBaseInfo - Map from all the direct non-virtual bases of the
+  /// class we're laying out to their base subobject info.
+  BaseSubobjectInfoMapTy NonVirtualBaseInfo;
+
+  /// ComputeBaseSubobjectInfo - Compute the base subobject information for the
+  /// bases of the given class.
+  void ComputeBaseSubobjectInfo(const CXXRecordDecl *RD);
+
+  /// ComputeBaseSubobjectInfo - Compute the base subobject information for a
+  /// single class and all of its base classes.
+  BaseSubobjectInfo *ComputeBaseSubobjectInfo(const CXXRecordDecl *RD, 
+                                              bool IsVirtual,
+                                              BaseSubobjectInfo *Derived);
+
+  /// DeterminePrimaryBase - Determine the primary base of the given class.
+  void DeterminePrimaryBase(const CXXRecordDecl *RD);
+
+  void SelectPrimaryVBase(const CXXRecordDecl *RD);
+
+  virtual uint64_t GetVirtualPointersSize(const CXXRecordDecl *RD) const;
+
+  /// 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);
+
+  virtual 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 BaseSubobjectInfo *Base);
+
+  void AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info, 
+                                            uint64_t Offset);
+
+  /// 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 BaseSubobjectInfo *Base);
+
+  /// LayoutBase - Will lay out a base and return the offset where it was
+  /// placed, in bits.
+  uint64_t LayoutBase(const BaseSubobjectInfo *Base);
+
+  /// InitializeLayout - Initialize record layout for the given record decl.
+  void InitializeLayout(const Decl *D);
+
+  /// FinishLayout - Finalize record layout. Adjust record size based on the
+  /// alignment.
+  void FinishLayout();
+
+  void UpdateAlignment(unsigned NewAlignment);
+
+  RecordLayoutBuilder(const RecordLayoutBuilder&);   // DO NOT IMPLEMENT
+  void operator=(const RecordLayoutBuilder&); // DO NOT IMPLEMENT
+public:
+  static const CXXMethodDecl *ComputeKeyFunction(const CXXRecordDecl *RD);
+
+  virtual ~RecordLayoutBuilder() { }
+};
+} // end anonymous namespace
 
 /// IsNearlyEmpty - Indicates when a class has a vtable pointer, but
 /// no other data.
-bool ASTRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
+bool RecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
   // FIXME: Audit the corners
   if (!RD->isDynamicClass())
     return false;
@@ -38,7 +686,7 @@
   return false;
 }
 
-void ASTRecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) {
+void RecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) {
   const ASTRecordLayout::PrimaryBaseInfo &BaseInfo =
     Context.getASTRecordLayout(RD).getPrimaryBaseInfo();
 
@@ -63,7 +711,7 @@
 }
 
 void
-ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
+RecordLayoutBuilder::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() &&
@@ -77,8 +725,8 @@
       // 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);
+        PrimaryBase = Base;
+        PrimaryBaseIsVirtual = true;
         return;
       }
 
@@ -88,13 +736,18 @@
     }
 
     SelectPrimaryVBase(Base);
-    if (PrimaryBase.getBase())
+    if (PrimaryBase)
       return;
   }
 }
 
+uint64_t
+RecordLayoutBuilder::GetVirtualPointersSize(const CXXRecordDecl *RD) const {
+  return Context.Target.getPointerWidth(0);
+}
+
 /// DeterminePrimaryBase - Determine the primary base of the given class.
-void ASTRecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
+void RecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
   // If the class isn't dynamic, it won't have a primary base.
   if (!RD->isDynamicClass())
     return;
@@ -124,7 +777,8 @@
 
     if (Base->isDynamicClass()) {
       // We found it.
-      PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base, /*IsVirtual=*/false);
+      PrimaryBase = Base;
+      PrimaryBaseIsVirtual = false;
       return;
     }
   }
@@ -133,49 +787,169 @@
   // indirect primary virtual base class, if one exists.
   if (RD->getNumVBases() != 0) {
     SelectPrimaryVBase(RD);
-    if (PrimaryBase.getBase())
+    if (PrimaryBase)
       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);
+    PrimaryBase = FirstNearlyEmptyVBase;
+    PrimaryBaseIsVirtual = true;
     return;
   }
 
   // Otherwise there is no primary base class.
-  assert(!PrimaryBase.getBase() && "Should not get here with a primary base!");
+  assert(!PrimaryBase && "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);
+  Size += GetVirtualPointersSize(RD);
   DataSize = Size;
 
   // Update the alignment.
   UpdateAlignment(Context.Target.getPointerAlign(0));
 }
 
+BaseSubobjectInfo *
+RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD, 
+                                              bool IsVirtual,
+                                              BaseSubobjectInfo *Derived) {
+  BaseSubobjectInfo *Info;
+  
+  if (IsVirtual) {
+    // Check if we already have info about this virtual base.
+    BaseSubobjectInfo *&InfoSlot = VirtualBaseInfo[RD];
+    if (InfoSlot) {
+      assert(InfoSlot->Class == RD && "Wrong class for virtual base info!");
+      return InfoSlot;
+    }
+
+    // We don't, create it.
+    InfoSlot = new (BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo;
+    Info = InfoSlot;
+  } else {
+    Info = new (BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo;
+  }
+  
+  Info->Class = RD;
+  Info->IsVirtual = IsVirtual;
+  Info->Derived = 0;
+  Info->PrimaryVirtualBaseInfo = 0;
+  
+  const CXXRecordDecl *PrimaryVirtualBase = 0;
+  BaseSubobjectInfo *PrimaryVirtualBaseInfo = 0;
+
+  // Check if this base has a primary virtual base.
+  if (RD->getNumVBases()) {
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    if (Layout.getPrimaryBaseWasVirtual()) {
+      // This base does have a primary virtual base.
+      PrimaryVirtualBase = Layout.getPrimaryBase();
+      assert(PrimaryVirtualBase && "Didn't have a primary virtual base!");
+      
+      // Now check if we have base subobject info about this primary base.
+      PrimaryVirtualBaseInfo = VirtualBaseInfo.lookup(PrimaryVirtualBase);
+      
+      if (PrimaryVirtualBaseInfo) {
+        if (PrimaryVirtualBaseInfo->Derived) {
+          // We did have info about this primary base, and it turns out that it
+          // has already been claimed as a primary virtual base for another
+          // base. 
+          PrimaryVirtualBase = 0;        
+        } else {
+          // We can claim this base as our primary base.
+          Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo;
+          PrimaryVirtualBaseInfo->Derived = Info;
+        }
+      }
+    }
+  }
+
+  // Now go through all direct bases.
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    bool IsVirtual = I->isVirtual();
+    
+    const CXXRecordDecl *BaseDecl =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+    
+    Info->Bases.push_back(ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, Info));
+  }
+  
+  if (PrimaryVirtualBase && !PrimaryVirtualBaseInfo) {
+    // Traversing the bases must have created the base info for our primary
+    // virtual base.
+    PrimaryVirtualBaseInfo = VirtualBaseInfo.lookup(PrimaryVirtualBase);
+    assert(PrimaryVirtualBaseInfo &&
+           "Did not create a primary virtual base!");
+      
+    // Claim the primary virtual base as our primary virtual base.
+    Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo;
+    PrimaryVirtualBaseInfo->Derived = Info;
+  }
+  
+  return Info;
+}
+
+void RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD) {
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    bool IsVirtual = I->isVirtual();
+
+    const CXXRecordDecl *BaseDecl =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+    
+    // Compute the base subobject info for this base.
+    BaseSubobjectInfo *Info = ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, 0);
+
+    if (IsVirtual) {
+      // ComputeBaseInfo has already added this base for us.
+      assert(VirtualBaseInfo.count(BaseDecl) &&
+             "Did not add virtual base!");
+    } else {
+      // Add the base info to the map of non-virtual bases.
+      assert(!NonVirtualBaseInfo.count(BaseDecl) &&
+             "Non-virtual base already exists!");
+      NonVirtualBaseInfo.insert(std::make_pair(BaseDecl, Info));
+    }
+  }
+}
+
 void
-ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
-  // First, determine the primary base class.
+RecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
+  // Then, determine the primary base class.
   DeterminePrimaryBase(RD);
 
+  // Compute base subobject info.
+  ComputeBaseSubobjectInfo(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);
+  if (PrimaryBase) {
+    if (PrimaryBaseIsVirtual) {
+      // If the primary virtual base was a primary virtual base of some other
+      // base class we'll have to steal it.
+      BaseSubobjectInfo *PrimaryBaseInfo = VirtualBaseInfo.lookup(PrimaryBase);
+      PrimaryBaseInfo->Derived = 0;
       
-      LayoutVirtualBase(Base);
-    } else
-      LayoutNonVirtualBase(Base);
+      // We have a virtual primary base, insert it as an indirect primary base.
+      IndirectPrimaryBases.insert(PrimaryBase);
+
+      assert(!VisitedVirtualBases.count(PrimaryBase) &&
+             "vbase already visited!");
+      VisitedVirtualBases.insert(PrimaryBase);
+
+      LayoutVirtualBase(PrimaryBaseInfo);
+    } else {
+      BaseSubobjectInfo *PrimaryBaseInfo = 
+        NonVirtualBaseInfo.lookup(PrimaryBase);
+      assert(PrimaryBaseInfo && 
+             "Did not find base info for non-virtual primary base!");
+
+      LayoutNonVirtualBase(PrimaryBaseInfo);
+    }
   }
 
   // Now lay out the non-virtual bases.
@@ -186,93 +960,76 @@
     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.
+    // Skip the primary base.
+    if (BaseDecl == PrimaryBase && !PrimaryBaseIsVirtual)
       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);
-    }
+    // Lay out the base.
+    BaseSubobjectInfo *BaseInfo = NonVirtualBaseInfo.lookup(BaseDecl);
+    assert(BaseInfo && "Did not find base info for non-virtual base!");
 
-    AddPrimaryVirtualBaseOffsets(BaseDecl, BaseOffset, MostDerivedClass);
+    LayoutNonVirtualBase(BaseInfo);
+  }
+}
+
+void RecordLayoutBuilder::LayoutNonVirtualBase(const BaseSubobjectInfo *Base) {
+  // Layout the base.
+  uint64_t Offset = LayoutBase(Base);
+
+  // Add its base class offset.
+  assert(!Bases.count(Base->Class) && "base offset already exists!");
+  Bases.insert(std::make_pair(Base->Class, Offset));
+
+  AddPrimaryVirtualBaseOffsets(Base, Offset);
+}
+
+void
+RecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info, 
+                                                  uint64_t Offset) {
+  // This base isn't interesting, it has no virtual bases.
+  if (!Info->Class->getNumVBases())
+    return;
+  
+  // First, check if we have a virtual primary base to add offsets for.
+  if (Info->PrimaryVirtualBaseInfo) {
+    assert(Info->PrimaryVirtualBaseInfo->IsVirtual && 
+           "Primary virtual base is not virtual!");
+    if (Info->PrimaryVirtualBaseInfo->Derived == Info) {
+      // Add the offset.
+      assert(!VBases.count(Info->PrimaryVirtualBaseInfo->Class) && 
+             "primary vbase offset already exists!");
+      VBases.insert(std::make_pair(Info->PrimaryVirtualBaseInfo->Class,
+                                   Offset));
+
+      // Traverse the primary virtual base.
+      AddPrimaryVirtualBaseOffsets(Info->PrimaryVirtualBaseInfo, Offset);
+    }
+  }
+
+  // Now go through all direct non-virtual bases.
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class);
+  for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) {
+    const BaseSubobjectInfo *Base = Info->Bases[I];
+    if (Base->IsVirtual)
+      continue;
+
+    uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class);
+    AddPrimaryVirtualBaseOffsets(Base, BaseOffset);
   }
 }
 
 void
-ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
+RecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
                                         const CXXRecordDecl *MostDerivedClass) {
   const CXXRecordDecl *PrimaryBase;
   bool PrimaryBaseIsVirtual;
 
   if (MostDerivedClass == RD) {
-    PrimaryBase = this->PrimaryBase.getBase();
-    PrimaryBaseIsVirtual = this->PrimaryBase.isVirtual();
+    PrimaryBase = this->PrimaryBase;
+    PrimaryBaseIsVirtual = this->PrimaryBaseIsVirtual;
   } else {
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
     PrimaryBase = Layout.getPrimaryBase();
@@ -284,293 +1041,159 @@
     assert(!I->getType()->isDependentType() &&
            "Cannot layout class with dependent bases.");
 
-    const CXXRecordDecl *Base =
+    const CXXRecordDecl *BaseDecl =
       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
 
     if (I->isVirtual()) {
-      if (PrimaryBase != Base || !PrimaryBaseIsVirtual) {
-        bool IndirectPrimaryBase = IndirectPrimaryBases.count(Base);
+      if (PrimaryBase != BaseDecl || !PrimaryBaseIsVirtual) {
+        bool IndirectPrimaryBase = IndirectPrimaryBases.count(BaseDecl);
 
         // 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))
+          if (!VisitedVirtualBases.insert(BaseDecl))
             continue;
-          
-          LayoutVirtualBase(Base);
+
+          const BaseSubobjectInfo *BaseInfo = VirtualBaseInfo.lookup(BaseDecl);
+          assert(BaseInfo && "Did not find virtual base info!");
+          LayoutVirtualBase(BaseInfo);
         }
       }
     }
 
-    if (!Base->getNumVBases()) {
+    if (!BaseDecl->getNumVBases()) {
       // This base isn't interesting since it doesn't have any virtual bases.
       continue;
     }
 
-    LayoutVirtualBases(Base, MostDerivedClass);
+    LayoutVirtualBases(BaseDecl, MostDerivedClass);
   }
 }
 
-void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) {
+void RecordLayoutBuilder::LayoutVirtualBase(const BaseSubobjectInfo *Base) {
+  assert(!Base->Derived && "Trying to lay out a primary virtual base!");
+  
   // Layout the base.
-  uint64_t Offset = LayoutBase(RD);
+  uint64_t Offset = LayoutBase(Base);
 
   // Add its base class offset.
-  if (!VBases.insert(std::make_pair(RD, Offset)).second)
-    assert(false && "Added same vbase offset more than once!");
+  assert(!VBases.count(Base->Class) && "vbase offset already exists!");
+  VBases.insert(std::make_pair(Base->Class, Offset));
+  
+  AddPrimaryVirtualBaseOffsets(Base, Offset);
 }
 
-uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) {
-  const ASTRecordLayout &BaseInfo = Context.getASTRecordLayout(RD);
+uint64_t RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base->Class);
 
   // 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());
+  if (Base->Class->isEmpty() &&
+      EmptySubobjects->CanPlaceBaseAtOffset(Base, 0)) {
+    Size = std::max(Size, Layout.getSize());
 
     return 0;
   }
 
-  unsigned BaseAlign = BaseInfo.getNonVirtualAlign();
+  unsigned BaseAlign = Layout.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;
-
+  while (!EmptySubobjects->CanPlaceBaseAtOffset(Base, Offset))
     Offset += BaseAlign;
-  }
 
-  if (!RD->isEmpty()) {
+  if (!Base->Class->isEmpty()) {
     // Update the data size.
-    DataSize = Offset + BaseInfo.getNonVirtualSize();
+    DataSize = Offset + Layout.getNonVirtualSize();
 
     Size = std::max(Size, DataSize);
   } else
-    Size = std::max(Size, Offset + BaseInfo.getSize());
+    Size = std::max(Size, Offset + Layout.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();
+void RecordLayoutBuilder::InitializeLayout(const Decl *D) {
+  if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
+    IsUnion = RD->isUnion();
 
   Packed = D->hasAttr<PackedAttr>();
 
-  // The #pragma pack attribute specifies the maximum field alignment.
-  if (const PragmaPackAttr *PPA = D->getAttr<PragmaPackAttr>())
-    MaxFieldAlignment = PPA->getAlignment();
+  // mac68k alignment supersedes maximum field alignment and attribute aligned,
+  // and forces all structures to have 2-byte alignment. The IBM docs on it
+  // allude to additional (more complicated) semantics, especially with regard
+  // to bit-fields, but gcc appears not to follow that.
+  if (D->hasAttr<AlignMac68kAttr>()) {
+    IsMac68kAlign = true;
+    MaxFieldAlignment = 2 * 8;
+    Alignment = 2 * 8;
+  } else {
+    if (const MaxFieldAlignmentAttr *MFAA = D->getAttr<MaxFieldAlignmentAttr>())
+      MaxFieldAlignment = MFAA->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);
+    if (unsigned MaxAlign = D->getMaxAlignment())
+      UpdateAlignment(MaxAlign);
   }
+}
+
+void RecordLayoutBuilder::Layout(const RecordDecl *D) {
+  InitializeLayout(D);
+  LayoutFields(D);
 
   // Finally, round the size of the total struct up to the alignment of the
   // struct itself.
   FinishLayout();
-  
+}
+
+void RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) {
+  InitializeLayout(RD);
+
+  // Lay out the vtable and the non-virtual bases.
+  LayoutNonVirtualBases(RD);
+
+  LayoutFields(RD);
+
+  NonVirtualSize = Size;
+  NonVirtualAlignment = Alignment;
+
+  // Lay out the virtual bases and add the primary virtual base offsets.
+  LayoutVirtualBases(RD, RD);
+
+  VisitedVirtualBases.clear();
+
+  // 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!");
-    }
+  // 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) {
+void RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) {
   if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
     const ASTRecordLayout &SL = Context.getASTObjCInterfaceLayout(SD);
 
@@ -582,14 +1205,8 @@
     DataSize = Size;
   }
 
-  Packed = D->hasAttr<PackedAttr>();
+  InitializeLayout(D);
 
-  // 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);
@@ -601,7 +1218,7 @@
   FinishLayout();
 }
 
-void ASTRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
+void RecordLayoutBuilder::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(),
@@ -609,17 +1226,17 @@
     LayoutField(*Field);
 }
 
-void ASTRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, 
+void RecordLayoutBuilder::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 
+  //   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.UnsignedCharTy, Context.UnsignedShortTy, Context.UnsignedIntTy,
     Context.UnsignedLongTy, Context.UnsignedLongLongTy
   };
 
@@ -634,24 +1251,24 @@
     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. 
+    // for T', with length n bits.
     FieldOffset = llvm::RoundUpToAlignment(DataSize, TypeAlign);
-    
+
     uint64_t NewSizeInBits = FieldOffset + FieldSize;
-    
+
     DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8);
     UnfilledBitsInLastByte = DataSize - NewSizeInBits;
   }
@@ -661,12 +1278,12 @@
 
   // Update the size.
   Size = std::max(Size, DataSize);
-  
+
   // Remember max struct/class alignment.
   UpdateAlignment(TypeAlign);
 }
 
-void ASTRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
+void RecordLayoutBuilder::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();
@@ -682,8 +1299,7 @@
 
   if (FieldPacked || !Context.Target.useBitFieldTypeAlignment())
     FieldAlign = 1;
-  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
-    FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
+  FieldAlign = std::max(FieldAlign, D->getMaxAlignment());
 
   // The maximum field alignment overrides the aligned attribute.
   if (MaxFieldAlignment)
@@ -691,7 +1307,7 @@
 
   // 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);
+    FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
 
   // Padding members don't affect overall alignment.
   if (!D->getIdentifier())
@@ -718,7 +1334,7 @@
   UpdateAlignment(FieldAlign);
 }
 
-void ASTRecordLayoutBuilder::LayoutField(const FieldDecl *D) {
+void RecordLayoutBuilder::LayoutField(const FieldDecl *D) {
   if (D->isBitField()) {
     LayoutBitField(D);
     return;
@@ -752,8 +1368,7 @@
 
   if (FieldPacked)
     FieldAlign = 8;
-  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
-    FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
+  FieldAlign = std::max(FieldAlign, D->getMaxAlignment());
 
   // The maximum field alignment overrides the aligned attribute.
   if (MaxFieldAlignment)
@@ -762,17 +1377,12 @@
   // 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;
-
+  if (!IsUnion && EmptySubobjects) {
+    // Check if we can place the field at this offset.
+    while (!EmptySubobjects->CanPlaceFieldAtOffset(D, FieldOffset)) {
       // 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.
@@ -791,7 +1401,7 @@
   UpdateAlignment(FieldAlign);
 }
 
-void ASTRecordLayoutBuilder::FinishLayout() {
+void RecordLayoutBuilder::FinishLayout() {
   // In C++, records cannot be of size 0.
   if (Context.getLangOptions().CPlusPlus && Size == 0)
     Size = 8;
@@ -800,7 +1410,11 @@
   Size = llvm::RoundUpToAlignment(Size, Alignment);
 }
 
-void ASTRecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) {
+void RecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) {
+  // The alignment is not modified when using 'mac68k' alignment.
+  if (IsMac68kAlign)
+    return;
+
   if (NewAlignment <= Alignment)
     return;
 
@@ -809,57 +1423,8 @@
   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!");
-
+RecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) {
   // If a class isn't polymorphic it doesn't have a key function.
   if (!RD->isPolymorphic())
     return 0;
@@ -898,6 +1463,163 @@
   return 0;
 }
 
+// This class implements layout specific to the Microsoft ABI.
+class MSRecordLayoutBuilder: public RecordLayoutBuilder {
+public:
+  MSRecordLayoutBuilder(ASTContext& Ctx, EmptySubobjectMap *EmptySubobjects):
+    RecordLayoutBuilder(Ctx, EmptySubobjects) {}
+
+  virtual bool IsNearlyEmpty(const CXXRecordDecl *RD) const;
+  virtual uint64_t GetVirtualPointersSize(const CXXRecordDecl *RD) const;
+};
+
+bool MSRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
+  // FIXME: Audit the corners
+  if (!RD->isDynamicClass())
+    return false;
+  const ASTRecordLayout &BaseInfo = Context.getASTRecordLayout(RD);
+  // In the Microsoft ABI, classes can have one or two vtable pointers.
+  if (BaseInfo.getNonVirtualSize() == Context.Target.getPointerWidth(0) ||
+      BaseInfo.getNonVirtualSize() == Context.Target.getPointerWidth(0) * 2)
+    return true;
+  return false;
+}
+
+uint64_t
+MSRecordLayoutBuilder::GetVirtualPointersSize(const CXXRecordDecl *RD) const {
+  // We should reserve space for two pointers if the class has both
+  // virtual functions and virtual bases.
+  if (RD->isPolymorphic() && RD->getNumVBases() > 0)
+    return 2 * Context.Target.getPointerWidth(0);
+  return Context.Target.getPointerWidth(0);
+}
+
+/// 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;
+
+  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
+    EmptySubobjectMap EmptySubobjects(*this, RD);
+
+    // When compiling for Microsoft, use the special MS builder.
+    llvm::OwningPtr<RecordLayoutBuilder> Builder;
+    switch (Target.getCXXABI()) {
+    default:
+      Builder.reset(new RecordLayoutBuilder(*this, &EmptySubobjects));
+      break;
+    case CXXABI_Microsoft:
+      Builder.reset(new MSRecordLayoutBuilder(*this, &EmptySubobjects));
+    }
+    Builder->Layout(RD);
+
+    // 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;
+
+    NewEntry =
+      new (*this) ASTRecordLayout(*this, Builder->Size, Builder->Alignment,
+                                  DataSize, Builder->FieldOffsets.data(),
+                                  Builder->FieldOffsets.size(),
+                                  NonVirtualSize,
+                                  Builder->NonVirtualAlignment,
+                                  EmptySubobjects.SizeOfLargestEmptySubobject,
+                                  Builder->PrimaryBase,
+                                  Builder->PrimaryBaseIsVirtual,
+                                  Builder->Bases, Builder->VBases);
+  } else {
+    RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
+    Builder.Layout(D);
+
+    NewEntry =
+      new (*this) ASTRecordLayout(*this, Builder.Size, Builder.Alignment,
+                                  Builder.Size,
+                                  Builder.FieldOffsets.data(),
+                                  Builder.FieldOffsets.size());
+  }
+
+  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 = RecordLayoutBuilder::ComputeKeyFunction(RD);
+  else
+    assert(Entry == RecordLayoutBuilder::ComputeKeyFunction(RD) &&
+           "Key function changed!");
+
+  return Entry;
+}
+
+/// 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);
+  }
+
+  RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
+  Builder.Layout(D);
+
+  const ASTRecordLayout *NewEntry =
+    new (*this) ASTRecordLayout(*this, Builder.Size, Builder.Alignment,
+                                Builder.DataSize,
+                                Builder.FieldOffsets.data(),
+                                Builder.FieldOffsets.size());
+
+  ObjCLayouts[Key] = NewEntry;
+
+  return *NewEntry;
+}
+
 static void PrintOffset(llvm::raw_ostream &OS,
                         uint64_t Offset, unsigned IndentLevel) {
   OS << llvm::format("%4d | ", Offset);
@@ -957,7 +1679,7 @@
     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(),
+                            Field->getName().data(),
                             /*IncludeVirtualBases=*/true);
         continue;
       }
diff --git a/lib/AST/RecordLayoutBuilder.h b/lib/AST/RecordLayoutBuilder.h
deleted file mode 100644
index f277c29..0000000
--- a/lib/AST/RecordLayoutBuilder.h
+++ /dev/null
@@ -1,170 +0,0 @@
-//===- 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
index 67fd74c..fc88981 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -27,7 +27,7 @@
   const char *Name;
   unsigned Counter;
   unsigned Size;
-} StmtClassInfo[Stmt::lastExprConstant+1];
+} StmtClassInfo[Stmt::lastStmtConstant+1];
 
 static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) {
   static bool Initialized = false;
@@ -36,11 +36,11 @@
 
   // Intialize the table on the first use.
   Initialized = true;
-#define ABSTRACT_EXPR(CLASS, PARENT)
+#define ABSTRACT_STMT(STMT)
 #define STMT(CLASS, PARENT) \
   StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS;    \
   StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS);
-#include "clang/AST/StmtNodes.def"
+#include "clang/AST/StmtNodes.inc"
 
   return StmtClassInfo[E];
 }
@@ -55,13 +55,13 @@
 
   unsigned sum = 0;
   fprintf(stderr, "*** Stmt/Expr Stats:\n");
-  for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
+  for (int i = 0; i != Stmt::lastStmtConstant+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++) {
+  for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
     if (StmtClassInfo[i].Name == 0) continue;
     if (StmtClassInfo[i].Counter == 0) continue;
     fprintf(stderr, "    %d %s, %d each (%d bytes)\n",
@@ -119,7 +119,7 @@
 
     case Stmt::BinaryOperatorClass: {
       const BinaryOperator* B = cast<BinaryOperator>(this);
-      if (B->isLogicalOp() || B->getOpcode() == BinaryOperator::Comma)
+      if (B->isLogicalOp() || B->getOpcode() == BO_Comma)
         return true;
       else
         return false;
@@ -215,8 +215,9 @@
 /// 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();
+  llvm::StringRef Str = getAsmString()->getString();
+  const char *StrStart = Str.begin();
+  const char *StrEnd = Str.end();
   const char *CurPtr = StrStart;
 
   // "Simple" inline asms have no constraints or operands, just convert the asm
@@ -451,6 +452,15 @@
   return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers, numHandlers);
 }
 
+CXXTryStmt *CXXTryStmt::Create(ASTContext &C, EmptyShell Empty,
+                               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(Empty, numHandlers);
+}
+
 CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
                        Stmt **handlers, unsigned numHandlers)
   : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(numHandlers) {
@@ -459,82 +469,120 @@
   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);
+IfStmt::IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, 
+               Stmt *then, SourceLocation EL, Stmt *elsev)
+  : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL)
+{
+  setConditionVariable(C, var);
+  SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
+  SubExprs[THEN] = then;
+  SubExprs[ELSE] = elsev;  
 }
 
-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);
+VarDecl *IfStmt::getConditionVariable() const {
+  if (!SubExprs[VAR])
+    return 0;
   
-  S->~Stmt();
-  C.Deallocate((void *) S);
+  DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
+  return cast<VarDecl>(DS->getSingleDecl());
 }
 
-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;
+void IfStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
+  if (!V) {
+    SubExprs[VAR] = 0;
+    return;
   }
   
-  BranchDestroy(C, this, SubExprs, END_EXPR);
+  SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), 
+                                   V->getSourceRange().getBegin(),
+                                   V->getSourceRange().getEnd());
 }
 
-void WhileStmt::DoDestroy(ASTContext &C) {
-  BranchDestroy(C, this, SubExprs, END_EXPR);
+ForStmt::ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, 
+                 Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP, 
+                 SourceLocation RP)
+  : Stmt(ForStmtClass), ForLoc(FL), LParenLoc(LP), RParenLoc(RP) 
+{
+  SubExprs[INIT] = Init;
+  setConditionVariable(C, condVar);
+  SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
+  SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
+  SubExprs[BODY] = Body;
 }
 
-void AsmStmt::DoDestroy(ASTContext &C) {
-  DestroyChildren(C);
+VarDecl *ForStmt::getConditionVariable() const {
+  if (!SubExprs[CONDVAR])
+    return 0;
   
-  C.Deallocate(Names);
-  C.Deallocate(Constraints);
-  C.Deallocate(Exprs);
-  C.Deallocate(Clobbers);
+  DeclStmt *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
+  return cast<VarDecl>(DS->getSingleDecl());
+}
+
+void ForStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
+  if (!V) {
+    SubExprs[CONDVAR] = 0;
+    return;
+  }
   
-  this->~AsmStmt();
-  C.Deallocate((void *)this);
+  SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), 
+                                       V->getSourceRange().getBegin(),
+                                       V->getSourceRange().getEnd());
+}
+
+SwitchStmt::SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond) 
+  : Stmt(SwitchStmtClass), FirstCase(0) 
+{
+  setConditionVariable(C, Var);
+  SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
+  SubExprs[BODY] = NULL;
+}
+
+VarDecl *SwitchStmt::getConditionVariable() const {
+  if (!SubExprs[VAR])
+    return 0;
+  
+  DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
+  return cast<VarDecl>(DS->getSingleDecl());
+}
+
+void SwitchStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
+  if (!V) {
+    SubExprs[VAR] = 0;
+    return;
+  }
+  
+  SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), 
+                                   V->getSourceRange().getBegin(),
+                                   V->getSourceRange().getEnd());
+}
+
+WhileStmt::WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, 
+                     SourceLocation WL)
+: Stmt(WhileStmtClass)
+{
+  setConditionVariable(C, Var);
+  SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
+  SubExprs[BODY] = body;
+  WhileLoc = WL;
+}
+
+VarDecl *WhileStmt::getConditionVariable() const {
+  if (!SubExprs[VAR])
+    return 0;
+  
+  DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
+  return cast<VarDecl>(DS->getSingleDecl());
+}
+
+void WhileStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
+  if (!V) {
+    SubExprs[VAR] = 0;
+    return;
+  }
+  
+  SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), 
+                                   V->getSourceRange().getBegin(),
+                                   V->getSourceRange().getEnd());
 }
 
 //===----------------------------------------------------------------------===//
@@ -572,26 +620,26 @@
 
 // IfStmt
 Stmt::child_iterator IfStmt::child_begin() {
-  return child_iterator(Var, &SubExprs[0]);
+  return &SubExprs[0];
 }
 Stmt::child_iterator IfStmt::child_end() {
-  return child_iterator(0, &SubExprs[0]+END_EXPR);
+  return &SubExprs[0]+END_EXPR;
 }
 
 // SwitchStmt
 Stmt::child_iterator SwitchStmt::child_begin() {
-  return child_iterator(Var, &SubExprs[0]);
+  return &SubExprs[0];
 }
 Stmt::child_iterator SwitchStmt::child_end() {
-  return child_iterator(0, &SubExprs[0]+END_EXPR);
+  return &SubExprs[0]+END_EXPR;
 }
 
 // WhileStmt
 Stmt::child_iterator WhileStmt::child_begin() {
-  return child_iterator(Var, &SubExprs[0]);
+  return &SubExprs[0];
 }
 Stmt::child_iterator WhileStmt::child_end() {
-  return child_iterator(0, &SubExprs[0]+END_EXPR);
+  return &SubExprs[0]+END_EXPR;
 }
 
 // DoStmt
@@ -600,10 +648,10 @@
 
 // ForStmt
 Stmt::child_iterator ForStmt::child_begin() {
-  return child_iterator(CondVar, &SubExprs[0]);
+  return &SubExprs[0];
 }
 Stmt::child_iterator ForStmt::child_end() {
-  return child_iterator(0, &SubExprs[0]+END_EXPR);
+  return &SubExprs[0]+END_EXPR;
 }
 
 // ObjCForCollectionStmt
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index ca62ed1..850bba4 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -66,8 +66,8 @@
               DumpSubTree(*CI++);
             }
           }
-          OS << ')';
         }
+        OS << ')';
       } else {
         Indent();
         OS << "<<<NULL>>>";
@@ -225,7 +225,7 @@
     OS << "\"";
     // Emit storage class for vardecls.
     if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
-      if (V->getStorageClass() != VarDecl::None)
+      if (V->getStorageClass() != SC_None)
         OS << VarDecl::getStorageClassSpecifierString(V->getStorageClass())
            << " ";
     }
@@ -260,6 +260,13 @@
     else
       ns = "<anonymous>";
     OS << '"' << UD->getDeclKindName() << ns << ";\"";
+  } else if (UsingDecl *UD = dyn_cast<UsingDecl>(D)) {
+    // print using decl (e.g. "using std::string;")
+    const char *tn = UD->isTypeName() ? "typename " : "";
+    OS << '"' << UD->getDeclKindName() << tn;
+    UD->getTargetNestedNameDecl()->print(OS,
+        PrintingPolicy(UD->getASTContext().getLangOptions()));
+    OS << ";\"";
   } else {
     assert(0 && "Unexpected decl");
   }
@@ -301,13 +308,13 @@
 }
 
 static void DumpBasePath(llvm::raw_ostream &OS, CastExpr *Node) {
-  if (Node->getBasePath().empty())
+  if (Node->path_empty())
     return;
 
   OS << " (";
   bool First = true;
-  for (CXXBaseSpecifierArray::iterator I = Node->getBasePath().begin(),
-       E = Node->getBasePath().end(); I != E; ++I) {
+  for (CastExpr::path_iterator
+         I = Node->path_begin(), E = Node->path_end(); I != E; ++I) {
     const CXXBaseSpecifier *Base = *I;
     if (!First)
       OS << " -> ";
@@ -333,8 +340,16 @@
 
 void StmtDumper::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
   VisitCastExpr(Node);
-  if (Node->isLvalueCast())
+  switch (Node->getValueKind()) {
+  case VK_LValue:
     OS << " lvalue";
+    break;
+  case VK_XValue:
+    OS << " xvalue";
+    break;
+  case VK_RValue:
+    break;
+  }
 }
 
 void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
@@ -414,8 +429,7 @@
   if (Str->isWide())
     OS << "L";
   OS << '"';
-  OS.write_escaped(llvm::StringRef(Str->getStrData(),
-                                   Str->getByteLength()));
+  OS.write_escaped(Str->getString());
   OS << '"';
 }
 
@@ -504,6 +518,8 @@
   DumpType(Ctor->getType());
   if (Node->isElidable())
     OS << " elidable";
+  if (Node->requiresZeroInitialization())
+    OS << " zeroing";
 }
 
 void StmtDumper::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
@@ -616,9 +632,13 @@
 /// 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);
+  dump(llvm::errs(), SM);
+}
+
+void Stmt::dump(llvm::raw_ostream &OS, SourceManager &SM) const {
+  StmtDumper P(&SM, OS, 4);
   P.DumpSubTree(const_cast<Stmt*>(this));
-  llvm::errs() << "\n";
+  OS << "\n";
 }
 
 /// dump - This does a local dump of the specified AST fragment.  It dumps the
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 3996528..ea528c2 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -17,6 +17,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "llvm/Support/Format.h"
+#include "clang/AST/Expr.h"
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
@@ -76,19 +77,24 @@
       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) ATTRIBUTE_UNUSED {
+      Indent() << "<<unknown stmt type>>\n";
+    }
+    void VisitExpr(Expr *Node) ATTRIBUTE_UNUSED {
+      OS << "<<unknown expr type>>";
+    }
+    void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
 
-    void VisitStmt(Stmt *Node);
+#define ABSTRACT_STMT(CLASS)
 #define STMT(CLASS, PARENT) \
     void Visit##CLASS(CLASS *Node);
-#include "clang/AST/StmtNodes.def"
+#include "clang/AST/StmtNodes.inc"
   };
 }
 
@@ -96,10 +102,6 @@
 //  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) {
@@ -464,15 +466,11 @@
 //  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 << Node->getNameInfo();
+  if (Node->hasExplicitTemplateArgs())
     OS << TemplateSpecializationType::PrintTemplateArgumentList(
                                                     Node->getTemplateArgs(),
                                                     Node->getNumTemplateArgs(),
@@ -482,7 +480,7 @@
 void StmtPrinter::VisitDependentScopeDeclRefExpr(
                                            DependentScopeDeclRefExpr *Node) {
   Node->getQualifier()->print(OS, Policy);
-  OS << Node->getDeclName().getAsString();
+  OS << Node->getNameInfo();
   if (Node->hasExplicitTemplateArgs())
     OS << TemplateSpecializationType::PrintTemplateArgumentList(
                                                    Node->getTemplateArgs(),
@@ -493,7 +491,7 @@
 void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
   if (Node->getQualifier())
     Node->getQualifier()->print(OS, Policy);
-  OS << Node->getName().getAsString();
+  OS << Node->getNameInfo();
   if (Node->hasExplicitTemplateArgs())
     OS << TemplateSpecializationType::PrintTemplateArgumentList(
                                                    Node->getTemplateArgs(),
@@ -514,7 +512,7 @@
     PrintExpr(Node->getBase());
     OS << ".";
   }
-  OS << Node->getProperty()->getNameAsCString();
+  OS << Node->getProperty()->getName();
 }
 
 void StmtPrinter::VisitObjCImplicitSetterGetterRefExpr(
@@ -623,8 +621,10 @@
   OS << '"';
 
   // FIXME: this doesn't print wstrings right.
-  for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
-    unsigned char Char = Str->getStrData()[i];
+  llvm::StringRef StrData = Str->getString();
+  for (llvm::StringRef::iterator I = StrData.begin(), E = StrData.end(); 
+                                                             I != E; ++I) {
+    unsigned char Char = *I;
 
     switch (Char) {
     default:
@@ -660,13 +660,13 @@
     // it might be concatenated incorrectly like '+'.
     switch (Node->getOpcode()) {
     default: break;
-    case UnaryOperator::Real:
-    case UnaryOperator::Imag:
-    case UnaryOperator::Extension:
+    case UO_Real:
+    case UO_Imag:
+    case UO_Extension:
       OS << ' ';
       break;
-    case UnaryOperator::Plus:
-    case UnaryOperator::Minus:
+    case UO_Plus:
+    case UO_Minus:
       if (isa<UnaryOperator>(Node->getSubExpr()))
         OS << ' ';
       break;
@@ -678,35 +678,43 @@
     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) {
+void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
   OS << "__builtin_offsetof(";
-  PrintOffsetOfDesignator(Node->getSubExpr());
+  OS << Node->getTypeSourceInfo()->getType().getAsString(Policy) << ", ";
+  bool PrintedSomething = false;
+  for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
+    OffsetOfExpr::OffsetOfNode ON = Node->getComponent(i);
+    if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Array) {
+      // Array node
+      OS << "[";
+      PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
+      OS << "]";
+      PrintedSomething = true;
+      continue;
+    }
+
+    // Skip implicit base indirections.
+    if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Base)
+      continue;
+
+    // Field or identifier node.
+    IdentifierInfo *Id = ON.getFieldName();
+    if (!Id)
+      continue;
+    
+    if (PrintedSomething)
+      OS << ".";
+    else
+      PrintedSomething = true;
+    OS << Id->getName();    
+  }
   OS << ")";
 }
 
 void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
   OS << (Node->isSizeOf() ? "sizeof" : "__alignof");
   if (Node->isArgumentType())
-    OS << "(" << Node->getArgumentType().getAsString() << ")";
+    OS << "(" << Node->getArgumentType().getAsString(Policy) << ")";
   else {
     OS << " ";
     PrintExpr(Node->getArgumentExpr());
@@ -743,9 +751,9 @@
   if (NestedNameSpecifier *Qualifier = Node->getQualifier())
     Qualifier->print(OS, Policy);
 
-  OS << Node->getMemberDecl();
+  OS << Node->getMemberNameInfo();
 
-  if (Node->hasExplicitTemplateArgumentList())
+  if (Node->hasExplicitTemplateArgs())
     OS << TemplateSpecializationType::PrintTemplateArgumentList(
                                                     Node->getTemplateArgs(),
                                                     Node->getNumTemplateArgs(),
@@ -761,18 +769,12 @@
   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() << ")";
+  OS << "(" << Node->getType().getAsString(Policy) << ")";
   PrintExpr(Node->getSubExpr());
 }
 void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
-  OS << "(" << Node->getType().getAsString() << ")";
+  OS << "(" << Node->getType().getAsString(Policy) << ")";
   PrintExpr(Node->getInitializer());
 }
 void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
@@ -818,8 +820,8 @@
 
 void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
   OS << "__builtin_types_compatible_p(";
-  OS << Node->getArgType1().getAsString() << ",";
-  OS << Node->getArgType2().getAsString() << ")";
+  OS << Node->getArgType1().getAsString(Policy) << ",";
+  OS << Node->getArgType2().getAsString(Policy) << ")";
 }
 
 void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
@@ -913,7 +915,7 @@
   OS << "__builtin_va_arg(";
   PrintExpr(Node->getSubExpr());
   OS << ", ";
-  OS << Node->getType().getAsString();
+  OS << Node->getType().getAsString(Policy);
   OS << ")";
 }
 
@@ -968,7 +970,7 @@
 
 void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
   OS << Node->getCastName() << '<';
-  OS << Node->getTypeAsWritten().getAsString() << ">(";
+  OS << Node->getTypeAsWritten().getAsString(Policy) << ">(";
   PrintExpr(Node->getSubExpr());
   OS << ")";
 }
@@ -992,7 +994,7 @@
 void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
   OS << "typeid(";
   if (Node->isTypeOperand()) {
-    OS << Node->getTypeOperand().getAsString();
+    OS << Node->getTypeOperand().getAsString(Policy);
   } else {
     PrintExpr(Node->getExprOperand());
   }
@@ -1025,7 +1027,7 @@
 }
 
 void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
-  OS << Node->getType().getAsString();
+  OS << Node->getType().getAsString(Policy);
   OS << "(";
   PrintExpr(Node->getSubExpr());
   OS << ")";
@@ -1040,7 +1042,7 @@
 }
 
 void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
-  OS << Node->getType().getAsString();
+  OS << Node->getType().getAsString(Policy);
   OS << "(";
   for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
                                          ArgEnd = Node->arg_end();
@@ -1052,8 +1054,8 @@
   OS << ")";
 }
 
-void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) {
-  OS << Node->getType().getAsString() << "()";
+void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
+  OS << Node->getType().getAsString(Policy) << "()";
 }
 
 void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
@@ -1143,7 +1145,7 @@
 void
 StmtPrinter::VisitCXXUnresolvedConstructExpr(
                                            CXXUnresolvedConstructExpr *Node) {
-  OS << Node->getTypeAsWritten().getAsString();
+  OS << Node->getTypeAsWritten().getAsString(Policy);
   OS << "(";
   for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
                                              ArgEnd = Node->arg_end();
@@ -1167,7 +1169,7 @@
     // FIXME: Track use of "template" keyword explicitly?
     OS << "template ";
 
-  OS << Node->getMember().getAsString();
+  OS << Node->getMemberNameInfo();
 
   if (Node->hasExplicitTemplateArgs()) {
     OS << TemplateSpecializationType::PrintTemplateArgumentList(
@@ -1187,7 +1189,7 @@
 
   // FIXME: this might originally have been written with 'template'
 
-  OS << Node->getMemberName().getAsString();
+  OS << Node->getMemberNameInfo();
 
   if (Node->hasExplicitTemplateArgs()) {
     OS << TemplateSpecializationType::PrintTemplateArgumentList(
@@ -1220,7 +1222,7 @@
 
 void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
   OS << getTypeTraitName(E->getTrait()) << "("
-     << E->getQueriedType().getAsString() << ")";
+     << E->getQueriedType().getAsString(Policy) << ")";
 }
 
 // Obj-C
@@ -1231,7 +1233,7 @@
 }
 
 void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
-  OS << "@encode(" << Node->getEncodedType().getAsString() << ')';
+  OS << "@encode(" << Node->getEncodedType().getAsString(Policy) << ')';
 }
 
 void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
@@ -1334,7 +1336,7 @@
   }
 
   if (Policy.Dump && &Context) {
-    dump(Context.getSourceManager());
+    dump(OS, Context.getSourceManager());
     return;
   }
 
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 3a19ec2..098aec0 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -36,7 +36,7 @@
     void VisitStmt(Stmt *S);
 
 #define STMT(Node, Base) void Visit##Node(Node *S);
-#include "clang/AST/StmtNodes.def"
+#include "clang/AST/StmtNodes.inc"
 
     /// \brief Visit a declaration that is referenced within an expression
     /// or statement.
@@ -211,9 +211,11 @@
 
 void StmtProfiler::VisitDeclRefExpr(DeclRefExpr *S) {
   VisitExpr(S);
-  VisitNestedNameSpecifier(S->getQualifier());
+  if (!Canonical)
+    VisitNestedNameSpecifier(S->getQualifier());
   VisitDecl(S->getDecl());
-  VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
+  if (!Canonical)
+    VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
 }
 
 void StmtProfiler::VisitPredefinedExpr(PredefinedExpr *S) {
@@ -261,6 +263,34 @@
   ID.AddInteger(S->getOpcode());
 }
 
+void StmtProfiler::VisitOffsetOfExpr(OffsetOfExpr *S) {
+  VisitType(S->getTypeSourceInfo()->getType());
+  unsigned n = S->getNumComponents();
+  for (unsigned i = 0; i < n; ++i) {
+    const OffsetOfExpr::OffsetOfNode& ON = S->getComponent(i);
+    ID.AddInteger(ON.getKind());
+    switch (ON.getKind()) {
+    case OffsetOfExpr::OffsetOfNode::Array:
+      // Expressions handled below.
+      break;
+
+    case OffsetOfExpr::OffsetOfNode::Field:
+      VisitDecl(ON.getField());
+      break;
+
+    case OffsetOfExpr::OffsetOfNode::Identifier:
+      ID.AddPointer(ON.getFieldName());
+      break;
+        
+    case OffsetOfExpr::OffsetOfNode::Base:
+      // These nodes are implicit, and therefore don't need profiling.
+      break;
+    }
+  }
+  
+  VisitExpr(S);
+}
+
 void StmtProfiler::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *S) {
   VisitExpr(S);
   ID.AddBoolean(S->isSizeOf());
@@ -279,7 +309,8 @@
 void StmtProfiler::VisitMemberExpr(MemberExpr *S) {
   VisitExpr(S);
   VisitDecl(S->getMemberDecl());
-  VisitNestedNameSpecifier(S->getQualifier());
+  if (!Canonical)
+    VisitNestedNameSpecifier(S->getQualifier());
   ID.AddBoolean(S->isArrow());
 }
 
@@ -294,7 +325,7 @@
 
 void StmtProfiler::VisitImplicitCastExpr(ImplicitCastExpr *S) {
   VisitCastExpr(S);
-  ID.AddBoolean(S->isLvalueCast());
+  ID.AddInteger(S->getValueKind());
 }
 
 void StmtProfiler::VisitExplicitCastExpr(ExplicitCastExpr *S) {
@@ -400,9 +431,219 @@
   VisitDecl(S->getDecl());
   ID.AddBoolean(S->isByRef());
   ID.AddBoolean(S->isConstQualAdded());
+  if (S->getCopyConstructorExpr())
+    Visit(S->getCopyConstructorExpr());
 }
 
+static Stmt::StmtClass DecodeOperatorCall(CXXOperatorCallExpr *S,
+                                          UnaryOperatorKind &UnaryOp,
+                                          BinaryOperatorKind &BinaryOp) {
+  switch (S->getOperator()) {
+  case OO_None:
+  case OO_New:
+  case OO_Delete:
+  case OO_Array_New:
+  case OO_Array_Delete:
+  case OO_Arrow:
+  case OO_Call:
+  case OO_Conditional:
+  case NUM_OVERLOADED_OPERATORS:
+    llvm_unreachable("Invalid operator call kind");
+    return Stmt::ArraySubscriptExprClass;
+      
+  case OO_Plus:
+    if (S->getNumArgs() == 1) {
+      UnaryOp = UO_Plus;
+      return Stmt::UnaryOperatorClass;
+    }
+    
+    BinaryOp = BO_Add;
+    return Stmt::BinaryOperatorClass;
+      
+  case OO_Minus:
+    if (S->getNumArgs() == 1) {
+      UnaryOp = UO_Minus;
+      return Stmt::UnaryOperatorClass;
+    }
+    
+    BinaryOp = BO_Sub;
+    return Stmt::BinaryOperatorClass;
+
+  case OO_Star:
+    if (S->getNumArgs() == 1) {
+      UnaryOp = UO_Minus;
+      return Stmt::UnaryOperatorClass;
+    }
+    
+    BinaryOp = BO_Sub;
+    return Stmt::BinaryOperatorClass;
+
+  case OO_Slash:
+    BinaryOp = BO_Div;
+    return Stmt::BinaryOperatorClass;
+      
+  case OO_Percent:
+    BinaryOp = BO_Rem;
+    return Stmt::BinaryOperatorClass;
+
+  case OO_Caret:
+    BinaryOp = BO_Xor;
+    return Stmt::BinaryOperatorClass;
+
+  case OO_Amp:
+    if (S->getNumArgs() == 1) {
+      UnaryOp = UO_AddrOf;
+      return Stmt::UnaryOperatorClass;
+    }
+    
+    BinaryOp = BO_And;
+    return Stmt::BinaryOperatorClass;
+      
+  case OO_Pipe:
+    BinaryOp = BO_Or;
+    return Stmt::BinaryOperatorClass;
+
+  case OO_Tilde:
+    UnaryOp = UO_Not;
+    return Stmt::UnaryOperatorClass;
+
+  case OO_Exclaim:
+    UnaryOp = UO_LNot;
+    return Stmt::UnaryOperatorClass;
+
+  case OO_Equal:
+    BinaryOp = BO_Assign;
+    return Stmt::BinaryOperatorClass;
+
+  case OO_Less:
+    BinaryOp = BO_LT;
+    return Stmt::BinaryOperatorClass;
+
+  case OO_Greater:
+    BinaryOp = BO_GT;
+    return Stmt::BinaryOperatorClass;
+      
+  case OO_PlusEqual:
+    BinaryOp = BO_AddAssign;
+    return Stmt::CompoundAssignOperatorClass;
+
+  case OO_MinusEqual:
+    BinaryOp = BO_SubAssign;
+    return Stmt::CompoundAssignOperatorClass;
+
+  case OO_StarEqual:
+    BinaryOp = BO_MulAssign;
+    return Stmt::CompoundAssignOperatorClass;
+
+  case OO_SlashEqual:
+    BinaryOp = BO_DivAssign;
+    return Stmt::CompoundAssignOperatorClass;
+
+  case OO_PercentEqual:
+    BinaryOp = BO_RemAssign;
+    return Stmt::CompoundAssignOperatorClass;
+
+  case OO_CaretEqual:
+    BinaryOp = BO_XorAssign;
+    return Stmt::CompoundAssignOperatorClass;
+    
+  case OO_AmpEqual:
+    BinaryOp = BO_AndAssign;
+    return Stmt::CompoundAssignOperatorClass;
+    
+  case OO_PipeEqual:
+    BinaryOp = BO_OrAssign;
+    return Stmt::CompoundAssignOperatorClass;
+      
+  case OO_LessLess:
+    BinaryOp = BO_Shl;
+    return Stmt::BinaryOperatorClass;
+    
+  case OO_GreaterGreater:
+    BinaryOp = BO_Shr;
+    return Stmt::BinaryOperatorClass;
+
+  case OO_LessLessEqual:
+    BinaryOp = BO_ShlAssign;
+    return Stmt::CompoundAssignOperatorClass;
+    
+  case OO_GreaterGreaterEqual:
+    BinaryOp = BO_ShrAssign;
+    return Stmt::CompoundAssignOperatorClass;
+
+  case OO_EqualEqual:
+    BinaryOp = BO_EQ;
+    return Stmt::BinaryOperatorClass;
+    
+  case OO_ExclaimEqual:
+    BinaryOp = BO_NE;
+    return Stmt::BinaryOperatorClass;
+      
+  case OO_LessEqual:
+    BinaryOp = BO_LE;
+    return Stmt::BinaryOperatorClass;
+    
+  case OO_GreaterEqual:
+    BinaryOp = BO_GE;
+    return Stmt::BinaryOperatorClass;
+      
+  case OO_AmpAmp:
+    BinaryOp = BO_LAnd;
+    return Stmt::BinaryOperatorClass;
+    
+  case OO_PipePipe:
+    BinaryOp = BO_LOr;
+    return Stmt::BinaryOperatorClass;
+
+  case OO_PlusPlus:
+    UnaryOp = S->getNumArgs() == 1? UO_PreInc 
+                                  : UO_PostInc;
+    return Stmt::UnaryOperatorClass;
+
+  case OO_MinusMinus:
+    UnaryOp = S->getNumArgs() == 1? UO_PreDec
+                                  : UO_PostDec;
+    return Stmt::UnaryOperatorClass;
+
+  case OO_Comma:
+    BinaryOp = BO_Comma;
+    return Stmt::BinaryOperatorClass;
+
+
+  case OO_ArrowStar:
+    BinaryOp = BO_PtrMemI;
+    return Stmt::BinaryOperatorClass;
+      
+  case OO_Subscript:
+    return Stmt::ArraySubscriptExprClass;
+  }
+  
+  llvm_unreachable("Invalid overloaded operator expression");
+}
+                               
+
 void StmtProfiler::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
+  if (S->isTypeDependent()) {
+    // Type-dependent operator calls are profiled like their underlying
+    // syntactic operator.
+    UnaryOperatorKind UnaryOp = UO_Extension;
+    BinaryOperatorKind BinaryOp = BO_Comma;
+    Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp);
+    
+    ID.AddInteger(SC);
+    for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
+      Visit(S->getArg(I));
+    if (SC == Stmt::UnaryOperatorClass)
+      ID.AddInteger(UnaryOp);
+    else if (SC == Stmt::BinaryOperatorClass || 
+             SC == Stmt::CompoundAssignOperatorClass)
+      ID.AddInteger(BinaryOp);
+    else
+      assert(SC == Stmt::ArraySubscriptExprClass);
+                    
+    return;
+  }
+  
   VisitCallExpr(S);
   ID.AddInteger(S->getOperator());
 }
@@ -483,7 +724,7 @@
   VisitCXXConstructExpr(S);
 }
 
-void StmtProfiler::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *S) {
+void StmtProfiler::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *S) {
   VisitExpr(S);
 }
 
@@ -516,14 +757,19 @@
   VisitType(S->getDestroyedType());
 }
 
-void
-StmtProfiler::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *S) {
+void StmtProfiler::VisitOverloadExpr(OverloadExpr *S) {
   VisitExpr(S);
   VisitNestedNameSpecifier(S->getQualifier());
   VisitName(S->getName());
   ID.AddBoolean(S->hasExplicitTemplateArgs());
   if (S->hasExplicitTemplateArgs())
-    VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
+    VisitTemplateArguments(S->getExplicitTemplateArgs().getTemplateArgs(),
+                           S->getExplicitTemplateArgs().NumTemplateArgs);
+}
+
+void
+StmtProfiler::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *S) {
+  VisitOverloadExpr(S);
 }
 
 void StmtProfiler::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *S) {
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index e9b1725..351aebe 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/TypeLoc.h"
+#include "clang/Basic/Diagnostic.h"
 
 using namespace clang;
 
@@ -89,6 +90,33 @@
   }
 }
 
+bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
+  if (getKind() != Other.getKind()) return false;
+
+  switch (getKind()) {
+  case Null:
+  case Type:
+  case Declaration:
+  case Template:
+  case Expression:
+    return TypeOrValue == Other.TypeOrValue;
+
+  case Integral:
+    return getIntegralType() == Other.getIntegralType() &&
+           *getAsIntegral() == *Other.getAsIntegral();
+
+  case Pack:
+    if (Args.NumArgs != Other.Args.NumArgs) return false;
+    for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
+      if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
+        return false;
+    return true;
+  }
+
+  // Suppress warnings.
+  return false;
+}
+
 //===----------------------------------------------------------------------===//
 // TemplateArgumentLoc Implementation
 //===----------------------------------------------------------------------===//
@@ -102,7 +130,7 @@
     return getSourceDeclExpression()->getSourceRange();
       
   case TemplateArgument::Type:
-    return getTypeSourceInfo()->getTypeLoc().getFullSourceRange();
+    return getTypeSourceInfo()->getTypeLoc().getSourceRange();
       
   case TemplateArgument::Template:
     if (getTemplateQualifierRange().isValid())
@@ -119,3 +147,44 @@
   // Silence bonus gcc warning.
   return SourceRange();
 }
+
+const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
+                                           const TemplateArgument &Arg) {
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+    // This is bad, but not as bad as crashing because of argument
+    // count mismatches.
+    return DB << "(null template argument)";
+      
+  case TemplateArgument::Type:
+    return DB << Arg.getAsType();
+      
+  case TemplateArgument::Declaration:
+    return DB << Arg.getAsDecl();
+      
+  case TemplateArgument::Integral:
+    return DB << Arg.getAsIntegral()->toString(10);
+      
+  case TemplateArgument::Template:
+    return DB << Arg.getAsTemplate();
+      
+  case TemplateArgument::Expression: {
+    // This shouldn't actually ever happen, so it's okay that we're
+    // regurgitating an expression here.
+    // FIXME: We're guessing at LangOptions!
+    llvm::SmallString<32> Str;
+    llvm::raw_svector_ostream OS(Str);
+    LangOptions LangOpts;
+    LangOpts.CPlusPlus = true;
+    PrintingPolicy Policy(LangOpts);
+    Arg.getAsExpr()->printPretty(OS, 0, Policy);
+    return DB << OS.str();
+  }
+      
+  case TemplateArgument::Pack:
+    // FIXME: Format arguments in a list!
+    return DB << "<parameter pack>";
+  }
+  
+  return DB;
+}
diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp
index 14722f7..ef7b315 100644
--- a/lib/AST/TemplateName.cpp
+++ b/lib/AST/TemplateName.cpp
@@ -21,6 +21,17 @@
 using namespace clang;
 using namespace llvm;
 
+TemplateName::NameKind TemplateName::getKind() const {
+  if (Storage.is<TemplateDecl *>())
+    return Template;
+  if (Storage.is<OverloadedTemplateStorage *>())
+    return OverloadedTemplate;
+  if (Storage.is<QualifiedTemplateName *>())
+    return QualifiedTemplate;
+  assert(Storage.is<DependentTemplateName *>() && "There's a case unhandled!");
+  return DependentTemplate;
+}
+
 TemplateDecl *TemplateName::getAsTemplateDecl() const {
   if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
     return Template;
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 52ee60b..c2fc69f 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -12,14 +12,17 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/CharUnits.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 "clang/Basic/Specifiers.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/raw_ostream.h"
+#include <algorithm>
 using namespace clang;
 
 bool QualType::isConstant(QualType T, ASTContext &Ctx) {
@@ -32,24 +35,32 @@
   return false;
 }
 
-void Type::Destroy(ASTContext& C) {
-  this->~Type();
-  C.Deallocate(this);
+Type::~Type() { }
+
+unsigned ConstantArrayType::getNumAddressingBits(ASTContext &Context,
+                                                 QualType ElementType,
+                                               const llvm::APInt &NumElements) {
+  llvm::APSInt SizeExtended(NumElements, true);
+  unsigned SizeTypeBits = Context.getTypeSize(Context.getSizeType());
+  SizeExtended.extend(std::max(SizeTypeBits, SizeExtended.getBitWidth()) * 2);
+
+  uint64_t ElementSize
+    = Context.getTypeSizeInChars(ElementType).getQuantity();
+  llvm::APSInt TotalSize(llvm::APInt(SizeExtended.getBitWidth(), ElementSize));
+  TotalSize *= SizeExtended;  
+  
+  return TotalSize.getActiveBits();
 }
 
-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);
+unsigned ConstantArrayType::getMaxSizeBits(ASTContext &Context) {
+  unsigned Bits = Context.getTypeSize(Context.getSizeType());
+  
+  // GCC appears to only allow 63 bits worth of address space when compiling
+  // for 64-bit, so we do the same.
+  if (Bits == 64)
+    --Bits;
+  
+  return Bits;
 }
 
 void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID,
@@ -72,14 +83,6 @@
   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.
@@ -191,13 +194,6 @@
   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:
@@ -276,6 +272,9 @@
 /// array types and types that contain variable array types in their
 /// declarator
 bool Type::isVariablyModifiedType() const {
+  // FIXME: We should really keep a "variably modified" bit in Type, rather
+  // than walking the type hierarchy to recompute it.
+  
   // A VLA is a variably modified type.
   if (isVariableArrayType())
     return true;
@@ -344,29 +343,26 @@
   return 0;
 }
 
-ObjCInterfaceType::ObjCInterfaceType(QualType Canonical,
-                                     ObjCInterfaceDecl *D,
-                                     ObjCProtocolDecl **Protos, unsigned NumP) :
-  Type(ObjCInterface, Canonical, /*Dependent=*/false),
-  Decl(D), NumProtocols(NumP)
-{
+ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base,
+                               ObjCProtocolDecl * const *Protocols,
+                               unsigned NumProtocols)
+  : Type(ObjCObject, Canonical, false),
+    NumProtocols(NumProtocols),
+    BaseType(Base) {
+  assert(this->NumProtocols == NumProtocols &&
+         "bitfield overflow in protocol count");
   if (NumProtocols)
-    memcpy(reinterpret_cast<ObjCProtocolDecl**>(this + 1), Protos, 
-           NumProtocols * sizeof(*Protos));
+    memcpy(getProtocolStorage(), Protocols,
+           NumProtocols * sizeof(ObjCProtocolDecl*));
 }
 
-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
+const ObjCObjectType *Type::getAsObjCQualifiedInterfaceType() const {
+  // There is no sugar for ObjCObjectType'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;
+  if (const ObjCObjectType *T = getAs<ObjCObjectType>())
+    if (T->getNumProtocols() && T->getInterface())
+      return T;
   return 0;
 }
 
@@ -374,22 +370,6 @@
   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.
@@ -415,6 +395,16 @@
   return 0;
 }
 
+CXXRecordDecl *Type::getAsCXXRecordDecl() const {
+  if (const RecordType *RT = getAs<RecordType>())
+    return dyn_cast<CXXRecordDecl>(RT->getDecl());
+  else if (const InjectedClassNameType *Injected
+                                  = getAs<InjectedClassNameType>())
+    return Injected->getDecl();
+  
+  return 0;
+}
+
 bool Type::isIntegerType() const {
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
     return BT->getKind() >= BuiltinType::Bool &&
@@ -424,20 +414,60 @@
     // 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 {
+bool Type::hasIntegerRepresentation() const {
+  if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
+    return VT->getElementType()->isIntegerType();
+  else
+    return isIntegerType();
+}
+
+/// \brief Determine whether this type is an integral type.
+///
+/// This routine determines whether the given type is an integral type per 
+/// C++ [basic.fundamental]p7. Although the C standard does not define the
+/// term "integral type", it has a similar term "integer type", and in C++
+/// the two terms are equivalent. However, C's "integer type" includes 
+/// enumeration types, while C++'s "integer type" does not. The \c ASTContext
+/// parameter is used to determine whether we should be following the C or
+/// C++ rules when determining whether this type is an integral/integer type.
+///
+/// For cases where C permits "an integer type" and C++ permits "an integral
+/// type", use this routine.
+///
+/// For cases where C permits "an integer type" and C++ permits "an integral
+/// or enumeration type", use \c isIntegralOrEnumerationType() instead. 
+///
+/// \param Ctx The context in which this type occurs.
+///
+/// \returns true if the type is considered an integral type, false otherwise.
+bool Type::isIntegralType(ASTContext &Ctx) const {
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
     return BT->getKind() >= BuiltinType::Bool &&
     BT->getKind() <= BuiltinType::Int128;
+  
+  if (!Ctx.getLangOptions().CPlusPlus)
+    if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
+      if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
+        return true;  // Complete enum types are integral in C.
+  
+  return false;
+}
+
+bool Type::isIntegralOrEnumerationType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() >= BuiltinType::Bool &&
+           BT->getKind() <= BuiltinType::Int128;
+
+  // Check for a complete enum type; incomplete enum types are not properly an
+  // enumeration type in the sense required here.
   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;
+      return true;
+
+  return false;  
 }
 
 bool Type::isEnumeralType() const {
@@ -481,8 +511,7 @@
 
 /// 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.
+/// an enum decl which has a signed representation
 bool Type::isSignedIntegerType() const {
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
     return BT->getKind() >= BuiltinType::Char_S &&
@@ -492,15 +521,19 @@
   if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
     return ET->getDecl()->getIntegerType()->isSignedIntegerType();
 
+  return false;
+}
+
+bool Type::hasSignedIntegerRepresentation() const {
   if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
     return VT->getElementType()->isSignedIntegerType();
-  return false;
+  else
+    return isSignedIntegerType();
 }
 
 /// 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.
+/// decl which has an unsigned representation
 bool Type::isUnsignedIntegerType() const {
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
     return BT->getKind() >= BuiltinType::Bool &&
@@ -510,9 +543,14 @@
   if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
     return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
 
+  return false;
+}
+
+bool Type::hasUnsignedIntegerRepresentation() const {
   if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
     return VT->getElementType()->isUnsignedIntegerType();
-  return false;
+  else
+    return isUnsignedIntegerType();
 }
 
 bool Type::isFloatingType() const {
@@ -521,16 +559,19 @@
            BT->getKind() <= BuiltinType::LongDouble;
   if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
     return CT->getElementType()->isFloatingType();
+  return false;
+}
+
+bool Type::hasFloatingRepresentation() const {
   if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
     return VT->getElementType()->isFloatingType();
-  return false;
+  else
+    return isFloatingType();
 }
 
 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;
 }
 
@@ -540,8 +581,6 @@
            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;
 }
 
@@ -553,7 +592,7 @@
     // 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);
+  return isa<ComplexType>(CanonicalType);
 }
 
 bool Type::isScalarType() const {
@@ -627,9 +666,12 @@
   case IncompleteArray:
     // An array of unknown size is an incomplete type (C99 6.2.5p22).
     return true;
+  case ObjCObject:
+    return cast<ObjCObjectType>(CanonicalType)->getBaseType()
+                                                         ->isIncompleteType();
   case ObjCInterface:
     // ObjC interfaces are incomplete if they are @class, not @interface.
-    return cast<ObjCInterfaceType>(this)->getDecl()->isForwardDecl();
+    return cast<ObjCInterfaceType>(CanonicalType)->getDecl()->isForwardDecl();
   }
 }
 
@@ -754,36 +796,142 @@
   case TemplateTypeParm:
   case SubstTemplateTypeParm:
   case TemplateSpecialization:
-  case QualifiedName:
-  case DependentName:
-  case ObjCInterface:
-  case ObjCObjectPointer:
   case Elaborated:
+  case DependentName:
+  case DependentTemplateSpecialization:
+  case ObjCInterface:
+  case ObjCObject:
+  case ObjCObjectPointer: // FIXME: object pointers aren't really specifiers
     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;
-    }
+TypeWithKeyword::~TypeWithKeyword() {
+}
+
+ElaboratedTypeKeyword
+TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) {
+  switch (TypeSpec) {
+  default: return ETK_None;
+  case TST_typename: return ETK_Typename;
+  case TST_class: return ETK_Class;
+  case TST_struct: return ETK_Struct;
+  case TST_union: return ETK_Union;
+  case TST_enum: return ETK_Enum;
   }
-  
-  return false;
+}
+
+TagTypeKind
+TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) {
+  switch(TypeSpec) {
+  case TST_class: return TTK_Class;
+  case TST_struct: return TTK_Struct;
+  case TST_union: return TTK_Union;
+  case TST_enum: return TTK_Enum;
+  default: llvm_unreachable("Type specifier is not a tag type kind.");
+  }
+}
+
+ElaboratedTypeKeyword
+TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) {
+  switch (Kind) {
+  case TTK_Class: return ETK_Class;
+  case TTK_Struct: return ETK_Struct;
+  case TTK_Union: return ETK_Union;
+  case TTK_Enum: return ETK_Enum;
+  }
+  llvm_unreachable("Unknown tag type kind.");
+}
+
+TagTypeKind
+TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) {
+  switch (Keyword) {
+  case ETK_Class: return TTK_Class;
+  case ETK_Struct: return TTK_Struct;
+  case ETK_Union: return TTK_Union;
+  case ETK_Enum: return TTK_Enum;
+  case ETK_None: // Fall through.
+  case ETK_Typename:
+    llvm_unreachable("Elaborated type keyword is not a tag type kind.");
+  }
+  llvm_unreachable("Unknown elaborated type keyword.");
+}
+
+bool
+TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) {
+  switch (Keyword) {
+  case ETK_None:
+  case ETK_Typename:
+    return false;
+  case ETK_Class:
+  case ETK_Struct:
+  case ETK_Union:
+  case ETK_Enum:
+    return true;
+  }
+  llvm_unreachable("Unknown elaborated type keyword.");
+}
+
+const char*
+TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) {
+  switch (Keyword) {
+  default: llvm_unreachable("Unknown elaborated type keyword.");
+  case ETK_None: return "";
+  case ETK_Typename: return "typename";
+  case ETK_Class:  return "class";
+  case ETK_Struct: return "struct";
+  case ETK_Union:  return "union";
+  case ETK_Enum:   return "enum";
+  }
+}
+
+ElaboratedType::~ElaboratedType() {}
+DependentNameType::~DependentNameType() {}
+DependentTemplateSpecializationType::~DependentTemplateSpecializationType() {}
+
+DependentTemplateSpecializationType::DependentTemplateSpecializationType(
+                         ElaboratedTypeKeyword Keyword,
+                         NestedNameSpecifier *NNS, const IdentifierInfo *Name,
+                         unsigned NumArgs, const TemplateArgument *Args,
+                         QualType Canon)
+  : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true),
+    NNS(NNS), Name(Name), NumArgs(NumArgs) {
+  assert(NNS && NNS->isDependent() &&
+         "DependentTemplateSpecializatonType requires dependent qualifier");
+  for (unsigned I = 0; I != NumArgs; ++I)
+    new (&getArgBuffer()[I]) TemplateArgument(Args[I]);
+}
+
+void
+DependentTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
+                                             ASTContext &Context,
+                                             ElaboratedTypeKeyword Keyword,
+                                             NestedNameSpecifier *Qualifier,
+                                             const IdentifierInfo *Name,
+                                             unsigned NumArgs,
+                                             const TemplateArgument *Args) {
+  ID.AddInteger(Keyword);
+  ID.AddPointer(Qualifier);
+  ID.AddPointer(Name);
+  for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
+    Args[Idx].Profile(ID, Context);
+}
+
+bool Type::isElaboratedTypeSpecifier() const {
+  ElaboratedTypeKeyword Keyword;
+  if (const ElaboratedType *Elab = dyn_cast<ElaboratedType>(this))
+    Keyword = Elab->getKeyword();
+  else if (const DependentNameType *DepName = dyn_cast<DependentNameType>(this))
+    Keyword = DepName->getKeyword();
+  else if (const DependentTemplateSpecializationType *DepTST =
+             dyn_cast<DependentTemplateSpecializationType>(this))
+    Keyword = DepTST->getKeyword();
+  else
+    return false;
+
+  return TypeWithKeyword::KeywordIsTagTypeKind(Keyword);
 }
 
 const char *Type::getTypeClassName() const {
@@ -826,10 +974,28 @@
   case UndeducedAuto:     return "auto";
   case ObjCId:            return "id";
   case ObjCClass:         return "Class";
-  case ObjCSel:         return "SEL";
+  case ObjCSel:           return "SEL";
   }
 }
 
+void FunctionType::ANCHOR() {} // Key function for FunctionType.
+
+QualType QualType::getNonLValueExprType(ASTContext &Context) const {
+  if (const ReferenceType *RefType = getTypePtr()->getAs<ReferenceType>())
+    return RefType->getPointeeType();
+  
+  // C++0x [basic.lval]:
+  //   Class prvalues can have cv-qualified types; non-class prvalues always 
+  //   have cv-unqualified types.
+  //
+  // See also C99 6.3.2.1p2.
+  if (!Context.getLangOptions().CPlusPlus ||
+      (!getTypePtr()->isDependentType() && !getTypePtr()->isRecordType()))
+    return getUnqualifiedType();
+  
+  return *this;
+}
+
 llvm::StringRef FunctionType::getNameForCallConv(CallingConv CC) {
   switch (CC) {
   case CC_Default: llvm_unreachable("no name for default cc");
@@ -838,6 +1004,7 @@
   case CC_C: return "cdecl";
   case CC_X86StdCall: return "stdcall";
   case CC_X86FastCall: return "fastcall";
+  case CC_X86ThisCall: return "thiscall";
   }
 }
 
@@ -871,19 +1038,6 @@
           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:
@@ -942,7 +1096,30 @@
 
 TagType::TagType(TypeClass TC, const TagDecl *D, QualType can)
   : Type(TC, can, D->isDependentType()),
-    decl(const_cast<TagDecl*>(D), 0) {}
+    decl(const_cast<TagDecl*>(D)) {}
+
+static TagDecl *getInterestingTagDecl(TagDecl *decl) {
+  for (TagDecl::redecl_iterator I = decl->redecls_begin(),
+                                E = decl->redecls_end();
+       I != E; ++I) {
+    if (I->isDefinition() || I->isBeingDefined())
+      return *I;
+  }
+  // If there's no definition (not even in progress), return what we have.
+  return decl;
+}
+
+TagDecl *TagType::getDecl() const {
+  return getInterestingTagDecl(decl);
+}
+
+bool TagType::isBeingDefined() const {
+  return getDecl()->isBeingDefined();
+}
+
+CXXRecordDecl *InjectedClassNameType::getDecl() const {
+  return cast<CXXRecordDecl>(getInterestingTagDecl(Decl));
+}
 
 bool RecordType::classof(const TagType *TT) {
   return isa<RecordDecl>(TT->getDecl());
@@ -965,6 +1142,10 @@
     return Arg.getAsTemplate().isDependent();
       
   case TemplateArgument::Declaration:
+    if (DeclContext *DC = dyn_cast<DeclContext>(Arg.getAsDecl()))
+      return DC->isDependentContext();
+    return Arg.getAsDecl()->getDeclContext()->isDependentContext();
+
   case TemplateArgument::Integral:
     // Never dependent
     return false;
@@ -974,7 +1155,13 @@
             Arg.getAsExpr()->isValueDependent());
 
   case TemplateArgument::Pack:
-    assert(0 && "FIXME: Implement!");
+    for (TemplateArgument::pack_iterator P = Arg.pack_begin(), 
+                                      PEnd = Arg.pack_end();
+         P != PEnd; ++P) {
+      if (isDependent(*P))
+        return true;
+    }
+
     return false;
   }
 
@@ -1003,14 +1190,12 @@
 }
 
 TemplateSpecializationType::
-TemplateSpecializationType(ASTContext &Context, TemplateName T,
-                           bool IsCurrentInstantiation,
+TemplateSpecializationType(TemplateName T,
                            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)) &&
@@ -1022,34 +1207,12 @@
     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);
@@ -1071,36 +1234,53 @@
   return Context->getQualifiedType(T, *this);
 }
 
-void ObjCInterfaceType::Profile(llvm::FoldingSetNodeID &ID,
-                                         const ObjCInterfaceDecl *Decl,
-                                         ObjCProtocolDecl * const *protocols,
-                                         unsigned NumProtocols) {
-  ID.AddPointer(Decl);
+void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID,
+                                 QualType BaseType,
+                                 ObjCProtocolDecl * const *Protocols,
+                                 unsigned NumProtocols) {
+  ID.AddPointer(BaseType.getAsOpaquePtr());
   for (unsigned i = 0; i != NumProtocols; i++)
-    ID.AddPointer(protocols[i]);
+    ID.AddPointer(Protocols[i]);
 }
 
-void ObjCInterfaceType::Profile(llvm::FoldingSetNodeID &ID) {
-  Profile(ID, getDecl(), qual_begin(), getNumProtocols());
+void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID) {
+  Profile(ID, getBaseType(), qual_begin(), getNumProtocols());
 }
 
-Linkage Type::getLinkage() const { 
-  // C++ [basic.link]p8:
-  //   Names not covered by these rules have no linkage.
+/// \brief Determine the linkage of this type.
+Linkage Type::getLinkage() const {
   if (this != CanonicalType.getTypePtr())
     return CanonicalType->getLinkage();
+  
+  if (!LinkageKnown) {
+    CachedLinkage = getLinkageImpl();
+    LinkageKnown = true;
+  }
+  
+  return static_cast<clang::Linkage>(CachedLinkage);
+}
 
+Linkage Type::getLinkageImpl() const { 
+  // C++ [basic.link]p8:
+  //   Names not covered by these rules have no linkage.
   return NoLinkage; 
 }
 
-Linkage BuiltinType::getLinkage() const {
+void Type::ClearLinkageCache() {
+  if (this != CanonicalType.getTypePtr())
+    CanonicalType->ClearLinkageCache();
+  else
+    LinkageKnown = false;
+}
+
+Linkage BuiltinType::getLinkageImpl() 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 {
+Linkage TagType::getLinkageImpl() 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
@@ -1111,39 +1291,39 @@
 // 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 {
+Linkage ComplexType::getLinkageImpl() const {
   return ElementType->getLinkage();
 }
 
-Linkage PointerType::getLinkage() const {
+Linkage PointerType::getLinkageImpl() const {
   return PointeeType->getLinkage();
 }
 
-Linkage BlockPointerType::getLinkage() const {
+Linkage BlockPointerType::getLinkageImpl() const {
   return PointeeType->getLinkage();
 }
 
-Linkage ReferenceType::getLinkage() const {
+Linkage ReferenceType::getLinkageImpl() const {
   return PointeeType->getLinkage();
 }
 
-Linkage MemberPointerType::getLinkage() const {
+Linkage MemberPointerType::getLinkageImpl() const {
   return minLinkage(Class->getLinkage(), PointeeType->getLinkage());
 }
 
-Linkage ArrayType::getLinkage() const {
+Linkage ArrayType::getLinkageImpl() const {
   return ElementType->getLinkage();
 }
 
-Linkage VectorType::getLinkage() const {
+Linkage VectorType::getLinkageImpl() const {
   return ElementType->getLinkage();
 }
 
-Linkage FunctionNoProtoType::getLinkage() const {
+Linkage FunctionNoProtoType::getLinkageImpl() const {
   return getResultType()->getLinkage();
 }
 
-Linkage FunctionProtoType::getLinkage() const {
+Linkage FunctionProtoType::getLinkageImpl() const {
   Linkage L = getResultType()->getLinkage();
   for (arg_type_iterator A = arg_type_begin(), AEnd = arg_type_end();
        A != AEnd; ++A)
@@ -1152,10 +1332,10 @@
   return L;
 }
 
-Linkage ObjCInterfaceType::getLinkage() const {
+Linkage ObjCObjectType::getLinkageImpl() const {
   return ExternalLinkage;
 }
 
-Linkage ObjCObjectPointerType::getLinkage() const {
+Linkage ObjCObjectPointerType::getLinkageImpl() const {
   return ExternalLinkage;
 }
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index fd9fbc1..66578fb 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -27,13 +27,13 @@
 #define ABSTRACT_TYPELOC(CLASS, PARENT)
 #define TYPELOC(CLASS, PARENT) \
     SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
-      return TyLoc.getSourceRange(); \
+      return TyLoc.getLocalSourceRange(); \
     }
 #include "clang/AST/TypeLocNodes.def"
   };
 }
 
-SourceRange TypeLoc::getSourceRangeImpl(TypeLoc TL) {
+SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {
   if (TL.isNull()) return SourceRange();
   return TypeLocRanger().Visit(TL);
 }
@@ -74,29 +74,62 @@
   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()));
+  while (true) {
+    switch (TL.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT)        \
+    case CLASS: {                     \
+      CLASS##TypeLoc TLCasted = cast<CLASS##TypeLoc>(TL); \
+      TLCasted.initializeLocal(Loc);  \
+      TL = TLCasted.getNextTypeLoc(); \
+      if (!TL) return;                \
+      continue;                       \
+    }
+#include "clang/AST/TypeLocNodes.def"
+    }
+  }
 }
 
+SourceLocation TypeLoc::getBeginLoc() const {
+  TypeLoc Cur = *this;
+  while (true) {
+    switch (Cur.getTypeLocClass()) {
+    // FIXME: Currently QualifiedTypeLoc does not have a source range
+    // case Qualified:
+    case Elaborated:
+      break;
+    default:
+      TypeLoc Next = Cur.getNextTypeLoc();
+      if (Next.isNull()) break;
+      Cur = Next;
+      continue;
+    }
+    break;
+  }
+  return Cur.getLocalSourceRange().getBegin();
+}
+
+SourceLocation TypeLoc::getEndLoc() const {
+  TypeLoc Cur = *this;
+  while (true) {
+    switch (Cur.getTypeLocClass()) {
+    default:
+      break;
+    case Qualified:
+    case Elaborated:
+      Cur = Cur.getNextTypeLoc();
+      continue;
+    }
+    break;
+  }
+  return Cur.getLocalSourceRange().getEnd();
+}
+
+
 namespace {
   struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
     // Overload resolution does the real work for us.
@@ -129,7 +162,7 @@
 // Reimplemented to account for GNU/C++ extension
 //     typeof unary-expression
 // where there are no parentheses.
-SourceRange TypeOfExprTypeLoc::getSourceRange() const {
+SourceRange TypeOfExprTypeLoc::getLocalSourceRange() const {
   if (getRParenLoc().isValid())
     return SourceRange(getTypeofLoc(), getRParenLoc());
   else
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 7953b86..463e909 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -29,7 +29,7 @@
 
   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);
@@ -227,12 +227,13 @@
 }
 
 void TypePrinter::PrintVector(const VectorType *T, std::string &S) { 
-  if (T->isAltiVec()) {
-    if (T->isPixel())
+  if (T->getAltiVecSpecific() != VectorType::NotAltiVec) {
+    if (T->getAltiVecSpecific() == VectorType::Pixel)
       S = "__vector __pixel " + S;
     else {
       Print(T->getElementType(), S);
-      S = "__vector " + S;
+      S = ((T->getAltiVecSpecific() == VectorType::Bool)
+           ? "__vector __bool " : "__vector ") + S;
     }
   } else {
     // FIXME: We prefer to print the size directly here, but have no way
@@ -295,6 +296,9 @@
   case CC_X86FastCall:
     S += " __attribute__((fastcall))";
     break;
+  case CC_X86ThisCall:
+    S += " __attribute__((thiscall))";
+    break;
   }
   if (Info.getNoReturn())
     S += " __attribute__((noreturn))";
@@ -449,15 +453,16 @@
       if (!HasKindDecoration)
         OS << " " << D->getKindName();
 
-      PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
-        D->getLocation());
-      OS << " at " << PLoc.getFilename()
-         << ':' << PLoc.getLine()
-         << ':' << PLoc.getColumn();
+      if (D->getLocation().isValid()) {
+        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
@@ -497,16 +502,6 @@
   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'.
@@ -549,13 +544,17 @@
   PrintTemplateSpecialization(T->getInjectedTST(), S);
 }
 
-void TypePrinter::PrintQualifiedName(const QualifiedNameType *T, 
-                                     std::string &S) { 
+void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) {
   std::string MyString;
   
   {
     llvm::raw_string_ostream OS(MyString);
-    T->getQualifier()->print(OS, Policy);
+    OS << TypeWithKeyword::getKeywordName(T->getKeyword());
+    if (T->getKeyword() != ETK_None)
+      OS << " ";
+    NestedNameSpecifier* Qualifier = T->getQualifier();
+    if (Qualifier)
+      Qualifier->print(OS, Policy);
   }
   
   std::string TypeStr;
@@ -575,26 +574,37 @@
   
   {
     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;
-    }
+    OS << TypeWithKeyword::getKeywordName(T->getKeyword());
+    if (T->getKeyword() != ETK_None)
+      OS << " ";
     
     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(),
+    OS << T->getIdentifier()->getName();
+  }
+  
+  if (S.empty())
+    S.swap(MyString);
+  else
+    S = MyString + ' ' + S;
+}
+
+void TypePrinter::PrintDependentTemplateSpecialization(
+        const DependentTemplateSpecializationType *T, std::string &S) { 
+  std::string MyString;
+  {
+    llvm::raw_string_ostream OS(MyString);
+  
+    OS << TypeWithKeyword::getKeywordName(T->getKeyword());
+    if (T->getKeyword() != ETK_None)
+      OS << " ";
+    
+    T->getQualifier()->print(OS, Policy);    
+    OS << T->getIdentifier()->getName();
+    OS << TemplateSpecializationType::PrintTemplateArgumentList(
+                                                            T->getArgs(),
+                                                            T->getNumArgs(),
                                                             Policy);
-    }
   }
   
   if (S.empty())
@@ -607,25 +617,37 @@
                                      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::PrintObjCObject(const ObjCObjectType *T,
+                                  std::string &S) {
+  if (T->qual_empty())
+    return Print(T->getBaseType(), S);
+
+  std::string tmp;
+  Print(T->getBaseType(), tmp);
+  tmp += '<';
+  bool isFirst = true;
+  for (ObjCObjectType::qual_iterator
+         I = T->qual_begin(), E = T->qual_end(); I != E; ++I) {
+    if (isFirst)
+      isFirst = false;
+    else
+      tmp += ',';
+    tmp += (*I)->getNameAsString();
+  }
+  tmp += '>';
+
+  if (!S.empty()) {
+    tmp += ' ';
+    tmp += S;
+  }
+  std::swap(tmp, S);
+}
+
 void TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T, 
                                          std::string &S) { 
   std::string ObjCQIString;
diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp
index 06d8aec..884cbc6 100644
--- a/lib/Analysis/AnalysisContext.cpp
+++ b/lib/Analysis/AnalysisContext.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/ParentMap.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Analysis/Analyses/PseudoConstantAnalysis.h"
 #include "clang/Analysis/AnalysisContext.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/Support/BumpVector.h"
@@ -54,8 +55,11 @@
 }
 
 CFG *AnalysisContext::getCFG() {
+  if (UseUnoptimizedCFG)
+    return getUnoptimizedCFG();
+
   if (!builtCFG) {
-    cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), AddEHEdges);
+    cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), true, AddEHEdges);
     // Even when the cfg is not successfully built, we don't
     // want to try building it again.
     builtCFG = true;
@@ -63,12 +67,29 @@
   return cfg;
 }
 
+CFG *AnalysisContext::getUnoptimizedCFG() {
+  if (!builtCompleteCFG) {
+    completeCFG = CFG::buildCFG(D, getBody(), &D->getASTContext(),
+                                false, AddEHEdges);
+    // Even when the cfg is not successfully built, we don't
+    // want to try building it again.
+    builtCompleteCFG = true;
+  }
+  return completeCFG;
+}
+
 ParentMap &AnalysisContext::getParentMap() {
   if (!PM)
     PM = new ParentMap(getBody());
   return *PM;
 }
 
+PseudoConstantAnalysis *AnalysisContext::getPseudoConstantAnalysis() {
+  if (!PCA)
+    PCA = new PseudoConstantAnalysis(getBody());
+  return PCA;
+}
+
 LiveVariables *AnalysisContext::getLiveVariables() {
   if (!liveness) {
     CFG *c = getCFG();
@@ -83,10 +104,25 @@
   return liveness;
 }
 
-AnalysisContext *AnalysisContextManager::getContext(const Decl *D) {
+LiveVariables *AnalysisContext::getRelaxedLiveVariables() {
+  if (!relaxedLiveness) {
+    CFG *c = getCFG();
+    if (!c)
+      return 0;
+
+    relaxedLiveness = new LiveVariables(*this, false);
+    relaxedLiveness->runOnCFG(*c);
+    relaxedLiveness->runOnAllBlocks(*c, 0, true);
+  }
+
+  return relaxedLiveness;
+}
+
+AnalysisContext *AnalysisContextManager::getContext(const Decl *D,
+                                                    idx::TranslationUnit *TU) {
   AnalysisContext *&AC = Contexts[D];
   if (!AC)
-    AC = new AnalysisContext(D);
+    AC = new AnalysisContext(D, TU, UseUnoptimizedCFG);
 
   return AC;
 }
@@ -296,8 +332,10 @@
 
 AnalysisContext::~AnalysisContext() {
   delete cfg;
+  delete completeCFG;
   delete liveness;
   delete PM;
+  delete PCA;
   delete ReferencedBlockVars;
 }
 
diff --git a/lib/Analysis/Android.mk b/lib/Analysis/Android.mk
index 66b1408..587c22c 100644
--- a/lib/Analysis/Android.mk
+++ b/lib/Analysis/Android.mk
@@ -6,15 +6,23 @@
 include $(CLEAR_TBLGEN_VARS)
 
 TBLGEN_TABLES :=    \
-    DiagnosticCommonKinds.inc	\
-	DiagnosticAnalysisKinds.inc
+	AttrList.inc	\
+	Attrs.inc	\
+	DeclNodes.inc	\
+	DiagnosticCommonKinds.inc	\
+	DiagnosticAnalysisKinds.inc	\
+	StmtNodes.inc
 
 clang_analysis_SRC_FILES :=	\
 	AnalysisContext.cpp	\
 	CFG.cpp	\
+	CFGStmtMap.cpp	\
+	FormatString.cpp	\
 	LiveVariables.cpp	\
 	PrintfFormatString.cpp	\
+	PseudoConstantAnalysis.cpp	\
 	ReachableCode.cpp	\
+	ScanfFormatString.cpp	\
 	UninitializedValues.cpp
 
 
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index e447657..78979a4 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -35,7 +35,7 @@
 
   return D->getLocation();
 }
-  
+
 class AddStmtChoice {
 public:
   enum Kind { NotAlwaysAdd = 0,
@@ -99,7 +99,8 @@
                           TryTerminatedBlock(NULL) {}
 
   // buildCFG - Used by external clients to construct the CFG.
-  CFG* buildCFG(const Decl *D, Stmt *Statement, ASTContext *C, bool AddEHEdges,
+  CFG* buildCFG(const Decl *D, Stmt *Statement, ASTContext *C,
+                bool pruneTriviallyFalseEdges, bool AddEHEdges,
                 bool AddScopes);
 
 private:
@@ -171,15 +172,15 @@
   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);
+  CFGBlock *addStmt(Stmt *S) {
+    return Visit(S, AddStmtChoice::AlwaysAdd);
   }
-  
+
   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());
   }
@@ -206,6 +207,9 @@
   /// 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) {
+    if (!PruneTriviallyFalseEdges)
+      return TryResult();
+
     Expr::EvalResult Result;
     if (!S->isTypeDependent() && !S->isValueDependent() &&
         S->Evaluate(Result, *Context) && Result.Val.isInt())
@@ -216,6 +220,9 @@
 
   bool badCFG;
 
+  // True iff trivially false edges should be pruned from the CFG.
+  bool PruneTriviallyFalseEdges;
+
   // True iff EH edges on CallExprs should be added to the CFG.
   bool AddEHEdges;
 
@@ -243,8 +250,12 @@
 ///  transferred to the caller.  If CFG construction fails, this method returns
 ///  NULL.
 CFG* CFGBuilder::buildCFG(const Decl *D, Stmt* Statement, ASTContext* C,
+                          bool pruneTriviallyFalseEdges,
                           bool addehedges, bool AddScopes) {
+
   AddEHEdges = addehedges;
+  PruneTriviallyFalseEdges = pruneTriviallyFalseEdges;
+
   Context = C;
   assert(cfg.get());
   if (!Statement)
@@ -338,6 +349,10 @@
 ///   DeclStmts (which may contain nested control-flow).
 CFGBlock* CFGBuilder::Visit(Stmt * S, AddStmtChoice asc) {
 tryAgain:
+  if (!S) {
+    badCFG = true;
+    return 0;
+  }
   switch (S->getStmtClass()) {
     default:
       return VisitStmt(S, asc);
@@ -375,15 +390,21 @@
     case Stmt::CXXCatchStmtClass:
       return VisitCXXCatchStmt(cast<CXXCatchStmt>(S));
 
+    case Stmt::CXXExprWithTemporariesClass: {
+      // FIXME: Handle temporaries.  For now, just visit the subexpression
+      // so we don't artificially create extra blocks.
+      return Visit(cast<CXXExprWithTemporaries>(S)->getSubExpr());    
+    }
+
     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));
 
@@ -498,20 +519,28 @@
     Succ = ConfluenceBlock;
     Block = NULL;
     CFGBlock* RHSBlock = addStmt(B->getRHS());
-    if (!FinishBlock(RHSBlock))
-      return 0;
+
+    if (RHSBlock) {
+      if (!FinishBlock(RHSBlock))
+        return 0;
+    }
+    else {
+      // Create an empty block for cases where the RHS doesn't require
+      // any explicit statements in the CFG.
+      RHSBlock = createBlock();
+    }
 
     // See if this is a known constant.
     TryResult KnownVal = TryEvaluateBool(B->getLHS());
-    if (KnownVal.isKnown() && (B->getOpcode() == BinaryOperator::LOr))
+    if (KnownVal.isKnown() && (B->getOpcode() == BO_LOr))
       KnownVal.negate();
 
     // Now link the LHSBlock with RHSBlock.
-    if (B->getOpcode() == BinaryOperator::LOr) {
+    if (B->getOpcode() == BO_LOr) {
       AddSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : ConfluenceBlock);
       AddSuccessor(LHSBlock, KnownVal.isFalse() ? NULL : RHSBlock);
     } else {
-      assert(B->getOpcode() == BinaryOperator::LAnd);
+      assert(B->getOpcode() == BO_LAnd);
       AddSuccessor(LHSBlock, KnownVal.isFalse() ? NULL : RHSBlock);
       AddSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : ConfluenceBlock);
     }
@@ -520,12 +549,21 @@
     Block = LHSBlock;
     return addStmt(B->getLHS());
   }
-  else if (B->getOpcode() == BinaryOperator::Comma) { // ,
+  else if (B->getOpcode() == BO_Comma) { // ,
     autoCreateBlock();
     AppendStmt(Block, B, asc);
     addStmt(B->getRHS());
     return addStmt(B->getLHS());
   }
+  else if (B->isAssignmentOp()) {
+    if (asc.alwaysAdd()) {
+      autoCreateBlock();
+      AppendStmt(Block, B, asc);
+    }
+
+    Visit(B->getRHS());
+    return Visit(B->getLHS(), AddStmtChoice::AsLValueNotAlwaysAdd);
+  }
 
   return VisitStmt(B, asc);
 }
@@ -565,7 +603,7 @@
     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))
@@ -600,8 +638,12 @@
   if (!CanThrow(C->getCallee()))
     AddEHEdge = false;
 
-  if (!NoReturn && !AddEHEdge)
-    return VisitStmt(C, AddStmtChoice::AlwaysAdd);
+  if (!NoReturn && !AddEHEdge) {
+    if (asc.asLValue())
+      return VisitStmt(C, AddStmtChoice::AlwaysAddAsLValue);
+    else
+      return VisitStmt(C, AddStmtChoice::AlwaysAdd);
+  }
 
   if (Block) {
     Succ = Block;
@@ -639,13 +681,13 @@
 
   Succ = ConfluenceBlock;
   Block = NULL;
-  CFGBlock* LHSBlock = addStmt(C->getLHS(), asc);
+  CFGBlock* LHSBlock = Visit(C->getLHS(), asc);
   if (!FinishBlock(LHSBlock))
     return 0;
 
   Succ = ConfluenceBlock;
   Block = NULL;
-  CFGBlock* RHSBlock = addStmt(C->getRHS(), asc);
+  CFGBlock* RHSBlock = Visit(C->getRHS(), asc);
   if (!FinishBlock(RHSBlock))
     return 0;
 
@@ -666,7 +708,10 @@
 
   for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend();
        I != E; ++I ) {
-    LastBlock = addStmt(*I);
+    // If we hit a segment of code just containing ';' (NullStmts), we can
+    // get a null block back.  In such cases, just use the LastBlock
+    if (CFGBlock *newBlock = addStmt(*I))
+      LastBlock = newBlock;
 
     if (badCFG)
       return NULL;
@@ -697,7 +742,7 @@
   Block = NULL;
   CFGBlock* LHSBlock = NULL;
   if (C->getLHS()) {
-    LHSBlock = addStmt(C->getLHS(), asc);
+    LHSBlock = Visit(C->getLHS(), asc);
     if (!FinishBlock(LHSBlock))
       return 0;
     Block = NULL;
@@ -705,7 +750,7 @@
 
   // Create the block for the RHS expression.
   Succ = ConfluenceBlock;
-  CFGBlock* RHSBlock = addStmt(C->getRHS(), asc);
+  CFGBlock* RHSBlock = Visit(C->getRHS(), asc);
   if (!FinishBlock(RHSBlock))
     return 0;
 
@@ -876,7 +921,7 @@
   // 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()) {
@@ -886,7 +931,7 @@
       addStmt(Init);
     }
   }
-  
+
   return Block;
 }
 
@@ -973,6 +1018,11 @@
   } else
     LoopSuccessor = Succ;
 
+  // Save the current value for the break targets.
+  // All breaks should go to the code following the loop.
+  SaveAndRestore<CFGBlock*> save_break(BreakTargetBlock);
+  BreakTargetBlock = LoopSuccessor;
+
   // 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.
@@ -999,7 +1049,7 @@
         assert(Block == EntryConditionBlock);
       }
     }
-    
+
     if (Block) {
       if (!FinishBlock(EntryConditionBlock))
         return 0;
@@ -1020,10 +1070,9 @@
   {
     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);
+   // Save the current values for Block, Succ, and continue targets.
+   SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
+      save_continue(ContinueTargetBlock);
 
     // Create a new block to contain the (bottom) of the loop body.
     Block = NULL;
@@ -1053,9 +1102,6 @@
     // 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());
@@ -1211,10 +1257,9 @@
       return 0;
 
     Block = 0;
+    Succ = SyncBlock;
   }
 
-  Succ = SyncBlock;
-
   // Inline the sync expression.
   return addStmt(S->getSynchExpr());
 }
@@ -1252,7 +1297,7 @@
     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()) {
@@ -1364,7 +1409,7 @@
   if (TryTerminatedBlock)
     // The current try statement is the only successor.
     AddSuccessor(Block, TryTerminatedBlock);
-  else 
+  else
     // otherwise the Exit block is the only successor.
     AddSuccessor(Block, &cfg->getExit());
 
@@ -1440,18 +1485,22 @@
         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);
+    if (!KnownVal.isFalse()) {
+      // 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);
+      // Add the loop body entry as a successor to the condition.
+      AddSuccessor(ExitConditionBlock, LoopBackBlock);
+    }
+    else
+      AddSuccessor(ExitConditionBlock, NULL);
   }
 
   // Link up the condition block with the code that follows the loop.
@@ -1564,7 +1613,7 @@
   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()) {
@@ -1574,16 +1623,37 @@
       addStmt(Init);
     }
   }
-  
+
   return Block;
 }
 
 CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* CS) {
   // CaseStmts are essentially labels, so they are the first statement in a
   // block.
+  CFGBlock *TopBlock = 0, *LastBlock = 0;
+  
+  if (Stmt *Sub = CS->getSubStmt()) {
+    // For deeply nested chains of CaseStmts, instead of doing a recursion
+    // (which can blow out the stack), manually unroll and create blocks
+    // along the way.
+    while (isa<CaseStmt>(Sub)) {
+      CFGBlock *CurrentBlock = createBlock(false);
+      CurrentBlock->setLabel(CS);
 
-  if (CS->getSubStmt())
-    addStmt(CS->getSubStmt());
+      if (TopBlock)
+        AddSuccessor(LastBlock, CurrentBlock);
+      else
+        TopBlock = CurrentBlock;
+
+      AddSuccessor(SwitchTerminatedBlock, CurrentBlock);
+      LastBlock = CurrentBlock;
+
+      CS = cast<CaseStmt>(Sub);
+      Sub = CS->getSubStmt();
+    }
+
+    addStmt(Sub);
+  }
 
   CFGBlock* CaseBlock = Block;
   if (!CaseBlock)
@@ -1604,10 +1674,16 @@
   // 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;
+  if (TopBlock) {
+    AddSuccessor(LastBlock, CaseBlock);
+    Succ = TopBlock;
+  }
+  else {
+    // This block is now the implicit successor of other blocks.
+    Succ = CaseBlock;
+  }
 
-  return CaseBlock;
+  return Succ;
 }
 
 CFGBlock* CFGBuilder::VisitDefaultStmt(DefaultStmt* Terminator) {
@@ -1717,9 +1793,9 @@
   return CatchBlock;
 }
 
-CFGBlock *CFGBuilder::VisitCXXMemberCallExpr(CXXMemberCallExpr *C, 
+CFGBlock *CFGBuilder::VisitCXXMemberCallExpr(CXXMemberCallExpr *C,
                                              AddStmtChoice asc) {
-  AddStmtChoice::Kind K = asc.asLValue() ? AddStmtChoice::AlwaysAddAsLValue 
+  AddStmtChoice::Kind K = asc.asLValue() ? AddStmtChoice::AlwaysAddAsLValue
                                          : AddStmtChoice::AlwaysAdd;
   autoCreateBlock();
   AppendStmt(Block, C, AddStmtChoice(K));
@@ -1770,9 +1846,11 @@
 /// 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 PruneTriviallyFalse,
                    bool AddEHEdges, bool AddScopes) {
   CFGBuilder Builder;
-  return Builder.buildCFG(D, Statement, C, AddEHEdges, AddScopes);
+  return Builder.buildCFG(D, Statement, C, PruneTriviallyFalse,
+                          AddEHEdges, AddScopes);
 }
 
 //===----------------------------------------------------------------------===//
@@ -1789,10 +1867,10 @@
     return;
 
   for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I) {
-    Stmt *child = *I;    
+    Stmt *child = *I;
     if (!child)
       continue;
-    
+
     if (BinaryOperator* B = dyn_cast<BinaryOperator>(child))
       if (B->isAssignmentOp()) Set.insert(B);
 
@@ -2012,10 +2090,10 @@
     B->getLHS()->printPretty(OS, Helper, Policy);
 
     switch (B->getOpcode()) {
-      case BinaryOperator::LOr:
+      case BO_LOr:
         OS << " || ...";
         return;
-      case BinaryOperator::LAnd:
+      case BO_LAnd:
         OS << " && ...";
         return;
       default:
@@ -2058,7 +2136,7 @@
 
     // special printing for comma expressions.
     if (BinaryOperator* B = dyn_cast<BinaryOperator>(Terminator)) {
-      if (B->getOpcode() == BinaryOperator::Comma) {
+      if (B->getOpcode() == BO_Comma) {
         OS << "... , ";
         Helper->handledStmt(B->getRHS(),OS);
         OS << '\n';
diff --git a/lib/Analysis/CFGStmtMap.cpp b/lib/Analysis/CFGStmtMap.cpp
new file mode 100644
index 0000000..965eca1
--- /dev/null
+++ b/lib/Analysis/CFGStmtMap.cpp
@@ -0,0 +1,88 @@
+//===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- 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 CFGStmtMap class, which defines a mapping from
+//  Stmt* to CFGBlock*
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/DenseMap.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/CFGStmtMap.h"
+
+using namespace clang;
+
+typedef llvm::DenseMap<Stmt*,CFGBlock*> SMap;
+static SMap *AsMap(void *m) { return (SMap*) m; }
+
+CFGStmtMap::~CFGStmtMap() { delete AsMap(M); }
+
+CFGBlock *CFGStmtMap::getBlock(Stmt *S) {  
+  SMap *SM = AsMap(M);
+  Stmt *X = S;
+
+  // If 'S' isn't in the map, walk the ParentMap to see if one of its ancestors
+  // is in the map.
+  while (X) {
+    SMap::iterator I = SM->find(X);
+    if (I != SM->end()) {
+      CFGBlock *B = I->second;
+      // Memoize this lookup.
+      if (X != S)
+        (*SM)[X] = B;
+      return B;
+    }
+
+    X = PM->getParentIgnoreParens(X);
+  }
+  
+  return 0;
+}
+
+static void Accumulate(SMap &SM, CFGBlock *B) {
+  // First walk the block-level expressions.
+  for (CFGBlock::iterator I = B->begin(), E = B->end(); I != E; ++I) {
+    const CFGElement &CE = *I;
+    if (Stmt *S = CE.getStmt()) {
+      CFGBlock *&Entry = SM[S];
+      // If 'Entry' is already initialized (e.g., a terminator was already),
+      // skip.
+      if (Entry)
+        continue;
+      
+      Entry = B;
+    }
+  }
+  
+  // Look at the label of the block.
+  if (Stmt *Label = B->getLabel())
+    SM[Label] = B;
+
+  // Finally, look at the terminator.  If the terminator was already added
+  // because it is a block-level expression in another block, overwrite
+  // that mapping.
+  if (Stmt *Term = B->getTerminator())
+    SM[Term] = B;
+}
+
+CFGStmtMap *CFGStmtMap::Build(CFG *C, ParentMap *PM) {
+  if (!C || !PM)
+    return 0;
+
+  SMap *SM = new SMap();
+
+  // Walk all blocks, accumulating the block-level expressions, labels,
+  // and terminators.  
+  for (CFG::iterator I = C->begin(), E = C->end(); I != E; ++I)
+    Accumulate(*SM, *I);
+
+  return new CFGStmtMap(PM, SM);
+}
+
diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt
index b4e0e24..850e9b4 100644
--- a/lib/Analysis/CMakeLists.txt
+++ b/lib/Analysis/CMakeLists.txt
@@ -3,10 +3,15 @@
 add_clang_library(clangAnalysis
   AnalysisContext.cpp
   CFG.cpp
+  CFGStmtMap.cpp
+  FormatString.cpp
   LiveVariables.cpp
   PrintfFormatString.cpp
+  PseudoConstantAnalysis.cpp
   ReachableCode.cpp
+  ScanfFormatString.cpp
   UninitializedValues.cpp
   )
 
-add_dependencies(clangAnalysis ClangDiagnosticAnalysis)
+add_dependencies(clangAnalysis ClangAttrClasses ClangAttrList
+                 ClangDiagnosticAnalysis ClangDeclNodes ClangStmtNodes)
diff --git a/lib/Analysis/FormatString.cpp b/lib/Analysis/FormatString.cpp
new file mode 100644
index 0000000..388b9d3
--- /dev/null
+++ b/lib/Analysis/FormatString.cpp
@@ -0,0 +1,474 @@
+// FormatString.cpp - Common stuff for handling printf/scanf formats -*- C++ -*-
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Shared details for processing format strings of printf and scanf
+// (and friends).
+//
+//===----------------------------------------------------------------------===//
+
+#include "FormatStringParsing.h"
+
+using clang::analyze_format_string::ArgTypeResult;
+using clang::analyze_format_string::FormatStringHandler;
+using clang::analyze_format_string::FormatSpecifier;
+using clang::analyze_format_string::LengthModifier;
+using clang::analyze_format_string::OptionalAmount;
+using clang::analyze_format_string::PositionContext;
+using clang::analyze_format_string::ConversionSpecifier;
+using namespace clang;
+
+// Key function to FormatStringHandler.
+FormatStringHandler::~FormatStringHandler() {}
+
+//===----------------------------------------------------------------------===//
+// Functions for parsing format strings components in both printf and
+// scanf format strings.
+//===----------------------------------------------------------------------===//
+
+OptionalAmount
+clang::analyze_format_string::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, I - Beg,
+          false);
+
+    break;
+  }
+
+  return OptionalAmount();
+}
+
+OptionalAmount
+clang::analyze_format_string::ParseNonPositionAmount(const char *&Beg,
+                                                     const char *E,
+                                                     unsigned &argIndex) {
+  if (*Beg == '*') {
+    ++Beg;
+    return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false);
+  }
+
+  return ParseAmount(Beg, E);
+}
+
+OptionalAmount
+clang::analyze_format_string::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.HandleIncompleteSpecifier(Start, E - Start);
+      return OptionalAmount(false);
+    }
+
+    assert(Amt.getHowSpecified() == OptionalAmount::Constant);
+
+    if (*I == '$') {
+      // Handle positional arguments
+
+      // 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, 0, true);
+    }
+
+    H.HandleInvalidPosition(Beg, I - Beg, p);
+    return OptionalAmount(false);
+  }
+
+  return ParseAmount(Beg, E);
+}
+
+
+bool
+clang::analyze_format_string::ParseFieldWidth(FormatStringHandler &H,
+                                              FormatSpecifier &CS,
+                                              const char *Start,
+                                              const char *&Beg, const char *E,
+                                              unsigned *argIndex) {
+  // FIXME: Support negative field widths.
+  if (argIndex) {
+    CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex));
+  }
+  else {
+    const OptionalAmount Amt =
+      ParsePositionAmount(H, Start, Beg, E,
+                          analyze_format_string::FieldWidthPos);
+
+    if (Amt.isInvalid())
+      return true;
+    CS.setFieldWidth(Amt);
+  }
+  return false;
+}
+
+bool
+clang::analyze_format_string::ParseArgPosition(FormatStringHandler &H,
+                                               FormatSpecifier &FS,
+                                               const char *Start,
+                                               const char *&Beg,
+                                               const char *E) {
+  const char *I = Beg;
+
+  const OptionalAmount &Amt = ParseAmount(I, E);
+
+  if (I == E) {
+    // No more characters left?
+    H.HandleIncompleteSpecifier(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;
+}
+
+bool
+clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
+                                                  const char *&I,
+                                                  const char *E) {
+  LengthModifier::Kind lmKind = LengthModifier::None;
+  const char *lmPosition = I;
+  switch (*I) {
+    default:
+      return false;
+    case 'h':
+      ++I;
+      lmKind = (I != E && *I == 'h') ?
+      ++I, LengthModifier::AsChar : LengthModifier::AsShort;
+      break;
+    case 'l':
+      ++I;
+      lmKind = (I != E && *I == 'l') ?
+      ++I, LengthModifier::AsLongLong : LengthModifier::AsLong;
+      break;
+    case 'j': lmKind = LengthModifier::AsIntMax;     ++I; break;
+    case 'z': lmKind = LengthModifier::AsSizeT;      ++I; break;
+    case 't': lmKind = LengthModifier::AsPtrDiff;    ++I; break;
+    case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break;
+    case 'q': lmKind = LengthModifier::AsLongLong;   ++I; break;
+  }
+  LengthModifier lm(lmPosition, lmKind);
+  FS.setLengthModifier(lm);
+  return true;
+}
+
+//===----------------------------------------------------------------------===//
+// Methods on ArgTypeResult.
+//===----------------------------------------------------------------------===//
+
+bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const {
+  switch (K) {
+    case InvalidTy:
+      assert(false && "ArgTypeResult must be valid");
+      return true;
+
+    case UnknownTy:
+      return true;
+
+    case 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;
+    }
+
+    case 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;
+    }
+
+    case WCStrTy: {
+      const PointerType *PT = argTy->getAs<PointerType>();
+      if (!PT)
+        return false;
+      QualType pointeeTy =
+        C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
+      return pointeeTy == C.getWCharType();
+    }
+    
+    case WIntTy: {
+      // Instead of doing a lookup for the definition of 'wint_t' (which
+      // is defined by the system headers) instead see if wchar_t and
+      // the argument type promote to the same type.
+      QualType PromoWChar =
+        C.getWCharType()->isPromotableIntegerType() 
+          ? C.getPromotedIntegerType(C.getWCharType()) : C.getWCharType();
+      QualType PromoArg = 
+        argTy->isPromotableIntegerType()
+          ? C.getPromotedIntegerType(argTy) : argTy;
+      
+      PromoWChar = C.getCanonicalType(PromoWChar).getUnqualifiedType();
+      PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
+      
+      return PromoWChar == PromoArg;
+    }
+
+    case CPointerTy:
+      return argTy->getAs<PointerType>() != NULL ||
+             argTy->getAs<ObjCObjectPointerType>() != NULL;
+
+    case ObjCPointerTy:
+      return argTy->getAs<ObjCObjectPointerType>() != NULL;
+  }
+
+  // FIXME: Should be unreachable, but Clang is currently emitting
+  // a warning.
+  return false;
+}
+
+QualType ArgTypeResult::getRepresentativeType(ASTContext &C) const {
+  switch (K) {
+    case InvalidTy:
+      assert(false && "No representative type for Invalid ArgTypeResult");
+      // Fall-through.
+    case UnknownTy:
+      return QualType();
+    case SpecificTy:
+      return T;
+    case CStrTy:
+      return C.getPointerType(C.CharTy);
+    case WCStrTy:
+      return C.getPointerType(C.getWCharType());
+    case ObjCPointerTy:
+      return C.ObjCBuiltinIdTy;
+    case CPointerTy:
+      return C.VoidPtrTy;
+    case WIntTy: {
+      QualType WC = C.getWCharType();
+      return WC->isPromotableIntegerType() ? C.getPromotedIntegerType(WC) : WC;
+    }
+  }
+
+  // FIXME: Should be unreachable, but Clang is currently emitting
+  // a warning.
+  return QualType();
+}
+
+//===----------------------------------------------------------------------===//
+// Methods on OptionalAmount.
+//===----------------------------------------------------------------------===//
+
+ArgTypeResult
+analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const {
+  return Ctx.IntTy;
+}
+
+//===----------------------------------------------------------------------===//
+// Methods on LengthModifier.
+//===----------------------------------------------------------------------===//
+
+const char *
+analyze_format_string::LengthModifier::toString() const {
+  switch (kind) {
+  case AsChar:
+    return "hh";
+  case AsShort:
+    return "h";
+  case AsLong: // or AsWideChar
+    return "l";
+  case AsLongLong:
+    return "ll";
+  case AsIntMax:
+    return "j";
+  case AsSizeT:
+    return "z";
+  case AsPtrDiff:
+    return "t";
+  case AsLongDouble:
+    return "L";
+  case None:
+    return "";
+  }
+  return NULL;
+}
+
+//===----------------------------------------------------------------------===//
+// Methods on OptionalAmount.
+//===----------------------------------------------------------------------===//
+
+void OptionalAmount::toString(llvm::raw_ostream &os) const {
+  switch (hs) {
+  case Invalid:
+  case NotSpecified:
+    return;
+  case Arg:
+    if (UsesDotPrefix)
+        os << ".";
+    if (usesPositionalArg())
+      os << "*" << getPositionalArgIndex() << "$";
+    else
+      os << "*";
+    break;
+  case Constant:
+    if (UsesDotPrefix)
+        os << ".";
+    os << amt;
+    break;
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Methods on ConversionSpecifier.
+//===----------------------------------------------------------------------===//
+
+bool FormatSpecifier::hasValidLengthModifier() const {
+  switch (LM.getKind()) {
+    case LengthModifier::None:
+      return true;
+      
+        // Handle most integer flags
+    case LengthModifier::AsChar:
+    case LengthModifier::AsShort:
+    case LengthModifier::AsLongLong:
+    case LengthModifier::AsIntMax:
+    case LengthModifier::AsSizeT:
+    case LengthModifier::AsPtrDiff:
+      switch (CS.getKind()) {
+        case ConversionSpecifier::dArg:
+        case ConversionSpecifier::iArg:
+        case ConversionSpecifier::oArg:
+        case ConversionSpecifier::uArg:
+        case ConversionSpecifier::xArg:
+        case ConversionSpecifier::XArg:
+        case ConversionSpecifier::nArg:
+          return true;
+        default:
+          return false;
+      }
+      
+        // Handle 'l' flag
+    case LengthModifier::AsLong:
+      switch (CS.getKind()) {
+        case ConversionSpecifier::dArg:
+        case ConversionSpecifier::iArg:
+        case ConversionSpecifier::oArg:
+        case ConversionSpecifier::uArg:
+        case ConversionSpecifier::xArg:
+        case ConversionSpecifier::XArg:
+        case ConversionSpecifier::aArg:
+        case ConversionSpecifier::AArg:
+        case ConversionSpecifier::fArg:
+        case ConversionSpecifier::FArg:
+        case ConversionSpecifier::eArg:
+        case ConversionSpecifier::EArg:
+        case ConversionSpecifier::gArg:
+        case ConversionSpecifier::GArg:
+        case ConversionSpecifier::nArg:
+        case ConversionSpecifier::cArg:
+        case ConversionSpecifier::sArg:
+          return true;
+        default:
+          return false;
+      }
+      
+    case LengthModifier::AsLongDouble:
+      switch (CS.getKind()) {
+        case ConversionSpecifier::aArg:
+        case ConversionSpecifier::AArg:
+        case ConversionSpecifier::fArg:
+        case ConversionSpecifier::FArg:
+        case ConversionSpecifier::eArg:
+        case ConversionSpecifier::EArg:
+        case ConversionSpecifier::gArg:
+        case ConversionSpecifier::GArg:
+          return true;
+        default:
+          return false;
+      }
+  }
+  return false;
+}
+
+
diff --git a/lib/Analysis/FormatStringParsing.h b/lib/Analysis/FormatStringParsing.h
new file mode 100644
index 0000000..607e99c
--- /dev/null
+++ b/lib/Analysis/FormatStringParsing.h
@@ -0,0 +1,72 @@
+#ifndef LLVM_CLANG_FORMAT_PARSING_H
+#define LLVM_CLANG_FORMAT_PARSING_H
+
+#include "clang/Analysis/Analyses/FormatString.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+
+template <typename T>
+class UpdateOnReturn {
+  T &ValueToUpdate;
+  const T &ValueToCopy;
+public:
+  UpdateOnReturn(T &valueToUpdate, const T &valueToCopy)
+    : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {}
+
+  ~UpdateOnReturn() {
+    ValueToUpdate = ValueToCopy;
+  }
+};
+
+namespace analyze_format_string {
+  
+OptionalAmount ParseAmount(const char *&Beg, const char *E);
+OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E,
+                                      unsigned &argIndex);
+
+OptionalAmount ParsePositionAmount(FormatStringHandler &H,
+                                   const char *Start, const char *&Beg,
+                                   const char *E, PositionContext p);
+  
+bool ParseFieldWidth(FormatStringHandler &H,
+                     FormatSpecifier &CS,
+                     const char *Start, const char *&Beg, const char *E,
+                     unsigned *argIndex);
+    
+bool ParseArgPosition(FormatStringHandler &H,
+                      FormatSpecifier &CS, const char *Start,
+                      const char *&Beg, const char *E);
+
+/// Returns true if a LengthModifier was parsed and installed in the
+/// FormatSpecifier& argument, and false otherwise.
+bool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E);
+  
+template <typename T> class SpecifierResult {
+  T FS;
+  const char *Start;
+  bool Stop;
+public:
+  SpecifierResult(bool stop = false)
+  : Start(0), Stop(stop) {}
+  SpecifierResult(const char *start,
+                  const T &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 T &getValue() const {
+    assert(hasValue());
+    return FS;
+  }
+  const T &getValue() { return FS; }
+};
+  
+} // end analyze_format_string namespace
+} // end clang namespace
+
+#endif
+
diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp
index 01a36a1..47b2e3d 100644
--- a/lib/Analysis/LiveVariables.cpp
+++ b/lib/Analysis/LiveVariables.cpp
@@ -77,12 +77,13 @@
 };
 } // end anonymous namespace
 
-LiveVariables::LiveVariables(AnalysisContext &AC) {  
+LiveVariables::LiveVariables(AnalysisContext &AC, bool killAtAssign) {
   // Register all referenced VarDecls.
   CFG &cfg = *AC.getCFG();
   getAnalysisData().setCFG(cfg);
   getAnalysisData().setContext(AC.getASTContext());
   getAnalysisData().AC = &AC;
+  getAnalysisData().killAtAssign = killAtAssign;
 
   RegisterDecls R(getAnalysisData());
   cfg.VisitBlockStmts(R);
@@ -229,10 +230,10 @@
   Expr *E = U->getSubExpr();
 
   switch (U->getOpcode()) {
-  case UnaryOperator::PostInc:
-  case UnaryOperator::PostDec:
-  case UnaryOperator::PreInc:
-  case UnaryOperator::PreDec:
+  case UO_PostInc:
+  case UO_PostDec:
+  case UO_PreInc:
+  case UO_PreDec:
     // Walk through the subexpressions, blasting through ParenExprs
     // until we either find a DeclRefExpr or some non-DeclRefExpr
     // expression.
@@ -256,17 +257,22 @@
 
   // 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)
+    // Assignments to references don't kill the ref's address
+    if (DR->getDecl()->getType()->isReferenceType()) {
       VisitDeclRefExpr(DR);
+    } else {
+      if (AD.killAtAssign) {
+        // 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() != BO_Assign)
+        VisitDeclRefExpr(DR);
+    }
   }
   else // Not assigning to a variable.  Process LHS as usual.
     Visit(LHS);
diff --git a/lib/Analysis/Makefile b/lib/Analysis/Makefile
index 9b47380..fbbb83d 100644
--- a/lib/Analysis/Makefile
+++ b/lib/Analysis/Makefile
@@ -11,11 +11,8 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
+CLANG_LEVEL := ../..
 LIBRARYNAME := clangAnalysis
-BUILD_ARCHIVE = 1
 
-CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
 
diff --git a/lib/Analysis/PrintfFormatString.cpp b/lib/Analysis/PrintfFormatString.cpp
index c38aae3..b8c327c 100644
--- a/lib/Analysis/PrintfFormatString.cpp
+++ b/lib/Analysis/PrintfFormatString.cpp
@@ -1,4 +1,4 @@
-//= PrintfFormatStrings.cpp - Analysis of printf format strings --*- C++ -*-==//
+//== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -12,135 +12,28 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Analysis/Analyses/PrintfFormatString.h"
-#include "clang/AST/ASTContext.h"
+#include "clang/Analysis/Analyses/FormatString.h"
+#include "FormatStringParsing.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 clang::analyze_format_string::ArgTypeResult;
+using clang::analyze_format_string::FormatStringHandler;
+using clang::analyze_format_string::LengthModifier;
+using clang::analyze_format_string::OptionalAmount;
+using clang::analyze_format_string::ConversionSpecifier;
+using clang::analyze_printf::PrintfSpecifier;
 
 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;
-  }
-};
+typedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier>
+        PrintfSpecifierResult;
 
 //===----------------------------------------------------------------------===//
 // Methods for parsing format strings.
 //===----------------------------------------------------------------------===//
 
-static OptionalAmount ParseAmount(const char *&Beg, const char *E) {
-  const char *I = Beg;
-  UpdateOnReturn <const char*> UpdateBeg(Beg, I);
+using analyze_format_string::ParseNonPositionAmount;
 
-  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,
+static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS,
                            const char *Start, const char *&Beg, const char *E,
                            unsigned *argIndex) {
   if (argIndex) {
@@ -148,7 +41,7 @@
   }
   else {
     const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E,
-                                                  analyze_printf::PrecisionPos);
+                                           analyze_format_string::PrecisionPos);
     if (Amt.isInvalid())
       return true;
     FS.setPrecision(Amt);
@@ -156,62 +49,12 @@
   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,
+static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
                                                   const char *&Beg,
                                                   const char *E,
                                                   unsigned &argIndex) {
 
+  using namespace clang::analyze_format_string;
   using namespace clang::analyze_printf;
 
   const char *I = Beg;
@@ -238,17 +81,17 @@
 
   if (I == E) {
     // No more characters left?
-    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    H.HandleIncompleteSpecifier(Start, E - Start);
     return true;
   }
 
-  FormatSpecifier FS;
+  PrintfSpecifier FS;
   if (ParseArgPosition(H, FS, Start, I, E))
     return true;
 
   if (I == E) {
     // No more characters left?
-    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    H.HandleIncompleteSpecifier(Start, E - Start);
     return true;
   }
 
@@ -257,11 +100,11 @@
   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;
+      case '-': FS.setIsLeftJustified(I); break;
+      case '+': FS.setHasPlusPrefix(I); break;
+      case ' ': FS.setHasSpacePrefix(I); break;
+      case '#': FS.setHasAlternativeForm(I); break;
+      case '0': FS.setHasLeadingZeros(I); break;
     }
     if (!hasMore)
       break;
@@ -269,7 +112,7 @@
 
   if (I == E) {
     // No more characters left?
-    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    H.HandleIncompleteSpecifier(Start, E - Start);
     return true;
   }
 
@@ -280,7 +123,7 @@
 
   if (I == E) {
     // No more characters left?
-    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    H.HandleIncompleteSpecifier(Start, E - Start);
     return true;
   }
 
@@ -288,7 +131,7 @@
   if (*I == '.') {
     ++I;
     if (I == E) {
-      H.HandleIncompleteFormatSpecifier(Start, E - Start);
+      H.HandleIncompleteSpecifier(Start, E - Start);
       return true;
     }
 
@@ -298,35 +141,15 @@
 
     if (I == E) {
       // No more characters left?
-      H.HandleIncompleteFormatSpecifier(Start, E - Start);
+      H.HandleIncompleteSpecifier(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) {
+  if (ParseLengthModifier(FS, I, E) && I == E) {
     // No more characters left?
-    H.HandleIncompleteFormatSpecifier(Start, E - Start);
+    H.HandleIncompleteSpecifier(Start, E - Start);
     return true;
   }
 
@@ -350,46 +173,47 @@
     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 'c': k = ConversionSpecifier::cArg; 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 'n': k = ConversionSpecifier::nArg; break;
     case 'o': k = ConversionSpecifier::oArg; break;
-    case 'p': k = ConversionSpecifier::VoidPtrArg;   break;
-    case 's': k = ConversionSpecifier::CStrArg;      break;
+    case 'p': k = ConversionSpecifier::pArg;   break;
+    case 's': k = ConversionSpecifier::sArg;      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;
+    case 'S': k = ConversionSpecifier::SArg; break;
     // Objective-C.
     case '@': k = ConversionSpecifier::ObjCObjArg; break;
     // Glibc specific.
     case 'm': k = ConversionSpecifier::PrintErrno; break;
   }
-  ConversionSpecifier CS(conversionPosition, k);
+  PrintfConversionSpecifier 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 !H.HandleInvalidPrintfConversionSpecifier(FS, Beg, I - Beg);
   }
-  return FormatSpecifierResult(Start, FS);
+  return PrintfSpecifierResult(Start, FS);
 }
 
-bool clang::analyze_printf::ParseFormatString(FormatStringHandler &H,
-                       const char *I, const char *E) {
+bool clang::analyze_format_string::ParsePrintfString(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);
+    const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(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())
@@ -399,7 +223,7 @@
     if (!FSR.hasValue())
       continue;
     // We have a format specifier.  Pass it to the callback.
-    if (!H.HandleFormatSpecifier(FSR.getValue(), FSR.getStart(),
+    if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
                                  I - FSR.getStart()))
       return true;
   }
@@ -407,173 +231,119 @@
   return false;
 }
 
-FormatStringHandler::~FormatStringHandler() {}
-
 //===----------------------------------------------------------------------===//
-// Methods on ArgTypeResult.
+// Methods on ConversionSpecifier.
 //===----------------------------------------------------------------------===//
+const char *ConversionSpecifier::toString() const {
+  switch (kind) {
+  case dArg: return "d";
+  case iArg: return "i";
+  case oArg: return "o";
+  case uArg: return "u";
+  case xArg: return "x";
+  case XArg: return "X";
+  case fArg: return "f";
+  case FArg: return "F";
+  case eArg: return "e";
+  case EArg: return "E";
+  case gArg: return "g";
+  case GArg: return "G";
+  case aArg: return "a";
+  case AArg: return "A";
+  case cArg: return "c";
+  case sArg: return "s";
+  case pArg: return "p";
+  case nArg: return "n";
+  case PercentArg:  return "%";
+  case ScanListArg: return "[";
+  case InvalidSpecifier: return NULL;
 
-bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const {
-  assert(isValid());
+  // MacOS X unicode extensions.
+  case CArg: return "C";
+  case SArg: return "S";
 
-  if (K == UnknownTy)
-    return true;
+  // Objective-C specific specifiers.
+  case ObjCObjArg: return "@";
 
-  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;
+  // GlibC specific specifiers.
+  case PrintErrno: return "m";
   }
-
-  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();
+  return NULL;
 }
 
 //===----------------------------------------------------------------------===//
-// Methods on OptionalAmount.
+// Methods on PrintfSpecifier.
 //===----------------------------------------------------------------------===//
 
-ArgTypeResult OptionalAmount::getArgType(ASTContext &Ctx) const {
-  return Ctx.IntTy;
-}
-
-//===----------------------------------------------------------------------===//
-// Methods on FormatSpecifier.
-//===----------------------------------------------------------------------===//
-
-ArgTypeResult FormatSpecifier::getArgType(ASTContext &Ctx) const {
+ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx) const {
+  const PrintfConversionSpecifier &CS = getConversionSpecifier();
+  
   if (!CS.consumesDataArgument())
     return ArgTypeResult::Invalid();
 
-  if (CS.isIntArg())
-    switch (LM) {
-      case AsLongDouble:
+  if (CS.getKind() == ConversionSpecifier::cArg)
+    switch (LM.getKind()) {
+      case LengthModifier::None: return Ctx.IntTy;
+      case LengthModifier::AsLong: return ArgTypeResult::WIntTy;
+      default:
         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:
+    }
+  
+  if (CS.isIntArg())
+    switch (LM.getKind()) {
+      case LengthModifier::AsLongDouble:
+        return ArgTypeResult::Invalid();
+      case LengthModifier::None: return Ctx.IntTy;
+      case LengthModifier::AsChar: return Ctx.SignedCharTy;
+      case LengthModifier::AsShort: return Ctx.ShortTy;
+      case LengthModifier::AsLong: return Ctx.LongTy;
+      case LengthModifier::AsLongLong: return Ctx.LongLongTy;
+      case LengthModifier::AsIntMax:
         // FIXME: Return unknown for now.
         return ArgTypeResult();
-      case AsSizeT: return Ctx.getSizeType();
-      case AsPtrDiff: return Ctx.getPointerDiffType();
+      case LengthModifier::AsSizeT: return Ctx.getSizeType();
+      case LengthModifier::AsPtrDiff: return Ctx.getPointerDiffType();
     }
 
   if (CS.isUIntArg())
-    switch (LM) {
-      case AsLongDouble:
+    switch (LM.getKind()) {
+      case LengthModifier::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:
+      case LengthModifier::None: return Ctx.UnsignedIntTy;
+      case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
+      case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
+      case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
+      case LengthModifier::AsLongLong: return Ctx.UnsignedLongLongTy;
+      case LengthModifier::AsIntMax:
         // FIXME: Return unknown for now.
         return ArgTypeResult();
-      case AsSizeT:
+      case LengthModifier::AsSizeT:
         // FIXME: How to get the corresponding unsigned
         // version of size_t?
         return ArgTypeResult();
-      case AsPtrDiff:
+      case LengthModifier::AsPtrDiff:
         // FIXME: How to get the corresponding unsigned
         // version of ptrdiff_t?
         return ArgTypeResult();
     }
 
   if (CS.isDoubleArg()) {
-    if (LM == AsLongDouble)
+    if (LM.getKind() == LengthModifier::AsLongDouble)
       return Ctx.LongDoubleTy;
     return Ctx.DoubleTy;
   }
 
   switch (CS.getKind()) {
-    case ConversionSpecifier::CStrArg:
-      return ArgTypeResult(LM == AsWideChar ? ArgTypeResult::WCStrTy                                            : ArgTypeResult::CStrTy);
-    case ConversionSpecifier::UnicodeStrArg:
+    case ConversionSpecifier::sArg:
+      return ArgTypeResult(LM.getKind() == LengthModifier::AsWideChar ?
+          ArgTypeResult::WCStrTy : ArgTypeResult::CStrTy);
+    case ConversionSpecifier::SArg:
       // FIXME: This appears to be Mac OS X specific.
       return ArgTypeResult::WCStrTy;
     case ConversionSpecifier::CArg:
       return Ctx.WCharTy;
+    case ConversionSpecifier::pArg:
+      return ArgTypeResult::CPointerTy;
     default:
       break;
   }
@@ -582,3 +352,261 @@
   return ArgTypeResult();
 }
 
+bool PrintfSpecifier::fixType(QualType QT) {
+  // Handle strings first (char *, wchar_t *)
+  if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
+    CS.setKind(ConversionSpecifier::sArg);
+
+    // Disable irrelevant flags
+    HasAlternativeForm = 0;
+    HasLeadingZeroes = 0;
+
+    // Set the long length modifier for wide characters
+    if (QT->getPointeeType()->isWideCharType())
+      LM.setKind(LengthModifier::AsWideChar);
+
+    return true;
+  }
+
+  // We can only work with builtin types.
+  if (!QT->isBuiltinType())
+    return false;
+
+  // Everything else should be a base type
+  const BuiltinType *BT = QT->getAs<BuiltinType>();
+
+  // Set length modifier
+  switch (BT->getKind()) {
+  default:
+    // The rest of the conversions are either optional or for non-builtin types
+    LM.setKind(LengthModifier::None);
+    break;
+
+  case BuiltinType::WChar:
+  case BuiltinType::Long:
+  case BuiltinType::ULong:
+    LM.setKind(LengthModifier::AsLong);
+    break;
+
+  case BuiltinType::LongLong:
+  case BuiltinType::ULongLong:
+    LM.setKind(LengthModifier::AsLongLong);
+    break;
+
+  case BuiltinType::LongDouble:
+    LM.setKind(LengthModifier::AsLongDouble);
+    break;
+  }
+
+  // Set conversion specifier and disable any flags which do not apply to it.
+  if (QT->isAnyCharacterType()) {
+    CS.setKind(ConversionSpecifier::cArg);
+    Precision.setHowSpecified(OptionalAmount::NotSpecified);
+    HasAlternativeForm = 0;
+    HasLeadingZeroes = 0;
+    HasPlusPrefix = 0;
+  }
+  // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
+  else if (QT->isRealFloatingType()) {
+    CS.setKind(ConversionSpecifier::fArg);
+  }
+  else if (QT->isPointerType()) {
+    CS.setKind(ConversionSpecifier::pArg);
+    Precision.setHowSpecified(OptionalAmount::NotSpecified);
+    HasAlternativeForm = 0;
+    HasLeadingZeroes = 0;
+    HasPlusPrefix = 0;
+  }
+  else if (QT->isSignedIntegerType()) {
+    CS.setKind(ConversionSpecifier::dArg);
+    HasAlternativeForm = 0;
+  }
+  else if (QT->isUnsignedIntegerType()) {
+    CS.setKind(ConversionSpecifier::uArg);
+    HasAlternativeForm = 0;
+    HasPlusPrefix = 0;
+  }
+  else {
+    return false;
+  }
+
+  return true;
+}
+
+void PrintfSpecifier::toString(llvm::raw_ostream &os) const {
+  // Whilst some features have no defined order, we are using the order
+  // appearing in the C99 standard (ISO/IEC 9899:1999 (E) ¤7.19.6.1)
+  os << "%";
+
+  // Positional args
+  if (usesPositionalArg()) {
+    os << getPositionalArgIndex() << "$";
+  }
+
+  // Conversion flags
+  if (IsLeftJustified)    os << "-";
+  if (HasPlusPrefix)      os << "+";
+  if (HasSpacePrefix)     os << " ";
+  if (HasAlternativeForm) os << "#";
+  if (HasLeadingZeroes)   os << "0";
+
+  // Minimum field width
+  FieldWidth.toString(os);
+  // Precision
+  Precision.toString(os);
+  // Length modifier
+  os << LM.toString();
+  // Conversion specifier
+  os << CS.toString();
+}
+
+bool PrintfSpecifier::hasValidPlusPrefix() const {
+  if (!HasPlusPrefix)
+    return true;
+
+  // The plus prefix only makes sense for signed conversions
+  switch (CS.getKind()) {
+  case ConversionSpecifier::dArg:
+  case ConversionSpecifier::iArg:
+  case ConversionSpecifier::fArg:
+  case ConversionSpecifier::FArg:
+  case ConversionSpecifier::eArg:
+  case ConversionSpecifier::EArg:
+  case ConversionSpecifier::gArg:
+  case ConversionSpecifier::GArg:
+  case ConversionSpecifier::aArg:
+  case ConversionSpecifier::AArg:
+    return true;
+
+  default:
+    return false;
+  }
+}
+
+bool PrintfSpecifier::hasValidAlternativeForm() const {
+  if (!HasAlternativeForm)
+    return true;
+
+  // Alternate form flag only valid with the oxaAeEfFgG conversions
+  switch (CS.getKind()) {
+  case ConversionSpecifier::oArg:
+  case ConversionSpecifier::xArg:
+  case ConversionSpecifier::aArg:
+  case ConversionSpecifier::AArg:
+  case ConversionSpecifier::eArg:
+  case ConversionSpecifier::EArg:
+  case ConversionSpecifier::fArg:
+  case ConversionSpecifier::FArg:
+  case ConversionSpecifier::gArg:
+  case ConversionSpecifier::GArg:
+    return true;
+
+  default:
+    return false;
+  }
+}
+
+bool PrintfSpecifier::hasValidLeadingZeros() const {
+  if (!HasLeadingZeroes)
+    return true;
+
+  // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
+  switch (CS.getKind()) {
+  case ConversionSpecifier::dArg:
+  case ConversionSpecifier::iArg:
+  case ConversionSpecifier::oArg:
+  case ConversionSpecifier::uArg:
+  case ConversionSpecifier::xArg:
+  case ConversionSpecifier::XArg:
+  case ConversionSpecifier::aArg:
+  case ConversionSpecifier::AArg:
+  case ConversionSpecifier::eArg:
+  case ConversionSpecifier::EArg:
+  case ConversionSpecifier::fArg:
+  case ConversionSpecifier::FArg:
+  case ConversionSpecifier::gArg:
+  case ConversionSpecifier::GArg:
+    return true;
+
+  default:
+    return false;
+  }
+}
+
+bool PrintfSpecifier::hasValidSpacePrefix() const {
+  if (!HasSpacePrefix)
+    return true;
+
+  // The space prefix only makes sense for signed conversions
+  switch (CS.getKind()) {
+  case ConversionSpecifier::dArg:
+  case ConversionSpecifier::iArg:
+  case ConversionSpecifier::fArg:
+  case ConversionSpecifier::FArg:
+  case ConversionSpecifier::eArg:
+  case ConversionSpecifier::EArg:
+  case ConversionSpecifier::gArg:
+  case ConversionSpecifier::GArg:
+  case ConversionSpecifier::aArg:
+  case ConversionSpecifier::AArg:
+    return true;
+
+  default:
+    return false;
+  }
+}
+
+bool PrintfSpecifier::hasValidLeftJustified() const {
+  if (!IsLeftJustified)
+    return true;
+
+  // The left justified flag is valid for all conversions except n
+  switch (CS.getKind()) {
+  case ConversionSpecifier::nArg:
+    return false;
+
+  default:
+    return true;
+  }
+}
+
+bool PrintfSpecifier::hasValidPrecision() const {
+  if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
+    return true;
+
+  // Precision is only valid with the diouxXaAeEfFgGs conversions
+  switch (CS.getKind()) {
+  case ConversionSpecifier::dArg:
+  case ConversionSpecifier::iArg:
+  case ConversionSpecifier::oArg:
+  case ConversionSpecifier::uArg:
+  case ConversionSpecifier::xArg:
+  case ConversionSpecifier::XArg:
+  case ConversionSpecifier::aArg:
+  case ConversionSpecifier::AArg:
+  case ConversionSpecifier::eArg:
+  case ConversionSpecifier::EArg:
+  case ConversionSpecifier::fArg:
+  case ConversionSpecifier::FArg:
+  case ConversionSpecifier::gArg:
+  case ConversionSpecifier::GArg:
+  case ConversionSpecifier::sArg:
+    return true;
+
+  default:
+    return false;
+  }
+}
+bool PrintfSpecifier::hasValidFieldWidth() const {
+  if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
+      return true;
+
+  // The field width is valid for all conversions except n
+  switch (CS.getKind()) {
+  case ConversionSpecifier::nArg:
+    return false;
+
+  default:
+    return true;
+  }
+}
diff --git a/lib/Analysis/PseudoConstantAnalysis.cpp b/lib/Analysis/PseudoConstantAnalysis.cpp
new file mode 100644
index 0000000..ff43fc2
--- /dev/null
+++ b/lib/Analysis/PseudoConstantAnalysis.cpp
@@ -0,0 +1,238 @@
+//== PseudoConstantAnalysis.cpp - Find Pseudoconstants in the AST-*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tracks the usage of variables in a Decl body to see if they are
+// never written to, implying that they constant. This is useful in static
+// analysis to see if a developer might have intended a variable to be const.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/Analyses/PseudoConstantAnalysis.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
+#include <deque>
+
+using namespace clang;
+
+// The number of ValueDecls we want to keep track of by default (per-function)
+#define VARDECL_SET_SIZE 256
+typedef llvm::SmallPtrSet<const VarDecl*, VARDECL_SET_SIZE> VarDeclSet;
+
+PseudoConstantAnalysis::PseudoConstantAnalysis(const Stmt *DeclBody) :
+      DeclBody(DeclBody), Analyzed(false) {
+  NonConstantsImpl = new VarDeclSet;
+  UsedVarsImpl = new VarDeclSet;
+}
+
+PseudoConstantAnalysis::~PseudoConstantAnalysis() {
+  delete (VarDeclSet*)NonConstantsImpl;
+  delete (VarDeclSet*)UsedVarsImpl;
+}
+
+// Returns true if the given ValueDecl is never written to in the given DeclBody
+bool PseudoConstantAnalysis::isPseudoConstant(const VarDecl *VD) {
+  // Only local and static variables can be pseudoconstants
+  if (!VD->hasLocalStorage() && !VD->isStaticLocal())
+    return false;
+
+  if (!Analyzed) {
+    RunAnalysis();
+    Analyzed = true;
+  }
+
+  VarDeclSet *NonConstants = (VarDeclSet*)NonConstantsImpl;
+
+  return !NonConstants->count(VD);
+}
+
+// Returns true if the variable was used (self assignments don't count)
+bool PseudoConstantAnalysis::wasReferenced(const VarDecl *VD) {
+  if (!Analyzed) {
+    RunAnalysis();
+    Analyzed = true;
+  }
+
+  VarDeclSet *UsedVars = (VarDeclSet*)UsedVarsImpl;
+
+  return UsedVars->count(VD);
+}
+
+// Returns a Decl from a (Block)DeclRefExpr (if any)
+const Decl *PseudoConstantAnalysis::getDecl(const Expr *E) {
+  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E))
+    return DR->getDecl();
+  else if (const BlockDeclRefExpr *BDR = dyn_cast<BlockDeclRefExpr>(E))
+    return BDR->getDecl();
+  else
+    return 0;
+}
+
+void PseudoConstantAnalysis::RunAnalysis() {
+  std::deque<const Stmt *> WorkList;
+  VarDeclSet *NonConstants = (VarDeclSet*)NonConstantsImpl;
+  VarDeclSet *UsedVars = (VarDeclSet*)UsedVarsImpl;
+
+  // Start with the top level statement of the function
+  WorkList.push_back(DeclBody);
+
+  while (!WorkList.empty()) {
+    const Stmt* Head = WorkList.front();
+    WorkList.pop_front();
+
+    switch (Head->getStmtClass()) {
+    // Case 1: Assignment operators modifying VarDecls
+    case Stmt::BinaryOperatorClass: {
+      const BinaryOperator *BO = cast<BinaryOperator>(Head);
+      // Look for a Decl on the LHS
+      const Decl *LHSDecl = getDecl(BO->getLHS()->IgnoreParenCasts());
+      if (!LHSDecl)
+        break;
+
+      // We found a binary operator with a DeclRefExpr on the LHS. We now check
+      // for any of the assignment operators, implying that this Decl is being
+      // written to.
+      switch (BO->getOpcode()) {
+      // Self-assignments don't count as use of a variable
+      case BO_Assign: {
+        // Look for a DeclRef on the RHS
+        const Decl *RHSDecl = getDecl(BO->getRHS()->IgnoreParenCasts());
+
+        // If the Decls match, we have self-assignment
+        if (LHSDecl == RHSDecl)
+          // Do not visit the children
+          continue;
+
+      }
+      case BO_AddAssign:
+      case BO_SubAssign:
+      case BO_MulAssign:
+      case BO_DivAssign:
+      case BO_AndAssign:
+      case BO_OrAssign:
+      case BO_XorAssign:
+      case BO_ShlAssign:
+      case BO_ShrAssign: {
+        const VarDecl *VD = dyn_cast<VarDecl>(LHSDecl);
+        // The DeclRefExpr is being assigned to - mark it as non-constant
+        if (VD)
+          NonConstants->insert(VD);
+        break;
+      }
+
+      default:
+        break;
+      }
+      break;
+    }
+
+    // Case 2: Pre/post increment/decrement and address of
+    case Stmt::UnaryOperatorClass: {
+      const UnaryOperator *UO = cast<UnaryOperator>(Head);
+
+      // Look for a DeclRef in the subexpression
+      const Decl *D = getDecl(UO->getSubExpr()->IgnoreParenCasts());
+      if (!D)
+        break;
+
+      // We found a unary operator with a DeclRef as a subexpression. We now
+      // check for any of the increment/decrement operators, as well as
+      // addressOf.
+      switch (UO->getOpcode()) {
+      case UO_PostDec:
+      case UO_PostInc:
+      case UO_PreDec:
+      case UO_PreInc:
+        // The DeclRef is being changed - mark it as non-constant
+      case UO_AddrOf: {
+        // If we are taking the address of the DeclRefExpr, assume it is
+        // non-constant.
+        const VarDecl *VD = dyn_cast<VarDecl>(D);
+        if (VD)
+          NonConstants->insert(VD);
+        break;
+      }
+
+      default:
+        break;
+      }
+      break;
+    }
+
+    // Case 3: Reference Declarations
+    case Stmt::DeclStmtClass: {
+      const DeclStmt *DS = cast<DeclStmt>(Head);
+      // Iterate over each decl and see if any of them contain reference decls
+      for (DeclStmt::const_decl_iterator I = DS->decl_begin(),
+          E = DS->decl_end(); I != E; ++I) {
+        // We only care about VarDecls
+        const VarDecl *VD = dyn_cast<VarDecl>(*I);
+        if (!VD)
+          continue;
+
+        // We found a VarDecl; make sure it is a reference type
+        if (!VD->getType().getTypePtr()->isReferenceType())
+          continue;
+
+        // Try to find a Decl in the initializer
+        const Decl *D = getDecl(VD->getInit()->IgnoreParenCasts());
+        if (!D)
+          break;
+
+        // If the reference is to another var, add the var to the non-constant
+        // list
+        if (const VarDecl *RefVD = dyn_cast<VarDecl>(D)) {
+          NonConstants->insert(RefVD);
+          continue;
+        }
+      }
+      break;
+    }
+
+    // Case 4: Block variable references
+    case Stmt::BlockDeclRefExprClass: {
+      const BlockDeclRefExpr *BDR = cast<BlockDeclRefExpr>(Head);
+      if (const VarDecl *VD = dyn_cast<VarDecl>(BDR->getDecl())) {
+        // Add the Decl to the used list
+        UsedVars->insert(VD);
+        continue;
+      }
+      break;
+    }
+
+    // Case 5: Variable references
+    case Stmt::DeclRefExprClass: {
+      const DeclRefExpr *DR = cast<DeclRefExpr>(Head);
+      if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
+        // Add the Decl to the used list
+        UsedVars->insert(VD);
+        continue;
+      }
+      break;
+    }
+
+    // Case 6: Block expressions
+    case Stmt::BlockExprClass: {
+      const BlockExpr *B = cast<BlockExpr>(Head);
+      // Add the body of the block to the list
+      WorkList.push_back(B->getBody());
+      continue;
+    }
+
+      default:
+        break;
+    } // switch (head->getStmtClass())
+
+    // Add all substatements to the worklist
+    for (Stmt::const_child_iterator I = Head->child_begin(),
+        E = Head->child_end(); I != E; ++I)
+      if (*I)
+        WorkList.push_back(*I);
+  } // while (!WorkList.empty())
+}
diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp
index f959e5c..0543939 100644
--- a/lib/Analysis/ReachableCode.cpp
+++ b/lib/Analysis/ReachableCode.cpp
@@ -41,7 +41,7 @@
   switch (S->getStmtClass()) {
     case Expr::BinaryOperatorClass: {
       const BinaryOperator *BO = cast<BinaryOperator>(S);
-      if (BO->getOpcode() == BinaryOperator::Comma) {
+      if (BO->getOpcode() == BO_Comma) {
         if (sn+1 < b.size())
           return b[sn+1].getStmt()->getLocStart();
         const CFGBlock *n = &b;
diff --git a/lib/Analysis/ScanfFormatString.cpp b/lib/Analysis/ScanfFormatString.cpp
new file mode 100644
index 0000000..6a8673a
--- /dev/null
+++ b/lib/Analysis/ScanfFormatString.cpp
@@ -0,0 +1,221 @@
+//= ScanfFormatString.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 scanf and friends.  The structure of format
+// strings for fscanf() are described in C99 7.19.6.2.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/Analyses/FormatString.h"
+#include "FormatStringParsing.h"
+
+using clang::analyze_format_string::ArgTypeResult;
+using clang::analyze_format_string::FormatStringHandler;
+using clang::analyze_format_string::LengthModifier;
+using clang::analyze_format_string::OptionalAmount;
+using clang::analyze_format_string::ConversionSpecifier;
+using clang::analyze_scanf::ScanfConversionSpecifier;
+using clang::analyze_scanf::ScanfSpecifier;
+using clang::UpdateOnReturn;
+
+typedef clang::analyze_format_string::SpecifierResult<ScanfSpecifier>
+        ScanfSpecifierResult;
+
+static bool ParseScanList(FormatStringHandler &H,
+                          ScanfConversionSpecifier &CS,
+                          const char *&Beg, const char *E) {
+  const char *I = Beg;
+  const char *start = I - 1;
+  UpdateOnReturn <const char*> UpdateBeg(Beg, I);
+
+  // No more characters?
+  if (I == E) {
+    H.HandleIncompleteScanList(start, I);
+    return true;
+  }
+  
+  // Special case: ']' is the first character.
+  if (*I == ']') {
+    if (++I == E) {
+      H.HandleIncompleteScanList(start, I - 1);
+      return true;
+    }
+  }
+
+  // Look for a ']' character which denotes the end of the scan list.
+  while (*I != ']') {
+    if (++I == E) {
+      H.HandleIncompleteScanList(start, I - 1);
+      return true;
+    }
+  }    
+
+  CS.setEndScanList(I);
+  return false;
+}
+
+// FIXME: Much of this is copy-paste from ParsePrintfSpecifier.
+// We can possibly refactor.
+static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H,
+                                                const char *&Beg,
+                                                const char *E,
+                                                unsigned &argIndex) {
+  
+  using namespace clang::analyze_scanf;
+  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.HandleIncompleteSpecifier(Start, E - Start);
+    return true;
+  }
+  
+  ScanfSpecifier FS;
+  if (ParseArgPosition(H, FS, Start, I, E))
+    return true;
+
+  if (I == E) {
+      // No more characters left?
+    H.HandleIncompleteSpecifier(Start, E - Start);
+    return true;
+  }
+  
+  // Look for '*' flag if it is present.
+  if (*I == '*') {
+    FS.setSuppressAssignment(I);
+    if (++I == E) {
+      H.HandleIncompleteSpecifier(Start, E - Start);
+      return true;
+    }
+  }
+  
+  // Look for the field width (if any).  Unlike printf, this is either
+  // a fixed integer or isn't present.
+  const OptionalAmount &Amt = clang::analyze_format_string::ParseAmount(I, E);
+  if (Amt.getHowSpecified() != OptionalAmount::NotSpecified) {
+    assert(Amt.getHowSpecified() == OptionalAmount::Constant);
+    FS.setFieldWidth(Amt);
+
+    if (I == E) {
+      // No more characters left?
+      H.HandleIncompleteSpecifier(Start, E - Start);
+      return true;
+    }
+  }
+  
+  // Look for the length modifier.
+  if (ParseLengthModifier(FS, I, E) && I == E) {
+      // No more characters left?
+    H.HandleIncompleteSpecifier(Start, E - Start);
+    return true;
+  }
+  
+  // Detect spurious null characters, which are likely errors.
+  if (*I == '\0') {
+    H.HandleNullChar(I);
+    return true;
+  }
+  
+  // Finally, look for the conversion specifier.
+  const char *conversionPosition = I++;
+  ScanfConversionSpecifier::Kind k = ScanfConversionSpecifier::InvalidSpecifier;
+  switch (*conversionPosition) {
+    default:
+      break;
+    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 '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::nArg; break;
+    case 'c': k = ConversionSpecifier::cArg; break;
+    case 'C': k = ConversionSpecifier::CArg; break;
+    case 'S': k = ConversionSpecifier::SArg; break;
+    case '[': k = ConversionSpecifier::ScanListArg; break;
+    case 'u': k = ConversionSpecifier::uArg; break;
+    case 'x': k = ConversionSpecifier::xArg; break;
+    case 'o': k = ConversionSpecifier::oArg; break;
+    case 's': k = ConversionSpecifier::sArg; break;
+    case 'p': k = ConversionSpecifier::pArg; break;
+  }
+  ScanfConversionSpecifier CS(conversionPosition, k);
+  if (k == ScanfConversionSpecifier::ScanListArg) {
+    if (!ParseScanList(H, CS, I, E))
+      return true;
+  }
+  FS.setConversionSpecifier(CS);
+  if (CS.consumesDataArgument() && !FS.getSuppressAssignment()
+      && !FS.usesPositionalArg())
+    FS.setArgIndex(argIndex++);
+  
+  // FIXME: '%' and '*' doesn't make sense.  Issue a warning.
+  // FIXME: 'ConsumedSoFar' and '*' doesn't make sense.
+  
+  if (k == ScanfConversionSpecifier::InvalidSpecifier) {
+    // Assume the conversion takes one argument.
+    return !H.HandleInvalidScanfConversionSpecifier(FS, Beg, I - Beg);
+  }
+  return ScanfSpecifierResult(Start, FS);
+}
+  
+bool clang::analyze_format_string::ParseScanfString(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 ScanfSpecifierResult &FSR = ParseScanfSpecifier(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.HandleScanfSpecifier(FSR.getValue(), FSR.getStart(),
+                                I - FSR.getStart())) {
+      return true;
+    }
+  }
+  assert(I == E && "Format string not exhausted");
+  return false;
+}
+
+
diff --git a/lib/Analysis/UninitializedValues.cpp b/lib/Analysis/UninitializedValues.cpp
index 7a62864..0f43efa 100644
--- a/lib/Analysis/UninitializedValues.cpp
+++ b/lib/Analysis/UninitializedValues.cpp
@@ -121,7 +121,7 @@
 
   if (VarDecl* VD = FindBlockVarDecl(B->getLHS()))
     if (B->isAssignmentOp()) {
-      if (B->getOpcode() == BinaryOperator::Assign)
+      if (B->getOpcode() == BO_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());
@@ -168,7 +168,7 @@
 
 bool TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
   switch (U->getOpcode()) {
-    case UnaryOperator::AddrOf: {
+    case UO_AddrOf: {
       VarDecl* VD = FindBlockVarDecl(U->getSubExpr());
       if (VD && VD->isBlockVarDecl())
         return V(VD,AD) = Initialized;
diff --git a/lib/Basic/Android.mk b/lib/Basic/Android.mk
index 128c258..7abe6d2 100644
--- a/lib/Basic/Android.mk
+++ b/lib/Basic/Android.mk
@@ -14,7 +14,8 @@
 	DiagnosticDriverKinds.inc	\
 	DiagnosticParseKinds.inc	\
 	DiagnosticAnalysisKinds.inc	\
-	DiagnosticFrontendKinds.inc
+	DiagnosticFrontendKinds.inc	\
+	arm_neon.inc
 
 clang_basic_SRC_FILES :=	\
 	Builtins.cpp	\
@@ -34,5 +35,6 @@
 LOCAL_MODULE:= libclangBasic
 
 include $(CLANG_HOST_BUILD_MK)
+include $(CLANG_VERSION_INC_MK)
 include $(CLANG_TBLGEN_RULES_MK)
 include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/lib/Basic/Builtins.cpp b/lib/Basic/Builtins.cpp
index 1a32937..040cdb5 100644
--- a/lib/Basic/Builtins.cpp
+++ b/lib/Basic/Builtins.cpp
@@ -93,3 +93,23 @@
   return true;
 }
 
+// FIXME: Refactor with isPrintfLike.
+bool
+Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx,
+                              bool &HasVAListArg) {
+  const char *Scanf = strpbrk(GetRecord(ID).Attributes, "sS");
+  if (!Scanf)
+    return false;
+
+  HasVAListArg = (*Scanf == 'S');
+
+  ++Scanf;
+  assert(*Scanf == ':' && "s or S specifier must have be followed by a ':'");
+  ++Scanf;
+
+  assert(strchr(Scanf, ':') && "printf specifier must end with a ':'");
+  FormatIdx = strtol(Scanf, 0, 10);
+  return true;
+}
+
+
diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt
index 1a89acc..87bf834 100644
--- a/lib/Basic/CMakeLists.txt
+++ b/lib/Basic/CMakeLists.txt
@@ -25,6 +25,8 @@
 endif()
 
 add_dependencies(clangBasic 
+                 ClangARMNeon
+                 ClangAttrList
                  ClangDiagnosticAnalysis
                  ClangDiagnosticAST
                  ClangDiagnosticCommon
@@ -34,3 +36,4 @@
                  ClangDiagnosticLex
                  ClangDiagnosticParse
                  ClangDiagnosticSema)
+                 
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index 1870195..d8095f4 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -38,6 +38,8 @@
 // Builtin Diagnostic information
 //===----------------------------------------------------------------------===//
 
+namespace {
+
 // Diagnostic classes.
 enum {
   CLASS_NOTE       = 0x01,
@@ -51,20 +53,21 @@
   unsigned Mapping : 3;
   unsigned Class : 3;
   bool SFINAE : 1;
+  unsigned Category : 5;
+  
   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 },
+#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP,SFINAE, CATEGORY)    \
+  { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, CATEGORY, DESC, GROUP },
 #include "clang/Basic/DiagnosticCommonKinds.inc"
 #include "clang/Basic/DiagnosticDriverKinds.inc"
 #include "clang/Basic/DiagnosticFrontendKinds.inc"
@@ -73,7 +76,7 @@
 #include "clang/Basic/DiagnosticASTKinds.inc"
 #include "clang/Basic/DiagnosticSemaKinds.inc"
 #include "clang/Basic/DiagnosticAnalysisKinds.inc"
-  { 0, 0, 0, 0, 0, 0}
+  { 0, 0, 0, 0, 0, 0, 0}
 };
 #undef DIAG
 
@@ -99,7 +102,7 @@
 #endif
 
   // Search the diagnostic table with a binary search.
-  StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0 };
+  StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0, 0 };
 
   const StaticDiagInfoRec *Found =
     std::lower_bound(StaticDiagInfo, StaticDiagInfo + NumDiagEntries, Find);
@@ -125,6 +128,35 @@
   return 0;
 }
 
+/// getWarningOptionForDiag - Return the category number that a specified
+/// DiagID belongs to, or 0 if no category.
+unsigned Diagnostic::getCategoryNumberForDiag(unsigned DiagID) {
+  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
+    return Info->Category;
+  return 0;
+}
+
+/// getCategoryNameFromID - Given a category ID, return the name of the
+/// category, an empty string if CategoryID is zero, or null if CategoryID is
+/// invalid.
+const char *Diagnostic::getCategoryNameFromID(unsigned CategoryID) {
+  // Second the table of options, sorted by name for fast binary lookup.
+  static const char *CategoryNameTable[] = {
+#define GET_CATEGORY_TABLE
+#define CATEGORY(X) X,
+#include "clang/Basic/DiagnosticGroups.inc"
+#undef GET_CATEGORY_TABLE
+    "<<END>>"
+  };
+  static const size_t CategoryNameTableSize =
+    sizeof(CategoryNameTable) / sizeof(CategoryNameTable[0])-1;
+  
+  if (CategoryID >= CategoryNameTableSize) return 0;
+  return CategoryNameTable[CategoryID];
+}
+
+
+
 Diagnostic::SFINAEResponse 
 Diagnostic::getDiagnosticSFINAEResponse(unsigned DiagID) {
   if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) {
@@ -213,34 +245,27 @@
 
 
 Diagnostic::Diagnostic(DiagnosticClient *client) : Client(client) {
+  ArgToStringFn = DummyArgToStringFn;
+  ArgToStringCookie = 0;
+
   AllExtensionsSilenced = 0;
   IgnoreAllWarnings = false;
   WarningsAsErrors = false;
   ErrorsAsFatal = false;
   SuppressSystemWarnings = false;
   SuppressAllDiagnostics = false;
+  ShowOverloads = Ovl_All;
   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);
+  DiagMappingsStack.clear();
+  DiagMappingsStack.push_back(DiagMappings());
+
+  Reset();
 }
 
 Diagnostic::~Diagnostic() {
@@ -299,10 +324,21 @@
       getBuiltinDiagClass(DiagID) != CLASS_EXTENSION)
     return false;
   
-  EnabledByDefault = StaticDiagInfo[DiagID].Mapping != diag::MAP_IGNORE;
+  EnabledByDefault = GetDefaultDiagMapping(DiagID) != diag::MAP_IGNORE;
   return true;
 }
 
+void Diagnostic::Reset() {
+  ErrorOccurred = false;
+  FatalErrorOccurred = false;
+  
+  NumWarnings = 0;
+  NumErrors = 0;
+  NumErrorsSuppressed = 0;
+  CurDiagID = ~0U;
+  LastDiagLevel = Ignored;
+  DelayedDiagID = 0;
+}
 
 /// getDescription - Given a diagnostic ID, return a description of the
 /// issue.
@@ -430,7 +466,7 @@
 struct WarningOption {
   const char  *Name;
   const short *Members;
-  const char  *SubGroups;
+  const short *SubGroups;
 };
 
 #define GET_DIAG_ARRAYS
@@ -460,9 +496,9 @@
   }
 
   // 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);
+  if (const short *SubGroups = Group->SubGroups) {
+    for (; *SubGroups != (short)-1; ++SubGroups)
+      MapGroupMembers(&OptionTable[(short)*SubGroups], Mapping, Diags);
   }
 }
 
@@ -540,11 +576,11 @@
   // If a fatal error has already been emitted, silence all subsequent
   // diagnostics.
   if (FatalErrorOccurred) {
-    if (DiagLevel >= Diagnostic::Error) {
+    if (DiagLevel >= Diagnostic::Error && Client->IncludeInDiagnosticCounts()) {
       ++NumErrors;
       ++NumErrorsSuppressed;
     }
-    
+
     return false;
   }
 
@@ -565,9 +601,11 @@
   }
 
   if (DiagLevel >= Diagnostic::Error) {
-    ErrorOccurred = true;
-    ++NumErrors;
-    
+    if (Client->IncludeInDiagnosticCounts()) {
+      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 &&
@@ -1011,8 +1049,7 @@
 
 StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level, 
                                    const DiagnosticInfo &Info)
-  : Level(Level), Loc(Info.getLocation()) 
-{
+  : Level(Level), Loc(Info.getLocation()) {
   llvm::SmallString<64> Message;
   Info.FormatDiagnostic(Message);
   this->Message.assign(Message.begin(), Message.end());
@@ -1099,6 +1136,7 @@
       
       WriteSourceLocation(OS, SM, R->getBegin());
       WriteSourceLocation(OS, SM, R->getEnd());
+      WriteUnsigned(OS, R->isTokenRange());
     }
   }
 
@@ -1114,11 +1152,6 @@
       break;
     }
 
-    if (F->InsertionLoc.isValid() && F->InsertionLoc.isMacroID()) {
-      NumFixIts = 0;
-      break;
-    }
-
     ++NumFixIts;
   }
 
@@ -1127,7 +1160,7 @@
   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);
+    WriteUnsigned(OS, F->RemoveRange.isTokenRange());
     WriteString(OS, F->CodeToInsert);
   }
 }
@@ -1240,11 +1273,14 @@
     return Diag;
   for (unsigned I = 0; I != NumSourceRanges; ++I) {
     SourceLocation Begin, End;
+    unsigned IsTokenRange;
     if (ReadSourceLocation(FM, SM, Memory, MemoryEnd, Begin) ||
-        ReadSourceLocation(FM, SM, Memory, MemoryEnd, End))
+        ReadSourceLocation(FM, SM, Memory, MemoryEnd, End) ||
+        ReadUnsigned(Memory, MemoryEnd, IsTokenRange))
       return Diag;
 
-    Diag.Ranges.push_back(SourceRange(Begin, End));
+    Diag.Ranges.push_back(CharSourceRange(SourceRange(Begin, End),
+                                          IsTokenRange));
   }
 
   // Read the fix-it hints.
@@ -1252,11 +1288,11 @@
   if (ReadUnsigned(Memory, MemoryEnd, NumFixIts))
     return Diag;
   for (unsigned I = 0; I != NumFixIts; ++I) {
-    SourceLocation RemoveBegin, RemoveEnd, InsertionLoc;
-    unsigned InsertLen = 0;
+    SourceLocation RemoveBegin, RemoveEnd;
+    unsigned InsertLen = 0, RemoveIsTokenRange;
     if (ReadSourceLocation(FM, SM, Memory, MemoryEnd, RemoveBegin) ||
         ReadSourceLocation(FM, SM, Memory, MemoryEnd, RemoveEnd) ||
-        ReadSourceLocation(FM, SM, Memory, MemoryEnd, InsertionLoc) ||
+        ReadUnsigned(Memory, MemoryEnd, RemoveIsTokenRange) ||
         ReadUnsigned(Memory, MemoryEnd, InsertLen) ||
         Memory + InsertLen > MemoryEnd) {
       Diag.FixIts.clear();
@@ -1264,8 +1300,8 @@
     }
 
     FixItHint Hint;
-    Hint.RemoveRange = SourceRange(RemoveBegin, RemoveEnd);
-    Hint.InsertionLoc = InsertionLoc;
+    Hint.RemoveRange = CharSourceRange(SourceRange(RemoveBegin, RemoveEnd),
+                                       RemoveIsTokenRange);
     Hint.CodeToInsert.assign(Memory, Memory + InsertLen);
     Memory += InsertLen;
     Diag.FixIts.push_back(Hint);
diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp
index c4296c3..565f8a6 100644
--- a/lib/Basic/FileManager.cpp
+++ b/lib/Basic/FileManager.cpp
@@ -19,6 +19,7 @@
 
 #include "clang/Basic/FileManager.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/System/Path.h"
 #include "llvm/Config/config.h"
@@ -83,6 +84,9 @@
 public:
   FileEntry &getFile(const char *Name, struct stat &StatBuf) {
     std::string FullPath(GetFullPath(Name));
+    
+    // LowercaseString because Windows filesystem is case insensitive.
+    FullPath = llvm::LowercaseString(FullPath);
     return UniqueFiles.GetOrCreateValue(
                                FullPath.c_str(),
                                FullPath.c_str() + FullPath.size()
@@ -331,8 +335,8 @@
 }
 
 const FileEntry *
-FileManager::getVirtualFile(const llvm::StringRef &Filename,
-                            off_t Size, time_t ModificationTime) {
+FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size,
+                            time_t ModificationTime) {
   const char *NameStart = Filename.begin(), *NameEnd = Filename.end();
 
   ++NumFileLookups;
@@ -365,6 +369,18 @@
   UFE->ModTime = ModificationTime;
   UFE->Dir     = DirInfo;
   UFE->UID     = NextFileUID++;
+  
+  // If this virtual file resolves to a file, also map that file to the 
+  // newly-created file entry.
+  const char *InterndFileName = NamedFileEnt.getKeyData();
+  struct stat StatBuf;
+  if (!stat_cached(InterndFileName, &StatBuf) &&
+      !S_ISDIR(StatBuf.st_mode)) {
+    llvm::sys::Path FilePath(InterndFileName);
+    FilePath.makeAbsolute();
+    FileEntries[FilePath.str()] = UFE;
+  }
+  
   return UFE;
 }
 
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index ed0de8c..e0d8571 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/lib/Basic/IdentifierTable.cpp
@@ -34,6 +34,8 @@
   IsPoisoned = false;
   IsCPPOperatorKeyword = false;
   NeedsHandleIdentifier = false;
+  IsFromAST = false;
+  RevertedTokenID = false;
   FETokenInfo = 0;
   Entry = 0;
 }
@@ -70,7 +72,8 @@
     KEYGNU = 16,
     KEYMS = 32,
     BOOLSUPPORT = 64,
-    KEYALTIVEC = 128
+    KEYALTIVEC = 128,
+    KEYNOMS = 256
   };
 }
 
@@ -94,12 +97,12 @@
   else if (LangOpts.Microsoft && (Flags & KEYMS)) AddResult = 1;
   else if (LangOpts.Bool && (Flags & BOOLSUPPORT)) AddResult = 2;
   else if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) AddResult = 2;
+  else if (!LangOpts.Microsoft && (Flags & KEYNOMS)) AddResult = 2;
 
   // Don't add this keyword if disabled in this language.
   if (AddResult == 0) return;
 
-  IdentifierInfo &Info = Table.get(Keyword);
-  Info.setTokenID(TokenCode);
+  IdentifierInfo &Info = Table.get(Keyword, TokenCode);
   Info.setIsExtensionToken(AddResult == 1);
 }
 
@@ -108,8 +111,7 @@
 static void AddCXXOperatorKeyword(llvm::StringRef Keyword,
                                   tok::TokenKind TokenCode,
                                   IdentifierTable &Table) {
-  IdentifierInfo &Info = Table.get(Keyword);
-  Info.setTokenID(TokenCode);
+  IdentifierInfo &Info = Table.get(Keyword, TokenCode);
   Info.setIsCPlusPlusOperatorKeyword();
 }
 
diff --git a/lib/Basic/Makefile b/lib/Basic/Makefile
index 58ac7eb..c156304 100644
--- a/lib/Basic/Makefile
+++ b/lib/Basic/Makefile
@@ -11,16 +11,10 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
+CLANG_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
+include $(CLANG_LEVEL)/Makefile
 
 SVN_REVISION := $(shell $(LLVM_SRC_ROOT)/utils/GetSourceVersion $(PROJ_SRC_DIR)/../..)
 
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index 3ecab1d..633d86c 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -32,7 +32,8 @@
 //===----------------------------------------------------------------------===//
 
 ContentCache::~ContentCache() {
-  delete Buffer.getPointer();
+  if (shouldFreeBuffer())
+    delete Buffer.getPointer();
 }
 
 /// getSizeBytesMapped - Returns the number of bytes actually mapped for
@@ -51,12 +52,14 @@
                              : (unsigned) Entry->getSize();
 }
 
-void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B) {
+void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B,
+                                 bool DoNotFree) {
   assert(B != Buffer.getPointer());
   
-  delete Buffer.getPointer();
+  if (shouldFreeBuffer())
+    delete Buffer.getPointer();
   Buffer.setPointer(B);
-  Buffer.setInt(false);
+  Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
 }
 
 const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
@@ -72,7 +75,6 @@
     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
@@ -99,7 +101,7 @@
         Diag.Report(FullSourceLoc(Loc, SM), diag::err_cannot_open_file)
           << Entry->getName() << ErrorStr;
 
-      Buffer.setInt(true);
+      Buffer.setInt(Buffer.getInt() | InvalidFlag);
 
     // 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
@@ -119,14 +121,14 @@
         Diag.Report(FullSourceLoc(Loc, SM), diag::err_file_modified)
           << Entry->getName();
 
-      Buffer.setInt(true);
+      Buffer.setInt(Buffer.getInt() | InvalidFlag);
 #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()) {
+    if (!isBufferInvalid()) {
       llvm::StringRef BufStr = Buffer.getPointer()->getBuffer();
       const char *BOM = 0;
       if (BufStr.startswith("\xFE\xBB\xBF"))
@@ -161,7 +163,7 @@
   }
   
   if (Invalid)
-    *Invalid = Buffer.getInt();
+    *Invalid = isBufferInvalid();
   
   return Buffer.getPointer();
 }
@@ -422,9 +424,12 @@
                                            unsigned NextOffset) {
   ExternalSLocEntries = Source;
   this->NextOffset = NextOffset;
+  unsigned CurPrealloc = SLocEntryLoaded.size();
+  // If we've ever preallocated, we must not count the dummy entry.
+  if (CurPrealloc) --CurPrealloc;
   SLocEntryLoaded.resize(NumSLocEntries + 1);
   SLocEntryLoaded[0] = true;
-  SLocEntryTable.resize(SLocEntryTable.size() + NumSLocEntries);
+  SLocEntryTable.resize(SLocEntryTable.size() + NumSLocEntries - CurPrealloc);
 }
 
 void SourceManager::ClearPreallocatedSLocEntries() {
@@ -448,7 +453,7 @@
 // Methods to create new FileID's and instantiations.
 //===----------------------------------------------------------------------===//
 
-/// createFileID - Create a new fileID for the specified ContentCache and
+/// 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,
@@ -521,12 +526,13 @@
 }
 
 bool SourceManager::overrideFileContents(const FileEntry *SourceFile,
-                                         const llvm::MemoryBuffer *Buffer) {
+                                         const llvm::MemoryBuffer *Buffer,
+                                         bool DoNotFree) {
   const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
   if (IR == 0)
     return true;
 
-  const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(Buffer);
+  const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(Buffer, DoNotFree);
   return false;
 }
 
@@ -1154,6 +1160,27 @@
   return getLocForStartOfFile(FirstFID).getFileLocWithOffset(FilePos + Col - 1);
 }
 
+/// Given a decomposed source location, move it up the include/instantiation
+/// stack to the parent source location.  If this is possible, return the
+/// decomposed version of the parent in Loc and return false.  If Loc is the
+/// top-level entry, return true and don't modify it.
+static bool MoveUpIncludeHierarchy(std::pair<FileID, unsigned> &Loc,
+                                   const SourceManager &SM) {
+  SourceLocation UpperLoc;
+  const SrcMgr::SLocEntry &Entry = SM.getSLocEntry(Loc.first);
+  if (Entry.isInstantiation())
+    UpperLoc = Entry.getInstantiation().getInstantiationLocStart();
+  else
+    UpperLoc = Entry.getFile().getIncludeLoc();
+  
+  if (UpperLoc.isInvalid())
+    return true; // We reached the top.
+  
+  Loc = SM.getDecomposedLoc(UpperLoc);
+  return false;
+}
+  
+
 /// \brief Determines the order of 2 source locations in the translation unit.
 ///
 /// \returns true if LHS source location comes before RHS, false otherwise.
@@ -1172,78 +1199,74 @@
 
   // If we are comparing a source location with multiple locations in the same
   // file, we get a big win by caching the result.
+  if (IsBeforeInTUCache.isCacheValid(LOffs.first, ROffs.first))
+    return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second);
 
-  if (LastLFIDForBeforeTUCheck == LOffs.first &&
-      LastRFIDForBeforeTUCheck == ROffs.first)
-    return LastResForBeforeTUCheck;
-
-  LastLFIDForBeforeTUCheck = LOffs.first;
-  LastRFIDForBeforeTUCheck = ROffs.first;
+  // Okay, we missed in the cache, start updating the cache for this query.
+  IsBeforeInTUCache.setQueryFIDs(LOffs.first, ROffs.first);
 
   // "Traverse" the include/instantiation stacks of both locations and try to
-  // find a common "ancestor".
+  // find a common "ancestor".  FileIDs build a tree-like structure that
+  // reflects the #include hierarchy, and this algorithm needs to find the
+  // nearest common ancestor between the two locations.  For example, if you
+  // have a.c that includes b.h and c.h, and are comparing a location in b.h to
+  // a location in c.h, we need to find that their nearest common ancestor is
+  // a.c, and compare the locations of the two #includes to find their relative
+  // ordering.
   //
-  // 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".
+  // SourceManager assigns FileIDs in order of parsing.  This means that an
+  // includee always has a larger FileID than an includer.  While you might
+  // think that we could just compare the FileID's here, that doesn't work to
+  // compare a point at the end of a.c with a point within c.h.  Though c.h has
+  // a larger FileID, we have to compare the include point of c.h to the
+  // location in a.c.
+  //
+  // Despite not being able to directly compare FileID's, we can tell that a
+  // larger FileID is necessarily more deeply nested than a lower one and use
+  // this information to walk up the tree to the nearest common ancestor.
+  do {
+    // If LOffs is larger than ROffs, then LOffs must be more deeply nested than
+    // ROffs, walk up the #include chain.
+    if (LOffs.first.ID > ROffs.first.ID) {
+      if (MoveUpIncludeHierarchy(LOffs, *this))
+        break; // We reached the top.
+      
+    } else {
+      // Otherwise, ROffs is larger than LOffs, so ROffs must be more deeply
+      // nested than LOffs, walk up the #include chain.
+      if (MoveUpIncludeHierarchy(ROffs, *this))
+        break; // We reached the top.
+    }
+  } while (LOffs.first != ROffs.first);
 
-  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;
+  // If we exited because we found a nearest common ancestor, compare the
+  // locations within the common file and cache them.
+  if (LOffs.first == ROffs.first) {
+    IsBeforeInTUCache.setCommonLoc(LOffs.first, LOffs.second, ROffs.second);
+    return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second);
   }
 
   // There is no common ancestor, most probably because one location is in the
-  // predefines buffer.
-  //
+  // predefines buffer or an AST file.
   // FIXME: We should rearrange the external interface so this simply never
   // happens; it can't conceptually happen. Also see PR5662.
+  IsBeforeInTUCache.setQueryFIDs(FileID(), FileID()); // Don't try caching.
 
+  // Zip both entries up to the top level record.
+  while (!MoveUpIncludeHierarchy(LOffs, *this)) /*empty*/;
+  while (!MoveUpIncludeHierarchy(ROffs, *this)) /*empty*/;
+  
   // 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;
+  
+  // Strip off macro instantation locations, going up to the top-level File
+  // SLocEntry.
+  bool LIsMB = getFileEntryForID(LOffs.first) == 0;
+  bool RIsMB = getFileEntryForID(ROffs.first) == 0;
   if (LIsMB != RIsMB)
-    return LastResForBeforeTUCheck = LIsMB;
+    return LIsMB;
 
   // Otherwise, just assume FileIDs were created in order.
-  return LastResForBeforeTUCheck = (LOffs.first < ROffs.first);
+  return LOffs.first < ROffs.first;
 }
 
 /// PrintStats - Print statistics to stderr.
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index 4c0c59a..6d42883 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/lib/Basic/TargetInfo.cpp
@@ -34,6 +34,8 @@
   DoubleAlign = 64;
   LongDoubleWidth = 64;
   LongDoubleAlign = 64;
+  LargeArrayMinWidth = 0;
+  LargeArrayAlign = 0;
   SizeType = UnsignedLong;
   PtrDiffType = SignedLong;
   IntMaxType = SignedLongLong;
@@ -52,6 +54,13 @@
   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 = "_";
+  HasAlignMac68kSupport = false;
+
+  // Default to no types using fpret.
+  RealTypeUsesObjCFPRet = 0;
+
+  // Default to using the Itanium ABI.
+  CXXABI = CXXABI_Itanium;
 }
 
 // Out of line virtual dtor for TargetInfo.
@@ -281,6 +290,15 @@
       Info.setAllowsRegister();
       Info.setAllowsMemory();
       break;
+    case ',': // multiple alternative constraint.  Pass it.
+      Name++;
+      // Handle additional optional '=' or '+' modifiers.
+      if (*Name == '=' || *Name == '+')
+        Name++;
+      break;
+    case '?': // Disparage slightly code.
+    case '!': // Disparage severly.
+      break;  // Pass them.
     }
 
     Name++;
@@ -344,6 +362,7 @@
       if (!resolveSymbolicName(Name, OutputConstraints, NumOutputs, Index))
         return false;
 
+      Info.setTiedOperand(Index, OutputConstraints[Index]);
       break;
     }
     case '%': // commutative
@@ -374,6 +393,11 @@
       Info.setAllowsRegister();
       Info.setAllowsMemory();
       break;
+    case ',': // multiple alternative constraint.  Ignore comma.
+      break;
+    case '?': // Disparage slightly code.
+    case '!': // Disparage severly.
+      break;  // Pass them.
     }
 
     Name++;
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 3d5048c..ebda7fb 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -150,7 +150,7 @@
 public:
   DarwinTargetInfo(const std::string& triple) :
     OSTargetInfo<Target>(triple) {
-      this->TLSSupported = false;
+      this->TLSSupported = llvm::Triple(triple).getDarwinMajorNumber() > 10;
     }
 
   virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const {
@@ -160,6 +160,12 @@
     return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
                                                        TAA, StubSize);
   }
+  
+  virtual const char *getStaticInitSectionSpecifier() const {
+    // FIXME: We should return 0 when building kexts.
+    return "__TEXT,__StaticInit,regular,pure_instructions";
+  }
+  
 };
 
 
@@ -206,6 +212,30 @@
     }
 };
 
+// Minix Target
+template<typename Target>
+class MinixTargetInfo : public OSTargetInfo<Target> {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const {
+    // Minix defines
+
+    Builder.defineMacro("__minix", "3");
+    Builder.defineMacro("_EM_WSIZE", "4");
+    Builder.defineMacro("_EM_PSIZE", "4");
+    Builder.defineMacro("_EM_SSIZE", "2");
+    Builder.defineMacro("_EM_LSIZE", "4");
+    Builder.defineMacro("_EM_FSIZE", "4");
+    Builder.defineMacro("_EM_DSIZE", "8");
+    DefineStd(Builder, "unix", Opts);
+  }
+public:
+  MinixTargetInfo(const std::string &triple)
+    : OSTargetInfo<Target>(triple) {
+      this->UserLabelPrefix = "";
+    }
+};
+
 // Linux target
 template<typename Target>
 class LinuxTargetInfo : public OSTargetInfo<Target> {
@@ -299,13 +329,20 @@
     Builder.defineMacro("__CELLOS_LV2__");
     Builder.defineMacro("__ELF__");
     Builder.defineMacro("__LP32__");
+    Builder.defineMacro("_ARCH_PPC64");
+    Builder.defineMacro("__powerpc64__");
   }
 public:
   PS3PPUTargetInfo(const std::string& triple)
     : OSTargetInfo<Target>(triple) {
     this->UserLabelPrefix = "";
     this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32;
+    this->IntMaxType = TargetInfo::SignedLongLong;
+    this->UIntMaxType = TargetInfo::UnsignedLongLong;
+    this->Int64Type = TargetInfo::SignedLongLong;
     this->SizeType = TargetInfo::UnsignedInt;
+    this->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";
   }
 };
 
@@ -413,12 +450,98 @@
     switch (*Name) {
     default: return false;
     case 'O': // Zero
-      return true;
+      break;
     case 'b': // Base register
     case 'f': // Floating point register
       Info.setAllowsRegister();
-      return true;
+      break;
+    // FIXME: The following are added to allow parsing.
+    // I just took a guess at what the actions should be.
+    // Also, is more specific checking needed?  I.e. specific registers?
+    case 'd': // Floating point register (containing 64-bit value) 
+    case 'v': // Altivec vector register
+      Info.setAllowsRegister();
+      break;
+    case 'w':
+      switch (Name[1]) {
+        case 'd':// VSX vector register to hold vector double data 
+        case 'f':// VSX vector register to hold vector float data 
+        case 's':// VSX vector register to hold scalar float data 
+        case 'a':// Any VSX register 
+          break;
+        default:
+          return false;
+      }
+      Info.setAllowsRegister();
+      Name++; // Skip over 'w'.
+      break;
+    case 'h': // `MQ', `CTR', or `LINK' register 
+    case 'q': // `MQ' register 
+    case 'c': // `CTR' register 
+    case 'l': // `LINK' register 
+    case 'x': // `CR' register (condition register) number 0 
+    case 'y': // `CR' register (condition register) 
+    case 'z': // `XER[CA]' carry bit (part of the XER register) 
+      Info.setAllowsRegister();
+      break;
+    case 'I': // Signed 16-bit constant 
+    case 'J': // Unsigned 16-bit constant shifted left 16 bits
+              //  (use `L' instead for SImode constants) 
+    case 'K': // Unsigned 16-bit constant 
+    case 'L': // Signed 16-bit constant shifted left 16 bits 
+    case 'M': // Constant larger than 31 
+    case 'N': // Exact power of 2 
+    case 'P': // Constant whose negation is a signed 16-bit constant 
+    case 'G': // Floating point constant that can be loaded into a
+              // register with one instruction per word 
+    case 'H': // Integer/Floating point constant that can be loaded
+              // into a register using three instructions 
+      break;
+    case 'm': // Memory operand. Note that on PowerPC targets, m can
+              // include addresses that update the base register. It
+              // is therefore only safe to use `m' in an asm statement
+              // if that asm statement accesses the operand exactly once.
+              // The asm statement must also use `%U<opno>' as a
+              // placeholder for the "update" flag in the corresponding
+              // load or store instruction. For example: 
+              // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
+              // is correct but: 
+              // asm ("st %1,%0" : "=m" (mem) : "r" (val));
+              // is not. Use es rather than m if you don't want the base
+              // register to be updated. 
+    case 'e': 
+      if (Name[1] != 's')
+          return false;
+              // es: A "stable" memory operand; that is, one which does not
+              // include any automodification of the base register. Unlike
+              // `m', this constraint can be used in asm statements that
+              // might access the operand several times, or that might not
+              // access it at all.
+      Info.setAllowsMemory();
+      Name++; // Skip over 'e'.
+      break;
+    case 'Q': // Memory operand that is an offset from a register (it is
+              // usually better to use `m' or `es' in asm statements) 
+    case 'Z': // Memory operand that is an indexed or indirect from a
+              // register (it is usually better to use `m' or `es' in
+              // asm statements) 
+      Info.setAllowsMemory();
+      Info.setAllowsRegister();
+      break;
+    case 'R': // AIX TOC entry 
+    case 'a': // Address operand that is an indexed or indirect from a
+              // register (`p' is preferable for asm statements) 
+    case 'S': // Constant suitable as a 64-bit mask operand 
+    case 'T': // Constant suitable as a 32-bit mask operand 
+    case 'U': // System V Release 4 small data area reference 
+    case 't': // AND masks that can be performed by two rldic{l, r}
+              // instructions 
+    case 'W': // Vector constant that does not require memory 
+    case 'j': // Vector constant that is all zeros. 
+      break;
+    // End FIXME.
     }
+    return true;
   }
   virtual const char *getClobbers() const {
     return "";
@@ -600,6 +723,27 @@
 };
 } // end anonymous namespace.
 
+
+namespace {
+class DarwinPPCTargetInfo :
+  public DarwinTargetInfo<PPCTargetInfo> {
+public:
+  DarwinPPCTargetInfo(const std::string& triple)
+    : DarwinTargetInfo<PPCTargetInfo>(triple) {
+    HasAlignMac68kSupport = true;
+  }
+};
+
+class DarwinPPC64TargetInfo :
+  public DarwinTargetInfo<PPC64TargetInfo> {
+public:
+  DarwinPPC64TargetInfo(const std::string& triple)
+    : DarwinTargetInfo<PPC64TargetInfo>(triple) {
+    HasAlignMac68kSupport = true;
+  }
+};
+} // end anonymous namespace.
+
 namespace {
 // MBlaze abstract base class
 class MBlazeTargetInfo : public TargetInfo {
@@ -768,11 +912,12 @@
   } AMD3DNowLevel;
 
   bool HasAES;
-  
+  bool HasAVX;
+
 public:
   X86TargetInfo(const std::string& triple)
     : TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow),
-      HasAES(false) {
+      HasAES(false), HasAVX(false) {
     LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
   }
   virtual void getTargetBuiltins(const Builtin::Info *&Records,
@@ -819,6 +964,7 @@
   Features["sse41"] = false;
   Features["sse42"] = false;
   Features["aes"] = false;
+  Features["avx"] = false;
 
   // LLVM does not currently recognize this.
   // Features["sse4a"] = false;
@@ -902,6 +1048,8 @@
       Features["3dnow"] = Features["3dnowa"] = true;
     else if (Name == "aes")
       Features["aes"] = true;
+    else if (Name == "avx")
+      Features["avx"] = true;
   } else {
     if (Name == "mmx")
       Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
@@ -929,6 +1077,8 @@
       Features["3dnowa"] = false;
     else if (Name == "aes")
       Features["aes"] = false;
+    else if (Name == "avx")
+      Features["avx"] = false;
   }
 
   return true;
@@ -948,6 +1098,13 @@
       continue;
     }
 
+    // FIXME: Not sure yet how to treat AVX in regard to SSE levels.
+    // For now let it be enabled together with other SSE levels.
+    if (Features[i].substr(1) == "avx") {
+      HasAVX = true;
+      continue;
+    }
+
     assert(Features[i][0] == '+' && "Invalid target feature!");
     X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
       .Case("sse42", SSE42)
@@ -989,6 +1146,9 @@
   if (HasAES)
     Builder.defineMacro("__AES__");
 
+  if (HasAVX)
+    Builder.defineMacro("__AVX__");
+
   // Target properties.
   Builder.defineMacro("__LITTLE_ENDIAN__");
 
@@ -1042,6 +1202,15 @@
                                      TargetInfo::ConstraintInfo &Info) const {
   switch (*Name) {
   default: return false;
+  case 'Y': // first letter of a pair:
+    switch (*(Name+1)) {
+    default: return false;
+    case '0':  // First SSE register.
+    case 't':  // Any SSE register, when SSE2 is enabled.
+    case 'i':  // Any SSE register, when SSE2 and inter-unit moves enabled.
+    case 'm':  // any MMX register, when inter-unit moves enabled.
+      break;   // falls through to setAllowsRegister.
+  }
   case 'a': // eax.
   case 'b': // ebx.
   case 'c': // ecx.
@@ -1049,22 +1218,27 @@
   case 'S': // esi.
   case 'D': // edi.
   case 'A': // edx:eax.
+  case 'f': // any x87 floating point stack register.
   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 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
+  case 'l': // "Index" registers: any general register that can be used as an
+            // index in a base+index memory access.
+    Info.setAllowsRegister();
+    return true;
+  case 'C': // SSE floating point constant.
+  case 'G': // x87 floating point constant.
   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;
   }
+  return false;
 }
 
 std::string
@@ -1101,6 +1275,11 @@
     PtrDiffType = SignedInt;
     IntPtrType = SignedInt;
     RegParmMax = 3;
+
+    // Use fpret for all types.
+    RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
+                             (1 << TargetInfo::Double) |
+                             (1 << TargetInfo::LongDouble));
   }
   virtual const char *getVAListDeclaration() const {
     return "typedef char* __builtin_va_list;";
@@ -1138,6 +1317,7 @@
     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";
+    HasAlignMac68kSupport = true;
   }
 
 };
@@ -1183,6 +1363,8 @@
     // 300=386, 400=486, 500=Pentium, 600=Blend (default)
     // We lost the original triple, so we use the default.
     Builder.defineMacro("_M_IX86", "600");
+    Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
+    Builder.defineMacro("_STDCALL_SUPPORTED");
   }
 };
 } // end anonymous namespace
@@ -1238,7 +1420,7 @@
     SizeType = UnsignedLong;
     IntPtrType = SignedLong;
     PtrDiffType = SignedLong;
-  }                                       	
+  }
   virtual void getTargetDefines(const LangOptions &Opts,
                                 MacroBuilder &Builder) const {
     X86_32TargetInfo::getTargetDefines(Opts, Builder);
@@ -1256,6 +1438,8 @@
     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
     LongDoubleWidth = 128;
     LongDoubleAlign = 128;
+    LargeArrayMinWidth = 128;
+    LargeArrayAlign = 128;
     IntMaxType = SignedLong;
     UIntMaxType = UnsignedLong;
     Int64Type = SignedLong;
@@ -1264,6 +1448,9 @@
     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";
+
+    // Use fpret only for long double.
+    RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
   }
   virtual const char *getVAListDeclaration() const {
     return "typedef struct __va_list_tag {"
@@ -1292,7 +1479,10 @@
     TLSSupported = false;
     WCharType = UnsignedShort;
     LongWidth = LongAlign = 32;
-    DoubleAlign = LongLongAlign = 64;
+    DoubleAlign = LongLongAlign = 64;      
+    IntMaxType = SignedLongLong;
+    UIntMaxType = UnsignedLongLong;
+    Int64Type = SignedLongLong;
   }
   virtual void getTargetDefines(const LangOptions &Opts,
                                 MacroBuilder &Builder) const {
@@ -1314,9 +1504,7 @@
                                 MacroBuilder &Builder) const {
     WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
     Builder.defineMacro("_M_X64");
-  }
-  virtual const char *getVAListDeclaration() const {
-    return "typedef char* va_list;";
+    Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
   }
 };
 } // end anonymous namespace
@@ -1411,6 +1599,9 @@
                            "i64:64:64-f32:32:32-f64:64:64-"
                            "v64:64:64-v128:128:128-a0:0:64-n32");
     }
+
+    // ARM targets default to using the ARM C++ ABI.
+    CXXABI = CXXABI_ARM;
   }
   virtual const char *getABI() const { return ABI.c_str(); }
   virtual bool setABI(const std::string &Name) {
@@ -1614,18 +1805,27 @@
 };
 
 const char * const ARMTargetInfo::GCCRegNames[] = {
+  // Integer registers
   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
-  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+  "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
+
+  // Float registers
+  "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+  "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
+  "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
+  "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31"
+
+  // FIXME: Need double and NEON registers, but we need support for aliasing
+  // multiple registers for that.
 };
 
 void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
-                                       unsigned &NumNames) const {
+                                   unsigned &NumNames) const {
   Names = GCCRegNames;
   NumNames = llvm::array_lengthof(GCCRegNames);
 }
 
 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
-
   { { "a1" }, "r0" },
   { { "a2" }, "r1" },
   { { "a3" }, "r2" },
@@ -1639,9 +1839,9 @@
   { { "sl" }, "r10" },
   { { "fp" }, "r11" },
   { { "ip" }, "r12" },
-  { { "sp" }, "r13" },
-  { { "lr" }, "r14" },
-  { { "pc" }, "r15" },
+  { { "r13" }, "sp" },
+  { { "r14" }, "lr" },
+  { { "r15" }, "pc" },
 };
 
 void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
@@ -1669,7 +1869,9 @@
 
 public:
   DarwinARMTargetInfo(const std::string& triple)
-    : DarwinTargetInfo<ARMTargetInfo>(triple) {}
+    : DarwinTargetInfo<ARMTargetInfo>(triple) {
+    HasAlignMac68kSupport = true;
+  }
 };
 } // end anonymous namespace.
 
@@ -2291,6 +2493,8 @@
   case llvm::Triple::arm:
   case llvm::Triple::thumb:
     switch (os) {
+    case llvm::Triple::Linux:
+      return new LinuxTargetInfo<ARMTargetInfo>(T);
     case llvm::Triple::Darwin:
       return new DarwinARMTargetInfo(T);
     case llvm::Triple::FreeBSD:
@@ -2324,14 +2528,14 @@
 
   case llvm::Triple::ppc:
     if (os == llvm::Triple::Darwin)
-      return new DarwinTargetInfo<PPCTargetInfo>(T);
+      return new DarwinPPCTargetInfo(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);
+      return new DarwinPPC64TargetInfo(T);
     else if (os == llvm::Triple::Lv2)
       return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
     else if (os == llvm::Triple::FreeBSD)
@@ -2374,6 +2578,8 @@
       return new OpenBSDI386TargetInfo(T);
     case llvm::Triple::FreeBSD:
       return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
+    case llvm::Triple::Minix:
+      return new MinixTargetInfo<X86_32TargetInfo>(T);
     case llvm::Triple::Solaris:
       return new SolarisTargetInfo<X86_32TargetInfo>(T);
     case llvm::Triple::Cygwin:
@@ -2441,6 +2647,12 @@
     return 0;
   }
 
+  // Set the target C++ ABI.
+  if (!Opts.CXXABI.empty() && !Target->setCXXABI(Opts.CXXABI)) {
+    Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI;
+    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;
diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp
index 6d9bee8..036ee00 100644
--- a/lib/Basic/Version.cpp
+++ b/lib/Basic/Version.cpp
@@ -28,7 +28,8 @@
   if (End)
     URLEnd = End;
 
-  End = strstr(URL, "/clang/tools/clang");
+  // Strip off version from a build from an integration branch.
+  End = strstr(URL, "/src/tools/clang");
   if (End)
     URLEnd = End;
 
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index bc2cd46..bd5e342 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -8,6 +8,8 @@
 add_subdirectory(Analysis)
 add_subdirectory(Rewrite)
 add_subdirectory(Driver)
+add_subdirectory(Serialization)
 add_subdirectory(Frontend)
+add_subdirectory(FrontendTool)
 add_subdirectory(Index)
 add_subdirectory(Checker)
diff --git a/lib/Checker/AdjustedReturnValueChecker.cpp b/lib/Checker/AdjustedReturnValueChecker.cpp
index b92f2e7..0ed04fb 100644
--- a/lib/Checker/AdjustedReturnValueChecker.cpp
+++ b/lib/Checker/AdjustedReturnValueChecker.cpp
@@ -70,8 +70,7 @@
   }
   else if (const BlockDataRegion *BD = dyn_cast<BlockDataRegion>(callee)) {
     const BlockTextRegion *BR = BD->getCodeRegion();
-    const BlockPointerType *BT =
-      BR->getLocationType(C.getASTContext())->getAs<BlockPointerType>();
+    const BlockPointerType *BT=BR->getLocationType()->getAs<BlockPointerType>();
     const FunctionType *FT = BT->getPointeeType()->getAs<FunctionType>();
     actualResultTy = FT->getResultType();
   }
diff --git a/lib/Checker/AggExprVisitor.cpp b/lib/Checker/AggExprVisitor.cpp
index 343afec..e9c0b1e 100644
--- a/lib/Checker/AggExprVisitor.cpp
+++ b/lib/Checker/AggExprVisitor.cpp
@@ -38,8 +38,8 @@
   switch (E->getCastKind()) {
   default: 
     assert(0 && "Unhandled cast kind");
-  case CastExpr::CK_NoOp:
-  case CastExpr::CK_ConstructorConversion:
+  case CK_NoOp:
+  case CK_ConstructorConversion:
     Visit(E->getSubExpr());
     break;
   }
diff --git a/lib/Checker/AnalysisConsumer.cpp b/lib/Checker/AnalysisConsumer.cpp
new file mode 100644
index 0000000..ad5ccb5
--- /dev/null
+++ b/lib/Checker/AnalysisConsumer.cpp
@@ -0,0 +1,598 @@
+//===--- 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/Checker/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/Checker/PathDiagnosticClients.h"
+#include "GRExprEngineExperimentalChecks.h"
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/AnalyzerOptions.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();
+
+//===----------------------------------------------------------------------===//
+// 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;
+  Actions CXXMethodActions;
+  TUActions TranslationUnitActions; // Remove this.
+
+public:
+  ASTContext* Ctx;
+  const Preprocessor &PP;
+  const std::string OutDir;
+  AnalyzerOptions Opts;
+
+  // 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), 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)
+      return;
+
+    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);
+    CXXMethodActions.push_back(action);
+  }
+
+  void addTranslationUnitAction(TUAction action) {
+    TranslationUnitActions.push_back(action);
+  }
+
+  void addObjCImplementationAction(CodeAction action) {
+    ObjCImplementationActions.push_back(action);
+  }
+
+  virtual void Initialize(ASTContext &Context) {
+    Ctx = &Context;
+    Mgr.reset(new AnalysisManager(*Ctx, PP.getDiagnostics(),
+                                  PP.getLangOptions(), PD,
+                                  CreateStoreMgr, CreateConstraintMgr,
+                                  /* Indexer */ 0, 
+                                  Opts.MaxNodes, Opts.MaxLoop,
+                                  Opts.VisualizeEGDot, Opts.VisualizeEGUbi,
+                                  Opts.PurgeDead, Opts.EagerlyAssume,
+                                  Opts.TrimGraph, Opts.InlineCall,
+                                  Opts.UnoptimizedCFG));
+  }
+
+  virtual void HandleTranslationUnit(ASTContext &C);
+  void HandleCode(Decl *D, Actions& actions);
+};
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// AnalysisConsumer implementation.
+//===----------------------------------------------------------------------===//
+
+void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
+
+  TranslationUnitDecl *TU = C.getTranslationUnitDecl();
+
+  for (DeclContext::decl_iterator I = TU->decls_begin(), E = TU->decls_end();
+       I != E; ++I) {
+    Decl *D = *I;
+
+    switch (D->getKind()) {
+    case Decl::CXXConstructor:
+    case Decl::CXXDestructor:
+    case Decl::CXXConversion:
+    case Decl::CXXMethod:
+    case Decl::Function: {
+      FunctionDecl* FD = cast<FunctionDecl>(D);
+      
+      if (FD->isThisDeclarationADefinition()) {
+        if (!Opts.AnalyzeSpecificFunction.empty() &&
+            FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction)
+          break;
+        DisplayFunction(FD);
+        HandleCode(FD, FunctionActions);
+      }
+      break;
+    }
+
+    case Decl::ObjCMethod: {
+      ObjCMethodDecl* MD = cast<ObjCMethodDecl>(D);
+      
+      if (MD->isThisDeclarationADefinition()) {
+        if (!Opts.AnalyzeSpecificFunction.empty() &&
+            Opts.AnalyzeSpecificFunction != MD->getSelector().getAsString())
+          break;
+        DisplayFunction(MD);
+        HandleCode(MD, ObjCMethodActions);
+      }
+      break;
+    }
+
+    case Decl::ObjCImplementation: {
+      ObjCImplementationDecl* ID = cast<ObjCImplementationDecl>(*I);
+      HandleCode(ID, ObjCImplementationActions);
+
+      for (ObjCImplementationDecl::method_iterator MI = ID->meth_begin(), 
+             ME = ID->meth_end(); MI != ME; ++MI) {
+        if ((*MI)->isThisDeclarationADefinition()) {
+          if (!Opts.AnalyzeSpecificFunction.empty() &&
+             Opts.AnalyzeSpecificFunction != (*MI)->getSelector().getAsString())
+            break;
+          HandleCode(*MI, ObjCMethodActions);
+        }
+      }
+      break;
+    }
+
+    default:
+      break;
+    }
+  }
+
+  for (TUActions::iterator I = TranslationUnitActions.begin(),
+                           E = TranslationUnitActions.end(); I != E; ++I) {
+    (*I)(*this, *Mgr, *TU);
+  }
+
+  // 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, Actions& actions) {
+
+  // Don't run the actions if an error has occured with parsing the file.
+  Diagnostic &Diags = PP.getDiagnostics();
+  if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred())
+    return;
+
+  // Don't run the actions on declarations in header files unless
+  // otherwise specified.
+  SourceManager &SM = Ctx->getSourceManager();
+  SourceLocation SL = SM.getInstantiationLoc(D->getLocation());
+  if (!Opts.AnalyzeAll && !SM.isFromMainFile(SL))
+    return;
+
+  // Clear the AnalysisManager of old AnalysisContexts.
+  Mgr->ClearContexts();
+
+  // Dispatch on the actions.
+  llvm::SmallVector<Decl*, 10> WL;
+  WL.push_back(D);
+
+  if (D->hasBody() && 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)) {
+    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)) {
+    CheckUninitializedValues(*c, mgr.getASTContext(), mgr.getDiagnostic());
+  }
+}
+
+
+static void ActionGRExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
+                               Decl *D,
+                               GRTransferFuncs* tf) {
+
+  llvm::OwningPtr<GRTransferFuncs> TF(tf);
+
+  // 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);
+
+  // Enable idempotent operation checking if it was explicitly turned on, or if
+  // we are running experimental checks (i.e. everything)
+  if (C.Opts.IdempotentOps || C.Opts.EnableExperimentalChecks
+      || C.Opts.EnableExperimentalInternalChecks)
+    RegisterIdempotentOperationChecker(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, 0), 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)) {
+    L->dumpBlockLiveness(mgr.getSourceManager());
+  }
+}
+
+static void ActionCFGDump(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) {
+  if (CFG *cfg = mgr.getCFG(D)) {
+    cfg->dump(mgr.getLangOptions());
+  }
+}
+
+static void ActionCFGView(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) {
+  if (CFG *cfg = mgr.getCFG(D)) {
+    cfg->viewCFG(mgr.getLangOptions());
+  }
+}
+
+static void ActionSecuritySyntacticChecks(AnalysisConsumer &C,
+                                          AnalysisManager &mgr, Decl *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;
+  BugReporter BR(mgr);
+  CheckObjCDealloc(cast<ObjCImplementationDecl>(D), mgr.getLangOptions(), BR);
+}
+
+static void ActionWarnObjCUnusedIvars(AnalysisConsumer &C, AnalysisManager& mgr,
+                                      Decl *D) {
+  BugReporter BR(mgr);
+  CheckObjCUnusedIvar(cast<ObjCImplementationDecl>(D), BR);
+}
+
+static void ActionWarnObjCMethSigs(AnalysisConsumer &C, AnalysisManager& mgr,
+                                   Decl *D) {
+  BugReporter BR(mgr);
+  CheckObjCInstMethSignature(cast<ObjCImplementationDecl>(D), BR);
+}
+
+static void ActionWarnSizeofPointer(AnalysisConsumer &C, AnalysisManager &mgr,
+                                    Decl *D) {
+  BugReporter BR(mgr);
+  CheckSizeofPointer(D, BR);
+}
+
+//===----------------------------------------------------------------------===//
+// 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/Checker/AnalysisManager.cpp b/lib/Checker/AnalysisManager.cpp
new file mode 100644
index 0000000..339cdab
--- /dev/null
+++ b/lib/Checker/AnalysisManager.cpp
@@ -0,0 +1,31 @@
+//===-- AnalysisManager.cpp -------------------------------------*- 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/AnalysisManager.h"
+#include "clang/Index/Entity.h"
+#include "clang/Index/Indexer.h"
+
+using namespace clang;
+
+const AnalysisContext *
+AnalysisManager::getAnalysisContextInAnotherTU(const Decl *D) {
+  idx::Entity Ent = idx::Entity::get(const_cast<Decl *>(D), 
+                                     Idxer->getProgram());
+  FunctionDecl *FuncDef;
+  idx::TranslationUnit *TU;
+  llvm::tie(FuncDef, TU) = Idxer->getDefinitionFor(Ent);
+
+  if (FuncDef == 0)
+    return 0;
+
+  // This AnalysisContext wraps function definition in another translation unit.
+  // But it is still owned by the AnalysisManager associated with the current
+  // translation unit.
+  return AnaCtxMgr.getContext(FuncDef, TU);
+}
diff --git a/lib/Checker/ArrayBoundChecker.cpp b/lib/Checker/ArrayBoundChecker.cpp
index 746b3f9..98345bd 100644
--- a/lib/Checker/ArrayBoundChecker.cpp
+++ b/lib/Checker/ArrayBoundChecker.cpp
@@ -58,7 +58,7 @@
   // Get the size of the array.
   DefinedOrUnknownSVal NumElements 
     = C.getStoreManager().getSizeInElements(state, ER->getSuperRegion(), 
-                                         ER->getValueType(C.getASTContext()));
+                                            ER->getValueType());
 
   const GRState *StInBound = state->AssumeInBound(Idx, NumElements, true);
   const GRState *StOutBound = state->AssumeInBound(Idx, NumElements, false);
diff --git a/lib/Checker/AttrNonNullChecker.cpp b/lib/Checker/AttrNonNullChecker.cpp
index 309a74c..d0bccb2 100644
--- a/lib/Checker/AttrNonNullChecker.cpp
+++ b/lib/Checker/AttrNonNullChecker.cpp
@@ -60,9 +60,10 @@
     if (!Att->isNonNull(idx))
       continue;
 
-    const SVal &V = state->getSVal(*I);
-    const DefinedSVal *DV = dyn_cast<DefinedSVal>(&V);
+    SVal V = state->getSVal(*I);
+    DefinedSVal *DV = dyn_cast<DefinedSVal>(&V);
 
+    // If the value is unknown or undefined, we can't perform this check.
     if (!DV)
       continue;
 
diff --git a/lib/Checker/BasicConstraintManager.cpp b/lib/Checker/BasicConstraintManager.cpp
index e89546e..eee5c59 100644
--- a/lib/Checker/BasicConstraintManager.cpp
+++ b/lib/Checker/BasicConstraintManager.cpp
@@ -54,22 +54,28 @@
       ISetFactory(statemgr.getAllocator()) {}
 
   const GRState* AssumeSymNE(const GRState* state, SymbolRef sym,
-                             const llvm::APSInt& V);
+                             const llvm::APSInt& V,
+                             const llvm::APSInt& Adjustment);
 
   const GRState* AssumeSymEQ(const GRState* state, SymbolRef sym,
-                             const llvm::APSInt& V);
+                             const llvm::APSInt& V,
+                             const llvm::APSInt& Adjustment);
 
   const GRState* AssumeSymLT(const GRState* state, SymbolRef sym,
-                             const llvm::APSInt& V);
+                             const llvm::APSInt& V,
+                             const llvm::APSInt& Adjustment);
 
   const GRState* AssumeSymGT(const GRState* state, SymbolRef sym,
-                             const llvm::APSInt& V);
+                             const llvm::APSInt& V,
+                             const llvm::APSInt& Adjustment);
 
   const GRState* AssumeSymGE(const GRState* state, SymbolRef sym,
-                             const llvm::APSInt& V);
+                             const llvm::APSInt& V,
+                             const llvm::APSInt& Adjustment);
 
   const GRState* AssumeSymLE(const GRState* state, SymbolRef sym,
-                             const llvm::APSInt& V);
+                             const llvm::APSInt& V,
+                             const llvm::APSInt& Adjustment);
 
   const GRState* AddEQ(const GRState* state, SymbolRef sym, const llvm::APSInt& V);
 
@@ -94,46 +100,52 @@
   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.
+                                    const llvm::APSInt &V,
+                                    const llvm::APSInt &Adjustment) {
+  // First, determine if sym == X, where X+Adjustment != V.
+  llvm::APSInt Adjusted = V-Adjustment;
   if (const llvm::APSInt* X = getSymVal(state, sym)) {
-    bool isFeasible = (*X != V);
+    bool isFeasible = (*X != Adjusted);
     return isFeasible ? state : NULL;
   }
 
-  // Second, determine if sym != V.
-  if (isNotEqual(state, sym, V))
+  // Second, determine if sym+Adjustment != V.
+  if (isNotEqual(state, sym, Adjusted))
     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);
+  return AddNE(state, sym, Adjusted);
 }
 
-const GRState *BasicConstraintManager::AssumeSymEQ(const GRState *state,
-                                                   SymbolRef sym,
-                                                   const llvm::APSInt &V) {
-  // First, determine if sym == X, where X != V.
+const GRState*
+BasicConstraintManager::AssumeSymEQ(const GRState *state, SymbolRef sym,
+                                    const llvm::APSInt &V,
+                                    const llvm::APSInt &Adjustment) {
+  // First, determine if sym == X, where X+Adjustment != V.
+  llvm::APSInt Adjusted = V-Adjustment;
   if (const llvm::APSInt* X = getSymVal(state, sym)) {
-    bool isFeasible = *X == V;
+    bool isFeasible = (*X == Adjusted);
     return isFeasible ? state : NULL;
   }
 
-  // Second, determine if sym != V.
-  if (isNotEqual(state, sym, V))
+  // Second, determine if sym+Adjustment != V.
+  if (isNotEqual(state, sym, Adjusted))
     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);
+  return AddEQ(state, sym, Adjusted);
 }
 
-// These logic will be handled in another ConstraintManager.
-const GRState *BasicConstraintManager::AssumeSymLT(const GRState *state,
-                                                   SymbolRef sym,
-                                                   const llvm::APSInt& V) {
+// The logic for these will be handled in another ConstraintManager.
+const GRState*
+BasicConstraintManager::AssumeSymLT(const GRState *state, SymbolRef sym,
+                                    const llvm::APSInt &V,
+                                    const llvm::APSInt &Adjustment) {
   // 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.
@@ -141,13 +153,13 @@
   }
 
   // FIXME: For now have assuming x < y be the same as assuming sym != V;
-  return AssumeSymNE(state, sym, V);
+  return AssumeSymNE(state, sym, V, Adjustment);
 }
 
-const GRState *BasicConstraintManager::AssumeSymGT(const GRState *state,
-                                                   SymbolRef sym,
-                                                   const llvm::APSInt& V) {
-
+const GRState*
+BasicConstraintManager::AssumeSymGT(const GRState *state, SymbolRef sym,
+                                    const llvm::APSInt &V,
+                                    const llvm::APSInt &Adjustment) {
   // 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.
@@ -155,56 +167,60 @@
   }
 
   // FIXME: For now have assuming x > y be the same as assuming sym != V;
-  return AssumeSymNE(state, sym, V);
+  return AssumeSymNE(state, sym, V, Adjustment);
 }
 
-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).
+const GRState*
+BasicConstraintManager::AssumeSymGE(const GRState *state, SymbolRef sym,
+                                    const llvm::APSInt &V,
+                                    const llvm::APSInt &Adjustment) {
+  // Reject a path if the value of sym is a constant X and !(X+Adj >= V).
   if (const llvm::APSInt *X = getSymVal(state, sym)) {
-    bool isFeasible = *X >= V;
+    bool isFeasible = (*X >= V-Adjustment);
     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);
+    llvm::APSInt Adjusted = V-Adjustment;
+
+    // If we know that sym != V (after adjustment), then this condition
+    // is infeasible since there is no other value greater than V.
+    bool isFeasible = !isNotEqual(state, sym, Adjusted);
 
     // If the path is still feasible then as a consequence we know that
-    // 'sym == V' because we cannot have 'sym > V' (no larger values).
+    // 'sym+Adjustment == V' because there are no larger values.
     // Add this constraint.
-    return isFeasible ? AddEQ(state, sym, V) : NULL;
+    return isFeasible ? AddEQ(state, sym, Adjusted) : 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).
+BasicConstraintManager::AssumeSymLE(const GRState *state, SymbolRef sym,
+                                    const llvm::APSInt &V,
+                                    const llvm::APSInt &Adjustment) {
+  // Reject a path if the value of sym is a constant X and !(X+Adj <= V).
   if (const llvm::APSInt* X = getSymVal(state, sym)) {
-    bool isFeasible = *X <= V;
+    bool isFeasible = (*X <= V-Adjustment);
     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);
+    llvm::APSInt Adjusted = V-Adjustment;
+
+    // If we know that sym != V (after adjustment), then this condition
+    // is infeasible since there is no other value less than V.
+    bool isFeasible = !isNotEqual(state, sym, Adjusted);
 
     // If the path is still feasible then as a consequence we know that
-    // 'sym == V' because we cannot have 'sym < V' (no smaller values).
+    // 'sym+Adjustment == V' because there are no smaller values.
     // Add this constraint.
-    return isFeasible ? AddEQ(state, sym, V) : NULL;
+    return isFeasible ? AddEQ(state, sym, Adjusted) : NULL;
   }
 
   return state;
@@ -213,7 +229,7 @@
 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);
+  return state->set<ConstEq>(sym, &state->getBasicVals().getValue(V));
 }
 
 const GRState* BasicConstraintManager::AddNE(const GRState* state, SymbolRef sym,
@@ -224,7 +240,7 @@
   GRState::IntSetTy S = T ? *T : ISetFactory.GetEmptySet();
 
   // Now add V to the NE set.
-  S = ISetFactory.Add(S, &V);
+  S = ISetFactory.Add(S, &state->getBasicVals().getValue(V));
 
   // Create a new state with the old binding replaced.
   return state->set<ConstNotEq>(sym, S);
@@ -243,7 +259,7 @@
   const ConstNotEqTy::data_type* T = state->get<ConstNotEq>(sym);
 
   // See if V is present in the NE-set.
-  return T ? T->contains(&V) : false;
+  return T ? T->contains(&state->getBasicVals().getValue(V)) : false;
 }
 
 bool BasicConstraintManager::isEqual(const GRState* state, SymbolRef sym,
diff --git a/lib/Checker/BasicObjCFoundationChecks.cpp b/lib/Checker/BasicObjCFoundationChecks.cpp
index e7275ca..3c1a6d1 100644
--- a/lib/Checker/BasicObjCFoundationChecks.cpp
+++ b/lib/Checker/BasicObjCFoundationChecks.cpp
@@ -73,9 +73,6 @@
   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:
@@ -358,7 +355,7 @@
   if (!R)
     return false;
 
-  QualType T = Ctx.getCanonicalType(R->getValueType(Ctx));
+  QualType T = Ctx.getCanonicalType(R->getValueType());
 
   // FIXME: If the pointee isn't an integer type, should we flag a warning?
   //  People can do weird stuff with pointers.
@@ -415,59 +412,72 @@
 }
 
 //===----------------------------------------------------------------------===//
-// CFRetain/CFRelease auditing for null arguments.
+// CFRetain/CFRelease checking for null arguments.
 //===----------------------------------------------------------------------===//
 
 namespace {
-class AuditCFRetainRelease : public GRSimpleAPICheck {
+class CFRetainReleaseChecker : public CheckerVisitor<CFRetainReleaseChecker> {
   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){}
+  CFRetainReleaseChecker(ASTContext& Ctx): BT(NULL),
+    Retain(&Ctx.Idents.get("CFRetain")), Release(&Ctx.Idents.get("CFRelease"))
+    {}
 
-  ~AuditCFRetainRelease() {}
+  static void *getTag() { static int x = 0; return &x; }
 
-  bool Audit(ExplodedNode* N, GRStateManager&);
+  void PreVisitCallExpr(CheckerContext& C, const CallExpr* CE);
 };
 } // end anonymous namespace
 
 
-bool AuditCFRetainRelease::Audit(ExplodedNode* N, GRStateManager&) {
-  const CallExpr* CE = cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
-
+void CFRetainReleaseChecker::PreVisitCallExpr(CheckerContext& C,
+                                              const CallExpr* CE) {
   // If the CallExpr doesn't have exactly 1 argument just give up checking.
   if (CE->getNumArgs() != 1)
-    return false;
+    return;
 
-  // Check if we called CFRetain/CFRelease.
-  const GRState* state = N->getState();
+  // Get the function declaration of the callee.
+  const GRState* state = C.getState();
   SVal X = state->getSVal(CE->getCallee());
   const FunctionDecl* FD = X.getAsFunctionDecl();
 
   if (!FD)
-    return false;
+    return;
 
+  // Check if we called CFRetain/CFRelease.
   const IdentifierInfo *FuncII = FD->getIdentifier();
   if (!(FuncII == Retain || FuncII == Release))
-    return false;
+    return;
 
-  // 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)) {
+  // FIXME: The rest of this just checks that the argument is non-null.
+  // It should probably be refactored and combined with AttrNonNullChecker.
+
+  // Get the argument's value.
+  const Expr *Arg = CE->getArg(0);
+  SVal ArgVal = state->getSVal(Arg);
+  DefinedSVal *DefArgVal = dyn_cast<DefinedSVal>(&ArgVal);
+  if (!DefArgVal)
+    return;
+
+  // Get a NULL value.
+  ValueManager &ValMgr = C.getValueManager();
+  DefinedSVal Zero = cast<DefinedSVal>(ValMgr.makeZeroVal(Arg->getType()));
+
+  // Make an expression asserting that they're equal.
+  SValuator &SVator = ValMgr.getSValuator();
+  DefinedOrUnknownSVal ArgIsNull = SVator.EvalEQ(state, Zero, *DefArgVal);
+
+  // Are they equal?
+  const GRState *stateTrue, *stateFalse;
+  llvm::tie(stateTrue, stateFalse) = state->Assume(ArgIsNull);
+
+  if (stateTrue && !stateFalse) {
+    ExplodedNode *N = C.GenerateSink(stateTrue);
+    if (!N)
+      return;
+
     if (!BT)
       BT = new APIMisuse("null passed to CFRetain/CFRelease");
 
@@ -475,19 +485,16 @@
                             ? "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;
+    EnhancedBugReport *report = new EnhancedBugReport(*BT, description, N);
+    report->addRange(Arg->getSourceRange());
+    report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, Arg);
+
+    C.EmitReport(report);
+    return;
   }
 
-  return false;
-}
-
-
-GRSimpleAPICheck*
-clang::CreateAuditCFRetainRelease(ASTContext& Ctx, BugReporter& BR) {
-  return new AuditCFRetainRelease(Ctx, BR);
+  // From here on, we know the argument is non-null.
+  C.addTransition(stateFalse);
 }
 
 //===----------------------------------------------------------------------===//
@@ -521,11 +528,11 @@
   ObjCInterfaceDecl *Class = 0;
   switch (ME->getReceiverKind()) {
   case ObjCMessageExpr::Class:
-    Class = ME->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+    Class = ME->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
     break;
 
   case ObjCMessageExpr::SuperClass:
-    Class = ME->getSuperType()->getAs<ObjCInterfaceType>()->getDecl();
+    Class = ME->getSuperType()->getAs<ObjCObjectType>()->getInterface();
     break;
 
   case ObjCMessageExpr::Instance:
@@ -569,9 +576,10 @@
   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 CFRetainReleaseChecker(Ctx));
   Eng.registerCheck(new ClassReleaseChecker(Ctx));
 }
diff --git a/lib/Checker/BasicObjCFoundationChecks.h b/lib/Checker/BasicObjCFoundationChecks.h
index 679c6dc..8fb0570 100644
--- a/lib/Checker/BasicObjCFoundationChecks.h
+++ b/lib/Checker/BasicObjCFoundationChecks.h
@@ -30,9 +30,6 @@
 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);
 
diff --git a/lib/Checker/BasicStore.cpp b/lib/Checker/BasicStore.cpp
index 34470af..f82e1b2 100644
--- a/lib/Checker/BasicStore.cpp
+++ b/lib/Checker/BasicStore.cpp
@@ -46,9 +46,14 @@
 
   SVal Retrieve(Store store, Loc loc, QualType T = QualType());
 
-  Store InvalidateRegion(Store store, const MemRegion *R, const Expr *E, 
+  Store InvalidateRegion(Store store, const MemRegion *R, const Expr *E,
                          unsigned Count, InvalidatedSymbols *IS);
 
+  Store InvalidateRegions(Store store, const MemRegion * const *Begin,
+                          const MemRegion * const *End, const Expr *E,
+                          unsigned Count, InvalidatedSymbols *IS,
+                          bool invalidateGlobals, InvalidatedRegions *Regions);
+
   Store scanForIvars(Stmt *B, const Decl* SelfDecl,
                      const MemRegion *SelfRegion, Store St);
 
@@ -56,11 +61,6 @@
   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;
@@ -72,8 +72,7 @@
 
   /// 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,
+  Store RemoveDeadBindings(Store store, const StackFrameContext *LCtx,
                            SymbolReaper& SymReaper,
                           llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
 
@@ -98,8 +97,6 @@
 
 private:
   SVal LazyRetrieve(Store store, const TypedRegion *R);
-
-  ASTContext& getContext() { return StateMgr.getContext(); }
 };
 
 } // end anonymous namespace
@@ -144,9 +141,30 @@
 
   // Globals and parameters start with symbolic values.
   // Local variables initially are undefined.
+
+  // Non-static globals may have had their values reset by InvalidateRegions.
+  const MemSpaceRegion *MS = VR->getMemorySpace();
+  if (isa<NonStaticGlobalSpaceRegion>(MS)) {
+    BindingsTy B = GetBindings(store);
+    // FIXME: Copy-and-pasted from RegionStore.cpp.
+    if (BindingsTy::data_type *Val = B.lookup(MS)) {
+      if (SymbolRef parentSym = Val->getAsSymbol())
+        return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
+
+      if (Val->isZeroConstant())
+        return ValMgr.makeZeroVal(T);
+
+      if (Val->isUnknownOrUndef())
+        return *Val;
+
+      assert(0 && "Unknown default value.");
+    }
+  }
+
   if (VR->hasGlobalsOrParametersStorage() ||
       isa<UnknownSpaceRegion>(VR->getMemorySpace()))
     return ValMgr.getRegionValueSymbolVal(R);
+
   return UndefinedVal();
 }
 
@@ -194,7 +212,13 @@
     return store;
 
   const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
-  ASTContext &C = StateMgr.getContext();
+
+  // Special case: a default symbol assigned to the NonStaticGlobalsSpaceRegion
+  //  that is used to derive other symbols.
+  if (isa<NonStaticGlobalSpaceRegion>(R)) {
+    BindingsTy B = GetBindings(store);
+    return VBFactory.Add(B, R, V).getRoot();
+  }
 
   // Special case: handle store of pointer values (Loc) to pointers via
   // a cast to intXX_t*, void*, etc.  This is needed to handle
@@ -202,9 +226,9 @@
   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);
+      QualType T = ER->getLocationType();
 
-      if (isHigherOrderRawPtr(T, C))
+      if (isHigherOrderRawPtr(T, Ctx))
         R = ER->getSuperRegion();
     }
 
@@ -215,7 +239,7 @@
 
   // 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())
+  if (TyR->isBoundable() && TyR->getValueType()->isArrayType())
     return store;
 
   if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&V)) {
@@ -225,7 +249,7 @@
     // 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)))
+    if (TyR->isBoundable() && Loc::IsLocType(TyR->getValueType()))
       V = X->getLoc();
   }
 
@@ -251,7 +275,7 @@
   }
 }
 
-Store BasicStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
+Store BasicStoreManager::RemoveDeadBindings(Store store,
                                             const StackFrameContext *LCtx,
                                             SymbolReaper& SymReaper,
                            llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
@@ -262,14 +286,14 @@
   // 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))
+      if (SymReaper.isLive(VR))
         RegionRoots.push_back(VR);
       else
         continue;
     }
-    else if (isa<ObjCIvarRegion>(I.getKey())) {
+    else if (isa<ObjCIvarRegion>(I.getKey()) ||
+             isa<NonStaticGlobalSpaceRegion>(I.getKey()))
       RegionRoots.push_back(I.getKey());
-    }
     else
       continue;
 
@@ -291,7 +315,8 @@
         SymReaper.markLive(SymR->getSymbol());
         break;
       }
-      else if (isa<VarRegion>(MR) || isa<ObjCIvarRegion>(MR)) {
+      else if (isa<VarRegion>(MR) || isa<ObjCIvarRegion>(MR) ||
+               isa<NonStaticGlobalSpaceRegion>(MR)) {
         if (Marked.count(MR))
           break;
 
@@ -369,10 +394,10 @@
   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);
+    const NamedDecl* ND = I->first;
 
     // Handle implicit parameters.
-    if (ImplicitParamDecl* PD = dyn_cast<ImplicitParamDecl>(ND)) {
+    if (const ImplicitParamDecl* PD = dyn_cast<ImplicitParamDecl>(ND)) {
       const Decl& CD = *InitLoc->getDecl();
       if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(&CD)) {
         if (MD->getSelfDecl() == PD) {
@@ -412,11 +437,11 @@
     // will not be called more than once.
 
     // Static global variables should not be visited here.
-    assert(!(VD->getStorageClass() == VarDecl::Static &&
+    assert(!(VD->getStorageClass() == SC_Static &&
              VD->isFileVarDecl()));
 
     // Process static variables.
-    if (VD->getStorageClass() == VarDecl::Static) {
+    if (VD->getStorageClass() == SC_Static) {
       // C99: 6.7.8 Initialization
       //  If an object that has static storage duration is not initialized
       //  explicitly, then:
@@ -428,12 +453,9 @@
         if (Loc::IsLocType(T))
           store = Bind(store, loc::MemRegionVal(VR),
                        loc::ConcreteInt(BasicVals.getValue(0, T)));
-        else if (T->isIntegerType())
+        else if (T->isIntegerType() && T->isScalarType())
           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);
       }
@@ -441,7 +463,8 @@
   } else {
     // Process local scalar variables.
     QualType T = VD->getType();
-    if (ValMgr.getSymbolManager().canSymbolicate(T)) {
+    // BasicStore only supports scalars.
+    if (T->isScalarType() && ValMgr.getSymbolManager().canSymbolicate(T)) {
       SVal V = InitVal ? *InitVal : UndefinedVal();
       store = Bind(store, loc::MemRegionVal(VR), V);
     }
@@ -473,7 +496,8 @@
   BindingsTy B = GetBindings(store);
 
   for (BindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I)
-    f.HandleBinding(*this, store, I.getKey(), I.getData());
+    if (!f.HandleBinding(*this, store, I.getKey(), I.getData()))
+      return;
 
 }
 
@@ -483,6 +507,54 @@
 // Binding invalidation.
 //===----------------------------------------------------------------------===//
 
+
+Store BasicStoreManager::InvalidateRegions(Store store,
+                                           const MemRegion * const *I,
+                                           const MemRegion * const *End,
+                                           const Expr *E, unsigned Count,
+                                           InvalidatedSymbols *IS,
+                                           bool invalidateGlobals,
+                                           InvalidatedRegions *Regions) {
+  if (invalidateGlobals) {
+    BindingsTy B = GetBindings(store);
+    for (BindingsTy::iterator I=B.begin(), End=B.end(); I != End; ++I) {
+      const MemRegion *R = I.getKey();
+      if (isa<NonStaticGlobalSpaceRegion>(R->getMemorySpace()))
+        store = InvalidateRegion(store, R, E, Count, IS);
+    }
+  }
+
+  for ( ; I != End ; ++I) {
+    const MemRegion *R = *I;
+    // Don't invalidate globals twice.
+    if (invalidateGlobals) {
+      if (isa<NonStaticGlobalSpaceRegion>(R->getMemorySpace()))
+        continue;
+    }
+    store = InvalidateRegion(store, *I, E, Count, IS);
+    if (Regions)
+      Regions->push_back(R);
+  }
+
+  // FIXME: This is copy-and-paste from RegionStore.cpp.
+  if (invalidateGlobals) {
+    // Bind the non-static globals memory space to a new symbol that we will
+    // use to derive the bindings for all non-static globals.
+    const GlobalsSpaceRegion *GS = MRMgr.getGlobalsRegion();
+    SVal V =
+      ValMgr.getConjuredSymbolVal(/* SymbolTag = */ (void*) GS, E,
+                                  /* symbol type, doesn't matter */ Ctx.IntTy,
+                                  Count);
+
+    store = Bind(store, loc::MemRegionVal(GS), V);
+    if (Regions)
+      Regions->push_back(GS);
+  }
+
+  return store;
+}
+
+
 Store BasicStoreManager::InvalidateRegion(Store store,
                                           const MemRegion *R,
                                           const Expr *E,
@@ -501,7 +573,7 @@
     }
   }
 
-  QualType T = cast<TypedRegion>(R)->getValueType(R->getContext());
+  QualType T = cast<TypedRegion>(R)->getValueType();
   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
index 246beea..4c9b109 100644
--- a/lib/Checker/BasicValueFactory.cpp
+++ b/lib/Checker/BasicValueFactory.cpp
@@ -149,22 +149,22 @@
     default:
       assert (false && "Invalid Opcode.");
 
-    case BinaryOperator::Mul:
+    case BO_Mul:
       return &getValue( V1 * V2 );
 
-    case BinaryOperator::Div:
+    case BO_Div:
       return &getValue( V1 / V2 );
 
-    case BinaryOperator::Rem:
+    case BO_Rem:
       return &getValue( V1 % V2 );
 
-    case BinaryOperator::Add:
+    case BO_Add:
       return &getValue( V1 + V2 );
 
-    case BinaryOperator::Sub:
+    case BO_Sub:
       return &getValue( V1 - V2 );
 
-    case BinaryOperator::Shl: {
+    case BO_Shl: {
 
       // FIXME: This logic should probably go higher up, where we can
       // test these conditions symbolically.
@@ -182,7 +182,7 @@
       return &getValue( V1.operator<<( (unsigned) Amt ));
     }
 
-    case BinaryOperator::Shr: {
+    case BO_Shr: {
 
       // FIXME: This logic should probably go higher up, where we can
       // test these conditions symbolically.
@@ -200,33 +200,33 @@
       return &getValue( V1.operator>>( (unsigned) Amt ));
     }
 
-    case BinaryOperator::LT:
+    case BO_LT:
       return &getTruthValue( V1 < V2 );
 
-    case BinaryOperator::GT:
+    case BO_GT:
       return &getTruthValue( V1 > V2 );
 
-    case BinaryOperator::LE:
+    case BO_LE:
       return &getTruthValue( V1 <= V2 );
 
-    case BinaryOperator::GE:
+    case BO_GE:
       return &getTruthValue( V1 >= V2 );
 
-    case BinaryOperator::EQ:
+    case BO_EQ:
       return &getTruthValue( V1 == V2 );
 
-    case BinaryOperator::NE:
+    case BO_NE:
       return &getTruthValue( V1 != V2 );
 
       // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
 
-    case BinaryOperator::And:
+    case BO_And:
       return &getValue( V1 & V2 );
 
-    case BinaryOperator::Or:
+    case BO_Or:
       return &getValue( V1 | V2 );
 
-    case BinaryOperator::Xor:
+    case BO_Xor:
       return &getValue( V1 ^ V2 );
   }
 }
diff --git a/lib/Checker/BugReporter.cpp b/lib/Checker/BugReporter.cpp
index 3bcc03f..bffbd52 100644
--- a/lib/Checker/BugReporter.cpp
+++ b/lib/Checker/BugReporter.cpp
@@ -94,8 +94,8 @@
         case Stmt::ChooseExprClass:
         case Stmt::ConditionalOperatorClass: continue;
         case Stmt::BinaryOperatorClass: {
-          BinaryOperator::Opcode Op = cast<BinaryOperator>(S)->getOpcode();
-          if (Op == BinaryOperator::LAnd || Op == BinaryOperator::LOr)
+          BinaryOperatorKind Op = cast<BinaryOperator>(S)->getOpcode();
+          if (Op == BO_LAnd || Op == BO_LOr)
             continue;
           break;
         }
@@ -177,18 +177,9 @@
   }
 
   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;
   }
@@ -541,9 +532,9 @@
     ProgramPoint P = N->getLocation();
 
     if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P)) {
-      CFGBlock* Src = BE->getSrc();
-      CFGBlock* Dst = BE->getDst();
-      Stmt* T = Src->getTerminator();
+      const CFGBlock* Src = BE->getSrc();
+      const CFGBlock* Dst = BE->getDst();
+      const Stmt* T = Src->getTerminator();
 
       if (!T)
         continue;
@@ -577,7 +568,7 @@
           std::string sbuf;
           llvm::raw_string_ostream os(sbuf);
 
-          if (Stmt* S = Dst->getLabel()) {
+          if (const Stmt* S = Dst->getLabel()) {
             PathDiagnosticLocation End(S, SMgr);
 
             switch (S->getStmtClass()) {
@@ -593,17 +584,17 @@
 
               case Stmt::CaseStmtClass: {
                 os << "Control jumps to 'case ";
-                CaseStmt* Case = cast<CaseStmt>(S);
-                Expr* LHS = Case->getLHS()->IgnoreParenCasts();
+                const CaseStmt* Case = cast<CaseStmt>(S);
+                const Expr* LHS = Case->getLHS()->IgnoreParenCasts();
 
                 // Determine if it is an enum.
                 bool GetRawInt = true;
 
-                if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS)) {
+                if (const 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());
+                  const EnumConstantDecl* D =
+                    dyn_cast<EnumConstantDecl>(DR->getDecl());
 
                   if (D) {
                     GetRawInt = false;
@@ -668,12 +659,12 @@
           if (!PDB.supportsLogicalOpControlFlow())
             break;
 
-          BinaryOperator *B = cast<BinaryOperator>(T);
+          const BinaryOperator *B = cast<BinaryOperator>(T);
           std::string sbuf;
           llvm::raw_string_ostream os(sbuf);
           os << "Left side of '";
 
-          if (B->getOpcode() == BinaryOperator::LAnd) {
+          if (B->getOpcode() == BO_LAnd) {
             os << "&&" << "' is ";
 
             if (*(Src->succ_begin()+1) == Dst) {
@@ -692,7 +683,7 @@
             }
           }
           else {
-            assert(B->getOpcode() == BinaryOperator::LOr);
+            assert(B->getOpcode() == BO_LOr);
             os << "||" << "' is ";
 
             if (*(Src->succ_begin()+1) == Dst) {
@@ -902,8 +893,6 @@
     CLocs.pop_back();
   }
 
-  PathDiagnosticLocation IgnoreParens(const PathDiagnosticLocation &L);
-
 public:
   EdgeBuilder(PathDiagnostic &pd, PathDiagnosticBuilder &pdb)
     : PD(pd), PDB(pdb) {
@@ -925,7 +914,7 @@
     // statement (if it doesn't already exist).
     // FIXME: Should handle CXXTryStmt if analyser starts supporting C++.
     if (const CompoundStmt *CS =
-          PDB.getCodeDecl().getCompoundBody())
+          dyn_cast_or_null<CompoundStmt>(PDB.getCodeDecl().getBody()))
       if (!CS->body_empty()) {
         SourceLocation Loc = (*CS->body_begin())->getLocStart();
         rawAddEdge(PathDiagnosticLocation(Loc, PDB.getSourceManager()));
@@ -935,10 +924,6 @@
 
   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);
@@ -1006,14 +991,6 @@
            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;
@@ -1403,7 +1380,7 @@
 
   // 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());
+  ExplodedGraph *GNew = new ExplodedGraph();
 
   // 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
diff --git a/lib/Checker/BugReporterVisitors.cpp b/lib/Checker/BugReporterVisitors.cpp
index 776e12b..cddc86e 100644
--- a/lib/Checker/BugReporterVisitors.cpp
+++ b/lib/Checker/BugReporterVisitors.cpp
@@ -31,7 +31,7 @@
   const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
 
   if (const UnaryOperator *U = dyn_cast<UnaryOperator>(S)) {
-    if (U->getOpcode() == UnaryOperator::Deref)
+    if (U->getOpcode() == UO_Deref)
       return U->getSubExpr()->IgnoreParenCasts();
   }
   else if (const MemberExpr *ME = dyn_cast<MemberExpr>(S)) {
@@ -143,10 +143,9 @@
 
         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()) {
+              if (TR->getValueType()->isObjCObjectPointerType()) {
                 os << "initialized to nil";
                 b = true;
               }
@@ -174,10 +173,9 @@
     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()) {
+            if (TR->getValueType()->isObjCObjectPointerType()) {
               os << "nil object reference stored to ";
               b = true;
             }
@@ -209,7 +207,7 @@
     ProgramPoint P = N->getLocation();
 
     if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
-      CFGBlock *BSrc = BE->getSrc();
+      const CFGBlock *BSrc = BE->getSrc();
       S = BSrc->getTerminatorCondition();
     }
     else if (PostStmt *PS = dyn_cast<PostStmt>(&P)) {
@@ -282,7 +280,7 @@
       ProgramPoint P = N->getLocation();
 
       if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
-        CFGBlock *BSrc = BE->getSrc();
+        const CFGBlock *BSrc = BE->getSrc();
         S = BSrc->getTerminatorCondition();
       }
       else if (PostStmt *PS = dyn_cast<PostStmt>(&P)) {
diff --git a/lib/Checker/BuiltinFunctionChecker.cpp b/lib/Checker/BuiltinFunctionChecker.cpp
index 9c8b516..057e474 100644
--- a/lib/Checker/BuiltinFunctionChecker.cpp
+++ b/lib/Checker/BuiltinFunctionChecker.cpp
@@ -57,15 +57,24 @@
   case Builtin::BI__builtin_alloca: {
     // FIXME: Refactor into StoreManager itself?
     MemRegionManager& RM = C.getStoreManager().getRegionManager();
-    const MemRegion* R =
+    const AllocaRegion* 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);
+    DefinedOrUnknownSVal Size =
+      cast<DefinedOrUnknownSVal>(state->getSVal(*(CE->arg_begin())));
+
+    ValueManager& ValMgr = C.getValueManager();
+    DefinedOrUnknownSVal Extent = R->getExtent(ValMgr);
+
+    SValuator& SVator = ValMgr.getSValuator();
+    DefinedOrUnknownSVal ExtentMatchesSizeArg =
+      SVator.EvalEQ(state, Extent, Size);
+    state = state->Assume(ExtentMatchesSizeArg, true);
+
     C.GenerateNode(state->BindExpr(CE, loc::MemRegionVal(R)));
     return true;
   }
diff --git a/lib/Checker/CFRefCount.cpp b/lib/Checker/CFRefCount.cpp
index d26ee1d..6fa48b2 100644
--- a/lib/Checker/CFRefCount.cpp
+++ b/lib/Checker/CFRefCount.cpp
@@ -37,10 +37,52 @@
 using llvm::StringRef;
 using llvm::StrInStrNoCase;
 
+namespace {
+class InstanceReceiver {
+  const ObjCMessageExpr *ME;
+  const LocationContext *LC;
+public:
+  InstanceReceiver(const ObjCMessageExpr *me = 0,
+                   const LocationContext *lc = 0) : ME(me), LC(lc) {}
+
+  bool isValid() const {
+    return ME && ME->isInstanceMessage();
+  }
+  operator bool() const {
+    return isValid();
+  }
+
+  SVal getSValAsScalarOrLoc(const GRState *state) {
+    assert(isValid());
+    // We have an expression for the receiver?  Fetch the value
+    // of that expression.
+    if (const Expr *Ex = ME->getInstanceReceiver())
+      return state->getSValAsScalarOrLoc(Ex);
+
+    // Otherwise we are sending a message to super.  In this case the
+    // object reference is the same as 'self'.
+    if (const ImplicitParamDecl *SelfDecl = LC->getSelfDecl())
+      return state->getSVal(state->getRegion(SelfDecl, LC));
+
+    return UnknownVal();
+  }
+
+  SourceRange getSourceRange() const {
+    assert(isValid());
+    if (const Expr *Ex = ME->getInstanceReceiver())
+      return Ex->getSourceRange();
+
+    // Otherwise we are sending a message to super.
+    SourceLocation L = ME->getSuperLoc();
+    assert(L.isValid());
+    return SourceRange(L, L);
+  }
+};
+}
+
 static const ObjCMethodDecl*
 ResolveToInterfaceMethodDecl(const ObjCMethodDecl *MD) {
-  ObjCInterfaceDecl *ID =
-    const_cast<ObjCInterfaceDecl*>(MD->getClassInterface());
+  const ObjCInterfaceDecl *ID = MD->getClassInterface();
 
   return MD->isInstanceMethod()
          ? ID->lookupInstanceMethod(MD->getSelector())
@@ -50,11 +92,11 @@
 namespace {
 class GenericNodeBuilder {
   GRStmtNodeBuilder *SNB;
-  Stmt *S;
+  const Stmt *S;
   const void *tag;
   GREndPathNodeBuilder *ENB;
 public:
-  GenericNodeBuilder(GRStmtNodeBuilder &snb, Stmt *s,
+  GenericNodeBuilder(GRStmtNodeBuilder &snb, const Stmt *s,
                      const void *t)
   : SNB(&snb), S(s), tag(t), ENB(0) {}
 
@@ -152,12 +194,6 @@
   static RetEffect MakeNoRet() {
     return RetEffect(NoRet);
   }
-
-  void Profile(llvm::FoldingSetNodeID& ID) const {
-    ID.AddInteger((unsigned)K);
-    ID.AddInteger((unsigned)O);
-    ID.AddInteger(index);
-  }
 };
 
 //===----------------------------------------------------------------------===//
@@ -185,111 +221,97 @@
     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: {
@@ -298,69 +320,69 @@
       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 << ']';
   }
@@ -431,11 +453,6 @@
     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; }
 
@@ -449,28 +466,6 @@
   /// 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
 
@@ -575,11 +570,6 @@
     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.
@@ -591,47 +581,6 @@
     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];
   }
@@ -653,7 +602,7 @@
   //  Typedefs.
   //==-----------------------------------------------------------------==//
 
-  typedef llvm::DenseMap<FunctionDecl*, RetainSummary*>
+  typedef llvm::DenseMap<const FunctionDecl*, RetainSummary*>
           FuncSummariesTy;
 
   typedef ObjCSummaryCache ObjCMethodSummariesTy;
@@ -723,9 +672,10 @@
 
   RetainSummary* getUnarySummary(const FunctionType* FT, UnaryFuncKind func);
 
-  RetainSummary* getCFSummaryCreateRule(FunctionDecl* FD);
-  RetainSummary* getCFSummaryGetRule(FunctionDecl* FD);
-  RetainSummary* getCFCreateGetRuleSummary(FunctionDecl* FD, StringRef FName);
+  RetainSummary* getCFSummaryCreateRule(const FunctionDecl* FD);
+  RetainSummary* getCFSummaryGetRule(const FunctionDecl* FD);
+  RetainSummary* getCFCreateGetRuleSummary(const FunctionDecl* FD, 
+                                           StringRef FName);
 
   RetainSummary* getPersistentSummary(ArgEffects AE, RetEffect RetEff,
                                       ArgEffect ReceiverEff = DoNothing,
@@ -753,12 +703,6 @@
   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;
   }
@@ -849,12 +793,12 @@
 
   ~RetainSummaryManager();
 
-  RetainSummary* getSummary(FunctionDecl* FD);
+  RetainSummary* getSummary(const 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,
@@ -884,7 +828,7 @@
       break;
     }
 
-    return getClassMethodSummary(ME->getSelector(), 
+    return getClassMethodSummary(ME->getSelector(),
                                  Class? Class->getIdentifier() : 0,
                                  Class,
                                  ME->getMethodDecl(), ME->getType());
@@ -956,15 +900,15 @@
 // Summary creation for functions (largely uses of Core Foundation).
 //===----------------------------------------------------------------------===//
 
-static bool isRetain(FunctionDecl* FD, StringRef FName) {
+static bool isRetain(const FunctionDecl* FD, StringRef FName) {
   return FName.endswith("Retain");
 }
 
-static bool isRelease(FunctionDecl* FD, StringRef FName) {
+static bool isRelease(const FunctionDecl* FD, StringRef FName) {
   return FName.endswith("Release");
 }
 
-RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) {
+RetainSummary* RetainSummaryManager::getSummary(const FunctionDecl* FD) {
   // Look up a summary in our cache of FunctionDecls -> Summaries.
   FuncSummariesTy::iterator I = FuncSummaries.find(FD);
   if (I != FuncSummaries.end())
@@ -1158,7 +1102,7 @@
 }
 
 RetainSummary*
-RetainSummaryManager::getCFCreateGetRuleSummary(FunctionDecl* FD,
+RetainSummaryManager::getCFCreateGetRuleSummary(const FunctionDecl* FD,
                                                 StringRef FName) {
 
   if (FName.find("Create") != StringRef::npos ||
@@ -1207,7 +1151,8 @@
   }
 }
 
-RetainSummary* RetainSummaryManager::getCFSummaryCreateRule(FunctionDecl* FD) {
+RetainSummary* 
+RetainSummaryManager::getCFSummaryCreateRule(const FunctionDecl* FD) {
   assert (ScratchArgs.isEmpty());
 
   if (FD->getIdentifier() == CFDictionaryCreateII) {
@@ -1218,7 +1163,8 @@
   return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true));
 }
 
-RetainSummary* RetainSummaryManager::getCFSummaryGetRule(FunctionDecl* FD) {
+RetainSummary* 
+RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl* FD) {
   assert (ScratchArgs.isEmpty());
   return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::CF),
                               DoNothing, DoNothing);
@@ -1374,18 +1320,18 @@
   //  we just use the 'ID' from the message expression.
   SVal receiverV;
 
-  if (const Expr *Receiver = ME->getInstanceReceiver()) {
+  if (Receiver) {
     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 = 
+        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) {
@@ -1401,7 +1347,7 @@
   // 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) {
@@ -1418,7 +1364,7 @@
       }
     }
   }
-  
+
   return Summ ? Summ : getDefaultSummary();
 }
 
@@ -1724,7 +1670,7 @@
 
   void ProcessNonLeakError(ExplodedNodeSet& Dst,
                            GRStmtNodeBuilder& Builder,
-                           Expr* NodeExpr, Expr* ErrorExpr,
+                           const Expr* NodeExpr, SourceRange ErrorRange,
                            ExplodedNode* Pred,
                            const GRState* St,
                            RefVal::Kind hasErr, SymbolRef Sym);
@@ -1767,33 +1713,26 @@
   void EvalSummary(ExplodedNodeSet& Dst,
                    GRExprEngine& Eng,
                    GRStmtNodeBuilder& Builder,
-                   Expr* Ex,
-                   Expr* Receiver,
+                   const Expr* Ex,
+                   InstanceReceiver Receiver,
                    const RetainSummary& Summ,
                    const MemRegion *Callee,
-                   ExprIterator arg_beg, ExprIterator arg_end,
+                   ConstExprIterator arg_beg, ConstExprIterator arg_end,
                    ExplodedNode* Pred, const GRState *state);
 
   virtual void EvalCall(ExplodedNodeSet& Dst,
                         GRExprEngine& Eng,
                         GRStmtNodeBuilder& Builder,
-                        CallExpr* CE, SVal L,
+                        const CallExpr* CE, SVal L,
                         ExplodedNode* Pred);
 
 
   virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst,
                                    GRExprEngine& Engine,
                                    GRStmtNodeBuilder& Builder,
-                                   ObjCMessageExpr* ME,
+                                   const 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);
 
@@ -1806,7 +1745,7 @@
                                GRExprEngine& Engine,
                                GRStmtNodeBuilder& Builder,
                                ExplodedNode* Pred,
-                               Stmt* S, const GRState* state,
+                               const GRState* state,
                                SymbolReaper& SymReaper);
 
   std::pair<ExplodedNode*, const GRState *>
@@ -1818,7 +1757,7 @@
   virtual void EvalReturn(ExplodedNodeSet& Dst,
                           GRExprEngine& Engine,
                           GRStmtNodeBuilder& Builder,
-                          ReturnStmt* S,
+                          const ReturnStmt* S,
                           ExplodedNode* Pred);
 
   // Assumptions.
@@ -1891,7 +1830,6 @@
   public:
 
     CFRefCount& getTF() { return TF; }
-    const CFRefCount& getTF() const { return TF; }
 
     // FIXME: Eventually remove.
     virtual const char* getDescription() const = 0;
@@ -2006,9 +1944,6 @@
     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())
@@ -2552,7 +2487,8 @@
         // 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 !D ? RetTy :
+                    Ctx.getObjCObjectPointerType(Ctx.getObjCInterfaceType(D));
       }
 
   return RetTy;
@@ -2561,34 +2497,41 @@
 void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
                              GRExprEngine& Eng,
                              GRStmtNodeBuilder& Builder,
-                             Expr* Ex,
-                             Expr* Receiver,
+                             const Expr* Ex,
+                             InstanceReceiver Receiver,
                              const RetainSummary& Summ,
                              const MemRegion *Callee,
-                             ExprIterator arg_beg, ExprIterator arg_end,
+                             ConstExprIterator arg_beg, 
+                             ConstExprIterator 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;
+  SourceRange ErrorRange;
   SymbolRef ErrorSym = 0;
 
   llvm::SmallVector<const MemRegion*, 10> RegionsToInvalidate;
-  
-  for (ExprIterator I = arg_beg; I != arg_end; ++I, ++idx) {
+
+  // HACK: Symbols that have ref-count state that are referenced directly
+  //  (not as structure or array elements, or via bindings) by an argument
+  //  should not have their ref-count state stripped after we have
+  //  done an invalidation pass.
+  llvm::DenseSet<SymbolRef> WhitelistedSymbols;
+
+  for (ConstExprIterator 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)) {
+        WhitelistedSymbols.insert(Sym);
         state = Update(state, Sym, *T, Summ.getArg(idx), hasErr);
         if (hasErr) {
-          ErrorExpr = *I;
+          ErrorRange = (*I)->getSourceRange();
           ErrorSym = Sym;
           break;
         }
-        continue;
       }
 
   tryAgain:
@@ -2615,7 +2558,7 @@
           // 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()) {
+          if (ER->getElementType()->isIntegralOrEnumerationType()) {
             const MemRegion *superReg = ER->getSuperRegion();
             if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
                 isa<ObjCIvarRegion>(superReg))
@@ -2623,7 +2566,7 @@
           }
           // FIXME: What about layers of ElementRegions?
         }
-        
+
         // Mark this region for invalidation.  We batch invalidate regions
         // below for efficiency.
         RegionsToInvalidate.push_back(R);
@@ -2643,47 +2586,49 @@
       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);
-    }
+  // 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::InvalidatedSymbols IS;
+
+  // NOTE: Even if RegionsToInvalidate is empty, we must still invalidate
+  //  global variables.
+  state = state->InvalidateRegions(RegionsToInvalidate.data(),
+                                   RegionsToInvalidate.data() +
+                                   RegionsToInvalidate.size(),
+                                   Ex, Count, &IS,
+                                   /* invalidateGlobals = */ true);
+
+  for (StoreManager::InvalidatedSymbols::iterator I = IS.begin(),
+       E = IS.end(); I!=E; ++I) {
+    SymbolRef sym = *I;
+    if (WhitelistedSymbols.count(sym))
+      continue;
+    // 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 (!ErrorRange.isValid() && Receiver) {
+    SymbolRef Sym = Receiver.getSValAsScalarOrLoc(state).getAsLocSymbol();
     if (Sym) {
       if (const RefVal* T = state->get<RefBindings>(Sym)) {
         state = Update(state, Sym, *T, Summ.getReceiverEffect(), hasErr);
         if (hasErr) {
-          ErrorExpr = Receiver;
+          ErrorRange = Receiver.getSourceRange();
           ErrorSym = Sym;
         }
       }
@@ -2692,7 +2637,7 @@
 
   // Process any errors.
   if (hasErr) {
-    ProcessNonLeakError(Dst, Builder, Ex, ErrorExpr, Pred, state,
+    ProcessNonLeakError(Dst, Builder, Ex, ErrorRange, Pred, state,
                         hasErr, ErrorSym);
     return;
   }
@@ -2703,7 +2648,7 @@
   if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
     bool found = false;
     if (Receiver) {
-      SVal V = state->getSValAsScalarOrLoc(Receiver);
+      SVal V = Receiver.getSValAsScalarOrLoc(state);
       if (SymbolRef Sym = V.getAsLocSymbol())
         if (state->get<RefBindings>(Sym)) {
           found = true;
@@ -2759,8 +2704,8 @@
     }
 
     case RetEffect::ReceiverAlias: {
-      assert (Receiver);
-      SVal V = state->getSValAsScalarOrLoc(Receiver);
+      assert(Receiver);
+      SVal V = Receiver.getSValAsScalarOrLoc(state);
       state = state->BindExpr(Ex, V, false);
       break;
     }
@@ -2814,11 +2759,11 @@
 void CFRefCount::EvalCall(ExplodedNodeSet& Dst,
                           GRExprEngine& Eng,
                           GRStmtNodeBuilder& Builder,
-                          CallExpr* CE, SVal L,
+                          const 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.
@@ -2828,7 +2773,7 @@
   else {
     const FunctionDecl* FD = L.getAsFunctionDecl();
     Summ = !FD ? Summaries.getDefaultSummary() :
-                 Summaries.getSummary(const_cast<FunctionDecl*>(FD));
+                 Summaries.getSummary(FD);
   }
 
   assert(Summ);
@@ -2839,7 +2784,7 @@
 void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet& Dst,
                                      GRExprEngine& Eng,
                                      GRStmtNodeBuilder& Builder,
-                                     ObjCMessageExpr* ME,
+                                     const ObjCMessageExpr* ME,
                                      ExplodedNode* Pred,
                                      const GRState *state) {
   RetainSummary *Summ =
@@ -2848,7 +2793,8 @@
       : Summaries.getClassMethodSummary(ME);
 
   assert(Summ && "RetainSummary is null");
-  EvalSummary(Dst, Eng, Builder, ME, ME->getInstanceReceiver(), *Summ, NULL,
+  EvalSummary(Dst, Eng, Builder, ME,
+              InstanceReceiver(ME, Pred->getLocationContext()), *Summ, NULL,
               ME->arg_begin(), ME->arg_end(), Pred, state);
 }
 
@@ -2909,10 +2855,10 @@
 void CFRefCount::EvalReturn(ExplodedNodeSet& Dst,
                             GRExprEngine& Eng,
                             GRStmtNodeBuilder& Builder,
-                            ReturnStmt* S,
+                            const ReturnStmt* S,
                             ExplodedNode* Pred) {
 
-  Expr* RetE = S->getRetValue();
+  const Expr* RetE = S->getRetValue();
   if (!RetE)
     return;
 
@@ -3355,10 +3301,9 @@
                                  GRExprEngine& Eng,
                                  GRStmtNodeBuilder& Builder,
                                  ExplodedNode* Pred,
-                                 Stmt* S,
                                  const GRState* state,
                                  SymbolReaper& SymReaper) {
-
+  const Stmt *S = Builder.getStmt();
   RefBindings B = state->get<RefBindings>();
 
   // Update counts from autorelease pools
@@ -3408,7 +3353,8 @@
 
 void CFRefCount::ProcessNonLeakError(ExplodedNodeSet& Dst,
                                      GRStmtNodeBuilder& Builder,
-                                     Expr* NodeExpr, Expr* ErrorExpr,
+                                     const Expr* NodeExpr, 
+                                     SourceRange ErrorRange,
                                      ExplodedNode* Pred,
                                      const GRState* St,
                                      RefVal::Kind hasErr, SymbolRef Sym) {
@@ -3439,7 +3385,7 @@
   }
 
   CFRefReport *report = new CFRefReport(*BT, *this, N, Sym);
-  report->addRange(ErrorExpr->getSourceRange());
+  report->addRange(ErrorRange);
   BR->EmitReport(report);
 }
 
@@ -3456,7 +3402,7 @@
 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
@@ -3464,29 +3410,29 @@
 
 void RetainReleaseChecker::PostVisitBlockExpr(CheckerContext &C,
                                               const BlockExpr *BE) {
-  
+
   // Scan the BlockDecRefExprs for any object the retain/release checker
-  // may be tracking.  
+  // 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) {
@@ -3494,7 +3440,7 @@
     }
     Regions.push_back(VR);
   }
-  
+
   state =
     state->scanReachableSymbols<StopTrackingCallback>(Regions.data(),
                                     Regions.data() + Regions.size()).getState();
@@ -3507,28 +3453,28 @@
 
 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)
@@ -3538,12 +3484,12 @@
     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";
@@ -3554,15 +3500,15 @@
     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.
diff --git a/lib/Checker/CMakeLists.txt b/lib/Checker/CMakeLists.txt
index 82e93a4..5b54f0d 100644
--- a/lib/Checker/CMakeLists.txt
+++ b/lib/Checker/CMakeLists.txt
@@ -3,6 +3,8 @@
 add_clang_library(clangChecker
   AdjustedReturnValueChecker.cpp
   AggExprVisitor.cpp
+  AnalysisConsumer.cpp
+  AnalysisManager.cpp
   ArrayBoundChecker.cpp
   AttrNonNullChecker.cpp
   BasicConstraintManager.cpp
@@ -12,60 +14,71 @@
   BugReporter.cpp
   BugReporterVisitors.cpp
   BuiltinFunctionChecker.cpp
-  CallAndMessageChecker.cpp
-  CallInliner.cpp
-  CastToStructChecker.cpp
   CFRefCount.cpp
+  CallAndMessageChecker.cpp
+  CastSizeChecker.cpp
+  CastToStructChecker.cpp
   CheckDeadStores.cpp
-  Checker.cpp
   CheckObjCDealloc.cpp
   CheckObjCInstMethSignature.cpp
   CheckSecuritySyntaxOnly.cpp
   CheckSizeofPointer.cpp
+  Checker.cpp
+  CheckerHelpers.cpp
   CocoaConventions.cpp
+  CStringChecker.cpp
   DereferenceChecker.cpp
   DivZeroChecker.cpp
   Environment.cpp
   ExplodedGraph.cpp
   FixedAddressChecker.cpp
   FlatStore.cpp
+  FrontendActions.cpp
   GRBlockCounter.cpp
-  GRCoreEngine.cpp
   GRCXXExprEngine.cpp
+  GRCoreEngine.cpp
   GRExprEngine.cpp
   GRExprEngineExperimentalChecks.cpp
   GRState.cpp
+  HTMLDiagnostics.cpp
+  IdempotentOperationChecker.cpp
   LLVMConventionsChecker.cpp
   MacOSXAPIChecker.cpp
   MallocChecker.cpp
   ManagerRegistry.cpp
   MemRegion.cpp
-  NoReturnFunctionChecker.cpp
   NSAutoreleasePoolChecker.cpp
   NSErrorChecker.cpp
-  ObjCUnusedIVarsChecker.cpp
+  NoReturnFunctionChecker.cpp
   OSAtomicChecker.cpp
+  ObjCUnusedIVarsChecker.cpp
   PathDiagnostic.cpp
+  PlistDiagnostics.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
+  SimpleConstraintManager.cpp
+  SimpleSValuator.cpp
+  StackAddrLeakChecker.cpp
+  Store.cpp
+  StreamChecker.cpp
   SymbolManager.cpp
   UndefBranchChecker.cpp
   UndefCapturedBlockVarChecker.cpp
+  UndefResultChecker.cpp
   UndefinedArraySubscriptChecker.cpp
   UndefinedAssignmentChecker.cpp
-  UndefResultChecker.cpp
   UnixAPIChecker.cpp
-  ValueManager.cpp
+  UnreachableCodeChecker.cpp
   VLASizeChecker.cpp
+  ValueManager.cpp
   )
+
+add_dependencies(clangChecker ClangAttrClasses ClangAttrList ClangDeclNodes
+                 ClangStmtNodes)
diff --git a/lib/Checker/CStringChecker.cpp b/lib/Checker/CStringChecker.cpp
new file mode 100644
index 0000000..9ea572f
--- /dev/null
+++ b/lib/Checker/CStringChecker.cpp
@@ -0,0 +1,1055 @@
+//= CStringChecker.h - Checks calls to C string functions ----------*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines CStringChecker, which is an assortment of checks on calls
+// to functions in <string.h>.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineExperimentalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/PathSensitive/GRStateTrait.h"
+#include "llvm/ADT/StringSwitch.h"
+
+using namespace clang;
+
+namespace {
+class CStringChecker : public CheckerVisitor<CStringChecker> {
+  BugType *BT_Null, *BT_Bounds, *BT_BoundsWrite, *BT_Overlap, *BT_NotCString;
+public:
+  CStringChecker()
+  : BT_Null(0), BT_Bounds(0), BT_BoundsWrite(0), BT_Overlap(0), BT_NotCString(0)
+  {}
+  static void *getTag() { static int tag; return &tag; }
+
+  bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
+  void PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS);
+  void MarkLiveSymbols(const GRState *state, SymbolReaper &SR);
+  void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SR);
+  bool WantsRegionChangeUpdate(const GRState *state);
+
+  const GRState *EvalRegionChanges(const GRState *state,
+                                   const MemRegion * const *Begin,
+                                   const MemRegion * const *End,
+                                   bool*);
+
+  typedef void (CStringChecker::*FnCheck)(CheckerContext &, const CallExpr *);
+
+  void EvalMemcpy(CheckerContext &C, const CallExpr *CE);
+  void EvalMemmove(CheckerContext &C, const CallExpr *CE);
+  void EvalBcopy(CheckerContext &C, const CallExpr *CE);
+  void EvalCopyCommon(CheckerContext &C, const GRState *state,
+                      const Expr *Size, const Expr *Source, const Expr *Dest,
+                      bool Restricted = false);
+
+  void EvalMemcmp(CheckerContext &C, const CallExpr *CE);
+
+  void EvalStrlen(CheckerContext &C, const CallExpr *CE);
+
+  void EvalStrcpy(CheckerContext &C, const CallExpr *CE);
+  void EvalStpcpy(CheckerContext &C, const CallExpr *CE);
+  void EvalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool ReturnEnd);
+
+  // Utility methods
+  std::pair<const GRState*, const GRState*>
+  AssumeZero(CheckerContext &C, const GRState *state, SVal V, QualType Ty);
+
+  const GRState *SetCStringLength(const GRState *state, const MemRegion *MR,
+                                  SVal StrLen);
+  SVal GetCStringLengthForRegion(CheckerContext &C, const GRState *&state,
+                                 const Expr *Ex, const MemRegion *MR);
+  SVal GetCStringLength(CheckerContext &C, const GRState *&state,
+                        const Expr *Ex, SVal Buf);
+
+  const GRState *InvalidateBuffer(CheckerContext &C, const GRState *state,
+                                  const Expr *Ex, SVal V);
+
+  bool SummarizeRegion(llvm::raw_ostream& os, ASTContext& Ctx,
+                       const MemRegion *MR);
+
+  // Re-usable checks
+  const GRState *CheckNonNull(CheckerContext &C, const GRState *state,
+                               const Expr *S, SVal l);
+  const GRState *CheckLocation(CheckerContext &C, const GRState *state,
+                               const Expr *S, SVal l,
+                               bool IsDestination = false);
+  const GRState *CheckBufferAccess(CheckerContext &C, const GRState *state,
+                                   const Expr *Size,
+                                   const Expr *FirstBuf,
+                                   const Expr *SecondBuf = NULL,
+                                   bool FirstIsDestination = false);
+  const GRState *CheckOverlap(CheckerContext &C, const GRState *state,
+                              const Expr *Size, const Expr *First,
+                              const Expr *Second);
+  void EmitOverlapBug(CheckerContext &C, const GRState *state,
+                      const Stmt *First, const Stmt *Second);
+};
+
+class CStringLength {
+public:
+  typedef llvm::ImmutableMap<const MemRegion *, SVal> EntryMap;
+};
+} //end anonymous namespace
+
+namespace clang {
+  template <>
+  struct GRStateTrait<CStringLength> 
+    : public GRStatePartialTrait<CStringLength::EntryMap> {
+    static void *GDMIndex() { return CStringChecker::getTag(); }
+  };
+}
+
+void clang::RegisterCStringChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new CStringChecker());
+}
+
+//===----------------------------------------------------------------------===//
+// Individual checks and utility methods.
+//===----------------------------------------------------------------------===//
+
+std::pair<const GRState*, const GRState*>
+CStringChecker::AssumeZero(CheckerContext &C, const GRState *state, SVal V,
+                           QualType Ty) {
+  DefinedSVal *Val = dyn_cast<DefinedSVal>(&V);
+  if (!Val)
+    return std::pair<const GRState*, const GRState *>(state, state);
+
+  ValueManager &ValMgr = C.getValueManager();
+  SValuator &SV = ValMgr.getSValuator();
+
+  DefinedOrUnknownSVal Zero = ValMgr.makeZeroVal(Ty);
+  DefinedOrUnknownSVal ValIsZero = SV.EvalEQ(state, *Val, Zero);
+
+  return state->Assume(ValIsZero);
+}
+
+const GRState *CStringChecker::CheckNonNull(CheckerContext &C,
+                                            const GRState *state,
+                                            const Expr *S, SVal l) {
+  // If a previous check has failed, propagate the failure.
+  if (!state)
+    return NULL;
+
+  const GRState *stateNull, *stateNonNull;
+  llvm::tie(stateNull, stateNonNull) = AssumeZero(C, state, l, S->getType());
+
+  if (stateNull && !stateNonNull) {
+    ExplodedNode *N = C.GenerateSink(stateNull);
+    if (!N)
+      return NULL;
+
+    if (!BT_Null)
+      BT_Null = new BuiltinBug("API",
+        "Null pointer argument in call to byte string function");
+
+    // Generate a report for this bug.
+    BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Null);
+    EnhancedBugReport *report = new EnhancedBugReport(*BT,
+                                                      BT->getDescription(), N);
+
+    report->addRange(S->getSourceRange());
+    report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, S);
+    C.EmitReport(report);
+    return NULL;
+  }
+
+  // From here on, assume that the value is non-null.
+  assert(stateNonNull);
+  return stateNonNull;
+}
+
+// FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor?
+const GRState *CStringChecker::CheckLocation(CheckerContext &C,
+                                             const GRState *state,
+                                             const Expr *S, SVal l,
+                                             bool IsDestination) {
+  // If a previous check has failed, propagate the failure.
+  if (!state)
+    return NULL;
+
+  // Check for out of bound array element access.
+  const MemRegion *R = l.getAsRegion();
+  if (!R)
+    return state;
+
+  const ElementRegion *ER = dyn_cast<ElementRegion>(R);
+  if (!ER)
+    return state;
+
+  assert(ER->getValueType() == C.getASTContext().CharTy &&
+    "CheckLocation should only be called with char* ElementRegions");
+
+  // Get the size of the array.
+  const SubRegion *Super = cast<SubRegion>(ER->getSuperRegion());
+  ValueManager &ValMgr = C.getValueManager();
+  SVal Extent = ValMgr.convertToArrayIndex(Super->getExtent(ValMgr));
+  DefinedOrUnknownSVal Size = cast<DefinedOrUnknownSVal>(Extent);
+
+  // Get the index of the accessed element.
+  DefinedOrUnknownSVal &Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
+
+  const GRState *StInBound = state->AssumeInBound(Idx, Size, true);
+  const GRState *StOutBound = state->AssumeInBound(Idx, Size, false);
+  if (StOutBound && !StInBound) {
+    ExplodedNode *N = C.GenerateSink(StOutBound);
+    if (!N)
+      return NULL;
+
+    BuiltinBug *BT;
+    if (IsDestination) {
+      if (!BT_BoundsWrite) {
+        BT_BoundsWrite = new BuiltinBug("Out-of-bound array access",
+          "Byte string function overflows destination buffer");
+      }
+      BT = static_cast<BuiltinBug*>(BT_BoundsWrite);
+    } else {
+      if (!BT_Bounds) {
+        BT_Bounds = new BuiltinBug("Out-of-bound array access",
+          "Byte string function accesses out-of-bound array element");
+      }
+      BT = static_cast<BuiltinBug*>(BT_Bounds);
+    }
+
+    // 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 NULL;
+  }
+  
+  // Array bound check succeeded.  From this point forward the array bound
+  // should always succeed.
+  return StInBound;
+}
+
+const GRState *CStringChecker::CheckBufferAccess(CheckerContext &C,
+                                                 const GRState *state,
+                                                 const Expr *Size,
+                                                 const Expr *FirstBuf,
+                                                 const Expr *SecondBuf,
+                                                 bool FirstIsDestination) {
+  // If a previous check has failed, propagate the failure.
+  if (!state)
+    return NULL;
+
+  ValueManager &VM = C.getValueManager();
+  SValuator &SV = VM.getSValuator();
+  ASTContext &Ctx = C.getASTContext();
+
+  QualType SizeTy = Size->getType();
+  QualType PtrTy = Ctx.getPointerType(Ctx.CharTy);
+
+  // Check that the first buffer is non-null.
+  SVal BufVal = state->getSVal(FirstBuf);
+  state = CheckNonNull(C, state, FirstBuf, BufVal);
+  if (!state)
+    return NULL;
+
+  // Get the access length and make sure it is known.
+  SVal LengthVal = state->getSVal(Size);
+  NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
+  if (!Length)
+    return state;
+
+  // Compute the offset of the last element to be accessed: size-1.
+  NonLoc One = cast<NonLoc>(VM.makeIntVal(1, SizeTy));
+  NonLoc LastOffset = cast<NonLoc>(SV.EvalBinOpNN(state, BO_Sub,
+                                                  *Length, One, SizeTy));
+
+  // Check that the first buffer is sufficently long.
+  SVal BufStart = SV.EvalCast(BufVal, PtrTy, FirstBuf->getType());
+  if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
+    SVal BufEnd = SV.EvalBinOpLN(state, BO_Add, *BufLoc,
+                                 LastOffset, PtrTy);
+    state = CheckLocation(C, state, FirstBuf, BufEnd, FirstIsDestination);
+
+    // If the buffer isn't large enough, abort.
+    if (!state)
+      return NULL;
+  }
+
+  // If there's a second buffer, check it as well.
+  if (SecondBuf) {
+    BufVal = state->getSVal(SecondBuf);
+    state = CheckNonNull(C, state, SecondBuf, BufVal);
+    if (!state)
+      return NULL;
+
+    BufStart = SV.EvalCast(BufVal, PtrTy, SecondBuf->getType());
+    if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
+      SVal BufEnd = SV.EvalBinOpLN(state, BO_Add, *BufLoc,
+                                   LastOffset, PtrTy);
+      state = CheckLocation(C, state, SecondBuf, BufEnd);
+    }
+  }
+
+  // Large enough or not, return this state!
+  return state;
+}
+
+const GRState *CStringChecker::CheckOverlap(CheckerContext &C,
+                                            const GRState *state,
+                                            const Expr *Size,
+                                            const Expr *First,
+                                            const Expr *Second) {
+  // Do a simple check for overlap: if the two arguments are from the same
+  // buffer, see if the end of the first is greater than the start of the second
+  // or vice versa.
+
+  // If a previous check has failed, propagate the failure.
+  if (!state)
+    return NULL;
+
+  ValueManager &VM = state->getStateManager().getValueManager();
+  SValuator &SV = VM.getSValuator();
+  ASTContext &Ctx = VM.getContext();
+  const GRState *stateTrue, *stateFalse;
+
+  // Get the buffer values and make sure they're known locations.
+  SVal FirstVal = state->getSVal(First);
+  SVal SecondVal = state->getSVal(Second);
+
+  Loc *FirstLoc = dyn_cast<Loc>(&FirstVal);
+  if (!FirstLoc)
+    return state;
+
+  Loc *SecondLoc = dyn_cast<Loc>(&SecondVal);
+  if (!SecondLoc)
+    return state;
+
+  // Are the two values the same?
+  DefinedOrUnknownSVal EqualTest = SV.EvalEQ(state, *FirstLoc, *SecondLoc);
+  llvm::tie(stateTrue, stateFalse) = state->Assume(EqualTest);
+
+  if (stateTrue && !stateFalse) {
+    // If the values are known to be equal, that's automatically an overlap.
+    EmitOverlapBug(C, stateTrue, First, Second);
+    return NULL;
+  }
+
+  // Assume the two expressions are not equal.
+  assert(stateFalse);
+  state = stateFalse;
+
+  // Which value comes first?
+  QualType CmpTy = Ctx.IntTy;
+  SVal Reverse = SV.EvalBinOpLL(state, BO_GT,
+                                *FirstLoc, *SecondLoc, CmpTy);
+  DefinedOrUnknownSVal *ReverseTest = dyn_cast<DefinedOrUnknownSVal>(&Reverse);
+  if (!ReverseTest)
+    return state;
+
+  llvm::tie(stateTrue, stateFalse) = state->Assume(*ReverseTest);
+
+  if (stateTrue) {
+    if (stateFalse) {
+      // If we don't know which one comes first, we can't perform this test.
+      return state;
+    } else {
+      // Switch the values so that FirstVal is before SecondVal.
+      Loc *tmpLoc = FirstLoc;
+      FirstLoc = SecondLoc;
+      SecondLoc = tmpLoc;
+
+      // Switch the Exprs as well, so that they still correspond.
+      const Expr *tmpExpr = First;
+      First = Second;
+      Second = tmpExpr;
+    }
+  }
+
+  // Get the length, and make sure it too is known.
+  SVal LengthVal = state->getSVal(Size);
+  NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
+  if (!Length)
+    return state;
+
+  // Convert the first buffer's start address to char*.
+  // Bail out if the cast fails.
+  QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
+  SVal FirstStart = SV.EvalCast(*FirstLoc, CharPtrTy, First->getType());
+  Loc *FirstStartLoc = dyn_cast<Loc>(&FirstStart);
+  if (!FirstStartLoc)
+    return state;
+
+  // Compute the end of the first buffer. Bail out if THAT fails.
+  SVal FirstEnd = SV.EvalBinOpLN(state, BO_Add,
+                                 *FirstStartLoc, *Length, CharPtrTy);
+  Loc *FirstEndLoc = dyn_cast<Loc>(&FirstEnd);
+  if (!FirstEndLoc)
+    return state;
+
+  // Is the end of the first buffer past the start of the second buffer?
+  SVal Overlap = SV.EvalBinOpLL(state, BO_GT,
+                                *FirstEndLoc, *SecondLoc, CmpTy);
+  DefinedOrUnknownSVal *OverlapTest = dyn_cast<DefinedOrUnknownSVal>(&Overlap);
+  if (!OverlapTest)
+    return state;
+
+  llvm::tie(stateTrue, stateFalse) = state->Assume(*OverlapTest);
+
+  if (stateTrue && !stateFalse) {
+    // Overlap!
+    EmitOverlapBug(C, stateTrue, First, Second);
+    return NULL;
+  }
+
+  // Assume the two expressions don't overlap.
+  assert(stateFalse);
+  return stateFalse;
+}
+
+void CStringChecker::EmitOverlapBug(CheckerContext &C, const GRState *state,
+                                    const Stmt *First, const Stmt *Second) {
+  ExplodedNode *N = C.GenerateSink(state);
+  if (!N)
+    return;
+
+  if (!BT_Overlap)
+    BT_Overlap = new BugType("Unix API", "Improper arguments");
+
+  // Generate a report for this bug.
+  RangedBugReport *report = 
+    new RangedBugReport(*BT_Overlap,
+      "Arguments must not be overlapping buffers", N);
+  report->addRange(First->getSourceRange());
+  report->addRange(Second->getSourceRange());
+
+  C.EmitReport(report);
+}
+
+const GRState *CStringChecker::SetCStringLength(const GRState *state,
+                                                const MemRegion *MR,
+                                                SVal StrLen) {
+  assert(!StrLen.isUndef() && "Attempt to set an undefined string length");
+  if (StrLen.isUnknown())
+    return state;
+
+  MR = MR->StripCasts();
+
+  switch (MR->getKind()) {
+  case MemRegion::StringRegionKind:
+    // FIXME: This can happen if we strcpy() into a string region. This is
+    // undefined [C99 6.4.5p6], but we should still warn about it.
+    return state;
+
+  case MemRegion::SymbolicRegionKind:
+  case MemRegion::AllocaRegionKind:
+  case MemRegion::VarRegionKind:
+  case MemRegion::FieldRegionKind:
+  case MemRegion::ObjCIvarRegionKind:
+    return state->set<CStringLength>(MR, StrLen);
+
+  case MemRegion::ElementRegionKind:
+    // FIXME: Handle element regions by upper-bounding the parent region's
+    // string length.
+    return state;
+
+  default:
+    // Other regions (mostly non-data) can't have a reliable C string length.
+    // For now, just ignore the change.
+    // FIXME: These are rare but not impossible. We should output some kind of
+    // warning for things like strcpy((char[]){'a', 0}, "b");
+    return state;
+  }
+}
+
+SVal CStringChecker::GetCStringLengthForRegion(CheckerContext &C,
+                                               const GRState *&state,
+                                               const Expr *Ex,
+                                               const MemRegion *MR) {
+  // If there's a recorded length, go ahead and return it.
+  const SVal *Recorded = state->get<CStringLength>(MR);
+  if (Recorded)
+    return *Recorded;
+  
+  // Otherwise, get a new symbol and update the state.
+  unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
+  ValueManager &ValMgr = C.getValueManager();
+  QualType SizeTy = ValMgr.getContext().getSizeType();
+  SVal Strlen = ValMgr.getMetadataSymbolVal(getTag(), MR, Ex, SizeTy, Count);
+  
+  state = state->set<CStringLength>(MR, Strlen);
+  return Strlen;
+}
+
+SVal CStringChecker::GetCStringLength(CheckerContext &C, const GRState *&state,
+                                      const Expr *Ex, SVal Buf) {
+  const MemRegion *MR = Buf.getAsRegion();
+  if (!MR) {
+    // If we can't get a region, see if it's something we /know/ isn't a
+    // C string. In the context of locations, the only time we can issue such
+    // a warning is for labels.
+    if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&Buf)) {
+      if (ExplodedNode *N = C.GenerateNode(state)) {
+        if (!BT_NotCString)
+          BT_NotCString = new BuiltinBug("API",
+            "Argument is not a null-terminated string.");
+
+        llvm::SmallString<120> buf;
+        llvm::raw_svector_ostream os(buf);
+        os << "Argument to byte string function is the address of the label '"
+           << Label->getLabel()->getID()->getName()
+           << "', which is not a null-terminated string";
+
+        // Generate a report for this bug.
+        EnhancedBugReport *report = new EnhancedBugReport(*BT_NotCString,
+                                                          os.str(), N);
+
+        report->addRange(Ex->getSourceRange());
+        C.EmitReport(report);        
+      }
+
+      return UndefinedVal();
+    }
+
+    // If it's not a region and not a label, give up.
+    return UnknownVal();
+  }
+
+  // If we have a region, strip casts from it and see if we can figure out
+  // its length. For anything we can't figure out, just return UnknownVal.
+  MR = MR->StripCasts();
+
+  switch (MR->getKind()) {
+  case MemRegion::StringRegionKind: {
+    // Modifying the contents of string regions is undefined [C99 6.4.5p6],
+    // so we can assume that the byte length is the correct C string length.
+    ValueManager &ValMgr = C.getValueManager();
+    QualType SizeTy = ValMgr.getContext().getSizeType();
+    const StringLiteral *Str = cast<StringRegion>(MR)->getStringLiteral();
+    return ValMgr.makeIntVal(Str->getByteLength(), SizeTy);
+  }
+  case MemRegion::SymbolicRegionKind:
+  case MemRegion::AllocaRegionKind:
+  case MemRegion::VarRegionKind:
+  case MemRegion::FieldRegionKind:
+  case MemRegion::ObjCIvarRegionKind:
+    return GetCStringLengthForRegion(C, state, Ex, MR);
+  case MemRegion::CompoundLiteralRegionKind:
+    // FIXME: Can we track this? Is it necessary?
+    return UnknownVal();
+  case MemRegion::ElementRegionKind:
+    // FIXME: How can we handle this? It's not good enough to subtract the
+    // offset from the base string length; consider "123\x00567" and &a[5].
+    return UnknownVal();
+  default:
+    // Other regions (mostly non-data) can't have a reliable C string length.
+    // In this case, an error is emitted and UndefinedVal is returned.
+    // The caller should always be prepared to handle this case.
+    if (ExplodedNode *N = C.GenerateNode(state)) {
+      if (!BT_NotCString)
+        BT_NotCString = new BuiltinBug("API",
+          "Argument is not a null-terminated string.");
+
+      llvm::SmallString<120> buf;
+      llvm::raw_svector_ostream os(buf);
+
+      os << "Argument to byte string function is ";
+
+      if (SummarizeRegion(os, C.getASTContext(), MR))
+        os << ", which is not a null-terminated string";
+      else
+        os << "not a null-terminated string";
+
+      // Generate a report for this bug.
+      EnhancedBugReport *report = new EnhancedBugReport(*BT_NotCString,
+                                                        os.str(), N);
+
+      report->addRange(Ex->getSourceRange());
+      C.EmitReport(report);        
+    }
+
+    return UndefinedVal();
+  }
+}
+
+const GRState *CStringChecker::InvalidateBuffer(CheckerContext &C,
+                                                const GRState *state,
+                                                const Expr *E, SVal V) {
+  Loc *L = dyn_cast<Loc>(&V);
+  if (!L)
+    return state;
+
+  // FIXME: This is a simplified version of what's in CFRefCount.cpp -- it makes
+  // some assumptions about the value that CFRefCount can't. Even so, it should
+  // probably be refactored.
+  if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(L)) {
+    const MemRegion *R = MR->getRegion()->StripCasts();
+
+    // Are we dealing with an ElementRegion?  If so, we should be invalidating
+    // the super-region.
+    if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
+      R = ER->getSuperRegion();
+      // FIXME: What about layers of ElementRegions?
+    }
+
+    // Invalidate this region.
+    unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
+    return state->InvalidateRegion(R, E, Count, NULL);
+  }
+
+  // If we have a non-region value by chance, just remove the binding.
+  // FIXME: is this necessary or correct? This handles the non-Region
+  //  cases.  Is it ever valid to store to these?
+  return state->unbindLoc(*L);
+}
+
+bool CStringChecker::SummarizeRegion(llvm::raw_ostream& os, ASTContext& Ctx,
+                                     const MemRegion *MR) {
+  const TypedRegion *TR = dyn_cast<TypedRegion>(MR);
+  if (!TR)
+    return false;
+
+  switch (TR->getKind()) {
+  case MemRegion::FunctionTextRegionKind: {
+    const FunctionDecl *FD = cast<FunctionTextRegion>(TR)->getDecl();
+    if (FD)
+      os << "the address of the function '" << FD << "'";
+    else
+      os << "the address of a function";
+    return true;
+  }
+  case MemRegion::BlockTextRegionKind:
+    os << "block text";
+    return true;
+  case MemRegion::BlockDataRegionKind:
+    os << "a block";
+    return true;
+  case MemRegion::CXXThisRegionKind:
+  case MemRegion::CXXObjectRegionKind:
+    os << "a C++ object of type " << TR->getValueType().getAsString();
+    return true;
+  case MemRegion::VarRegionKind:
+    os << "a variable of type" << TR->getValueType().getAsString();
+    return true;
+  case MemRegion::FieldRegionKind:
+    os << "a field of type " << TR->getValueType().getAsString();
+    return true;
+  case MemRegion::ObjCIvarRegionKind:
+    os << "an instance variable of type " << TR->getValueType().getAsString();
+    return true;
+  default:
+    return false;
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Evaluation of individual function calls.
+//===----------------------------------------------------------------------===//
+
+void CStringChecker::EvalCopyCommon(CheckerContext &C, const GRState *state,
+                                    const Expr *Size, const Expr *Dest,
+                                    const Expr *Source, bool Restricted) {
+  // See if the size argument is zero.
+  SVal SizeVal = state->getSVal(Size);
+  QualType SizeTy = Size->getType();
+
+  const GRState *StZeroSize, *StNonZeroSize;
+  llvm::tie(StZeroSize, StNonZeroSize) = AssumeZero(C, state, SizeVal, SizeTy);
+
+  // If the size is zero, there won't be any actual memory access.
+  if (StZeroSize)
+    C.addTransition(StZeroSize);
+
+  // If the size can be nonzero, we have to check the other arguments.
+  if (StNonZeroSize) {
+    state = StNonZeroSize;
+    state = CheckBufferAccess(C, state, Size, Dest, Source,
+                              /* FirstIsDst = */ true);
+    if (Restricted)
+      state = CheckOverlap(C, state, Size, Dest, Source);
+
+    if (state) {
+      // Invalidate the destination.
+      // FIXME: Even if we can't perfectly model the copy, we should see if we
+      // can use LazyCompoundVals to copy the source values into the destination.
+      // This would probably remove any existing bindings past the end of the
+      // copied region, but that's still an improvement over blank invalidation.
+      state = InvalidateBuffer(C, state, Dest, state->getSVal(Dest));
+      C.addTransition(state);
+    }
+  }
+}
+
+
+void CStringChecker::EvalMemcpy(CheckerContext &C, const CallExpr *CE) {
+  // void *memcpy(void *restrict dst, const void *restrict src, size_t n);
+  // The return value is the address of the destination buffer.
+  const Expr *Dest = CE->getArg(0);
+  const GRState *state = C.getState();
+  state = state->BindExpr(CE, state->getSVal(Dest));
+  EvalCopyCommon(C, state, CE->getArg(2), Dest, CE->getArg(1), true);
+}
+
+void CStringChecker::EvalMemmove(CheckerContext &C, const CallExpr *CE) {
+  // void *memmove(void *dst, const void *src, size_t n);
+  // The return value is the address of the destination buffer.
+  const Expr *Dest = CE->getArg(0);
+  const GRState *state = C.getState();
+  state = state->BindExpr(CE, state->getSVal(Dest));
+  EvalCopyCommon(C, state, CE->getArg(2), Dest, CE->getArg(1));
+}
+
+void CStringChecker::EvalBcopy(CheckerContext &C, const CallExpr *CE) {
+  // void bcopy(const void *src, void *dst, size_t n);
+  EvalCopyCommon(C, C.getState(), CE->getArg(2), CE->getArg(1), CE->getArg(0));
+}
+
+void CStringChecker::EvalMemcmp(CheckerContext &C, const CallExpr *CE) {
+  // int memcmp(const void *s1, const void *s2, size_t n);
+  const Expr *Left = CE->getArg(0);
+  const Expr *Right = CE->getArg(1);
+  const Expr *Size = CE->getArg(2);
+
+  const GRState *state = C.getState();
+  ValueManager &ValMgr = C.getValueManager();
+  SValuator &SV = ValMgr.getSValuator();
+
+  // See if the size argument is zero.
+  SVal SizeVal = state->getSVal(Size);
+  QualType SizeTy = Size->getType();
+
+  const GRState *StZeroSize, *StNonZeroSize;
+  llvm::tie(StZeroSize, StNonZeroSize) = AssumeZero(C, state, SizeVal, SizeTy);
+
+  // If the size can be zero, the result will be 0 in that case, and we don't
+  // have to check either of the buffers.
+  if (StZeroSize) {
+    state = StZeroSize;
+    state = state->BindExpr(CE, ValMgr.makeZeroVal(CE->getType()));
+    C.addTransition(state);
+  }
+
+  // If the size can be nonzero, we have to check the other arguments.
+  if (StNonZeroSize) {
+    state = StNonZeroSize;
+
+    // If we know the two buffers are the same, we know the result is 0.
+    // First, get the two buffers' addresses. Another checker will have already
+    // made sure they're not undefined.
+    DefinedOrUnknownSVal LV = cast<DefinedOrUnknownSVal>(state->getSVal(Left));
+    DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(state->getSVal(Right));
+
+    // See if they are the same.
+    DefinedOrUnknownSVal SameBuf = SV.EvalEQ(state, LV, RV);
+    const GRState *StSameBuf, *StNotSameBuf;
+    llvm::tie(StSameBuf, StNotSameBuf) = state->Assume(SameBuf);
+
+    // If the two arguments might be the same buffer, we know the result is zero,
+    // and we only need to check one size.
+    if (StSameBuf) {
+      state = StSameBuf;
+      state = CheckBufferAccess(C, state, Size, Left);
+      if (state) {
+        state = StSameBuf->BindExpr(CE, ValMgr.makeZeroVal(CE->getType()));
+        C.addTransition(state); 
+      }
+    }
+
+    // If the two arguments might be different buffers, we have to check the
+    // size of both of them.
+    if (StNotSameBuf) {
+      state = StNotSameBuf;
+      state = CheckBufferAccess(C, state, Size, Left, Right);
+      if (state) {
+        // The return value is the comparison result, which we don't know.
+        unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
+        SVal CmpV = ValMgr.getConjuredSymbolVal(NULL, CE, Count);
+        state = state->BindExpr(CE, CmpV);
+        C.addTransition(state);
+      }
+    }
+  }
+}
+
+void CStringChecker::EvalStrlen(CheckerContext &C, const CallExpr *CE) {
+  // size_t strlen(const char *s);
+  const GRState *state = C.getState();
+  const Expr *Arg = CE->getArg(0);
+  SVal ArgVal = state->getSVal(Arg);
+
+  // Check that the argument is non-null.
+  state = CheckNonNull(C, state, Arg, ArgVal);
+
+  if (state) {
+    SVal StrLen = GetCStringLength(C, state, Arg, ArgVal);
+
+    // If the argument isn't a valid C string, there's no valid state to
+    // transition to.
+    if (StrLen.isUndef())
+      return;
+
+    // If GetCStringLength couldn't figure out the length, conjure a return
+    // value, so it can be used in constraints, at least.
+    if (StrLen.isUnknown()) {
+      ValueManager &ValMgr = C.getValueManager();
+      unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
+      StrLen = ValMgr.getConjuredSymbolVal(NULL, CE, Count);
+    }
+
+    // Bind the return value.
+    state = state->BindExpr(CE, StrLen);
+    C.addTransition(state);
+  }
+}
+
+void CStringChecker::EvalStrcpy(CheckerContext &C, const CallExpr *CE) {
+  // char *strcpy(char *restrict dst, const char *restrict src);
+  EvalStrcpyCommon(C, CE, /* ReturnEnd = */ false);
+}
+
+void CStringChecker::EvalStpcpy(CheckerContext &C, const CallExpr *CE) {
+  // char *stpcpy(char *restrict dst, const char *restrict src);
+  EvalStrcpyCommon(C, CE, /* ReturnEnd = */ true);
+}
+
+void CStringChecker::EvalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
+                                      bool ReturnEnd) {
+  const GRState *state = C.getState();
+
+  // Check that the destination is non-null
+  const Expr *Dst = CE->getArg(0);
+  SVal DstVal = state->getSVal(Dst);
+
+  state = CheckNonNull(C, state, Dst, DstVal);
+  if (!state)
+    return;
+
+  // Check that the source is non-null.
+  const Expr *Src = CE->getArg(1);
+  SVal SrcVal = state->getSVal(Src);
+
+  state = CheckNonNull(C, state, Src, SrcVal);
+  if (!state)
+    return;
+
+  // Get the string length of the source.
+  SVal StrLen = GetCStringLength(C, state, Src, SrcVal);
+
+  // If the source isn't a valid C string, give up.
+  if (StrLen.isUndef())
+    return;
+
+  SVal Result = (ReturnEnd ? UnknownVal() : DstVal);
+
+  // If the destination is a MemRegion, try to check for a buffer overflow and
+  // record the new string length.
+  if (loc::MemRegionVal *DstRegVal = dyn_cast<loc::MemRegionVal>(&DstVal)) {
+    // If the length is known, we can check for an overflow.
+    if (NonLoc *KnownStrLen = dyn_cast<NonLoc>(&StrLen)) {
+      SValuator &SV = C.getSValuator();
+
+      SVal LastElement = SV.EvalBinOpLN(state, BO_Add,
+                                        *DstRegVal, *KnownStrLen,
+                                        Dst->getType());
+
+      state = CheckLocation(C, state, Dst, LastElement, /* IsDst = */ true);
+      if (!state)
+        return;
+
+      // If this is a stpcpy-style copy, the last element is the return value.
+      if (ReturnEnd)
+        Result = LastElement;
+    }
+
+    // Invalidate the destination. This must happen before we set the C string
+    // length because invalidation will clear the length.
+    // FIXME: Even if we can't perfectly model the copy, we should see if we
+    // can use LazyCompoundVals to copy the source values into the destination.
+    // This would probably remove any existing bindings past the end of the
+    // string, but that's still an improvement over blank invalidation.
+    state = InvalidateBuffer(C, state, Dst, *DstRegVal);
+
+    // Set the C string length of the destination.
+    state = SetCStringLength(state, DstRegVal->getRegion(), StrLen);
+  }
+
+  // If this is a stpcpy-style copy, but we were unable to check for a buffer
+  // overflow, we still need a result. Conjure a return value.
+  if (ReturnEnd && Result.isUnknown()) {
+    ValueManager &ValMgr = C.getValueManager();
+    unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
+    StrLen = ValMgr.getConjuredSymbolVal(NULL, CE, Count);
+  }
+
+  // Set the return value.
+  state = state->BindExpr(CE, Result);
+  C.addTransition(state);
+}
+
+//===----------------------------------------------------------------------===//
+// The driver method, and other Checker callbacks.
+//===----------------------------------------------------------------------===//
+
+bool CStringChecker::EvalCallExpr(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 FunctionDecl *FD = state->getSVal(Callee).getAsFunctionDecl();
+
+  if (!FD)
+    return false;
+
+  // Get the name of the callee. If it's a builtin, strip off the prefix.
+  llvm::StringRef Name = FD->getName();
+  if (Name.startswith("__builtin_"))
+    Name = Name.substr(10);
+
+  FnCheck EvalFunction = llvm::StringSwitch<FnCheck>(Name)
+    .Cases("memcpy", "__memcpy_chk", &CStringChecker::EvalMemcpy)
+    .Cases("memcmp", "bcmp", &CStringChecker::EvalMemcmp)
+    .Cases("memmove", "__memmove_chk", &CStringChecker::EvalMemmove)
+    .Cases("strcpy", "__strcpy_chk", &CStringChecker::EvalStrcpy)
+    .Cases("stpcpy", "__stpcpy_chk", &CStringChecker::EvalStpcpy)
+    .Case("strlen", &CStringChecker::EvalStrlen)
+    .Case("bcopy", &CStringChecker::EvalBcopy)
+    .Default(NULL);
+
+  // If the callee isn't a string function, let another checker handle it.
+  if (!EvalFunction)
+    return false;
+
+  // Check and evaluate the call.
+  (this->*EvalFunction)(C, CE);
+  return true;
+}
+
+void CStringChecker::PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS) {
+  // Record string length for char a[] = "abc";
+  const GRState *state = C.getState();
+
+  for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end();
+       I != E; ++I) {
+    const VarDecl *D = dyn_cast<VarDecl>(*I);
+    if (!D)
+      continue;
+
+    // FIXME: Handle array fields of structs.
+    if (!D->getType()->isArrayType())
+      continue;
+
+    const Expr *Init = D->getInit();
+    if (!Init)
+      continue;
+    if (!isa<StringLiteral>(Init))
+      continue;
+
+    Loc VarLoc = state->getLValue(D, C.getPredecessor()->getLocationContext());
+    const MemRegion *MR = VarLoc.getAsRegion();
+    if (!MR)
+      continue;
+
+    SVal StrVal = state->getSVal(Init);
+    assert(StrVal.isValid() && "Initializer string is unknown or undefined");
+    DefinedOrUnknownSVal StrLen
+      = cast<DefinedOrUnknownSVal>(GetCStringLength(C, state, Init, StrVal));
+
+    state = state->set<CStringLength>(MR, StrLen);
+  }
+
+  C.addTransition(state);
+}
+
+bool CStringChecker::WantsRegionChangeUpdate(const GRState *state) {
+  CStringLength::EntryMap Entries = state->get<CStringLength>();
+  return !Entries.isEmpty();
+}
+
+const GRState *CStringChecker::EvalRegionChanges(const GRState *state,
+                                                 const MemRegion * const *Begin,
+                                                 const MemRegion * const *End,
+                                                 bool *) {
+  CStringLength::EntryMap Entries = state->get<CStringLength>();
+  if (Entries.isEmpty())
+    return state;
+
+  llvm::SmallPtrSet<const MemRegion *, 8> Invalidated;
+  llvm::SmallPtrSet<const MemRegion *, 32> SuperRegions;
+
+  // First build sets for the changed regions and their super-regions.
+  for ( ; Begin != End; ++Begin) {
+    const MemRegion *MR = *Begin;
+    Invalidated.insert(MR);
+
+    SuperRegions.insert(MR);
+    while (const SubRegion *SR = dyn_cast<SubRegion>(MR)) {
+      MR = SR->getSuperRegion();
+      SuperRegions.insert(MR);
+    }
+  }
+
+  CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>();
+
+  // Then loop over the entries in the current state.
+  for (CStringLength::EntryMap::iterator I = Entries.begin(),
+       E = Entries.end(); I != E; ++I) {
+    const MemRegion *MR = I.getKey();
+
+    // Is this entry for a super-region of a changed region?
+    if (SuperRegions.count(MR)) {
+      Entries = F.Remove(Entries, MR);
+      continue;
+    }
+
+    // Is this entry for a sub-region of a changed region?
+    const MemRegion *Super = MR;
+    while (const SubRegion *SR = dyn_cast<SubRegion>(Super)) {
+      Super = SR->getSuperRegion();
+      if (Invalidated.count(Super)) {
+        Entries = F.Remove(Entries, MR);
+        break;
+      }
+    }
+  }
+
+  return state->set<CStringLength>(Entries);
+}
+
+void CStringChecker::MarkLiveSymbols(const GRState *state, SymbolReaper &SR) {
+  // Mark all symbols in our string length map as valid.
+  CStringLength::EntryMap Entries = state->get<CStringLength>();
+
+  for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end();
+       I != E; ++I) {
+    SVal Len = I.getData();
+    if (SymbolRef Sym = Len.getAsSymbol())
+      SR.markInUse(Sym);
+  }
+}
+
+void CStringChecker::EvalDeadSymbols(CheckerContext &C, SymbolReaper &SR) {
+  if (!SR.hasDeadSymbols())
+    return;
+
+  const GRState *state = C.getState();
+  CStringLength::EntryMap Entries = state->get<CStringLength>();
+  if (Entries.isEmpty())
+    return;
+
+  CStringLength::EntryMap::Factory &F = state->get_context<CStringLength>();
+  for (CStringLength::EntryMap::iterator I = Entries.begin(), E = Entries.end();
+       I != E; ++I) {
+    SVal Len = I.getData();
+    if (SymbolRef Sym = Len.getAsSymbol()) {
+      if (SR.isDead(Sym))
+        Entries = F.Remove(Entries, I.getKey());
+    }
+  }
+
+  state = state->set<CStringLength>(Entries);
+  C.GenerateNode(state);
+}
diff --git a/lib/Checker/CallAndMessageChecker.cpp b/lib/Checker/CallAndMessageChecker.cpp
index c619d75..3c9ddce 100644
--- a/lib/Checker/CallAndMessageChecker.cpp
+++ b/lib/Checker/CallAndMessageChecker.cpp
@@ -114,7 +114,7 @@
       : C(c), StoreMgr(storeMgr), MrMgr(mrMgr), store(s) {}
 
       bool Find(const TypedRegion *R) {
-        QualType T = R->getValueType(C);
+        QualType T = R->getValueType();
         if (const RecordType *RT = T->getAsStructureType()) {
           const RecordDecl *RD = RT->getDecl()->getDefinition();
           assert(RD && "Referred record has no definition");
diff --git a/lib/Checker/CallInliner.cpp b/lib/Checker/CallInliner.cpp
deleted file mode 100644
index 88e1a05..0000000
--- a/lib/Checker/CallInliner.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//===--- 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/CastSizeChecker.cpp b/lib/Checker/CastSizeChecker.cpp
new file mode 100644
index 0000000..a502c10
--- /dev/null
+++ b/lib/Checker/CastSizeChecker.cpp
@@ -0,0 +1,87 @@
+//=== CastSizeChecker.cpp ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// CastSizeChecker checks when casting a malloc'ed symbolic region to type T,
+// whether the size of the symbolic region is a multiple of the size of T.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/CharUnits.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "GRExprEngineInternalChecks.h"
+
+using namespace clang;
+
+namespace {
+class CastSizeChecker : public CheckerVisitor<CastSizeChecker> {
+  BuiltinBug *BT;
+public:
+  CastSizeChecker() : BT(0) {}
+  static void *getTag();
+  void PreVisitCastExpr(CheckerContext &C, const CastExpr *B);
+};
+}
+
+void *CastSizeChecker::getTag() {
+  static int x;
+  return &x;
+}
+
+void CastSizeChecker::PreVisitCastExpr(CheckerContext &C, const CastExpr *CE) {
+  const Expr *E = CE->getSubExpr();
+  ASTContext &Ctx = C.getASTContext();
+  QualType ToTy = Ctx.getCanonicalType(CE->getType());
+  PointerType *ToPTy = dyn_cast<PointerType>(ToTy.getTypePtr());
+
+  if (!ToPTy)
+    return;
+
+  QualType ToPointeeTy = ToPTy->getPointeeType();
+
+  const GRState *state = C.getState();
+  const MemRegion *R = state->getSVal(E).getAsRegion();
+  if (R == 0)
+    return;
+
+  const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R);
+  if (SR == 0)
+    return;
+
+  ValueManager &ValMgr = C.getValueManager();
+  SVal Extent = SR->getExtent(ValMgr);
+
+  SValuator &SVator = ValMgr.getSValuator();
+  const llvm::APSInt *ExtentInt = SVator.getKnownValue(state, Extent);
+  if (!ExtentInt)
+    return;
+
+  CharUnits RegionSize = CharUnits::fromQuantity(ExtentInt->getSExtValue());
+  CharUnits TypeSize = C.getASTContext().getTypeSizeInChars(ToPointeeTy);
+  
+  // Ignore void, and a few other un-sizeable types.
+  if (TypeSize.isZero())
+    return;
+  
+  if (RegionSize % TypeSize != 0) {
+    if (ExplodedNode *N = C.GenerateSink()) {
+      if (!BT)
+        BT = new BuiltinBug("Cast region with wrong size.",
+                            "Cast a region whose size is not a multiple of the"
+                            " destination type size.");
+      RangedBugReport *R = new RangedBugReport(*BT, BT->getDescription(), N);
+      R->addRange(CE->getSourceRange());
+      C.EmitReport(R);
+    }
+  }
+}
+
+
+void clang::RegisterCastSizeChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new CastSizeChecker());
+}
diff --git a/lib/Checker/CheckDeadStores.cpp b/lib/Checker/CheckDeadStores.cpp
index d6ea187..3896100 100644
--- a/lib/Checker/CheckDeadStores.cpp
+++ b/lib/Checker/CheckDeadStores.cpp
@@ -217,7 +217,7 @@
               // 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))
+              if (E->isConstantInitializer(Ctx, false))
                 return;
 
               if (DeclRefExpr *DRE=dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
@@ -268,7 +268,7 @@
     // 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 (U->getOpcode() == UO_AddrOf)
       if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E))
         if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) {
           Escaped.insert(VD);
diff --git a/lib/Checker/CheckObjCDealloc.cpp b/lib/Checker/CheckObjCDealloc.cpp
index c23be87..11ddaca 100644
--- a/lib/Checker/CheckObjCDealloc.cpp
+++ b/lib/Checker/CheckObjCDealloc.cpp
@@ -115,7 +115,8 @@
     QualType T = ID->getType();
 
     if (!T->isObjCObjectPointerType() ||
-        ID->getAttr<IBOutletAttr>()) // Skip IBOutlets.
+        ID->getAttr<IBOutletAttr>() || // Skip IBOutlets.
+        ID->getAttr<IBOutletCollectionAttr>()) // Skip IBOutletCollections.
       continue;
 
     containsPointerIvar = true;
diff --git a/lib/Checker/CheckSecuritySyntaxOnly.cpp b/lib/Checker/CheckSecuritySyntaxOnly.cpp
index 74e12b1..9a2ac45 100644
--- a/lib/Checker/CheckSecuritySyntaxOnly.cpp
+++ b/lib/Checker/CheckSecuritySyntaxOnly.cpp
@@ -41,8 +41,8 @@
 
 public:
   WalkAST(BugReporter &br) : BR(br),
-			     II_gets(0), II_getpw(0), II_mktemp(0),
-			     II_rand(), II_random(0), II_setid(),
+                             II_gets(0), II_getpw(0), II_mktemp(0),
+                             II_rand(), II_random(0), II_setid(),
                  CheckRand(isArc4RandomAvailable(BR.getContext())) {}
 
   // Statement visitor methods.
@@ -131,7 +131,7 @@
 
   if (const BinaryOperator *B = dyn_cast<BinaryOperator>(expr)) {
     if (!(B->isAssignmentOp() || B->isCompoundAssignmentOp() ||
-          B->getOpcode() == BinaryOperator::Comma))
+          B->getOpcode() == BO_Comma))
       return NULL;
 
     if (const DeclRefExpr *lhs = GetIncrementedVar(B->getLHS(), x, y))
@@ -191,8 +191,8 @@
   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;
+  drLHS = drLHS && drLHS->getType()->isRealFloatingType() ? drLHS : NULL;
+  drRHS = drRHS && drRHS->getType()->isRealFloatingType() ? drRHS : NULL;
 
   if (!drLHS && !drRHS)
     return;
@@ -217,7 +217,7 @@
   llvm::SmallString<256> sbuf;
   llvm::raw_svector_ostream os(sbuf);
 
-  os << "Variable '" << drCond->getDecl()->getNameAsCString()
+  os << "Variable '" << drCond->getDecl()->getName()
      << "' with floating point type '" << drCond->getType().getAsString()
      << "' should not be used as a loop counter";
 
@@ -332,10 +332,10 @@
   // 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);
+                     "Security",
+                     "Call to function 'mktemp' is insecure as it always "
+                     "creates or uses insecure temporary file.  Use 'mkstemp' instead",
+                     CE->getLocStart(), &R, 1);
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/Checker/CheckerHelpers.cpp b/lib/Checker/CheckerHelpers.cpp
new file mode 100644
index 0000000..ece6943
--- /dev/null
+++ b/lib/Checker/CheckerHelpers.cpp
@@ -0,0 +1,80 @@
+//===---- CheckerHelpers.cpp - Helper functions 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 several static functions for use in checkers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Checker/PathSensitive/CheckerHelpers.h"
+#include "clang/AST/Expr.h"
+
+// Recursively find any substatements containing macros
+bool clang::containsMacro(const Stmt *S) {
+  if (S->getLocStart().isMacroID())
+    return true;
+
+  if (S->getLocEnd().isMacroID())
+    return true;
+
+  for (Stmt::const_child_iterator I = S->child_begin(); I != S->child_end();
+      ++I)
+    if (const Stmt *child = *I)
+      if (containsMacro(child))
+        return true;
+
+  return false;
+}
+
+// Recursively find any substatements containing enum constants
+bool clang::containsEnum(const Stmt *S) {
+  const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S);
+
+  if (DR && isa<EnumConstantDecl>(DR->getDecl()))
+    return true;
+
+  for (Stmt::const_child_iterator I = S->child_begin(); I != S->child_end();
+      ++I)
+    if (const Stmt *child = *I)
+      if (containsEnum(child))
+        return true;
+
+  return false;
+}
+
+// Recursively find any substatements containing static vars
+bool clang::containsStaticLocal(const Stmt *S) {
+  const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S);
+
+  if (DR)
+    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl()))
+      if (VD->isStaticLocal())
+        return true;
+
+  for (Stmt::const_child_iterator I = S->child_begin(); I != S->child_end();
+      ++I)
+    if (const Stmt *child = *I)
+      if (containsStaticLocal(child))
+        return true;
+
+  return false;
+}
+
+// Recursively find any substatements containing __builtin_offsetof
+bool clang::containsBuiltinOffsetOf(const Stmt *S) {
+  if (isa<OffsetOfExpr>(S))
+    return true;
+
+  for (Stmt::const_child_iterator I = S->child_begin(); I != S->child_end();
+      ++I)
+    if (const Stmt *child = *I)
+      if (containsBuiltinOffsetOf(child))
+        return true;
+
+  return false;
+}
diff --git a/lib/Checker/CocoaConventions.cpp b/lib/Checker/CocoaConventions.cpp
index 3ba887c..b446a04 100644
--- a/lib/Checker/CocoaConventions.cpp
+++ b/lib/Checker/CocoaConventions.cpp
@@ -173,9 +173,10 @@
   if (!PT)
     return true;
   
-  // We assume that id<..>, id, and "Class" all represent tracked objects.
+  // We assume that id<..>, id, Class, and Class<..> all represent tracked
+  // objects.
   if (PT->isObjCIdType() || PT->isObjCQualifiedIdType() ||
-      PT->isObjCClassType())
+      PT->isObjCClassType() || PT->isObjCQualifiedClassType())
     return true;
   
   // Does the interface subclass NSObject?
diff --git a/lib/Checker/DivZeroChecker.cpp b/lib/Checker/DivZeroChecker.cpp
index e09a871..32e2a17 100644
--- a/lib/Checker/DivZeroChecker.cpp
+++ b/lib/Checker/DivZeroChecker.cpp
@@ -40,10 +40,10 @@
 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)
+  if (Op != BO_Div &&
+      Op != BO_Rem &&
+      Op != BO_DivAssign &&
+      Op != BO_RemAssign)
     return;
 
   if (!B->getRHS()->getType()->isIntegerType() ||
diff --git a/lib/Checker/Environment.cpp b/lib/Checker/Environment.cpp
index addfc21..48152ce 100644
--- a/lib/Checker/Environment.cpp
+++ b/lib/Checker/Environment.cpp
@@ -125,7 +125,7 @@
 //   - Mark the region in DRoots if the binding is a loc::MemRegionVal.
 
 Environment
-EnvironmentManager::RemoveDeadBindings(Environment Env, const Stmt *S,
+EnvironmentManager::RemoveDeadBindings(Environment Env,
                                        SymbolReaper &SymReaper,
                                        const GRState *ST,
                               llvm::SmallVectorImpl<const MemRegion*> &DRoots) {
@@ -163,7 +163,7 @@
     if (!C.isBlkExpr(BlkExpr))
       continue;
 
-    if (SymReaper.isLive(S, BlkExpr)) {
+    if (SymReaper.isLive(BlkExpr)) {
       // Copy the binding to the new map.
       NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
 
diff --git a/lib/Checker/FixedAddressChecker.cpp b/lib/Checker/FixedAddressChecker.cpp
index 4fce45b..29a3c3a 100644
--- a/lib/Checker/FixedAddressChecker.cpp
+++ b/lib/Checker/FixedAddressChecker.cpp
@@ -40,7 +40,7 @@
   // 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)
+  if (B->getOpcode() != BO_Assign)
     return;
 
   QualType T = B->getType();
diff --git a/lib/Checker/FlatStore.cpp b/lib/Checker/FlatStore.cpp
index 2af9ffa..21fa422 100644
--- a/lib/Checker/FlatStore.cpp
+++ b/lib/Checker/FlatStore.cpp
@@ -44,8 +44,7 @@
   }
 
   SVal ArrayToPointer(Loc Array);
-  Store RemoveDeadBindings(Store store, Stmt* Loc, 
-                           const StackFrameContext *LCtx,
+  Store RemoveDeadBindings(Store store, const StackFrameContext *LCtx,
                            SymbolReaper& SymReaper,
                          llvm::SmallVectorImpl<const MemRegion*>& RegionRoots){
     return store;
@@ -57,8 +56,10 @@
 
   typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols;
   
-  Store InvalidateRegion(Store store, const MemRegion *R, const Expr *E, 
-                         unsigned Count, InvalidatedSymbols *IS);
+  Store InvalidateRegions(Store store, const MemRegion * const *I,
+                          const MemRegion * const *E, const Expr *Ex,
+                          unsigned Count, InvalidatedSymbols *IS,
+                          bool invalidateGlobals, InvalidatedRegions *Regions);
 
   void print(Store store, llvm::raw_ostream& Out, const char* nl, 
              const char *sep);
@@ -69,7 +70,14 @@
     return RegionBindings(static_cast<const RegionBindings::TreeTy*>(store));
   }
 
-  Interval RegionToInterval(const MemRegion *R);
+  class RegionInterval {
+  public:
+    const MemRegion *R;
+    Interval I;
+    RegionInterval(const MemRegion *r, int64_t s, int64_t e) : R(r), I(s, e){}
+  };
+
+  RegionInterval RegionToInterval(const MemRegion *R);
 
   SVal RetrieveRegionWithNoBinding(const MemRegion *R, QualType T);
 };
@@ -81,11 +89,15 @@
 
 SVal FlatStoreManager::Retrieve(Store store, Loc L, QualType T) {
   const MemRegion *R = cast<loc::MemRegionVal>(L).getRegion();
-  Interval I = RegionToInterval(R);
+  RegionInterval RI = RegionToInterval(R);
+  // FIXME: FlatStore should handle regions with unknown intervals.
+  if (!RI.R)
+    return UnknownVal();
+
   RegionBindings B = getRegionBindings(store);
-  const BindingVal *BV = B.lookup(R);
+  const BindingVal *BV = B.lookup(RI.R);
   if (BV) {
-    const SVal *V = BVFactory.Lookup(*BV, I);
+    const SVal *V = BVFactory.Lookup(*BV, RI.I);
     if (V)
       return *V;
     else
@@ -111,9 +123,12 @@
   if (V)
     BV = *V;
 
-  Interval I = RegionToInterval(R);
-  BV = BVFactory.Add(BV, I, val);
-  B = RBFactory.Add(B, R, BV);
+  RegionInterval RI = RegionToInterval(R);
+  // FIXME: FlatStore should handle regions with unknown intervals.
+  if (!RI.R)
+    return B.getRoot();
+  BV = BVFactory.Add(BV, RI.I, val);
+  B = RBFactory.Add(B, RI.R, BV);
   return B.getRoot();
 }
 
@@ -134,16 +149,21 @@
 
 Store FlatStoreManager::BindDecl(Store store, const VarRegion *VR, 
                                  SVal initVal) {
-  return store;
+  return Bind(store, ValMgr.makeLoc(VR), initVal);
 }
 
 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) {
+Store FlatStoreManager::InvalidateRegions(Store store,
+                                          const MemRegion * const *I,
+                                          const MemRegion * const *E,
+                                          const Expr *Ex, unsigned Count,
+                                          InvalidatedSymbols *IS,
+                                          bool invalidateGlobals,
+                                          InvalidatedRegions *Regions) {
+  assert(false && "Not implemented");
   return store;
 }
 
@@ -154,15 +174,29 @@
 void FlatStoreManager::iterBindings(Store store, BindingsHandler& f) {
 }
 
-Interval FlatStoreManager::RegionToInterval(const MemRegion *R) { 
+FlatStoreManager::RegionInterval 
+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);
+    QualType T = cast<VarRegion>(R)->getValueType();
+    int64_t Size = Ctx.getTypeSize(T);
+    return RegionInterval(R, 0, Size-1);
   }
+
+  case MemRegion::ElementRegionKind: 
+  case MemRegion::FieldRegionKind: {
+    RegionOffset Offset = R->getAsOffset();
+    // We cannot compute offset for all regions, for example, elements
+    // with symbolic offsets.
+    if (!Offset.getRegion())
+      return RegionInterval(0, 0, 0);
+    int64_t Start = Offset.getOffset();
+    int64_t Size = Ctx.getTypeSize(cast<TypedRegion>(R)->getValueType());
+    return RegionInterval(Offset.getRegion(), Start, Start+Size);
+  }
+
   default:
     llvm_unreachable("Region kind unhandled.");
-    return Interval(0, 0);
+    return RegionInterval(0, 0, 0);
   }
 }
diff --git a/lib/Checker/FrontendActions.cpp b/lib/Checker/FrontendActions.cpp
new file mode 100644
index 0000000..d9a54a0
--- /dev/null
+++ b/lib/Checker/FrontendActions.cpp
@@ -0,0 +1,21 @@
+//===--- 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/Checker/FrontendActions.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Checker/AnalysisConsumer.h"
+using namespace clang;
+
+ASTConsumer *AnalysisAction::CreateASTConsumer(CompilerInstance &CI,
+                                               llvm::StringRef InFile) {
+  return CreateAnalysisConsumer(CI.getPreprocessor(),
+                                CI.getFrontendOpts().OutputFile,
+                                CI.getAnalyzerOpts());
+}
+
diff --git a/lib/Checker/GRCXXExprEngine.cpp b/lib/Checker/GRCXXExprEngine.cpp
index 00ac995..a49989b 100644
--- a/lib/Checker/GRCXXExprEngine.cpp
+++ b/lib/Checker/GRCXXExprEngine.cpp
@@ -17,7 +17,7 @@
 
 using namespace clang;
 
-void GRExprEngine::EvalArguments(ExprIterator AI, ExprIterator AE,
+void GRExprEngine::EvalArguments(ConstExprIterator AI, ConstExprIterator AE,
                                  const FunctionProtoType *FnType, 
                                  ExplodedNode *Pred, ExplodedNodeSet &Dst) {
   llvm::SmallVector<CallExprWLItem, 20> WorkList;
@@ -55,7 +55,7 @@
   return ValMgr.getRegionManager().getCXXThisRegion(PT, SFC);
 }
 
-void GRExprEngine::CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred,
+void GRExprEngine::CreateCXXTemporaryObject(const Expr *Ex, ExplodedNode *Pred,
                                             ExplodedNodeSet &Dst) {
   ExplodedNodeSet Tmp;
   Visit(Ex, Pred, Tmp);
@@ -86,7 +86,7 @@
   const CXXConstructorDecl *CD = E->getConstructor();
   assert(CD);
 
-  if (!CD->isThisDeclarationADefinition())
+  if (!(CD->isThisDeclarationADefinition() && AMgr.shouldInlineCall()))
     // FIXME: invalidate the object.
     return;
 
@@ -94,9 +94,7 @@
   // 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);
+  EvalArguments(E->arg_begin(), 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(),
@@ -104,11 +102,12 @@
 
   const CXXThisRegion *ThisR = getCXXThisRegion(E->getConstructor(), SFC);
 
-  CallEnter Loc(E, CD, Pred->getLocationContext());
+  CallEnter Loc(E, SFC->getAnalysisContext(), Pred->getLocationContext());
   for (ExplodedNodeSet::iterator NI = ArgsEvaluated.begin(),
                                  NE = ArgsEvaluated.end(); NI != NE; ++NI) {
     const GRState *state = GetState(*NI);
-    // Setup 'this' region.
+    // Setup 'this' region, so that the ctor is evaluated on the object pointed
+    // by 'Dest'.
     state = state->bindLoc(loc::MemRegionVal(ThisR), Dest);
     ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
     if (N)
@@ -126,9 +125,7 @@
 
   // Evaluate explicit arguments with a worklist.
   ExplodedNodeSet ArgsEvaluated;
-  EvalArguments(const_cast<CXXMemberCallExpr*>(MCE)->arg_begin(),
-                const_cast<CXXMemberCallExpr*>(MCE)->arg_end(),
-                FnType, Pred, ArgsEvaluated);
+  EvalArguments(MCE->arg_begin(), MCE->arg_end(), FnType, Pred, ArgsEvaluated);
  
   // Evaluate the implicit object argument.
   ExplodedNodeSet AllArgsEvaluated;
@@ -147,7 +144,7 @@
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
   assert(MD && "not a CXXMethodDecl?");
 
-  if (!MD->isThisDeclarationADefinition())
+  if (!(MD->isThisDeclarationADefinition() && AMgr.shouldInlineCall()))
     // FIXME: conservative method call evaluation.
     return;
 
@@ -157,7 +154,7 @@
                                                     Builder->getBlock(), 
                                                     Builder->getIndex());
   const CXXThisRegion *ThisR = getCXXThisRegion(MD, SFC);
-  CallEnter Loc(MCE, MD, Pred->getLocationContext());
+  CallEnter Loc(MCE, SFC->getAnalysisContext(), Pred->getLocationContext());
   for (ExplodedNodeSet::iterator I = AllArgsEvaluated.begin(),
          E = AllArgsEvaluated.end(); I != E; ++I) {
     // Set up 'this' region.
@@ -169,7 +166,7 @@
   }
 }
 
-void GRExprEngine::VisitCXXNewExpr(CXXNewExpr *CNE, ExplodedNode *Pred,
+void GRExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
                                    ExplodedNodeSet &Dst) {
   if (CNE->isArray()) {
     // FIXME: allocating an array has not been handled.
@@ -177,7 +174,7 @@
   }
 
   unsigned Count = Builder->getCurrentBlockCount();
-  DefinedOrUnknownSVal SymVal = getValueManager().getConjuredSymbolVal(NULL,CNE, 
+  DefinedOrUnknownSVal SymVal = getValueManager().getConjuredSymbolVal(NULL,CNE,
                                                          CNE->getType(), Count);
   const MemRegion *NewReg = cast<loc::MemRegionVal>(SymVal).getRegion();
 
@@ -201,10 +198,7 @@
     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);
+      state = state->InvalidateRegion(EleReg, CNE, Count);
     } else {
       if (CNE->hasInitializer()) {
         SVal V = state->getSVal(*CNE->constructor_arg_begin());
@@ -220,8 +214,8 @@
   }
 }
 
-void GRExprEngine::VisitCXXDeleteExpr(CXXDeleteExpr *CDE, ExplodedNode *Pred,
-                                      ExplodedNodeSet &Dst) {
+void GRExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 
+                                      ExplodedNode *Pred,ExplodedNodeSet &Dst) {
   // Should do more checking.
   ExplodedNodeSet ArgEvaluated;
   Visit(CDE->getArgument(), Pred, ArgEvaluated);
@@ -232,7 +226,7 @@
   }
 }
 
-void GRExprEngine::VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred,
+void GRExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
                                     ExplodedNodeSet &Dst) {
   // Get the this object region from StoreManager.
   const MemRegion *R =
diff --git a/lib/Checker/GRCoreEngine.cpp b/lib/Checker/GRCoreEngine.cpp
index 23a87d3..5125f36 100644
--- a/lib/Checker/GRCoreEngine.cpp
+++ b/lib/Checker/GRCoreEngine.cpp
@@ -12,8 +12,10 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/Checker/PathSensitive/AnalysisManager.h"
 #include "clang/Checker/PathSensitive/GRCoreEngine.h"
 #include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Index/TranslationUnit.h"
 #include "clang/AST/Expr.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/ADT/DenseMap.h"
@@ -24,6 +26,12 @@
 using llvm::isa;
 using namespace clang;
 
+// This should be removed in the future.
+namespace clang {
+GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
+                                  const LangOptions& lopts);
+}
+
 //===----------------------------------------------------------------------===//
 // Worklist classes for exploration of reachable states.
 //===----------------------------------------------------------------------===//
@@ -118,47 +126,15 @@
 //===----------------------------------------------------------------------===//
 // 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) {
+bool GRCoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps,
+                                   const GRState *InitState) {
 
   if (G->num_roots() == 0) { // Initialize the analysis by constructing
     // the root if none exists.
 
-    CFGBlock* Entry = &(L->getCFG()->getEntry());
+    const CFGBlock* Entry = &(L->getCFG()->getEntry());
 
     assert (Entry->empty() &&
             "Entry block must be empty.");
@@ -167,7 +143,7 @@
             "Entry block must have 1 successor.");
 
     // Get the solitary successor.
-    CFGBlock* Succ = *(Entry->succ_begin());
+    const CFGBlock* Succ = *(Entry->succ_begin());
 
     // Construct an edge representing the
     // starting location in the function.
@@ -176,8 +152,11 @@
     // Set the current block counter to being empty.
     WList->setBlockCounter(BCounterFactory.GetEmptyCounter());
 
-    // Generate the root.
-    GenerateNode(StartLoc, getInitialState(L), 0);
+    if (!InitState)
+      // Generate the root.
+      GenerateNode(StartLoc, getInitialState(L), 0);
+    else
+      GenerateNode(StartLoc, InitState, 0);
   }
 
   while (Steps && WList->hasWork()) {
@@ -221,13 +200,25 @@
     }
   }
 
+  SubEngine.ProcessEndWorklist(hasWorkRemaining());
   return WList->hasWork();
 }
 
+void GRCoreEngine::ExecuteWorkListWithInitialState(const LocationContext *L, 
+                                                   unsigned Steps,
+                                                   const GRState *InitState, 
+                                                   ExplodedNodeSet &Dst) {
+  ExecuteWorkList(L, Steps, InitState);
+  for (llvm::SmallVectorImpl<ExplodedNode*>::iterator I = G->EndNodes.begin(), 
+                                           E = G->EndNodes.end(); I != E; ++I) {
+    Dst.Add(*I);
+  }
+}
+
 void GRCoreEngine::HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
                                    unsigned Index, ExplodedNode *Pred) {
-  GRCallEnterNodeBuilder Builder(*this, Pred, L.getCallExpr(), L.getCallee(), 
-                                 Block, Index);
+  GRCallEnterNodeBuilder Builder(*this, Pred, L.getCallExpr(), 
+                                 L.getCalleeContext(), Block, Index);
   ProcessCallEnter(Builder);
 }
 
@@ -238,7 +229,7 @@
 
 void GRCoreEngine::HandleBlockEdge(const BlockEdge& L, ExplodedNode* Pred) {
 
-  CFGBlock* Blk = L.getDst();
+  const CFGBlock* Blk = L.getDst();
 
   // Check if we are entering the EXIT block.
   if (Blk == &(L.getLocationContext()->getCFG()->getExit())) {
@@ -257,7 +248,11 @@
   // FIXME: Should we allow ProcessBlockEntrance to also manipulate state?
 
   if (ProcessBlockEntrance(Blk, Pred, WList->getBlockCounter()))
-    GenerateNode(BlockEntrance(Blk, Pred->getLocationContext()), Pred->State, Pred);
+    GenerateNode(BlockEntrance(Blk, Pred->getLocationContext()),
+                 Pred->State, Pred);
+  else {
+    blocksAborted.push_back(std::make_pair(L, Pred));
+  }
 }
 
 void GRCoreEngine::HandleBlockEntrance(const BlockEntrance& L,
@@ -280,9 +275,9 @@
     HandleBlockExit(L.getBlock(), Pred);
 }
 
-void GRCoreEngine::HandleBlockExit(CFGBlock * B, ExplodedNode* Pred) {
+void GRCoreEngine::HandleBlockExit(const CFGBlock * B, ExplodedNode* Pred) {
 
-  if (Stmt* Term = B->getTerminator()) {
+  if (const Stmt* Term = B->getTerminator()) {
     switch (Term->getStmtClass()) {
       default:
         assert(false && "Analysis for this terminator not implemented.");
@@ -368,8 +363,8 @@
                Pred->State, Pred);
 }
 
-void GRCoreEngine::HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock * B,
-                                ExplodedNode* Pred) {
+void GRCoreEngine::HandleBranch(const Stmt* Cond, const Stmt* Term, 
+                                const CFGBlock * B, ExplodedNode* Pred) {
   assert (B->succ_size() == 2);
 
   GRBranchNodeBuilder Builder(B, *(B->succ_begin()), *(B->succ_begin()+1),
@@ -378,7 +373,7 @@
   ProcessBranch(Cond, Term, Builder);
 }
 
-void GRCoreEngine::HandlePostStmt(const PostStmt& L, CFGBlock* B,
+void GRCoreEngine::HandlePostStmt(const PostStmt& L, const CFGBlock* B,
                                   unsigned StmtIdx, ExplodedNode* Pred) {
 
   assert (!B->empty());
@@ -411,7 +406,7 @@
   if (IsNew) WList->Enqueue(Node);
 }
 
-GRStmtNodeBuilder::GRStmtNodeBuilder(CFGBlock* b, unsigned idx,
+GRStmtNodeBuilder::GRStmtNodeBuilder(const CFGBlock* b, unsigned idx,
                                      ExplodedNode* N, GRCoreEngine* e,
                                      GRStateManager &mgr)
   : Eng(*e), B(*b), Idx(idx), Pred(N), Mgr(mgr), Auditor(0),
@@ -434,7 +429,7 @@
   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);
+    Eng.WList->Enqueue(N, &B, Idx);
     return;
   }
 
@@ -443,7 +438,7 @@
   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);
+    Eng.WList->Enqueue(N, &B, Idx+1);
     return;
   }
 
@@ -452,10 +447,10 @@
   Succ->addPredecessor(N, *Eng.G);
 
   if (IsNew)
-    Eng.WList->Enqueue(Succ, B, Idx+1);
+    Eng.WList->Enqueue(Succ, &B, Idx+1);
 }
 
-ExplodedNode* GRStmtNodeBuilder::MakeNode(ExplodedNodeSet& Dst, Stmt* S, 
+ExplodedNode* GRStmtNodeBuilder::MakeNode(ExplodedNodeSet& Dst, const Stmt* S, 
                                           ExplodedNode* Pred, const GRState* St,
                                           ProgramPoint::Kind K) {
   const GRState* PredState = GetState(Pred);
@@ -688,6 +683,59 @@
 
 void GRCallEnterNodeBuilder::GenerateNode(const GRState *state,
                                           const LocationContext *LocCtx) {
+  // Check if the callee is in the same translation unit.
+  if (CalleeCtx->getTranslationUnit() != 
+      Pred->getLocationContext()->getTranslationUnit()) {
+    // Create a new engine. We must be careful that the new engine should not
+    // reference data structures owned by the old engine.
+
+    AnalysisManager &OldMgr = Eng.SubEngine.getAnalysisManager();
+    
+    // Get the callee's translation unit.
+    idx::TranslationUnit *TU = CalleeCtx->getTranslationUnit();
+
+    // Create a new AnalysisManager with components of the callee's
+    // TranslationUnit.
+    // The Diagnostic is actually shared when we create ASTUnits from AST files.
+    AnalysisManager AMgr(TU->getASTContext(), TU->getDiagnostic(), 
+                         OldMgr.getLangOptions(), 
+                         OldMgr.getPathDiagnosticClient(),
+                         OldMgr.getStoreManagerCreator(),
+                         OldMgr.getConstraintManagerCreator(),
+                         OldMgr.getIndexer(),
+                         OldMgr.getMaxNodes(), OldMgr.getMaxLoop(),
+                         OldMgr.shouldVisualizeGraphviz(),
+                         OldMgr.shouldVisualizeUbigraph(),
+                         OldMgr.shouldPurgeDead(),
+                         OldMgr.shouldEagerlyAssume(),
+                         OldMgr.shouldTrimGraph(),
+                         OldMgr.shouldInlineCall(),
+                     OldMgr.getAnalysisContextManager().getUseUnoptimizedCFG());
+    llvm::OwningPtr<GRTransferFuncs> TF(MakeCFRefCountTF(AMgr.getASTContext(),
+                                                         /* GCEnabled */ false,
+                                                        AMgr.getLangOptions()));
+    // Create the new engine.
+    GRExprEngine NewEng(AMgr, TF.take());
+
+    // Create the new LocationContext.
+    AnalysisContext *NewAnaCtx = AMgr.getAnalysisContext(CalleeCtx->getDecl(), 
+                                               CalleeCtx->getTranslationUnit());
+    const StackFrameContext *OldLocCtx = cast<StackFrameContext>(LocCtx);
+    const StackFrameContext *NewLocCtx = AMgr.getStackFrame(NewAnaCtx, 
+                                               OldLocCtx->getParent(),
+                                               OldLocCtx->getCallSite(),
+                                               OldLocCtx->getCallSiteBlock(), 
+                                               OldLocCtx->getIndex());
+
+    // Now create an initial state for the new engine.
+    const GRState *NewState = NewEng.getStateManager().MarshalState(state,
+                                                                    NewLocCtx);
+    ExplodedNodeSet ReturnNodes;
+    NewEng.ExecuteWorkListWithInitialState(NewLocCtx, AMgr.getMaxNodes(), 
+                                           NewState, ReturnNodes);
+    return;
+  }
+
   // Get the callee entry block.
   const CFGBlock *Entry = &(LocCtx->getCFG()->getEntry());
   assert(Entry->empty());
@@ -717,6 +765,6 @@
   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()),
+    Eng.WList->Enqueue(Node, LocCtx->getCallSiteBlock(),
                        LocCtx->getIndex() + 1);
 }
diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp
index c11a16f..c9173aa 100644
--- a/lib/Checker/GRExprEngine.cpp
+++ b/lib/Checker/GRExprEngine.cpp
@@ -169,18 +169,46 @@
 // Checker worklist routines.
 //===----------------------------------------------------------------------===//
 
-void GRExprEngine::CheckerVisit(Stmt *S, ExplodedNodeSet &Dst,
-                                ExplodedNodeSet &Src, bool isPrevisit) {
+void GRExprEngine::CheckerVisit(const Stmt *S, ExplodedNodeSet &Dst,
+                                ExplodedNodeSet &Src, CallbackKind Kind) {
 
-  if (Checkers.empty()) {
+  // Determine if we already have a cached 'CheckersOrdered' vector
+  // specifically tailored for the provided <CallbackKind, Stmt kind>.  This
+  // can reduce the number of checkers actually called.
+  CheckersOrdered *CO = &Checkers;
+  llvm::OwningPtr<CheckersOrdered> NewCO;
+
+  // The cache key is made up of the and the callback kind (pre- or post-visit)
+  // and the statement kind.
+  CallbackTag K = GetCallbackTag(Kind, S->getStmtClass());
+
+  CheckersOrdered *& CO_Ref = COCache[K];
+  
+  if (!CO_Ref) {
+    // If we have no previously cached CheckersOrdered vector for this
+    // statement kind, then create one.
+    NewCO.reset(new CheckersOrdered);
+  }
+  else {
+    // Use the already cached set.
+    CO = CO_Ref;
+  }
+  
+  if (CO->empty()) {
+    // If there are no checkers, return early without doing any
+    // more work.
     Dst.insert(Src);
     return;
   }
 
   ExplodedNodeSet Tmp;
   ExplodedNodeSet *PrevSet = &Src;
+  unsigned checkersEvaluated = 0;
 
-  for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end(); I!=E;++I){
+  for (CheckersOrdered::iterator I=CO->begin(), E=CO->end(); I!=E; ++I) {
+    // If all nodes are sunk, bail out early.
+    if (PrevSet->empty())
+      break;
     ExplodedNodeSet *CurrSet = 0;
     if (I+1 == E)
       CurrSet = &Dst;
@@ -190,12 +218,32 @@
     }
     void *tag = I->first;
     Checker *checker = I->second;
+    bool respondsToCallback = true;
 
     for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
-         NI != NE; ++NI)
-      checker->GR_Visit(*CurrSet, *Builder, *this, S, *NI, tag, isPrevisit);
+         NI != NE; ++NI) {
+
+      checker->GR_Visit(*CurrSet, *Builder, *this, S, *NI, tag,
+                        Kind == PreVisitStmtCallback, respondsToCallback);
+      
+    }
+
     PrevSet = CurrSet;
+
+    if (NewCO.get()) {
+      ++checkersEvaluated;
+      if (respondsToCallback)
+        NewCO->push_back(*I);
+    }    
   }
+  
+  // If we built NewCO, check if we called all the checkers.  This is important
+  // so that we know that we accurately determined the entire set of checkers
+  // that responds to this callback.  Note that 'checkersEvaluated' might
+  // not be the same as Checkers.size() if one of the Checkers generates
+  // a sink node.
+  if (NewCO.get() && checkersEvaluated == Checkers.size())
+    CO_Ref = NewCO.take();
 
   // Don't autotransition.  The CheckerContext objects should do this
   // automatically.
@@ -312,18 +360,20 @@
   // automatically.  Note that the check itself is owned by the GRExprEngine
   // object.
   RegisterAdjustedReturnValueChecker(Eng);
-  RegisterAttrNonNullChecker(Eng);
+  // CallAndMessageChecker should be registered before AttrNonNullChecker,
+  // where we assume arguments are not undefined.
   RegisterCallAndMessageChecker(Eng);
+  RegisterAttrNonNullChecker(Eng);
   RegisterDereferenceChecker(Eng);
   RegisterVLASizeChecker(Eng);
   RegisterDivZeroChecker(Eng);
-  RegisterReturnStackAddressChecker(Eng);
   RegisterReturnUndefChecker(Eng);
   RegisterUndefinedArraySubscriptChecker(Eng);
   RegisterUndefinedAssignmentChecker(Eng);
   RegisterUndefBranchChecker(Eng);
   RegisterUndefCapturedBlockVarChecker(Eng);
   RegisterUndefResultChecker(Eng);
+  RegisterStackAddrLeakChecker(Eng);
 
   // This is not a checker yet.
   RegisterNoReturnFunctionChecker(Eng);
@@ -335,10 +385,10 @@
 
 GRExprEngine::GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf)
   : AMgr(mgr),
-    CoreEngine(mgr.getASTContext(), *this),
+    CoreEngine(*this),
     G(CoreEngine.getGraph()),
     Builder(NULL),
-    StateMgr(G.getContext(), mgr.getStoreManagerCreator(),
+    StateMgr(getContext(), mgr.getStoreManagerCreator(),
              mgr.getConstraintManagerCreator(), G.getAllocator(),
              *this),
     SymMgr(StateMgr.getSymbolManager()),
@@ -346,7 +396,7 @@
     SVator(ValMgr.getSValuator()),
     CurrentStmt(NULL),
     NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
-    RaiseSel(GetNullarySelector("raise", G.getContext())),
+    RaiseSel(GetNullarySelector("raise", getContext())),
     BR(mgr, *this), TF(tf) {
   // Register internal checks.
   RegisterInternalChecks(*this);
@@ -359,8 +409,14 @@
 GRExprEngine::~GRExprEngine() {
   BR.FlushReports();
   delete [] NSExceptionInstanceRaiseSelectors;
+  
+  // Delete the set of checkers.
   for (CheckersOrdered::iterator I=Checkers.begin(), E=Checkers.end(); I!=E;++I)
     delete I->second;
+  
+  for (CheckersOrderedCache::iterator I=COCache.begin(), E=COCache.end();
+       I!=E;++I)
+    delete I->second;
 }
 
 //===----------------------------------------------------------------------===//
@@ -407,7 +463,7 @@
         break;
 
       SVal V = state->getSVal(loc::MemRegionVal(R));
-      SVal Constraint_untested = EvalBinOp(state, BinaryOperator::GT, V,
+      SVal Constraint_untested = EvalBinOp(state, BO_GT, V,
                                            ValMgr.makeZeroVal(T),
                                            getContext().IntTy);
 
@@ -449,22 +505,135 @@
 ///  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) {
+  // Determine if we already have a cached 'CheckersOrdered' vector
+  // specifically tailored for processing assumptions.  This
+  // can reduce the number of checkers actually called.
+  CheckersOrdered *CO = &Checkers;
+  llvm::OwningPtr<CheckersOrdered> NewCO;
 
-    if (!state)
-      return NULL;
+  CallbackTag K = GetCallbackTag(ProcessAssumeCallback);
+  CheckersOrdered *& CO_Ref = COCache[K];
 
-    state = I->second->EvalAssume(state, cond, assumption);
+  if (!CO_Ref) {
+    // If we have no previously cached CheckersOrdered vector for this
+    // statement kind, then create one.
+    NewCO.reset(new CheckersOrdered);
+  }
+  else {
+    // Use the already cached set.
+    CO = CO_Ref;
   }
 
+  if (!CO->empty()) {
+    // Let the checkers have a crack at the assume before the transfer functions
+    // get their turn.
+    for (CheckersOrdered::iterator I = CO->begin(), E = CO->end(); I!=E; ++I) {
+
+      // If any checker declares the state infeasible (or if it starts that
+      // way), bail out.
+      if (!state)
+        return NULL;
+
+      Checker *C = I->second;
+      bool respondsToCallback = true;
+
+      state = C->EvalAssume(state, cond, assumption, &respondsToCallback);
+
+      // Check if we're building the cache of checkers that care about Assumes.
+      if (NewCO.get() && respondsToCallback)
+        NewCO->push_back(*I);
+    }
+
+    // If we got through all the checkers, and we built a list of those that
+    // care about Assumes, save it.
+    if (NewCO.get())
+      CO_Ref = NewCO.take();
+  }
+
+  // If the state is infeasible at this point, bail out.
   if (!state)
     return NULL;
 
   return TF->EvalAssume(state, cond, assumption);
 }
 
-void GRExprEngine::ProcessStmt(CFGElement CE, GRStmtNodeBuilder& builder) {
+bool GRExprEngine::WantsRegionChangeUpdate(const GRState* state) {
+  CallbackTag K = GetCallbackTag(EvalRegionChangesCallback);
+  CheckersOrdered *CO = COCache[K];
+
+  if (!CO)
+    CO = &Checkers;
+
+  for (CheckersOrdered::iterator I = CO->begin(), E = CO->end(); I != E; ++I) {
+    Checker *C = I->second;
+    if (C->WantsRegionChangeUpdate(state))
+      return true;
+  }
+
+  return false;
+}
+
+const GRState *
+GRExprEngine::ProcessRegionChanges(const GRState *state,
+                                   const MemRegion * const *Begin,
+                                   const MemRegion * const *End) {
+  // FIXME: Most of this method is copy-pasted from ProcessAssume.
+
+  // Determine if we already have a cached 'CheckersOrdered' vector
+  // specifically tailored for processing region changes.  This
+  // can reduce the number of checkers actually called.
+  CheckersOrdered *CO = &Checkers;
+  llvm::OwningPtr<CheckersOrdered> NewCO;
+
+  CallbackTag K = GetCallbackTag(EvalRegionChangesCallback);
+  CheckersOrdered *& CO_Ref = COCache[K];
+
+  if (!CO_Ref) {
+    // If we have no previously cached CheckersOrdered vector for this
+    // callback, then create one.
+    NewCO.reset(new CheckersOrdered);
+  }
+  else {
+    // Use the already cached set.
+    CO = CO_Ref;
+  }
+
+  // If there are no checkers, just return the state as is.
+  if (CO->empty())
+    return state;
+
+  for (CheckersOrdered::iterator I = CO->begin(), E = CO->end(); I != E; ++I) {
+    // If any checker declares the state infeasible (or if it starts that way),
+    // bail out.
+    if (!state)
+      return NULL;
+
+    Checker *C = I->second;
+    bool respondsToCallback = true;
+
+    state = C->EvalRegionChanges(state, Begin, End, &respondsToCallback);
+
+    // See if we're building a cache of checkers that care about region changes.
+    if (NewCO.get() && respondsToCallback)
+      NewCO->push_back(*I);
+  }
+
+  // If we got through all the checkers, and we built a list of those that
+  // care about region changes, save it.
+  if (NewCO.get())
+    CO_Ref = NewCO.take();
+
+  return state;
+}
+
+void GRExprEngine::ProcessEndWorklist(bool hasWorkRemaining) {
+  for (CheckersOrdered::iterator I = Checkers.begin(), E = Checkers.end();
+       I != E; ++I) {
+    I->second->VisitEndAnalysis(G, BR, *this);
+  }
+}
+
+void GRExprEngine::ProcessStmt(const CFGElement CE,GRStmtNodeBuilder& builder) {
   CurrentStmt = CE.getStmt();
   PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
                                 CurrentStmt->getLocStart(),
@@ -478,15 +647,23 @@
     Builder->setAuditor(BatchAuditor.get());
 
   // Create the cleaned state.
-  const ExplodedNode *BasePred = Builder->getBasePredecessor();
+  const LocationContext *LC = EntryNode->getLocationContext();
+  SymbolReaper SymReaper(LC, CurrentStmt, SymMgr);
 
-  SymbolReaper SymReaper(BasePred->getLocationContext(), SymMgr);
+  if (AMgr.shouldPurgeDead()) {
+    const GRState *St = EntryNode->getState();
 
-  CleanedState = AMgr.shouldPurgeDead()
-    ? StateMgr.RemoveDeadBindings(EntryNode->getState(), CurrentStmt, 
-                         BasePred->getLocationContext()->getCurrentStackFrame(),
-                                  SymReaper)
-    : EntryNode->getState();
+    for (CheckersOrdered::iterator I = Checkers.begin(), E = Checkers.end();
+         I != E; ++I) {
+      Checker *checker = I->second;
+      checker->MarkLiveSymbols(St, SymReaper);
+    }
+
+    const StackFrameContext *SFC = LC->getCurrentStackFrame();
+    CleanedState = StateMgr.RemoveDeadBindings(St, SFC, SymReaper);
+  } else {
+    CleanedState = EntryNode->getState();
+  }
 
   // Process any special transfer function for dead symbols.
   ExplodedNodeSet Tmp;
@@ -502,7 +679,7 @@
 
     // FIXME: This should soon be removed.
     ExplodedNodeSet Tmp2;
-    getTF().EvalDeadSymbols(Tmp2, *this, *Builder, EntryNode, CurrentStmt,
+    getTF().EvalDeadSymbols(Tmp2, *this, *Builder, EntryNode,
                             CleanedState, SymReaper);
 
     if (Checkers.empty())
@@ -568,7 +745,8 @@
   Builder = NULL;
 }
 
-void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
+void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred, 
+                         ExplodedNodeSet& Dst) {
   PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
                                 S->getLocStart(),
                                 "Error evaluating statement");
@@ -598,7 +776,7 @@
     case Stmt::CXXTryStmtClass:
     case Stmt::CXXTypeidExprClass:
     case Stmt::CXXUnresolvedConstructExprClass:
-    case Stmt::CXXZeroInitValueExprClass:
+    case Stmt::CXXScalarValueInitExprClass:
     case Stmt::DependentScopeDeclRefExprClass:
     case Stmt::UnaryTypeTraitExprClass:
     case Stmt::UnresolvedLookupExprClass:
@@ -627,10 +805,14 @@
       llvm_unreachable("Stmt should not be in analyzer evaluation loop");
       break;
 
+    case Stmt::GNUNullExprClass: {
+      MakeNode(Dst, S, Pred, GetState(Pred)->BindExpr(S, ValMgr.makeNull()));
+      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:
@@ -679,13 +861,13 @@
       break;
 
     case Stmt::BinaryOperatorClass: {
-      BinaryOperator* B = cast<BinaryOperator>(S);
+      const BinaryOperator* B = cast<BinaryOperator>(S);
 
       if (B->isLogicalOp()) {
         VisitLogicalExpr(B, Pred, Dst);
         break;
       }
-      else if (B->getOpcode() == BinaryOperator::Comma) {
+      else if (B->getOpcode() == BO_Comma) {
         const GRState* state = GetState(Pred);
         MakeNode(Dst, B, Pred, state->BindExpr(B, state->getSVal(B->getRHS())));
         break;
@@ -705,25 +887,25 @@
 
     case Stmt::CallExprClass:
     case Stmt::CXXOperatorCallExprClass: {
-      CallExpr* C = cast<CallExpr>(S);
+      const 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);
+      const CXXMemberCallExpr *MCE = cast<CXXMemberCallExpr>(S);
       VisitCXXMemberCallExpr(MCE, Pred, Dst);
       break;
     }
 
     case Stmt::CXXNewExprClass: {
-      CXXNewExpr *NE = cast<CXXNewExpr>(S);
+      const CXXNewExpr *NE = cast<CXXNewExpr>(S);
       VisitCXXNewExpr(NE, Pred, Dst);
       break;
     }
 
     case Stmt::CXXDeleteExprClass: {
-      CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S);
+      const CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S);
       VisitCXXDeleteExpr(CDE, Pred, Dst);
       break;
     }
@@ -731,7 +913,7 @@
       //        the CFG do not model them as explicit control-flow.
 
     case Stmt::ChooseExprClass: { // __builtin_choose_expr
-      ChooseExpr* C = cast<ChooseExpr>(S);
+      const ChooseExpr* C = cast<ChooseExpr>(S);
       VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
       break;
     }
@@ -745,7 +927,7 @@
       break;
 
     case Stmt::ConditionalOperatorClass: { // '?' operator
-      ConditionalOperator* C = cast<ConditionalOperator>(S);
+      const ConditionalOperator* C = cast<ConditionalOperator>(S);
       VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
       break;
     }
@@ -775,7 +957,7 @@
     case Stmt::CXXReinterpretCastExprClass:
     case Stmt::CXXConstCastExprClass:
     case Stmt::CXXFunctionalCastExprClass: {
-      CastExpr* C = cast<CastExpr>(S);
+      const CastExpr* C = cast<CastExpr>(S);
       VisitCast(C, C->getSubExpr(), Pred, Dst, false);
       break;
     }
@@ -823,12 +1005,16 @@
       VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
       break;
 
+    case Stmt::OffsetOfExprClass:
+      VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Pred, Dst);
+      break;
+
     case Stmt::SizeOfAlignOfExprClass:
       VisitSizeOfAlignOfExpr(cast<SizeOfAlignOfExpr>(S), Pred, Dst);
       break;
 
     case Stmt::StmtExprClass: {
-      StmtExpr* SE = cast<StmtExpr>(S);
+      const StmtExpr* SE = cast<StmtExpr>(S);
 
       if (SE->getSubStmt()->body_empty()) {
         // Empty statement expression.
@@ -859,8 +1045,8 @@
       break;
 
     case Stmt::UnaryOperatorClass: {
-      UnaryOperator *U = cast<UnaryOperator>(S);
-      if (AMgr.shouldEagerlyAssume()&&(U->getOpcode() == UnaryOperator::LNot)) {
+      const UnaryOperator *U = cast<UnaryOperator>(S);
+      if (AMgr.shouldEagerlyAssume()&&(U->getOpcode() == UO_LNot)) {
         ExplodedNodeSet Tmp;
         VisitUnaryOperator(U, Pred, Tmp, false);
         EvalEagerlyAssume(Dst, Tmp, U);
@@ -878,7 +1064,7 @@
   }
 }
 
-void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
+void GRExprEngine::VisitLValue(const Expr* Ex, ExplodedNode* Pred,
                                ExplodedNodeSet& Dst) {
 
   PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
@@ -897,7 +1083,7 @@
     // C++ stuff we don't support yet.
     case Stmt::CXXExprWithTemporariesClass:
     case Stmt::CXXMemberCallExprClass:
-    case Stmt::CXXZeroInitValueExprClass: {
+    case Stmt::CXXScalarValueInitExprClass: {
       SaveAndRestore<bool> OldSink(Builder->BuildSinks);
       Builder->BuildSinks = true;
       MakeNode(Dst, Ex, Pred, GetState(Pred));
@@ -919,7 +1105,7 @@
 
     case Stmt::CallExprClass:
     case Stmt::CXXOperatorCallExprClass: {
-      CallExpr *C = cast<CallExpr>(Ex);
+      const CallExpr *C = cast<CallExpr>(Ex);
       assert(CalleeReturnsReferenceOrRecord(C));
       VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst, true);
       break;
@@ -935,7 +1121,7 @@
 
     case Stmt::ImplicitCastExprClass:
     case Stmt::CStyleCastExprClass: {
-      CastExpr *C = cast<CastExpr>(Ex);
+      const CastExpr *C = cast<CastExpr>(Ex);
       QualType T = Ex->getType();
       VisitCast(C, C->getSubExpr(), Pred, Dst, true);
       break;
@@ -950,7 +1136,7 @@
       return;
 
     case Stmt::ObjCMessageExprClass: {
-      ObjCMessageExpr *ME = cast<ObjCMessageExpr>(Ex);
+      const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(Ex);
       assert(ReceiverReturnsReferenceOrRecord(ME));
       VisitObjCMessageExpr(ME, Pred, Dst, true);
       return;
@@ -991,19 +1177,27 @@
     // In C++, binding an rvalue to a reference requires to create an object.
     case Stmt::CXXBoolLiteralExprClass:
     case Stmt::IntegerLiteralClass:
+    case Stmt::CharacterLiteralClass:
+    case Stmt::FloatingLiteralClass:
+    case Stmt::ImaginaryLiteralClass:
       CreateCXXTemporaryObject(Ex, Pred, Dst);
       return;
 
-    default:
+    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.");
+
+      // NOTE: Do not use 'isAggregateType()' here as CXXRecordDecls that
+      //  are non-pod are not aggregates.
+      assert ((isa<RecordType>(Ex->getType().getDesugaredType()) ||
+               isa<ArrayType>(Ex->getType().getDesugaredType())) &&
+              "Other kinds of expressions with non-aggregate/union/class types"
+              " do not have lvalues.");
 
       Visit(Ex, Pred, Dst);
+    }
   }
 }
 
@@ -1011,18 +1205,18 @@
 // Block entrance.  (Update counters).
 //===----------------------------------------------------------------------===//
 
-bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
+bool GRExprEngine::ProcessBlockEntrance(const CFGBlock* B, 
+                                        const ExplodedNode *Pred,
                                         GRBlockCounter BC) {
-
   return BC.getNumVisited(Pred->getLocationContext()->getCurrentStackFrame(), 
-                          B->getBlockID()) < 3;
+                          B->getBlockID()) < AMgr.getMaxLoop();
 }
 
 //===----------------------------------------------------------------------===//
 // Generic node creation.
 //===----------------------------------------------------------------------===//
 
-ExplodedNode* GRExprEngine::MakeNode(ExplodedNodeSet& Dst, Stmt* S,
+ExplodedNode* GRExprEngine::MakeNode(ExplodedNodeSet& Dst, const Stmt* S,
                                      ExplodedNode* Pred, const GRState* St,
                                      ProgramPoint::Kind K, const void *tag) {
   assert (Builder && "GRStmtNodeBuilder not present.");
@@ -1036,8 +1230,8 @@
 //===----------------------------------------------------------------------===//
 
 const GRState* GRExprEngine::MarkBranch(const GRState* state,
-                                           Stmt* Terminator,
-                                           bool branchTaken) {
+                                        const Stmt* Terminator,
+                                        bool branchTaken) {
 
   switch (Terminator->getStmtClass()) {
     default:
@@ -1045,10 +1239,10 @@
 
     case Stmt::BinaryOperatorClass: { // '&&' and '||'
 
-      BinaryOperator* B = cast<BinaryOperator>(Terminator);
+      const BinaryOperator* B = cast<BinaryOperator>(Terminator);
       BinaryOperator::Opcode Op = B->getOpcode();
 
-      assert (Op == BinaryOperator::LAnd || Op == BinaryOperator::LOr);
+      assert (Op == BO_LAnd || Op == BO_LOr);
 
       // For &&, if we take the true branch, then the value of the whole
       // expression is that of the RHS expression.
@@ -1056,21 +1250,21 @@
       // 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();
+      const Expr* Ex = (Op == BO_LAnd && branchTaken) ||
+                       (Op == BO_LOr && !branchTaken)
+                       ? B->getRHS() : B->getLHS();
 
       return state->BindExpr(B, UndefinedVal(Ex));
     }
 
     case Stmt::ConditionalOperatorClass: { // ?:
 
-      ConditionalOperator* C = cast<ConditionalOperator>(Terminator);
+      const ConditionalOperator* C = cast<ConditionalOperator>(Terminator);
 
       // For ?, if branchTaken == true then the value is either the LHS or
       // the condition itself. (GNU extension).
 
-      Expr* Ex;
+      const Expr* Ex;
 
       if (branchTaken)
         Ex = C->getLHS() ? C->getLHS() : C->getCond();
@@ -1082,9 +1276,9 @@
 
     case Stmt::ChooseExprClass: { // ?:
 
-      ChooseExpr* C = cast<ChooseExpr>(Terminator);
+      const ChooseExpr* C = cast<ChooseExpr>(Terminator);
 
-      Expr* Ex = branchTaken ? C->getLHS() : C->getRHS();
+      const Expr* Ex = branchTaken ? C->getLHS() : C->getRHS();
       return state->BindExpr(C, UndefinedVal(Ex));
     }
   }
@@ -1096,16 +1290,16 @@
 /// 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) {
+                                const Stmt* Condition, ASTContext& Ctx) {
 
-  Expr *Ex = dyn_cast<Expr>(Condition);
+  const Expr *Ex = dyn_cast<Expr>(Condition);
   if (!Ex)
     return UnknownVal();
 
   uint64_t bits = 0;
   bool bitsInit = false;
 
-  while (CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
+  while (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
     QualType T = CE->getType();
 
     if (!T->isIntegerType())
@@ -1129,7 +1323,7 @@
   return state->getSVal(Ex);
 }
 
-void GRExprEngine::ProcessBranch(Stmt* Condition, Stmt* Term,
+void GRExprEngine::ProcessBranch(const Stmt* Condition, const Stmt* Term,
                                  GRBranchNodeBuilder& builder) {
 
   // Check for NULL conditions; e.g. "for(;;)"
@@ -1216,7 +1410,7 @@
   typedef GRIndirectGotoNodeBuilder::iterator iterator;
 
   if (isa<loc::GotoLabel>(V)) {
-    LabelStmt* L = cast<loc::GotoLabel>(V).getLabel();
+    const LabelStmt* L = cast<loc::GotoLabel>(V).getLabel();
 
     for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) {
       if (I.getLabel() == L) {
@@ -1245,7 +1439,8 @@
 }
 
 
-void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
+void GRExprEngine::VisitGuardedExpr(const Expr* Ex, const Expr* L, 
+                                    const Expr* R,
                                     ExplodedNode* Pred, ExplodedNodeSet& Dst) {
 
   assert(Ex == CurrentStmt &&
@@ -1256,7 +1451,7 @@
 
   assert (X.isUndef());
 
-  Expr *SE = (Expr*) cast<UndefinedVal>(X).getData();
+  const Expr *SE = (Expr*) cast<UndefinedVal>(X).getData();
   assert(SE);
   X = state->getSVal(SE);
 
@@ -1281,7 +1476,7 @@
 void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) {
   typedef GRSwitchNodeBuilder::iterator iterator;
   const GRState* state = builder.getState();
-  Expr* CondE = builder.getCondition();
+  const Expr* CondE = builder.getCondition();
   SVal  CondV_untested = state->getSVal(CondE);
 
   if (CondV_untested.isUndef()) {
@@ -1294,10 +1489,12 @@
   DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
 
   const GRState *DefaultSt = state;
-  bool defaultIsFeasible = false;
+  
+  iterator I = builder.begin(), EI = builder.end();
+  bool defaultIsFeasible = I == EI;
 
-  for (iterator I = builder.begin(), EI = builder.end(); I != EI; ++I) {
-    CaseStmt* Case = cast<CaseStmt>(I.getCase());
+  for ( ; I != EI; ++I) {
+    const CaseStmt* Case = I.getCase();
 
     // Evaluate the LHS of the case value.
     Expr::EvalResult V1;
@@ -1313,7 +1510,7 @@
     // Get the RHS of the case, if it exists.
     Expr::EvalResult V2;
 
-    if (Expr* E = Case->getRHS()) {
+    if (const Expr* E = Case->getRHS()) {
       b = E->Evaluate(V2, getContext());
       assert(b && V2.Val.isInt() && !V2.HasSideEffects
              && "Case condition must evaluate to an integer constant.");
@@ -1371,15 +1568,14 @@
 }
 
 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 StackFrameContext *LocCtx 
+    = AMgr.getStackFrame(B.getCalleeContext(),
+                         B.getLocationContext(),
+                         B.getCallExpr(),
+                         B.getBlock(),
+                         B.getIndex());
 
-  const GRState *state = B.getState();
-  state = getStoreManager().EnterStackFrame(state, LocCtx);
+  const GRState *state = B.getState()->EnterStackFrame(LocCtx);
 
   B.GenerateNode(state, LocCtx);
 }
@@ -1421,11 +1617,11 @@
 // Transfer functions: logical operations ('&&', '||').
 //===----------------------------------------------------------------------===//
 
-void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
+void GRExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode* Pred,
                                     ExplodedNodeSet& Dst) {
 
-  assert(B->getOpcode() == BinaryOperator::LAnd ||
-         B->getOpcode() == BinaryOperator::LOr);
+  assert(B->getOpcode() == BO_LAnd ||
+         B->getOpcode() == BO_LOr);
 
   assert(B==CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(B));
 
@@ -1465,7 +1661,7 @@
     // 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,
+    X = ValMgr.makeIntVal(B->getOpcode() == BO_LAnd ? 0U : 1U,
                           B->getType());
     MakeNode(Dst, B, Pred, state->BindExpr(B, X));
   }
@@ -1475,7 +1671,7 @@
 // Transfer functions: Loads and stores.
 //===----------------------------------------------------------------------===//
 
-void GRExprEngine::VisitBlockExpr(BlockExpr *BE, ExplodedNode *Pred,
+void GRExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
                                   ExplodedNodeSet &Dst) {
 
   ExplodedNodeSet Tmp;
@@ -1488,21 +1684,21 @@
            ProgramPoint::PostLValueKind);
 
   // Post-visit the BlockExpr.
-  CheckerVisit(BE, Dst, Tmp, false);
+  CheckerVisit(BE, Dst, Tmp, PostVisitStmtCallback);
 }
 
-void GRExprEngine::VisitDeclRefExpr(DeclRefExpr *Ex, ExplodedNode *Pred,
+void GRExprEngine::VisitDeclRefExpr(const DeclRefExpr *Ex, ExplodedNode *Pred,
                                     ExplodedNodeSet &Dst, bool asLValue) {
   VisitCommonDeclRefExpr(Ex, Ex->getDecl(), Pred, Dst, asLValue);
 }
 
-void GRExprEngine::VisitBlockDeclRefExpr(BlockDeclRefExpr *Ex,
+void GRExprEngine::VisitBlockDeclRefExpr(const BlockDeclRefExpr *Ex,
                                          ExplodedNode *Pred,
                                     ExplodedNodeSet &Dst, bool asLValue) {
   VisitCommonDeclRefExpr(Ex, Ex->getDecl(), Pred, Dst, asLValue);
 }
 
-void GRExprEngine::VisitCommonDeclRefExpr(Expr *Ex, const NamedDecl *D,
+void GRExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
                                           ExplodedNode *Pred,
                                           ExplodedNodeSet &Dst, bool asLValue) {
 
@@ -1549,12 +1745,12 @@
 }
 
 /// VisitArraySubscriptExpr - Transfer function for array accesses
-void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A,
+void GRExprEngine::VisitArraySubscriptExpr(const ArraySubscriptExpr* A,
                                            ExplodedNode* Pred,
                                            ExplodedNodeSet& Dst, bool asLValue){
 
-  Expr* Base = A->getBase()->IgnoreParens();
-  Expr* Idx  = A->getIdx()->IgnoreParens();
+  const Expr* Base = A->getBase()->IgnoreParens();
+  const Expr* Idx  = A->getIdx()->IgnoreParens();
   ExplodedNodeSet Tmp;
 
   if (Base->getType()->isVectorType()) {
@@ -1572,7 +1768,7 @@
     Visit(Idx, *I1, Tmp2);     // Evaluate the index.
 
     ExplodedNodeSet Tmp3;
-    CheckerVisit(A, Tmp3, Tmp2, true);
+    CheckerVisit(A, Tmp3, Tmp2, PreVisitStmtCallback);
 
     for (ExplodedNodeSet::iterator I2=Tmp3.begin(),E2=Tmp3.end();I2!=E2; ++I2) {
       const GRState* state = GetState(*I2);
@@ -1589,7 +1785,7 @@
 }
 
 /// VisitMemberExpr - Transfer function for member expressions.
-void GRExprEngine::VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred,
+void GRExprEngine::VisitMemberExpr(const MemberExpr* M, ExplodedNode* Pred,
                                    ExplodedNodeSet& Dst, bool asLValue) {
 
   Expr* Base = M->getBase()->IgnoreParens();
@@ -1620,8 +1816,8 @@
 
 /// 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,
+void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, const Stmt *AssignE,
+                            const Stmt* StoreE, ExplodedNode* Pred,
                             const GRState* state, SVal location, SVal Val,
                             bool atDeclInit) {
 
@@ -1675,8 +1871,8 @@
 ///  @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,
+void GRExprEngine::EvalStore(ExplodedNodeSet& Dst, const Expr *AssignE,
+                             const Expr* StoreE,
                              ExplodedNode* Pred,
                              const GRState* state, SVal location, SVal Val,
                              const void *tag) {
@@ -1701,7 +1897,8 @@
     EvalBind(Dst, AssignE, StoreE, *NI, GetState(*NI), location, Val);
 }
 
-void GRExprEngine::EvalLoad(ExplodedNodeSet& Dst, Expr *Ex, ExplodedNode* Pred,
+void GRExprEngine::EvalLoad(ExplodedNodeSet& Dst, const Expr *Ex, 
+                            ExplodedNode* Pred,
                             const GRState* state, SVal location,
                             const void *tag, QualType LoadTy) {
 
@@ -1711,7 +1908,7 @@
   if (const TypedRegion *TR =
         dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
 
-    QualType ValTy = TR->getValueType(getContext());
+    QualType ValTy = TR->getValueType();
     if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) {
       static int loadReferenceTag = 0;
       ExplodedNodeSet Tmp;
@@ -1731,7 +1928,7 @@
   EvalLoadCommon(Dst, Ex, Pred, state, location, tag, LoadTy);
 }
 
-void GRExprEngine::EvalLoadCommon(ExplodedNodeSet& Dst, Expr *Ex,
+void GRExprEngine::EvalLoadCommon(ExplodedNodeSet& Dst, const Expr *Ex,
                                   ExplodedNode* Pred,
                                   const GRState* state, SVal location,
                                   const void *tag, QualType LoadTy) {
@@ -1765,7 +1962,7 @@
   }
 }
 
-void GRExprEngine::EvalLocation(ExplodedNodeSet &Dst, Stmt *S,
+void GRExprEngine::EvalLocation(ExplodedNodeSet &Dst, const Stmt *S,
                                 ExplodedNode* Pred,
                                 const GRState* state, SVal location,
                                 const void *tag, bool isLoad) {
@@ -1806,9 +2003,44 @@
   }
 }
 
-void GRExprEngine::VisitCall(CallExpr* CE, ExplodedNode* Pred,
-                             CallExpr::arg_iterator AI,
-                             CallExpr::arg_iterator AE,
+bool GRExprEngine::InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, 
+                              ExplodedNode *Pred) {
+  const GRState *state = GetState(Pred);
+  const Expr *Callee = CE->getCallee();
+  SVal L = state->getSVal(Callee);
+  
+  const FunctionDecl *FD = L.getAsFunctionDecl();
+  if (!FD)
+    return false;
+
+  // Check if the function definition is in the same translation unit.
+  if (FD->hasBody(FD)) {
+    // Now we have the definition of the callee, create a CallEnter node.
+    CallEnter Loc(CE, AMgr.getAnalysisContext(FD), Pred->getLocationContext());
+
+    ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
+    Dst.Add(N);
+    return true;
+  }
+
+  // Check if we can find the function definition in other translation units.
+  if (AMgr.hasIndexer()) {
+    const AnalysisContext *C = AMgr.getAnalysisContextInAnotherTU(FD);
+    if (C == 0)
+      return false;
+
+    CallEnter Loc(CE, C, Pred->getLocationContext());
+    ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
+    Dst.Add(N);
+    return true;
+  }
+
+  return false;
+}
+
+void GRExprEngine::VisitCall(const CallExpr* CE, ExplodedNode* Pred,
+                             CallExpr::const_arg_iterator AI,
+                             CallExpr::const_arg_iterator AE,
                              ExplodedNodeSet& Dst, bool asLValue) {
 
   // Determine the type of function we're calling (if available).
@@ -1855,7 +2087,7 @@
 
   // Now process the call itself.
   ExplodedNodeSet DstTmp;
-  Expr* Callee = CE->getCallee()->IgnoreParens();
+  const Expr* Callee = CE->getCallee()->IgnoreParens();
 
   for (ExplodedNodeSet::iterator NI=ArgsEvaluated.begin(),
                                  NE=ArgsEvaluated.end(); NI != NE; ++NI) {
@@ -1863,7 +2095,7 @@
     ExplodedNodeSet DstTmp2;
     Visit(Callee, *NI, DstTmp2);
     // Perform the previsit of the CallExpr, storing the results in DstTmp.
-    CheckerVisit(CE, DstTmp, DstTmp2, true);
+    CheckerVisit(CE, DstTmp, DstTmp2, PreVisitStmtCallback);
   }
 
   // Finally, evaluate the function call.  We try each of the checkers
@@ -1885,6 +2117,10 @@
     // If the callee is processed by a checker, skip the rest logic.
     if (CheckerEvalCall(CE, DstChecker, *DI))
       DstTmp3.insert(DstChecker);
+    else if (AMgr.shouldInlineCall() && InlineCall(Dst, CE, *DI)) {
+      // Callee is inlined. We shouldn't do post call checking.
+      return;
+    }
     else {
       for (ExplodedNodeSet::iterator DI_Checker = DstChecker.begin(),
            DE_Checker = DstChecker.end();
@@ -1911,9 +2147,10 @@
 
   // Finally, perform the post-condition check of the CallExpr and store
   // the created nodes in 'Dst'.
-
+  // If the callee returns a reference and we want an rvalue, skip this check
+  // and do the load.
   if (!(!asLValue && CalleeReturnsReference(CE))) {
-    CheckerVisit(CE, Dst, DstTmp3, false);
+    CheckerVisit(CE, Dst, DstTmp3, PostVisitStmtCallback);
     return;
   }
 
@@ -1923,7 +2160,7 @@
   // FIXME: This conversion doesn't actually happen unless the result
   //  of CallExpr is consumed by another expression.
   ExplodedNodeSet DstTmp4;
-  CheckerVisit(CE, DstTmp4, DstTmp3, false);
+  CheckerVisit(CE, DstTmp4, DstTmp3, PostVisitStmtCallback);
   QualType LoadTy = CE->getType();
 
   static int *ConvertToRvalueTag = 0;
@@ -1940,10 +2177,10 @@
 //===----------------------------------------------------------------------===//
 
 static std::pair<const void*,const void*> EagerlyAssumeTag
-  = std::pair<const void*,const void*>(&EagerlyAssumeTag,0);
+  = std::pair<const void*,const void*>(&EagerlyAssumeTag,static_cast<void*>(0));
 
 void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
-                                     Expr *Ex) {
+                                     const Expr *Ex) {
   for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {
     ExplodedNode *Pred = *I;
 
@@ -1986,10 +2223,11 @@
 // Transfer function: Objective-C ivar references.
 //===----------------------------------------------------------------------===//
 
-void GRExprEngine::VisitObjCIvarRefExpr(ObjCIvarRefExpr* Ex, ExplodedNode* Pred,
+void GRExprEngine::VisitObjCIvarRefExpr(const ObjCIvarRefExpr* Ex, 
+                                        ExplodedNode* Pred,
                                         ExplodedNodeSet& Dst, bool asLValue) {
 
-  Expr* Base = cast<Expr>(Ex->getBase());
+  const Expr* Base = cast<Expr>(Ex->getBase());
   ExplodedNodeSet Tmp;
   Visit(Base, Pred, Tmp);
 
@@ -2009,7 +2247,7 @@
 // Transfer function: Objective-C fast enumeration 'for' statements.
 //===----------------------------------------------------------------------===//
 
-void GRExprEngine::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S,
+void GRExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt* S,
                                      ExplodedNode* Pred, ExplodedNodeSet& Dst) {
 
   // ObjCForCollectionStmts are processed in two places.  This method
@@ -2037,11 +2275,11 @@
   //    container is empty.  Thus this transfer function will by default
   //    result in state splitting.
 
-  Stmt* elem = S->getElement();
+  const Stmt* elem = S->getElement();
   SVal ElementV;
 
-  if (DeclStmt* DS = dyn_cast<DeclStmt>(elem)) {
-    VarDecl* ElemD = cast<VarDecl>(DS->getSingleDecl());
+  if (const DeclStmt* DS = dyn_cast<DeclStmt>(elem)) {
+    const VarDecl* ElemD = cast<VarDecl>(DS->getSingleDecl());
     assert (ElemD->getInit() == 0);
     ElementV = GetState(Pred)->getLValue(ElemD, Pred->getLocationContext());
     VisitObjCForCollectionStmtAux(S, Pred, Dst, ElementV);
@@ -2057,12 +2295,12 @@
   }
 }
 
-void GRExprEngine::VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
+void GRExprEngine::VisitObjCForCollectionStmtAux(const 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();
+  const Stmt* elem = S->getElement();
   ExplodedNodeSet Tmp;
   EvalLocation(Tmp, elem, Pred, GetState(Pred), ElementV, NULL, false);
 
@@ -2086,7 +2324,7 @@
         // 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());
+        QualType T = R->getValueType();
         assert(Loc::IsLocType(T));
         unsigned Count = Builder->getCurrentBlockCount();
         SymbolRef Sym = SymMgr.getConjuredSymbol(elem, T, Count);
@@ -2111,23 +2349,24 @@
 namespace {
 class ObjCMsgWLItem {
 public:
-  ObjCMessageExpr::arg_iterator I;
+  ObjCMessageExpr::const_arg_iterator I;
   ExplodedNode *N;
 
-  ObjCMsgWLItem(const ObjCMessageExpr::arg_iterator &i, ExplodedNode *n)
+  ObjCMsgWLItem(const ObjCMessageExpr::const_arg_iterator &i, ExplodedNode *n)
     : I(i), N(n) {}
 };
 } // end anonymous namespace
 
-void GRExprEngine::VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred,
+void GRExprEngine::VisitObjCMessageExpr(const 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()) {
+  ObjCMessageExpr::const_arg_iterator AI = ME->arg_begin(), AE = ME->arg_end();
+  if (const Expr *Receiver = ME->getInstanceReceiver()) {
     ExplodedNodeSet Tmp;
     Visit(Receiver, Pred, Tmp);
 
@@ -2165,7 +2404,7 @@
 
   // Now that the arguments are processed, handle the previsits checks.
   ExplodedNodeSet DstPrevisit;
-  CheckerVisit(ME, DstPrevisit, ArgsEvaluated, true);
+  CheckerVisit(ME, DstPrevisit, ArgsEvaluated, PreVisitStmtCallback);
 
   // Proceed with evaluate the message expression.
   ExplodedNodeSet DstEval;
@@ -2268,7 +2507,7 @@
   // 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);
+    CheckerVisit(ME, Dst, DstEval, PostVisitStmtCallback);
     return;
   }
 
@@ -2278,7 +2517,7 @@
   // FIXME: This conversion doesn't actually happen unless the result
   //  of ObjCMessageExpr is consumed by another expression.
   ExplodedNodeSet DstRValueConvert;
-  CheckerVisit(ME, DstRValueConvert, DstEval, false);
+  CheckerVisit(ME, DstRValueConvert, DstEval, PostVisitStmtCallback);
   QualType LoadTy = ME->getType();
 
   static int *ConvertToRvalueTag = 0;
@@ -2294,8 +2533,9 @@
 // Transfer functions: Miscellaneous statements.
 //===----------------------------------------------------------------------===//
 
-void GRExprEngine::VisitCast(CastExpr *CastE, Expr *Ex, ExplodedNode *Pred,
-                             ExplodedNodeSet &Dst, bool asLValue) {
+void GRExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, 
+                             ExplodedNode *Pred, ExplodedNodeSet &Dst, 
+                             bool asLValue) {
   ExplodedNodeSet S1;
   QualType T = CastE->getType();
   QualType ExTy = Ex->getType();
@@ -2310,7 +2550,7 @@
     Visit(Ex, Pred, S1);
 
   ExplodedNodeSet S2;
-  CheckerVisit(CastE, S2, S1, true);
+  CheckerVisit(CastE, S2, S1, PreVisitStmtCallback);
 
   // If we are evaluating the cast in an lvalue context, we implicitly want
   // the cast to evaluate to a location.
@@ -2321,14 +2561,14 @@
   }
 
   switch (CastE->getCastKind()) {
-  case CastExpr::CK_ToVoid:
+  case 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:
+  case CK_NoOp:
+  case CK_FunctionToPointerDecay:
     for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) {
       // Copy the SVal of Ex to CastE.
       ExplodedNode *N = *I;
@@ -2339,19 +2579,21 @@
     }
     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:
+  case CK_Unknown:
+  case CK_ArrayToPointerDecay:
+  case CK_BitCast:
+  case CK_LValueBitCast:
+  case CK_IntegralCast:
+  case CK_IntegralToPointer:
+  case CK_PointerToIntegral:
+  case CK_IntegralToFloating:
+  case CK_FloatingToIntegral:
+  case CK_FloatingCast:
+  case CK_AnyPointerToObjCPointerCast:
+  case CK_AnyPointerToBlockPointerCast:
+  case CK_DerivedToBase:
+  case CK_UncheckedDerivedToBase:
+  case CK_ObjCObjectLValueCast: {
     // Delegate to SValuator to process.
     for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) {
       ExplodedNode* N = *I;
@@ -2362,18 +2604,33 @@
       MakeNode(Dst, CastE, N, state);
     }
     return;
-
-  default:
-    llvm::errs() << "Cast kind " << CastE->getCastKind() << " not handled.\n";
-    assert(0);
+  }
+  
+  // Various C++ casts that are not handled yet.
+  case CK_Dynamic:  
+  case CK_ToUnion:
+  case CK_BaseToDerived:
+  case CK_NullToMemberPointer:
+  case CK_BaseToDerivedMemberPointer:
+  case CK_DerivedToBaseMemberPointer:
+  case CK_UserDefinedConversion:
+  case CK_ConstructorConversion:
+  case CK_VectorSplat:
+  case CK_MemberPointerToBoolean: {
+    SaveAndRestore<bool> OldSink(Builder->BuildSinks);
+    Builder->BuildSinks = true;
+    MakeNode(Dst, CastE, Pred, GetState(Pred));
+    return;
+  }
   }
 }
 
-void GRExprEngine::VisitCompoundLiteralExpr(CompoundLiteralExpr* CL,
+void GRExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr* CL,
                                             ExplodedNode* Pred,
                                             ExplodedNodeSet& Dst,
                                             bool asLValue) {
-  InitListExpr* ILE = cast<InitListExpr>(CL->getInitializer()->IgnoreParens());
+  const InitListExpr* ILE 
+    = cast<InitListExpr>(CL->getInitializer()->IgnoreParens());
   ExplodedNodeSet Tmp;
   Visit(ILE, Pred, Tmp);
 
@@ -2391,17 +2648,17 @@
   }
 }
 
-void GRExprEngine::VisitDeclStmt(DeclStmt *DS, ExplodedNode *Pred,
+void GRExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
                                  ExplodedNodeSet& Dst) {
 
   // The CFG has one DeclStmt per Decl.
-  Decl* D = *DS->decl_begin();
+  const 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());
+  const Expr* InitEx = VD->getInit();
 
   // FIXME: static variables may have an initializer, but the second
   //  time a function is called those values may not be current.
@@ -2423,7 +2680,7 @@
     Tmp.Add(Pred);
 
   ExplodedNodeSet Tmp2;
-  CheckerVisit(DS, Tmp2, Tmp, true);
+  CheckerVisit(DS, Tmp2, Tmp, PreVisitStmtCallback);
 
   for (ExplodedNodeSet::iterator I=Tmp2.begin(), E=Tmp2.end(); I!=E; ++I) {
     ExplodedNode *N = *I;
@@ -2454,10 +2711,10 @@
   }
 }
 
-void GRExprEngine::VisitCondInit(VarDecl *VD, Stmt *S,
+void GRExprEngine::VisitCondInit(const VarDecl *VD, const Stmt *S,
                                  ExplodedNode *Pred, ExplodedNodeSet& Dst) {
 
-  Expr* InitEx = VD->getInit();
+  const Expr* InitEx = VD->getInit();
   ExplodedNodeSet Tmp;
   Visit(InitEx, Pred, Tmp);
 
@@ -2488,16 +2745,16 @@
 public:
   llvm::ImmutableList<SVal> Vals;
   ExplodedNode* N;
-  InitListExpr::reverse_iterator Itr;
+  InitListExpr::const_reverse_iterator Itr;
 
   InitListWLItem(ExplodedNode* n, llvm::ImmutableList<SVal> vals,
-                 InitListExpr::reverse_iterator itr)
+                 InitListExpr::const_reverse_iterator itr)
   : Vals(vals), N(n), Itr(itr) {}
 };
 }
 
 
-void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
+void GRExprEngine::VisitInitListExpr(const InitListExpr* E, ExplodedNode* Pred,
                                      ExplodedNodeSet& Dst) {
 
   const GRState* state = GetState(Pred);
@@ -2519,7 +2776,7 @@
     llvm::SmallVector<InitListWLItem, 10> WorkList;
     WorkList.reserve(NumInitElements);
     WorkList.push_back(InitListWLItem(Pred, StartVals, E->rbegin()));
-    InitListExpr::reverse_iterator ItrEnd = E->rend();
+    InitListExpr::const_reverse_iterator ItrEnd = E->rend();
     assert(!(E->rbegin() == E->rend()));
 
     // Process the worklist until it is empty.
@@ -2530,7 +2787,7 @@
       ExplodedNodeSet Tmp;
       Visit(*X.Itr, X.N, Tmp);
 
-      InitListExpr::reverse_iterator NewItr = X.Itr + 1;
+      InitListExpr::const_reverse_iterator NewItr = X.Itr + 1;
 
       for (ExplodedNodeSet::iterator NI=Tmp.begin(),NE=Tmp.end();NI!=NE;++NI) {
         // Get the last initializer value.
@@ -2562,7 +2819,7 @@
   if (Loc::IsLocType(T) || T->isIntegerType()) {
     assert (E->getNumInits() == 1);
     ExplodedNodeSet Tmp;
-    Expr* Init = E->getInit(0);
+    const Expr* Init = E->getInit(0);
     Visit(Init, Pred, Tmp);
     for (ExplodedNodeSet::iterator I=Tmp.begin(), EI=Tmp.end(); I != EI; ++I) {
       state = GetState(*I);
@@ -2575,7 +2832,7 @@
 }
 
 /// VisitSizeOfAlignOfExpr - Transfer function for sizeof(type).
-void GRExprEngine::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex,
+void GRExprEngine::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr* Ex,
                                           ExplodedNode* Pred,
                                           ExplodedNodeSet& Dst) {
   QualType T = Ex->getTypeOfArgument();
@@ -2586,13 +2843,42 @@
       // sizeof(void) == 1 byte.
       amt = CharUnits::One();
     }
-    else if (!T.getTypePtr()->isConstantSizeType()) {
-      // FIXME: Add support for VLAs.
-      Dst.Add(Pred);
+    else if (!T->isConstantSizeType()) {
+      assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
+
+      // FIXME: Add support for VLA type arguments, not just VLA expressions.
+      // When that happens, we should probably refactor VLASizeChecker's code.
+      if (Ex->isArgumentType()) {
+        Dst.Add(Pred);
+        return;
+      }
+
+      // Get the size by getting the extent of the sub-expression.
+      // First, visit the sub-expression to find its region.
+      const Expr *Arg = Ex->getArgumentExpr();
+      ExplodedNodeSet Tmp;
+      VisitLValue(Arg, Pred, Tmp);
+
+      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+        const GRState* state = GetState(*I);
+        const MemRegion *MR = state->getSVal(Arg).getAsRegion();
+
+        // If the subexpression can't be resolved to a region, we don't know
+        // anything about its size. Just leave the state as is and continue.
+        if (!MR) {
+          Dst.Add(*I);
+          continue;
+        }
+
+        // The result is the extent of the VLA.
+        SVal Extent = cast<SubRegion>(MR)->getExtent(ValMgr);
+        MakeNode(Dst, Ex, *I, state->BindExpr(Ex, Extent));
+      }
+
       return;
     }
-    else if (T->isObjCInterfaceType()) {
-      // Some code tries to take the sizeof an ObjCInterfaceType, relying that
+    else if (T->getAs<ObjCObjectType>()) {
+      // Some code tries to take the sizeof an ObjCObjectType, relying that
       // the compiler has laid out its representation.  Just report Unknown
       // for these.
       Dst.Add(Pred);
@@ -2611,8 +2897,24 @@
               ValMgr.makeIntVal(amt.getQuantity(), Ex->getType())));
 }
 
+void GRExprEngine::VisitOffsetOfExpr(const OffsetOfExpr* OOE, 
+                                     ExplodedNode* Pred, ExplodedNodeSet& Dst) {
+  Expr::EvalResult Res;
+  if (OOE->Evaluate(Res, getContext()) && Res.Val.isInt()) {
+    const APSInt &IV = Res.Val.getInt();
+    assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
+    assert(OOE->getType()->isIntegerType());
+    assert(IV.isSigned() == OOE->getType()->isSignedIntegerType());
+    SVal X = ValMgr.makeIntVal(IV);
+    MakeNode(Dst, OOE, Pred, GetState(Pred)->BindExpr(OOE, X));
+    return;
+  }
+  // FIXME: Handle the case where __builtin_offsetof is not a constant.
+  Dst.Add(Pred);
+}
 
-void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
+void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U, 
+                                      ExplodedNode* Pred,
                                       ExplodedNodeSet& Dst, bool asLValue) {
 
   switch (U->getOpcode()) {
@@ -2620,9 +2922,9 @@
     default:
       break;
 
-    case UnaryOperator::Deref: {
+    case UO_Deref: {
 
-      Expr* Ex = U->getSubExpr()->IgnoreParens();
+      const Expr* Ex = U->getSubExpr()->IgnoreParens();
       ExplodedNodeSet Tmp;
       Visit(Ex, Pred, Tmp);
 
@@ -2641,9 +2943,9 @@
       return;
     }
 
-    case UnaryOperator::Real: {
+    case UO_Real: {
 
-      Expr* Ex = U->getSubExpr()->IgnoreParens();
+      const Expr* Ex = U->getSubExpr()->IgnoreParens();
       ExplodedNodeSet Tmp;
       Visit(Ex, Pred, Tmp);
 
@@ -2656,7 +2958,7 @@
           continue;
         }
 
-        // For all other types, UnaryOperator::Real is an identity operation.
+        // For all other types, UO_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)));
@@ -2665,9 +2967,9 @@
       return;
     }
 
-    case UnaryOperator::Imag: {
+    case UO_Imag: {
 
-      Expr* Ex = U->getSubExpr()->IgnoreParens();
+      const Expr* Ex = U->getSubExpr()->IgnoreParens();
       ExplodedNodeSet Tmp;
       Visit(Ex, Pred, Tmp);
 
@@ -2679,8 +2981,7 @@
           continue;
         }
 
-        // For all other types, UnaryOperator::Float returns 0.
-        assert (Ex->getType()->isIntegerType());
+        // For all other types, UO_Imag returns 0.
         const GRState* state = GetState(*I);
         SVal X = ValMgr.makeZeroVal(Ex->getType());
         MakeNode(Dst, U, *I, state->BindExpr(U, X));
@@ -2688,34 +2989,22 @@
 
       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: {
+      
+    case UO_Plus: assert(!asLValue);  // FALL-THROUGH.
+    case UO_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();
+      const Expr* Ex = U->getSubExpr()->IgnoreParens();
       ExplodedNodeSet Tmp;
-      Visit(Ex, Pred, Tmp);
+
+      if (asLValue)
+        VisitLValue(Ex, Pred, Tmp);
+      else
+        Visit(Ex, Pred, Tmp);
 
       for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
         const GRState* state = GetState(*I);
@@ -2725,10 +3014,10 @@
       return;
     }
 
-    case UnaryOperator::AddrOf: {
+    case UO_AddrOf: {
 
       assert(!asLValue);
-      Expr* Ex = U->getSubExpr()->IgnoreParens();
+      const Expr* Ex = U->getSubExpr()->IgnoreParens();
       ExplodedNodeSet Tmp;
       VisitLValue(Ex, Pred, Tmp);
 
@@ -2742,12 +3031,12 @@
       return;
     }
 
-    case UnaryOperator::LNot:
-    case UnaryOperator::Minus:
-    case UnaryOperator::Not: {
+    case UO_LNot:
+    case UO_Minus:
+    case UO_Not: {
 
       assert (!asLValue);
-      Expr* Ex = U->getSubExpr()->IgnoreParens();
+      const Expr* Ex = U->getSubExpr()->IgnoreParens();
       ExplodedNodeSet Tmp;
       Visit(Ex, Pred, Tmp);
 
@@ -2778,17 +3067,17 @@
             assert(false && "Invalid Opcode.");
             break;
 
-          case UnaryOperator::Not:
+          case UO_Not:
             // FIXME: Do we need to handle promotions?
             state = state->BindExpr(U, EvalComplement(cast<NonLoc>(V)));
             break;
 
-          case UnaryOperator::Minus:
+          case UO_Minus:
             // FIXME: Do we need to handle promotions?
             state = state->BindExpr(U, EvalMinus(cast<NonLoc>(V)));
             break;
 
-          case UnaryOperator::LNot:
+          case UO_LNot:
 
             // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
             //
@@ -2798,12 +3087,12 @@
 
             if (isa<Loc>(V)) {
               Loc X = ValMgr.makeNull();
-              Result = EvalBinOp(state, BinaryOperator::EQ, cast<Loc>(V), X,
+              Result = EvalBinOp(state, BO_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,
+              Result = EvalBinOp(state, BO_EQ, cast<NonLoc>(V), X,
                                  U->getType());
             }
 
@@ -2823,7 +3112,7 @@
 
   assert (U->isIncrementDecrementOp());
   ExplodedNodeSet Tmp;
-  Expr* Ex = U->getSubExpr()->IgnoreParens();
+  const Expr* Ex = U->getSubExpr()->IgnoreParens();
   VisitLValue(Ex, Pred, Tmp);
 
   for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
@@ -2848,8 +3137,8 @@
       DefinedSVal V2 = cast<DefinedSVal>(V2_untested);
 
       // Handle all other values.
-      BinaryOperator::Opcode Op = U->isIncrementOp() ? BinaryOperator::Add
-                                                     : BinaryOperator::Sub;
+      BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add
+                                                     : BO_Sub;
 
       // If the UnaryOperator has non-location type, use its type to create the
       // constant value. If the UnaryOperator has location type, create the
@@ -2898,14 +3187,14 @@
   }
 }
 
-void GRExprEngine::VisitAsmStmt(AsmStmt* A, ExplodedNode* Pred,
+void GRExprEngine::VisitAsmStmt(const 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,
+void GRExprEngine::VisitAsmStmtHelperOutputs(const AsmStmt* A,
+                                             AsmStmt::const_outputs_iterator I,
+                                             AsmStmt::const_outputs_iterator E,
                                      ExplodedNode* Pred, ExplodedNodeSet& Dst) {
   if (I == E) {
     VisitAsmStmtHelperInputs(A, A->begin_inputs(), A->end_inputs(), Pred, Dst);
@@ -2921,9 +3210,9 @@
     VisitAsmStmtHelperOutputs(A, I, E, *NI, Dst);
 }
 
-void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A,
-                                            AsmStmt::inputs_iterator I,
-                                            AsmStmt::inputs_iterator E,
+void GRExprEngine::VisitAsmStmtHelperInputs(const AsmStmt* A,
+                                            AsmStmt::const_inputs_iterator I,
+                                            AsmStmt::const_inputs_iterator E,
                                             ExplodedNode* Pred,
                                             ExplodedNodeSet& Dst) {
   if (I == E) {
@@ -2937,7 +3226,7 @@
 
     const GRState* state = GetState(Pred);
 
-    for (AsmStmt::outputs_iterator OI = A->begin_outputs(),
+    for (AsmStmt::const_outputs_iterator OI = A->begin_outputs(),
                                    OE = A->end_outputs(); OI != OE; ++OI) {
 
       SVal X = state->getSVal(*OI);
@@ -2960,10 +3249,10 @@
     VisitAsmStmtHelperInputs(A, I, E, *NI, Dst);
 }
 
-void GRExprEngine::VisitReturnStmt(ReturnStmt *RS, ExplodedNode *Pred,
+void GRExprEngine::VisitReturnStmt(const ReturnStmt *RS, ExplodedNode *Pred,
                                    ExplodedNodeSet &Dst) {
   ExplodedNodeSet Src;
-  if (Expr *RetE = RS->getRetValue()) {
+  if (const 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.
     {
@@ -2982,7 +3271,7 @@
   }
 
   ExplodedNodeSet CheckedSet;
-  CheckerVisit(RS, CheckedSet, Src, true);
+  CheckerVisit(RS, CheckedSet, Src, PreVisitStmtCallback);
 
   for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
        I != E; ++I) {
@@ -3008,7 +3297,7 @@
 // Transfer functions: Binary operators.
 //===----------------------------------------------------------------------===//
 
-void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
+void GRExprEngine::VisitBinaryOperator(const BinaryOperator* B,
                                        ExplodedNode* Pred,
                                        ExplodedNodeSet& Dst, bool asLValue) {
 
@@ -3035,7 +3324,7 @@
     Visit(RHS, *I1, Tmp2);
 
     ExplodedNodeSet CheckedSet;
-    CheckerVisit(B, CheckedSet, Tmp2, true);
+    CheckerVisit(B, CheckedSet, Tmp2, PreVisitStmtCallback);
 
     // With both the LHS and RHS evaluated, process the operation itself.
 
@@ -3048,13 +3337,13 @@
 
       BinaryOperator::Opcode Op = B->getOpcode();
 
-      if (Op == BinaryOperator::Assign) {
+      if (Op == BO_Assign) {
         // EXPERIMENTAL: "Conjured" symbols.
         // FIXME: Handle structs.
         QualType T = RHS->getType();
 
-        if ((RightV.isUnknown()||!getConstraintManager().canReasonAbout(RightV))
-            && (Loc::IsLocType(T) || (T->isScalarType()&&T->isIntegerType()))) {
+        if (RightV.isUnknown() ||!getConstraintManager().canReasonAbout(RightV))
+        {
           unsigned Count = Builder->getCurrentBlockCount();
           RightV = ValMgr.getConjuredSymbolVal(NULL, B->getRHS(), Count);
         }
@@ -3094,16 +3383,16 @@
       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;
+        case BO_MulAssign: Op = BO_Mul; break;
+        case BO_DivAssign: Op = BO_Div; break;
+        case BO_RemAssign: Op = BO_Rem; break;
+        case BO_AddAssign: Op = BO_Add; break;
+        case BO_SubAssign: Op = BO_Sub; break;
+        case BO_ShlAssign: Op = BO_Shl; break;
+        case BO_ShrAssign: Op = BO_Shr; break;
+        case BO_AndAssign: Op = BO_And; break;
+        case BO_XorAssign: Op = BO_Xor; break;
+        case BO_OrAssign:  Op = BO_Or;  break;
       }
 
       // Perform a load (the LHS).  This performs the checks for
@@ -3141,10 +3430,8 @@
 
         SVal LHSVal;
 
-        if ((Result.isUnknown() ||
-             !getConstraintManager().canReasonAbout(Result))
-            && (Loc::IsLocType(CTy)
-                || (CTy->isScalarType() && CTy->isIntegerType()))) {
+        if (Result.isUnknown() ||
+            !getConstraintManager().canReasonAbout(Result)) {
 
           unsigned Count = Builder->getCurrentBlockCount();
 
@@ -3168,7 +3455,7 @@
     }
   }
 
-  CheckerVisit(B, Dst, Tmp3, false);
+  CheckerVisit(B, Dst, Tmp3, PostVisitStmtCallback);
 }
 
 //===----------------------------------------------------------------------===//
@@ -3298,7 +3585,7 @@
         Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
             << E.getDst()->getBlockID()  << ')';
 
-        if (Stmt* T = E.getSrc()->getTerminator()) {
+        if (const Stmt* T = E.getSrc()->getTerminator()) {
 
           SourceLocation SLoc = T->getLocStart();
 
@@ -3314,15 +3601,15 @@
           }
 
           if (isa<SwitchStmt>(T)) {
-            Stmt* Label = E.getDst()->getLabel();
+            const Stmt* Label = E.getDst()->getLabel();
 
             if (Label) {
-              if (CaseStmt* C = dyn_cast<CaseStmt>(Label)) {
+              if (const CaseStmt* C = dyn_cast<CaseStmt>(Label)) {
                 Out << "\\lcase ";
                 LangOptions LO; // FIXME.
                 C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO));
 
-                if (Stmt* RHS = C->getRHS()) {
+                if (const Stmt* RHS = C->getRHS()) {
                   Out << " .. ";
                   RHS->printPretty(Out, 0, PrintingPolicy(LO));
                 }
diff --git a/lib/Checker/GRExprEngineExperimentalChecks.cpp b/lib/Checker/GRExprEngineExperimentalChecks.cpp
index 89b4e4b..84262b0 100644
--- a/lib/Checker/GRExprEngineExperimentalChecks.cpp
+++ b/lib/Checker/GRExprEngineExperimentalChecks.cpp
@@ -18,11 +18,14 @@
 
 using namespace clang;
 
-void clang::RegisterExperimentalChecks(GRExprEngine &Eng) {  
+void clang::RegisterExperimentalChecks(GRExprEngine &Eng) {
   // These are checks that never belong as internal checks
   // within GRExprEngine.
-  RegisterPthreadLockChecker(Eng);  
+  RegisterCStringChecker(Eng);
   RegisterMallocChecker(Eng);
+  RegisterPthreadLockChecker(Eng);
+  RegisterStreamChecker(Eng);
+  RegisterUnreachableCodeChecker(Eng);
 }
 
 void clang::RegisterExperimentalInternalChecks(GRExprEngine &Eng) {
@@ -32,9 +35,10 @@
   // Note that this must be registered after ReturnStackAddresEngsChecker.
   RegisterReturnPointerRangeChecker(Eng);
   
-  RegisterFixedAddressChecker(Eng);
-  RegisterPointerSubChecker(Eng);
-  RegisterPointerArithChecker(Eng);
-  RegisterCastToStructChecker(Eng);
   RegisterArrayBoundChecker(Eng);
+  RegisterCastSizeChecker(Eng);
+  RegisterCastToStructChecker(Eng);
+  RegisterFixedAddressChecker(Eng);
+  RegisterPointerArithChecker(Eng);
+  RegisterPointerSubChecker(Eng);
 }
diff --git a/lib/Checker/GRExprEngineExperimentalChecks.h b/lib/Checker/GRExprEngineExperimentalChecks.h
index 9a9da32..7b5b0ed 100644
--- a/lib/Checker/GRExprEngineExperimentalChecks.h
+++ b/lib/Checker/GRExprEngineExperimentalChecks.h
@@ -19,8 +19,12 @@
 
 class GRExprEngine;
 
-void RegisterPthreadLockChecker(GRExprEngine &Eng);
+void RegisterCStringChecker(GRExprEngine &Eng);
+void RegisterIdempotentOperationChecker(GRExprEngine &Eng);
 void RegisterMallocChecker(GRExprEngine &Eng);
+void RegisterPthreadLockChecker(GRExprEngine &Eng);
+void RegisterStreamChecker(GRExprEngine &Eng);
+void RegisterUnreachableCodeChecker(GRExprEngine &Eng);
 
 } // end clang namespace
 #endif
diff --git a/lib/Checker/GRExprEngineInternalChecks.h b/lib/Checker/GRExprEngineInternalChecks.h
index d117600..f91a759 100644
--- a/lib/Checker/GRExprEngineInternalChecks.h
+++ b/lib/Checker/GRExprEngineInternalChecks.h
@@ -26,6 +26,7 @@
 void RegisterBuiltinFunctionChecker(GRExprEngine &Eng);
 void RegisterCallAndMessageChecker(GRExprEngine &Eng);
 void RegisterCastToStructChecker(GRExprEngine &Eng);
+void RegisterCastSizeChecker(GRExprEngine &Eng);
 void RegisterDereferenceChecker(GRExprEngine &Eng);
 void RegisterDivZeroChecker(GRExprEngine &Eng);
 void RegisterFixedAddressChecker(GRExprEngine &Eng);
@@ -33,8 +34,8 @@
 void RegisterPointerArithChecker(GRExprEngine &Eng);
 void RegisterPointerSubChecker(GRExprEngine &Eng);
 void RegisterReturnPointerRangeChecker(GRExprEngine &Eng);
-void RegisterReturnStackAddressChecker(GRExprEngine &Eng);
 void RegisterReturnUndefChecker(GRExprEngine &Eng);
+void RegisterStackAddrLeakChecker(GRExprEngine &Eng);
 void RegisterUndefBranchChecker(GRExprEngine &Eng);
 void RegisterUndefCapturedBlockVarChecker(GRExprEngine &Eng);
 void RegisterUndefResultChecker(GRExprEngine &Eng);
diff --git a/lib/Checker/GRState.cpp b/lib/Checker/GRState.cpp
index f68e10b..024237c 100644
--- a/lib/Checker/GRState.cpp
+++ b/lib/Checker/GRState.cpp
@@ -14,6 +14,7 @@
 #include "clang/Analysis/CFG.h"
 #include "clang/Checker/PathSensitive/GRStateTrait.h"
 #include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/GRSubEngine.h"
 #include "clang/Checker/PathSensitive/GRTransferFuncs.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -34,7 +35,7 @@
 }
 
 const GRState*
-GRStateManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
+GRStateManager::RemoveDeadBindings(const GRState* state,
                                    const StackFrameContext *LCtx,
                                    SymbolReaper& SymReaper) {
 
@@ -47,27 +48,109 @@
   llvm::SmallVector<const MemRegion*, 10> RegionRoots;
   GRState NewState = *state;
 
-  NewState.Env = EnvMgr.RemoveDeadBindings(NewState.Env, Loc, SymReaper,
+  NewState.Env = EnvMgr.RemoveDeadBindings(NewState.Env, SymReaper,
                                            state, RegionRoots);
 
   // Clean up the store.
-  NewState.St = StoreMgr->RemoveDeadBindings(NewState.St, Loc, LCtx, SymReaper, 
-                                             RegionRoots);
+  NewState.St = StoreMgr->RemoveDeadBindings(NewState.St, LCtx, 
+                                             SymReaper, RegionRoots);
+  state = getPersistentState(NewState);
+  return ConstraintMgr->RemoveDeadBindings(state, SymReaper);
+}
 
-  return ConstraintMgr->RemoveDeadBindings(getPersistentState(NewState),
-                                           SymReaper);
+const GRState *GRStateManager::MarshalState(const GRState *state,
+                                            const StackFrameContext *InitLoc) {
+  // make up an empty state for now.
+  GRState State(this,
+                EnvMgr.getInitialEnvironment(),
+                StoreMgr->getInitialStore(InitLoc),
+                GDMFactory.GetEmptyMap());
+
+  return getPersistentState(State);
+}
+
+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);
+}
+
+const GRState *GRState::bindDecl(const VarRegion* VR, SVal IVal) const {
+  Store new_store = getStateManager().StoreMgr->BindDecl(St, VR, IVal);
+  return makeWithStore(new_store);
+}
+
+const GRState *GRState::bindDeclWithNoInit(const VarRegion* VR) const {
+  Store new_store = getStateManager().StoreMgr->BindDeclWithNoInit(St, VR);
+  return makeWithStore(new_store);
+}
+
+const GRState *GRState::bindLoc(Loc LV, SVal V) const {
+  GRStateManager &Mgr = getStateManager();
+  Store new_store = Mgr.StoreMgr->Bind(St, LV, V);
+  const GRState *new_state = makeWithStore(new_store);
+
+  const MemRegion *MR = LV.getAsRegion();
+  if (MR)
+    return Mgr.getOwningEngine().ProcessRegionChange(new_state, MR);
+
+  return new_state;
+}
+
+const GRState *GRState::bindDefault(SVal loc, SVal V) const {
+  GRStateManager &Mgr = getStateManager();
+  const MemRegion *R = cast<loc::MemRegionVal>(loc).getRegion();
+  Store new_store = Mgr.StoreMgr->BindDefault(St, R, V);
+  const GRState *new_state = makeWithStore(new_store);
+  return Mgr.getOwningEngine().ProcessRegionChange(new_state, R);
+}
+
+const GRState *GRState::InvalidateRegions(const MemRegion * const *Begin,
+                                          const MemRegion * const *End,
+                                          const Expr *E, unsigned Count,
+                                          StoreManager::InvalidatedSymbols *IS,
+                                          bool invalidateGlobals) const {
+  GRStateManager &Mgr = getStateManager();
+  GRSubEngine &Eng = Mgr.getOwningEngine();
+
+  if (Eng.WantsRegionChangeUpdate(this)) {
+    StoreManager::InvalidatedRegions Regions;
+
+    Store new_store = Mgr.StoreMgr->InvalidateRegions(St, Begin, End,
+                                                      E, Count, IS,
+                                                      invalidateGlobals,
+                                                      &Regions);
+    const GRState *new_state = makeWithStore(new_store);
+
+    return Eng.ProcessRegionChanges(new_state,
+                                    &Regions.front(),
+                                    &Regions.back()+1);
+  }
+
+  Store new_store = Mgr.StoreMgr->InvalidateRegions(St, Begin, End,
+                                                    E, Count, IS,
+                                                    invalidateGlobals,
+                                                    NULL);
+  return makeWithStore(new_store);
 }
 
 const GRState *GRState::unbindLoc(Loc LV) const {
+  assert(!isa<loc::MemRegionVal>(LV) && "Use InvalidateRegion instead.");
+
   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);
+  return makeWithStore(NewStore);
+}
+
+const GRState *GRState::EnterStackFrame(const StackFrameContext *frame) const {
+  Store new_store = getStateManager().StoreMgr->EnterStackFrame(this, frame);
+  return makeWithStore(new_store);
 }
 
 SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
@@ -78,7 +161,7 @@
     return UnknownVal();
 
   if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
-    QualType T = TR->getValueType(getStateManager().getContext());
+    QualType T = TR->getValueType();
     if (Loc::IsLocType(T) || T->isIntegerType())
       return getSVal(R);
   }
@@ -98,6 +181,50 @@
   return getStateManager().getPersistentState(NewSt);
 }
 
+const GRState *GRState::AssumeInBound(DefinedOrUnknownSVal Idx,
+                                      DefinedOrUnknownSVal UpperBound,
+                                      bool Assumption) const {
+  if (Idx.isUnknown() || UpperBound.isUnknown())
+    return this;
+
+  // Build an expression for 0 <= Idx < UpperBound.
+  // This is the same as Idx + MIN < UpperBound + MIN, if overflow is allowed.
+  // FIXME: This should probably be part of SValuator.
+  GRStateManager &SM = getStateManager();
+  ValueManager &VM = SM.getValueManager();
+  SValuator &SV = VM.getSValuator();
+  ASTContext &Ctx = VM.getContext();
+
+  // Get the offset: the minimum value of the array index type.
+  BasicValueFactory &BVF = VM.getBasicValueFactory();
+  // FIXME: This should be using ValueManager::ArrayIndexTy...somehow.
+  QualType IndexTy = Ctx.IntTy;
+  nonloc::ConcreteInt Min = BVF.getMinValue(IndexTy);
+
+  // Adjust the index.
+  SVal NewIdx = SV.EvalBinOpNN(this, BO_Add,
+                               cast<NonLoc>(Idx), Min, IndexTy);
+  if (NewIdx.isUnknownOrUndef())
+    return this;
+
+  // Adjust the upper bound.
+  SVal NewBound = SV.EvalBinOpNN(this, BO_Add,
+                                 cast<NonLoc>(UpperBound), Min, IndexTy);
+  if (NewBound.isUnknownOrUndef())
+    return this;
+
+  // Build the actual comparison.
+  SVal InBound = SV.EvalBinOpNN(this, BO_LT,
+                                cast<NonLoc>(NewIdx), cast<NonLoc>(NewBound),
+                                Ctx.IntTy);
+  if (InBound.isUnknownOrUndef())
+    return this;
+
+  // Finally, let the constraint manager take care of it.
+  ConstraintManager &CM = SM.getConstraintManager();
+  return CM.Assume(this, cast<DefinedSVal>(InBound), Assumption);
+}
+
 const GRState* GRStateManager::getInitialState(const LocationContext *InitLoc) {
   GRState State(this,
                 EnvMgr.getInitialEnvironment(),
@@ -344,28 +471,3 @@
   }
   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/HTMLDiagnostics.cpp b/lib/Checker/HTMLDiagnostics.cpp
new file mode 100644
index 0000000..ff9867f
--- /dev/null
+++ b/lib/Checker/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/Checker/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";
+    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/Checker/IdempotentOperationChecker.cpp b/lib/Checker/IdempotentOperationChecker.cpp
new file mode 100644
index 0000000..8a9e333
--- /dev/null
+++ b/lib/Checker/IdempotentOperationChecker.cpp
@@ -0,0 +1,643 @@
+//==- IdempotentOperationChecker.cpp - Idempotent Operations ----*- 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 path-sensitive checks for idempotent and/or
+// tautological operations. Each potential operation is checked along all paths
+// to see if every path results in a pointless operation.
+//                 +-------------------------------------------+
+//                 |Table of idempotent/tautological operations|
+//                 +-------------------------------------------+
+//+--------------------------------------------------------------------------+
+//|Operator | x op x | x op 1 | 1 op x | x op 0 | 0 op x | x op ~0 | ~0 op x |
+//+--------------------------------------------------------------------------+
+//  +, +=   |        |        |        |   x    |   x    |         |
+//  -, -=   |        |        |        |   x    |   -x   |         |
+//  *, *=   |        |   x    |   x    |   0    |   0    |         |
+//  /, /=   |   1    |   x    |        |  N/A   |   0    |         |
+//  &, &=   |   x    |        |        |   0    |   0    |   x     |    x
+//  |, |=   |   x    |        |        |   x    |   x    |   ~0    |    ~0
+//  ^, ^=   |   0    |        |        |   x    |   x    |         |
+//  <<, <<= |        |        |        |   x    |   0    |         |
+//  >>, >>= |        |        |        |   x    |   0    |         |
+//  ||      |   1    |   1    |   1    |   x    |   x    |   1     |    1
+//  &&      |   1    |   x    |   x    |   0    |   0    |   x     |    x
+//  =       |   x    |        |        |        |        |         |
+//  ==      |   1    |        |        |        |        |         |
+//  >=      |   1    |        |        |        |        |         |
+//  <=      |   1    |        |        |        |        |         |
+//  >       |   0    |        |        |        |        |         |
+//  <       |   0    |        |        |        |        |         |
+//  !=      |   0    |        |        |        |        |         |
+//===----------------------------------------------------------------------===//
+//
+// Things TODO:
+// - Improved error messages
+// - Handle mixed assumptions (which assumptions can belong together?)
+// - Finer grained false positive control (levels)
+// - Handling ~0 values
+
+#include "GRExprEngineExperimentalChecks.h"
+#include "clang/Analysis/CFGStmtMap.h"
+#include "clang/Analysis/Analyses/PseudoConstantAnalysis.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerHelpers.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/PathSensitive/GRCoreEngine.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "clang/AST/Stmt.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <deque>
+
+using namespace clang;
+
+namespace {
+class IdempotentOperationChecker
+  : public CheckerVisitor<IdempotentOperationChecker> {
+  public:
+    static void *getTag();
+    void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
+    void VisitEndAnalysis(ExplodedGraph &G, BugReporter &B, GRExprEngine &Eng);
+
+  private:
+    // Our assumption about a particular operation.
+    enum Assumption { Possible = 0, Impossible, Equal, LHSis1, RHSis1, LHSis0,
+        RHSis0 };
+
+    void UpdateAssumption(Assumption &A, const Assumption &New);
+
+    // False positive reduction methods
+    static bool isUnusedSelfAssign(const Expr *LHS,
+                                      const Expr *RHS,
+                                      AnalysisContext *AC);
+    static bool isTruncationExtensionAssignment(const Expr *LHS,
+                                                const Expr *RHS);
+    static bool PathWasCompletelyAnalyzed(const CFG *C,
+                                          const CFGBlock *CB,
+                                          const GRCoreEngine &CE);
+    static bool CanVary(const Expr *Ex, AnalysisContext *AC);
+    static bool isConstantOrPseudoConstant(const DeclRefExpr *DR,
+                                           AnalysisContext *AC);
+    static bool containsNonLocalVarDecl(const Stmt *S);
+
+    // Hash table
+    typedef llvm::DenseMap<const BinaryOperator *,
+                           std::pair<Assumption, AnalysisContext*> >
+                           AssumptionMap;
+    AssumptionMap hash;
+};
+}
+
+void *IdempotentOperationChecker::getTag() {
+  static int x = 0;
+  return &x;
+}
+
+void clang::RegisterIdempotentOperationChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new IdempotentOperationChecker());
+}
+
+void IdempotentOperationChecker::PreVisitBinaryOperator(
+                                                      CheckerContext &C,
+                                                      const BinaryOperator *B) {
+  // Find or create an entry in the hash for this BinaryOperator instance.
+  // If we haven't done a lookup before, it will get default initialized to
+  // 'Possible'.
+  std::pair<Assumption, AnalysisContext *> &Data = hash[B];
+  Assumption &A = Data.first;
+  AnalysisContext *AC = C.getCurrentAnalysisContext();
+  Data.second = AC;
+
+  // If we already have visited this node on a path that does not contain an
+  // idempotent operation, return immediately.
+  if (A == Impossible)
+    return;
+
+  // Retrieve both sides of the operator and determine if they can vary (which
+  // may mean this is a false positive.
+  const Expr *LHS = B->getLHS();
+  const Expr *RHS = B->getRHS();
+
+  // At this stage we can calculate whether each side contains a false positive
+  // that applies to all operators. We only need to calculate this the first
+  // time.
+  bool LHSContainsFalsePositive = false, RHSContainsFalsePositive = false;
+  if (A == Possible) {
+    // An expression contains a false positive if it can't vary, or if it
+    // contains a known false positive VarDecl.
+    LHSContainsFalsePositive = !CanVary(LHS, AC)
+        || containsNonLocalVarDecl(LHS);
+    RHSContainsFalsePositive = !CanVary(RHS, AC)
+        || containsNonLocalVarDecl(RHS);
+  }
+
+  const GRState *state = C.getState();
+
+  SVal LHSVal = state->getSVal(LHS);
+  SVal RHSVal = state->getSVal(RHS);
+
+  // If either value is unknown, we can't be 100% sure of all paths.
+  if (LHSVal.isUnknownOrUndef() || RHSVal.isUnknownOrUndef()) {
+    A = Impossible;
+    return;
+  }
+  BinaryOperator::Opcode Op = B->getOpcode();
+
+  // Dereference the LHS SVal if this is an assign operation
+  switch (Op) {
+  default:
+    break;
+
+  // Fall through intentional
+  case BO_AddAssign:
+  case BO_SubAssign:
+  case BO_MulAssign:
+  case BO_DivAssign:
+  case BO_AndAssign:
+  case BO_OrAssign:
+  case BO_XorAssign:
+  case BO_ShlAssign:
+  case BO_ShrAssign:
+  case BO_Assign:
+  // Assign statements have one extra level of indirection
+    if (!isa<Loc>(LHSVal)) {
+      A = Impossible;
+      return;
+    }
+    LHSVal = state->getSVal(cast<Loc>(LHSVal));
+  }
+
+
+  // We now check for various cases which result in an idempotent operation.
+
+  // x op x
+  switch (Op) {
+  default:
+    break; // We don't care about any other operators.
+
+  // Fall through intentional
+  case BO_Assign:
+    // x Assign x can be used to silence unused variable warnings intentionally,
+    // and has a slightly different definition for false positives.
+    if (isUnusedSelfAssign(RHS, LHS, AC)
+        || isTruncationExtensionAssignment(RHS, LHS)
+        || containsNonLocalVarDecl(RHS)
+        || containsNonLocalVarDecl(LHS)) {
+      A = Impossible;
+      return;
+    }
+    if (LHSVal != RHSVal)
+      break;
+    UpdateAssumption(A, Equal);
+    return;
+
+  case BO_SubAssign:
+  case BO_DivAssign:
+  case BO_AndAssign:
+  case BO_OrAssign:
+  case BO_XorAssign:
+  case BO_Sub:
+  case BO_Div:
+  case BO_And:
+  case BO_Or:
+  case BO_Xor:
+  case BO_LOr:
+  case BO_LAnd:
+  case BO_EQ:
+  case BO_NE:
+    if (LHSVal != RHSVal || LHSContainsFalsePositive
+        || RHSContainsFalsePositive)
+      break;
+    UpdateAssumption(A, Equal);
+    return;
+  }
+
+  // x op 1
+  switch (Op) {
+   default:
+     break; // We don't care about any other operators.
+
+   // Fall through intentional
+   case BO_MulAssign:
+   case BO_DivAssign:
+   case BO_Mul:
+   case BO_Div:
+   case BO_LOr:
+   case BO_LAnd:
+     if (!RHSVal.isConstant(1) || RHSContainsFalsePositive)
+       break;
+     UpdateAssumption(A, RHSis1);
+     return;
+  }
+
+  // 1 op x
+  switch (Op) {
+  default:
+    break; // We don't care about any other operators.
+
+  // Fall through intentional
+  case BO_MulAssign:
+  case BO_Mul:
+  case BO_LOr:
+  case BO_LAnd:
+    if (!LHSVal.isConstant(1) || LHSContainsFalsePositive)
+      break;
+    UpdateAssumption(A, LHSis1);
+    return;
+  }
+
+  // x op 0
+  switch (Op) {
+  default:
+    break; // We don't care about any other operators.
+
+  // Fall through intentional
+  case BO_AddAssign:
+  case BO_SubAssign:
+  case BO_MulAssign:
+  case BO_AndAssign:
+  case BO_OrAssign:
+  case BO_XorAssign:
+  case BO_Add:
+  case BO_Sub:
+  case BO_Mul:
+  case BO_And:
+  case BO_Or:
+  case BO_Xor:
+  case BO_Shl:
+  case BO_Shr:
+  case BO_LOr:
+  case BO_LAnd:
+    if (!RHSVal.isConstant(0) || RHSContainsFalsePositive)
+      break;
+    UpdateAssumption(A, RHSis0);
+    return;
+  }
+
+  // 0 op x
+  switch (Op) {
+  default:
+    break; // We don't care about any other operators.
+
+  // Fall through intentional
+  //case BO_AddAssign: // Common false positive
+  case BO_SubAssign: // Check only if unsigned
+  case BO_MulAssign:
+  case BO_DivAssign:
+  case BO_AndAssign:
+  //case BO_OrAssign: // Common false positive
+  //case BO_XorAssign: // Common false positive
+  case BO_ShlAssign:
+  case BO_ShrAssign:
+  case BO_Add:
+  case BO_Sub:
+  case BO_Mul:
+  case BO_Div:
+  case BO_And:
+  case BO_Or:
+  case BO_Xor:
+  case BO_Shl:
+  case BO_Shr:
+  case BO_LOr:
+  case BO_LAnd:
+    if (!LHSVal.isConstant(0) || LHSContainsFalsePositive)
+      break;
+    UpdateAssumption(A, LHSis0);
+    return;
+  }
+
+  // If we get to this point, there has been a valid use of this operation.
+  A = Impossible;
+}
+
+void IdempotentOperationChecker::VisitEndAnalysis(ExplodedGraph &G,
+                                                  BugReporter &BR,
+                                                  GRExprEngine &Eng) {
+  // Iterate over the hash to see if we have any paths with definite
+  // idempotent operations.
+  for (AssumptionMap::const_iterator i = hash.begin(); i != hash.end(); ++i) {
+    // Unpack the hash contents
+    const std::pair<Assumption, AnalysisContext *> &Data = i->second;
+    const Assumption &A = Data.first;
+    AnalysisContext *AC = Data.second;
+
+    const BinaryOperator *B = i->first;
+
+    if (A == Impossible)
+      continue;
+
+    // If the analyzer did not finish, check to see if we can still emit this
+    // warning
+    if (Eng.hasWorkRemaining()) {
+      const CFGStmtMap *CBM = CFGStmtMap::Build(AC->getCFG(),
+                                                &AC->getParentMap());
+
+      // If we can trace back
+      if (!PathWasCompletelyAnalyzed(AC->getCFG(),
+                                     CBM->getBlock(B),
+                                     Eng.getCoreEngine()))
+        continue;
+
+      delete CBM;
+    }
+
+    // Select the error message.
+    llvm::SmallString<128> buf;
+    llvm::raw_svector_ostream os(buf);
+    switch (A) {
+    case Equal:
+      if (B->getOpcode() == BO_Assign)
+        os << "Assigned value is always the same as the existing value";
+      else
+        os << "Both operands to '" << B->getOpcodeStr()
+           << "' always have the same value";
+      break;
+    case LHSis1:
+      os << "The left operand to '" << B->getOpcodeStr() << "' is always 1";
+      break;
+    case RHSis1:
+      os << "The right operand to '" << B->getOpcodeStr() << "' is always 1";
+      break;
+    case LHSis0:
+      os << "The left operand to '" << B->getOpcodeStr() << "' is always 0";
+      break;
+    case RHSis0:
+      os << "The right operand to '" << B->getOpcodeStr() << "' is always 0";
+      break;
+    case Possible:
+      llvm_unreachable("Operation was never marked with an assumption");
+    case Impossible:
+      llvm_unreachable(0);
+    }
+
+    // Create the SourceRange Arrays
+    SourceRange S[2] = { i->first->getLHS()->getSourceRange(),
+                         i->first->getRHS()->getSourceRange() };
+    BR.EmitBasicReport("Idempotent operation", "Dead code",
+                       os.str(), i->first->getOperatorLoc(), S, 2);
+  }
+}
+
+// Updates the current assumption given the new assumption
+inline void IdempotentOperationChecker::UpdateAssumption(Assumption &A,
+                                                        const Assumption &New) {
+// If the assumption is the same, there is nothing to do
+  if (A == New)
+    return;
+
+  switch (A) {
+  // If we don't currently have an assumption, set it
+  case Possible:
+    A = New;
+    return;
+
+  // If we have determined that a valid state happened, ignore the new
+  // assumption.
+  case Impossible:
+    return;
+
+  // Any other case means that we had a different assumption last time. We don't
+  // currently support mixing assumptions for diagnostic reasons, so we set
+  // our assumption to be impossible.
+  default:
+    A = Impossible;
+    return;
+  }
+}
+
+// Check for a statement where a variable is self assigned to avoid an unused
+// variable warning. We still report if the variable is used after the self
+// assignment.
+bool IdempotentOperationChecker::isUnusedSelfAssign(const Expr *LHS,
+                                                    const Expr *RHS,
+                                                    AnalysisContext *AC) {
+  LHS = LHS->IgnoreParenCasts();
+  RHS = RHS->IgnoreParenCasts();
+
+  const DeclRefExpr *LHS_DR = dyn_cast<DeclRefExpr>(LHS);
+  if (!LHS_DR)
+    return false;
+
+  const VarDecl *VD = dyn_cast<VarDecl>(LHS_DR->getDecl());
+  if (!VD)
+    return false;
+
+  const DeclRefExpr *RHS_DR = dyn_cast<DeclRefExpr>(RHS);
+  if (!RHS_DR)
+    return false;
+
+  if (VD != RHS_DR->getDecl())
+    return false;
+
+  // If the var was used outside of a selfassign, then we should still report
+  if (AC->getPseudoConstantAnalysis()->wasReferenced(VD))
+    return false;
+
+  return true;
+}
+
+// Check for self casts truncating/extending a variable
+bool IdempotentOperationChecker::isTruncationExtensionAssignment(
+                                                              const Expr *LHS,
+                                                              const Expr *RHS) {
+
+  const DeclRefExpr *LHS_DR = dyn_cast<DeclRefExpr>(LHS->IgnoreParenCasts());
+  if (!LHS_DR)
+    return false;
+
+  const VarDecl *VD = dyn_cast<VarDecl>(LHS_DR->getDecl());
+  if (!VD)
+    return false;
+
+  const DeclRefExpr *RHS_DR = dyn_cast<DeclRefExpr>(RHS->IgnoreParenCasts());
+  if (!RHS_DR)
+    return false;
+
+  if (VD != RHS_DR->getDecl())
+     return false;
+
+  return dyn_cast<DeclRefExpr>(RHS->IgnoreParens()) == NULL;
+}
+
+// Returns false if a path to this block was not completely analyzed, or true
+// otherwise.
+bool IdempotentOperationChecker::PathWasCompletelyAnalyzed(
+                                                       const CFG *C,
+                                                       const CFGBlock *CB,
+                                                       const GRCoreEngine &CE) {
+  std::deque<const CFGBlock *> WorkList;
+  llvm::SmallSet<unsigned, 8> Aborted;
+  llvm::SmallSet<unsigned, 128> Visited;
+
+  // Create a set of all aborted blocks
+  typedef GRCoreEngine::BlocksAborted::const_iterator AbortedIterator;
+  for (AbortedIterator I = CE.blocks_aborted_begin(),
+      E = CE.blocks_aborted_end(); I != E; ++I) {
+    const BlockEdge &BE =  I->first;
+
+    // The destination block on the BlockEdge is the first block that was not
+    // analyzed.
+    Aborted.insert(BE.getDst()->getBlockID());
+  }
+
+  // Save the entry block ID for early exiting
+  unsigned EntryBlockID = C->getEntry().getBlockID();
+
+  // Create initial node
+  WorkList.push_back(CB);
+
+  while (!WorkList.empty()) {
+    const CFGBlock *Head = WorkList.front();
+    WorkList.pop_front();
+    Visited.insert(Head->getBlockID());
+
+    // If we found the entry block, then there exists a path from the target
+    // node to the entry point of this function -> the path was completely
+    // analyzed.
+    if (Head->getBlockID() == EntryBlockID)
+      return true;
+
+    // If any of the aborted blocks are on the path to the beginning, then all
+    // paths to this block were not analyzed.
+    if (Aborted.count(Head->getBlockID()))
+      return false;
+
+    // Add the predecessors to the worklist unless we have already visited them
+    for (CFGBlock::const_pred_iterator I = Head->pred_begin();
+        I != Head->pred_end(); ++I)
+      if (!Visited.count((*I)->getBlockID()))
+        WorkList.push_back(*I);
+  }
+
+  // If we get to this point, there is no connection to the entry block or an
+  // aborted block. This path is unreachable and we can report the error.
+  return true;
+}
+
+// Recursive function that determines whether an expression contains any element
+// that varies. This could be due to a compile-time constant like sizeof. An
+// expression may also involve a variable that behaves like a constant. The
+// function returns true if the expression varies, and false otherwise.
+bool IdempotentOperationChecker::CanVary(const Expr *Ex,
+                                         AnalysisContext *AC) {
+  // Parentheses and casts are irrelevant here
+  Ex = Ex->IgnoreParenCasts();
+
+  if (Ex->getLocStart().isMacroID())
+    return false;
+
+  switch (Ex->getStmtClass()) {
+  // Trivially true cases
+  case Stmt::ArraySubscriptExprClass:
+  case Stmt::MemberExprClass:
+  case Stmt::StmtExprClass:
+  case Stmt::CallExprClass:
+  case Stmt::VAArgExprClass:
+  case Stmt::ShuffleVectorExprClass:
+    return true;
+  default:
+    return true;
+
+  // Trivially false cases
+  case Stmt::IntegerLiteralClass:
+  case Stmt::CharacterLiteralClass:
+  case Stmt::FloatingLiteralClass:
+  case Stmt::PredefinedExprClass:
+  case Stmt::ImaginaryLiteralClass:
+  case Stmt::StringLiteralClass:
+  case Stmt::OffsetOfExprClass:
+  case Stmt::CompoundLiteralExprClass:
+  case Stmt::AddrLabelExprClass:
+  case Stmt::TypesCompatibleExprClass:
+  case Stmt::GNUNullExprClass:
+  case Stmt::InitListExprClass:
+  case Stmt::DesignatedInitExprClass:
+  case Stmt::BlockExprClass:
+  case Stmt::BlockDeclRefExprClass:
+    return false;
+
+  // Cases requiring custom logic
+  case Stmt::SizeOfAlignOfExprClass: {
+    const SizeOfAlignOfExpr *SE = cast<const SizeOfAlignOfExpr>(Ex);
+    if (!SE->isSizeOf())
+      return false;
+    return SE->getTypeOfArgument()->isVariableArrayType();
+  }
+  case Stmt::DeclRefExprClass:
+    return !isConstantOrPseudoConstant(cast<DeclRefExpr>(Ex), AC);
+
+  // The next cases require recursion for subexpressions
+  case Stmt::BinaryOperatorClass: {
+    const BinaryOperator *B = cast<const BinaryOperator>(Ex);
+    return CanVary(B->getRHS(), AC)
+        || CanVary(B->getLHS(), AC);
+   }
+  case Stmt::UnaryOperatorClass: {
+    const UnaryOperator *U = cast<const UnaryOperator>(Ex);
+    // Handle trivial case first
+    switch (U->getOpcode()) {
+    case UO_Extension:
+      return false;
+    default:
+      return CanVary(U->getSubExpr(), AC);
+    }
+  }
+  case Stmt::ChooseExprClass:
+    return CanVary(cast<const ChooseExpr>(Ex)->getChosenSubExpr(
+        AC->getASTContext()), AC);
+  case Stmt::ConditionalOperatorClass:
+      return CanVary(cast<const ConditionalOperator>(Ex)->getCond(), AC);
+  }
+}
+
+// Returns true if a DeclRefExpr is or behaves like a constant.
+bool IdempotentOperationChecker::isConstantOrPseudoConstant(
+                                                         const DeclRefExpr *DR,
+                                                         AnalysisContext *AC) {
+  // Check if the type of the Decl is const-qualified
+  if (DR->getType().isConstQualified())
+    return true;
+
+  // Check for an enum
+  if (isa<EnumConstantDecl>(DR->getDecl()))
+    return true;
+
+  const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
+  if (!VD)
+    return true;
+
+  // Check if the Decl behaves like a constant. This check also takes care of
+  // static variables, which can only change between function calls if they are
+  // modified in the AST.
+  PseudoConstantAnalysis *PCA = AC->getPseudoConstantAnalysis();
+  if (PCA->isPseudoConstant(VD))
+    return true;
+
+  return false;
+}
+
+// Recursively find any substatements containing VarDecl's with storage other
+// than local
+bool IdempotentOperationChecker::containsNonLocalVarDecl(const Stmt *S) {
+  const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S);
+
+  if (DR)
+    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl()))
+      if (!VD->hasLocalStorage())
+        return true;
+
+  for (Stmt::const_child_iterator I = S->child_begin(); I != S->child_end();
+      ++I)
+    if (const Stmt *child = *I)
+      if (containsNonLocalVarDecl(child))
+        return true;
+
+  return false;
+}
diff --git a/lib/Checker/LLVMConventionsChecker.cpp b/lib/Checker/LLVMConventionsChecker.cpp
index 14f0fc1..2f87da1 100644
--- a/lib/Checker/LLVMConventionsChecker.cpp
+++ b/lib/Checker/LLVMConventionsChecker.cpp
@@ -34,20 +34,22 @@
           "class llvm::StringRef";
 }
 
-static bool InStdNamespace(const Decl *D) {
+/// Check whether the declaration is semantically inside the top-level
+/// namespace named by ns.
+static bool InNamespace(const Decl *D, llvm::StringRef NS) {
   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")
+  if (!II || !II->getName().equals(NS))
     return false;
   DC = ND->getDeclContext();
   return isa<TranslationUnitDecl>(DC);
 }
 
 static bool IsStdString(QualType T) {
-  if (const QualifiedNameType *QT = T->getAs<QualifiedNameType>())
+  if (const ElaboratedType *QT = T->getAs<ElaboratedType>())
     T = QT->getNamedType();
 
   const TypedefType *TT = T->getAs<TypedefType>();
@@ -56,50 +58,26 @@
 
   const TypedefDecl *TD = TT->getDecl();
 
-  if (!InStdNamespace(TD))
+  if (!InNamespace(TD, "std"))
     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);
+  return RD->getName() == "Type" && InNamespace(RD, "clang");
 }
 
 static bool IsClangDecl(const RecordDecl *RD) {
-  return RD->getName() == "Decl" && InClangNamespace(RD);
+  return RD->getName() == "Decl" && InNamespace(RD, "clang");
 }
 
 static bool IsClangStmt(const RecordDecl *RD) {
-  return RD->getName() == "Stmt" && InClangNamespace(RD);
+  return RD->getName() == "Stmt" && InNamespace(RD, "clang");
 }
 
-static bool isClangAttr(const RecordDecl *RD) {
-  return RD->getName() == "Attr" && InClangNamespace(RD);
+static bool IsClangAttr(const RecordDecl *RD) {
+  return RD->getName() == "Attr" && InNamespace(RD, "clang");
 }
 
 static bool IsStdVector(QualType T) {
@@ -110,7 +88,7 @@
   TemplateName TM = TS->getTemplateName();
   TemplateDecl *TD = TM.getAsTemplateDecl();
 
-  if (!TD || !InStdNamespace(TD))
+  if (!TD || !InNamespace(TD, "std"))
     return false;
 
   return TD->getName() == "vector";
@@ -124,7 +102,7 @@
   TemplateName TM = TS->getTemplateName();
   TemplateDecl *TD = TM.getAsTemplateDecl();
 
-  if (!TD || !InLLVMNamespace(TD))
+  if (!TD || !InNamespace(TD, "llvm"))
     return false;
 
   return TD->getName() == "SmallVector";
@@ -150,7 +128,6 @@
   void VisitDeclStmt(DeclStmt *DS);
 private:
   void VisitVarDecl(VarDecl *VD);
-  void CheckStringRefBoundtoTemporaryString(VarDecl *VD);
 };
 } // end anonymous namespace
 
@@ -214,7 +191,7 @@
 
 // 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))
+  if (IsClangStmt(R) || IsClangType(R) || IsClangDecl(R) || IsClangAttr(R))
     return true;
 
   for (CXXRecordDecl::base_class_const_iterator I = R->bases_begin(),
@@ -316,7 +293,7 @@
 
     Decl *D = *I;
 
-    if (D->getBody())
+    if (D->hasBody())
       CheckStringRefAssignedTemporary(D, BR);
 
     if (CXXRecordDecl *R = dyn_cast<CXXRecordDecl>(D))
diff --git a/lib/Checker/Makefile b/lib/Checker/Makefile
index c45ab29..4ec6f65 100644
--- a/lib/Checker/Makefile
+++ b/lib/Checker/Makefile
@@ -11,11 +11,8 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
+CLANG_LEVEL := ../..
 LIBRARYNAME := clangChecker
-BUILD_ARCHIVE = 1
 
-CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
 
diff --git a/lib/Checker/MallocChecker.cpp b/lib/Checker/MallocChecker.cpp
index a22df30..3224f7b 100644
--- a/lib/Checker/MallocChecker.cpp
+++ b/lib/Checker/MallocChecker.cpp
@@ -24,15 +24,18 @@
 namespace {
 
 class RefState {
-  enum Kind { AllocateUnchecked, AllocateFailed, Released, Escaped } K;
+  enum Kind { AllocateUnchecked, AllocateFailed, Released, Escaped,
+              Relinquished } K;
   const Stmt *S;
 
 public:
   RefState(Kind k, const Stmt *s) : K(k), S(s) {}
 
   bool isAllocated() const { return K == AllocateUnchecked; }
+  bool isFailed() const { return K == AllocateFailed; }
   bool isReleased() const { return K == Released; }
   bool isEscaped() const { return K == Escaped; }
+  bool isRelinquished() const { return K == Relinquished; }
 
   bool operator==(const RefState &X) const {
     return K == X.K && S == X.S;
@@ -46,6 +49,9 @@
   }
   static RefState getReleased(const Stmt *s) { return RefState(Released, s); }
   static RefState getEscaped(const Stmt *s) { return RefState(Escaped, s); }
+  static RefState getRelinquished(const Stmt *s) {
+    return RefState(Relinquished, s);
+  }
 
   void Profile(llvm::FoldingSetNodeID &ID) const {
     ID.AddInteger(K);
@@ -59,29 +65,52 @@
   BuiltinBug *BT_DoubleFree;
   BuiltinBug *BT_Leak;
   BuiltinBug *BT_UseFree;
-  IdentifierInfo *II_malloc, *II_free, *II_realloc;
+  BuiltinBug *BT_UseRelinquished;
+  BuiltinBug *BT_BadFree;
+  IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc;
 
 public:
   MallocChecker() 
-    : BT_DoubleFree(0), BT_Leak(0), BT_UseFree(0), 
-      II_malloc(0), II_free(0), II_realloc(0) {}
+    : BT_DoubleFree(0), BT_Leak(0), BT_UseFree(0), BT_UseRelinquished(0),
+      BT_BadFree(0),
+      II_malloc(0), II_free(0), II_realloc(0), II_calloc(0) {}
   static void *getTag();
   bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
-  void EvalDeadSymbols(CheckerContext &C,const Stmt *S,SymbolReaper &SymReaper);
+  void EvalDeadSymbols(CheckerContext &C, 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);
+  const GRState *EvalAssume(const GRState *state, SVal Cond, bool Assumption,
+                            bool *respondsToCallback);
   void VisitLocation(CheckerContext &C, const Stmt *S, SVal l);
+  virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
+                            const Stmt *StoreE, SVal location,
+                            SVal val);
 
 private:
   void MallocMem(CheckerContext &C, const CallExpr *CE);
+  void MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
+                            const OwnershipAttr* Att);
   const GRState *MallocMemAux(CheckerContext &C, const CallExpr *CE,
-                              const Expr *SizeEx, const GRState *state);
+                              const Expr *SizeEx, SVal Init,
+                              const GRState *state) {
+    return MallocMemAux(C, CE, state->getSVal(SizeEx), Init, state);
+  }
+  const GRState *MallocMemAux(CheckerContext &C, const CallExpr *CE,
+                              SVal SizeEx, SVal Init,
+                              const GRState *state);
+
   void FreeMem(CheckerContext &C, const CallExpr *CE);
+  void FreeMemAttr(CheckerContext &C, const CallExpr *CE,
+                   const OwnershipAttr* Att);
   const GRState *FreeMemAux(CheckerContext &C, const CallExpr *CE,
-                            const GRState *state);
+                            const GRState *state, unsigned Num, bool Hold);
 
   void ReallocMem(CheckerContext &C, const CallExpr *CE);
+  void CallocMem(CheckerContext &C, const CallExpr *CE);
+  
+  bool SummarizeValue(llvm::raw_ostream& os, SVal V);
+  bool SummarizeRegion(llvm::raw_ostream& os, const MemRegion *MR);
+  void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange range);
 };
 } // end anonymous namespace
 
@@ -90,7 +119,7 @@
 namespace clang {
   template <>
   struct GRStateTrait<RegionState> 
-    : public GRStatePartialTrait<llvm::ImmutableMap<SymbolRef, RefState> > {
+    : public GRStatePartialTrait<RegionStateTy> {
     static void *GDMIndex() { return MallocChecker::getTag(); }
   };
 }
@@ -120,6 +149,8 @@
     II_free = &Ctx.Idents.get("free");
   if (!II_realloc)
     II_realloc = &Ctx.Idents.get("realloc");
+  if (!II_calloc)
+    II_calloc = &Ctx.Idents.get("calloc");
 
   if (FD->getIdentifier() == II_malloc) {
     MallocMem(C, CE);
@@ -136,30 +167,86 @@
     return true;
   }
 
-  return false;
+  if (FD->getIdentifier() == II_calloc) {
+    CallocMem(C, CE);
+    return true;
+  }
+
+  // Check all the attributes, if there are any.
+  // There can be multiple of these attributes.
+  bool rv = false;
+  if (FD->hasAttrs()) {
+    for (specific_attr_iterator<OwnershipAttr>
+                  i = FD->specific_attr_begin<OwnershipAttr>(),
+                  e = FD->specific_attr_end<OwnershipAttr>();
+         i != e; ++i) {
+      switch ((*i)->getOwnKind()) {
+      case OwnershipAttr::Returns: {
+        MallocMemReturnsAttr(C, CE, *i);
+        rv = true;
+        break;
+      }
+      case OwnershipAttr::Takes:
+      case OwnershipAttr::Holds: {
+        FreeMemAttr(C, CE, *i);
+        rv = true;
+        break;
+      }
+      default:
+        break;
+      }
+    }
+  }
+  return rv;
 }
 
 void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) {
-  const GRState *state = MallocMemAux(C, CE, CE->getArg(0), C.getState());
+  const GRState *state = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(),
+                                      C.getState());
+  C.addTransition(state);
+}
+
+void MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
+                                         const OwnershipAttr* Att) {
+  if (Att->getModule() != "malloc")
+    return;
+
+  OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
+  if (I != E) {
+    const GRState *state =
+        MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState());
+    C.addTransition(state);
+    return;
+  }
+  const GRState *state = MallocMemAux(C, CE, UnknownVal(), UndefinedVal(),
+                                        C.getState());
   C.addTransition(state);
 }
 
 const GRState *MallocChecker::MallocMemAux(CheckerContext &C,  
                                            const CallExpr *CE,
-                                           const Expr *SizeEx,
+                                           SVal Size, SVal Init,
                                            const GRState *state) {
   unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
   ValueManager &ValMgr = C.getValueManager();
 
+  // Set the return value.
   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);
-  
+
+  // Fill the region with the initialization value.
+  state = state->bindDefault(RetVal, Init);
+
+  // Set the region's extent equal to the Size parameter.
+  const SymbolicRegion *R = cast<SymbolicRegion>(RetVal.getAsRegion());
+  DefinedOrUnknownSVal Extent = R->getExtent(ValMgr);
+  DefinedOrUnknownSVal DefinedSize = cast<DefinedOrUnknownSVal>(Size);
+
+  SValuator &SVator = ValMgr.getSValuator();
+  DefinedOrUnknownSVal ExtentMatchesSize =
+    SVator.EvalEQ(state, Extent, DefinedSize);
+  state = state->Assume(ExtentMatchesSize, true);
+
   SymbolRef Sym = RetVal.getAsLocSymbol();
   assert(Sym);
   // Set the symbol's state to Allocated.
@@ -167,37 +254,108 @@
 }
 
 void MallocChecker::FreeMem(CheckerContext &C, const CallExpr *CE) {
-  const GRState *state = FreeMemAux(C, CE, C.getState());
+  const GRState *state = FreeMemAux(C, CE, C.getState(), 0, false);
 
   if (state)
     C.addTransition(state);
 }
 
-const GRState *MallocChecker::FreeMemAux(CheckerContext &C, const CallExpr *CE,
-                                         const GRState *state) {
-  SVal ArgVal = state->getSVal(CE->getArg(0));
+void MallocChecker::FreeMemAttr(CheckerContext &C, const CallExpr *CE,
+                                const OwnershipAttr* Att) {
+  if (Att->getModule() != "malloc")
+    return;
 
-  // If ptr is NULL, no operation is preformed.
-  if (ArgVal.isZeroConstant())
+  for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
+       I != E; ++I) {
+    const GRState *state = FreeMemAux(C, CE, C.getState(), *I,
+                                      Att->getOwnKind() == OwnershipAttr::Holds);
+    if (state)
+      C.addTransition(state);
+  }
+}
+
+const GRState *MallocChecker::FreeMemAux(CheckerContext &C, const CallExpr *CE,
+                                         const GRState *state, unsigned Num,
+                                         bool Hold) {
+  const Expr *ArgExpr = CE->getArg(Num);
+  SVal ArgVal = state->getSVal(ArgExpr);
+
+  DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(ArgVal);
+
+  // Check for null dereferences.
+  if (!isa<Loc>(location))
     return state;
 
-  SymbolRef Sym = ArgVal.getAsLocSymbol();
-  assert(Sym);
+  // FIXME: Technically using 'Assume' here can result in a path
+  //  bifurcation.  In such cases we need to return two states, not just one.
+  const GRState *notNullState, *nullState;
+  llvm::tie(notNullState, nullState) = state->Assume(location);
 
+  // The explicit NULL case, no operation is performed.
+  if (nullState && !notNullState)
+    return nullState;
+
+  assert(notNullState);
+
+  // Unknown values could easily be okay
+  // Undefined values are handled elsewhere
+  if (ArgVal.isUnknownOrUndef())
+    return notNullState;
+
+  const MemRegion *R = ArgVal.getAsRegion();
+  
+  // Nonlocs can't be freed, of course.
+  // Non-region locations (labels and fixed addresses) also shouldn't be freed.
+  if (!R) {
+    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
+    return NULL;
+  }
+  
+  R = R->StripCasts();
+  
+  // Blocks might show up as heap data, but should not be free()d
+  if (isa<BlockDataRegion>(R)) {
+    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
+    return NULL;
+  }
+  
+  const MemSpaceRegion *MS = R->getMemorySpace();
+  
+  // Parameters, locals, statics, and globals shouldn't be freed.
+  if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
+    // FIXME: at the time this code was written, malloc() regions were
+    // represented by conjured symbols, which are all in UnknownSpaceRegion.
+    // This means that there isn't actually anything from HeapSpaceRegion
+    // that should be freed, even though we allow it here.
+    // Of course, free() can work on memory allocated outside the current
+    // function, so UnknownSpaceRegion is always a possibility.
+    // False negatives are better than false positives.
+    
+    ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
+    return NULL;
+  }
+  
+  const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R);
+  // Various cases could lead to non-symbol values here.
+  // For now, ignore them.
+  if (!SR)
+    return notNullState;
+
+  SymbolRef Sym = SR->getSymbol();
   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;
+    return notNullState;
 
   // Check double free.
   if (RS->isReleased()) {
-    ExplodedNode *N = C.GenerateSink();
-    if (N) {
+    if (ExplodedNode *N = C.GenerateSink()) {
       if (!BT_DoubleFree)
-        BT_DoubleFree = new BuiltinBug("Double free",
+        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, 
@@ -208,7 +366,137 @@
   }
 
   // Normal free.
-  return state->set<RegionState>(Sym, RefState::getReleased(CE));
+  if (Hold)
+    return notNullState->set<RegionState>(Sym, RefState::getRelinquished(CE));
+  return notNullState->set<RegionState>(Sym, RefState::getReleased(CE));
+}
+
+bool MallocChecker::SummarizeValue(llvm::raw_ostream& os, SVal V) {
+  if (nonloc::ConcreteInt *IntVal = dyn_cast<nonloc::ConcreteInt>(&V))
+    os << "an integer (" << IntVal->getValue() << ")";
+  else if (loc::ConcreteInt *ConstAddr = dyn_cast<loc::ConcreteInt>(&V))
+    os << "a constant address (" << ConstAddr->getValue() << ")";
+  else if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&V))
+    os << "the address of the label '"
+       << Label->getLabel()->getID()->getName()
+       << "'";
+  else
+    return false;
+  
+  return true;
+}
+
+bool MallocChecker::SummarizeRegion(llvm::raw_ostream& os,
+                                    const MemRegion *MR) {
+  switch (MR->getKind()) {
+  case MemRegion::FunctionTextRegionKind: {
+    const FunctionDecl *FD = cast<FunctionTextRegion>(MR)->getDecl();
+    if (FD)
+      os << "the address of the function '" << FD << "'";
+    else
+      os << "the address of a function";
+    return true;
+  }
+  case MemRegion::BlockTextRegionKind:
+    os << "block text";
+    return true;
+  case MemRegion::BlockDataRegionKind:
+    // FIXME: where the block came from?
+    os << "a block";
+    return true;
+  default: {
+    const MemSpaceRegion *MS = MR->getMemorySpace();
+    
+    switch (MS->getKind()) {
+    case MemRegion::StackLocalsSpaceRegionKind: {
+      const VarRegion *VR = dyn_cast<VarRegion>(MR);
+      const VarDecl *VD;
+      if (VR)
+        VD = VR->getDecl();
+      else
+        VD = NULL;
+      
+      if (VD)
+        os << "the address of the local variable '" << VD->getName() << "'";
+      else
+        os << "the address of a local stack variable";
+      return true;
+    }
+    case MemRegion::StackArgumentsSpaceRegionKind: {
+      const VarRegion *VR = dyn_cast<VarRegion>(MR);
+      const VarDecl *VD;
+      if (VR)
+        VD = VR->getDecl();
+      else
+        VD = NULL;
+      
+      if (VD)
+        os << "the address of the parameter '" << VD->getName() << "'";
+      else
+        os << "the address of a parameter";
+      return true;
+    }
+    case MemRegion::NonStaticGlobalSpaceRegionKind:
+    case MemRegion::StaticGlobalSpaceRegionKind: {
+      const VarRegion *VR = dyn_cast<VarRegion>(MR);
+      const VarDecl *VD;
+      if (VR)
+        VD = VR->getDecl();
+      else
+        VD = NULL;
+      
+      if (VD) {
+        if (VD->isStaticLocal())
+          os << "the address of the static variable '" << VD->getName() << "'";
+        else
+          os << "the address of the global variable '" << VD->getName() << "'";
+      } else
+        os << "the address of a global variable";
+      return true;
+    }
+    default:
+      return false;
+    }
+  }
+  }
+}
+
+void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
+                                  SourceRange range) {
+  if (ExplodedNode *N = C.GenerateSink()) {
+    if (!BT_BadFree)
+      BT_BadFree = new BuiltinBug("Bad free");
+    
+    llvm::SmallString<100> buf;
+    llvm::raw_svector_ostream os(buf);
+    
+    const MemRegion *MR = ArgVal.getAsRegion();
+    if (MR) {
+      while (const ElementRegion *ER = dyn_cast<ElementRegion>(MR))
+        MR = ER->getSuperRegion();
+      
+      // Special case for alloca()
+      if (isa<AllocaRegion>(MR))
+        os << "Argument to free() was allocated by alloca(), not malloc()";
+      else {
+        os << "Argument to free() is ";
+        if (SummarizeRegion(os, MR))
+          os << ", which is not memory allocated by malloc()";
+        else
+          os << "not memory allocated by malloc()";
+      }
+    } else {
+      os << "Argument to free() is ";
+      if (SummarizeValue(os, ArgVal))
+        os << ", which is not memory allocated by malloc()";
+      else
+        os << "not memory allocated by malloc()";
+    }
+    
+    EnhancedBugReport *R = new EnhancedBugReport(*BT_BadFree, os.str(), N);
+    R->addRange(range);
+    C.EmitReport(R);
+  }
 }
 
 void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) {
@@ -231,7 +519,8 @@
     if (Sym)
       stateEqual = stateEqual->set<RegionState>(Sym, RefState::getReleased(CE));
 
-    const GRState *stateMalloc = MallocMemAux(C, CE, CE->getArg(1), stateEqual);
+    const GRState *stateMalloc = MallocMemAux(C, CE, CE->getArg(1), 
+                                              UndefinedVal(), stateEqual);
     C.addTransition(stateMalloc);
   }
 
@@ -243,55 +532,77 @@
                                       ValMgr.makeIntValWithPtrWidth(0, false));
 
     if (const GRState *stateSizeZero = stateNotEqual->Assume(SizeZero, true)) {
-      const GRState *stateFree = FreeMemAux(C, CE, stateSizeZero);
+      const GRState *stateFree = FreeMemAux(C, CE, stateSizeZero, 0, false);
       if (stateFree)
         C.addTransition(stateFree->BindExpr(CE, UndefinedVal(), true));
     }
 
     if (const GRState *stateSizeNotZero=stateNotEqual->Assume(SizeZero,false)) {
-      const GRState *stateFree = FreeMemAux(C, CE, stateSizeNotZero);
+      const GRState *stateFree = FreeMemAux(C, CE, stateSizeNotZero, 0, false);
       if (stateFree) {
         // FIXME: We should copy the content of the original buffer.
         const GRState *stateRealloc = MallocMemAux(C, CE, CE->getArg(1), 
-                                                   stateFree);
+                                                   UnknownVal(), 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;
+void MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  
+  ValueManager &ValMgr = C.getValueManager();
+  SValuator &SVator = C.getSValuator();
 
-    if (RS->isAllocated()) {
-      ExplodedNode *N = C.GenerateSink();
-      if (N) {
-        if (!BT_Leak)
-          BT_Leak = new BuiltinBug("Memory leak",
+  SVal Count = state->getSVal(CE->getArg(0));
+  SVal EleSize = state->getSVal(CE->getArg(1));
+  SVal TotalSize = SVator.EvalBinOp(state, BO_Mul, Count, EleSize,
+                                    ValMgr.getContext().getSizeType());
+  
+  SVal Zero = ValMgr.makeZeroVal(ValMgr.getContext().CharTy);
+
+  state = MallocMemAux(C, CE, TotalSize, Zero, state);
+  C.addTransition(state);
+}
+
+void MallocChecker::EvalDeadSymbols(CheckerContext &C,SymbolReaper &SymReaper) {
+  if (!SymReaper.hasDeadSymbols())
+    return;
+
+  const GRState *state = C.getState();
+  RegionStateTy RS = state->get<RegionState>();
+  RegionStateTy::Factory &F = state->get_context<RegionState>();
+
+  for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
+    if (SymReaper.isDead(I->first)) {
+      if (I->second.isAllocated()) {
+        if (ExplodedNode *N = C.GenerateNode()) {
+          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);
+          // FIXME: where it is allocated.
+          BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
+          C.EmitReport(R);
+        }
       }
+
+      // Remove the dead symbol from the map.
+      RS = F.Remove(RS, I->first);
     }
   }
+
+  state = state->set<RegionState>(RS);
+  C.GenerateNode(state);
 }
 
 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>();
+  RegionStateTy M = state->get<RegionState>();
 
-  for (SymMap::iterator I = M.begin(), E = M.end(); I != E; ++I) {
+  for (RegionStateTy::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());
@@ -330,7 +641,8 @@
 }
 
 const GRState *MallocChecker::EvalAssume(const GRState *state, SVal Cond, 
-                                         bool Assumption) {
+                                         bool Assumption,
+                                         bool * /* respondsToCallback */) {
   // If a symblic region is assumed to NULL, set its state to AllocateFailed.
   // FIXME: should also check symbols assumed to non-null.
 
@@ -349,9 +661,8 @@
   SymbolRef Sym = l.getLocSymbolInBase();
   if (Sym) {
     const RefState *RS = C.getState()->get<RegionState>(Sym);
-    if (RS)
-      if (RS->isReleased()) {
-        ExplodedNode *N = C.GenerateSink();
+    if (RS && RS->isReleased()) {
+      if (ExplodedNode *N = C.GenerateNode()) {
         if (!BT_UseFree)
           BT_UseFree = new BuiltinBug("Use dynamically allocated memory after"
                                       " it is freed.");
@@ -360,5 +671,68 @@
                                      N);
         C.EmitReport(R);
       }
+    }
+  }
+}
+
+void MallocChecker::PreVisitBind(CheckerContext &C,
+                                 const Stmt *AssignE,
+                                 const Stmt *StoreE,
+                                 SVal location,
+                                 SVal val) {
+  // The PreVisitBind implements the same algorithm as already used by the 
+  // Objective C ownership checker: if the pointer escaped from this scope by 
+  // assignment, let it go.  However, assigning to fields of a stack-storage 
+  // structure does not transfer ownership.
+
+  const GRState *state = C.getState();
+  DefinedOrUnknownSVal l = cast<DefinedOrUnknownSVal>(location);
+
+  // Check for null dereferences.
+  if (!isa<Loc>(l))
+    return;
+
+  // Before checking if the state is null, check if 'val' has a RefState.
+  // Only then should we check for null and bifurcate the state.
+  SymbolRef Sym = val.getLocSymbolInBase();
+  if (Sym) {
+    if (const RefState *RS = state->get<RegionState>(Sym)) {
+      // If ptr is NULL, no operation is performed.
+      const GRState *notNullState, *nullState;
+      llvm::tie(notNullState, nullState) = state->Assume(l);
+
+      // Generate a transition for 'nullState' to record the assumption
+      // that the state was null.
+      if (nullState)
+        C.addTransition(nullState);
+
+      if (!notNullState)
+        return;
+
+      if (RS->isAllocated()) {
+        // Something we presently own is being assigned somewhere.
+        const MemRegion *AR = location.getAsRegion();
+        if (!AR)
+          return;
+        AR = AR->StripCasts()->getBaseRegion();
+        do {
+          // If it is on the stack, we still own it.
+          if (AR->hasStackNonParametersStorage())
+            break;
+
+          // If the state can't represent this binding, we still own it.
+          if (notNullState == (notNullState->bindLoc(cast<Loc>(location),
+                                                     UnknownVal())))
+            break;
+
+          // We no longer own this pointer.
+          notNullState =
+            notNullState->set<RegionState>(Sym,
+                                           RefState::getRelinquished(StoreE));
+        }
+        while (false);
+      }
+      C.addTransition(notNullState);
+    }
   }
 }
diff --git a/lib/Checker/MemRegion.cpp b/lib/Checker/MemRegion.cpp
index 9a664c7..3f706e1 100644
--- a/lib/Checker/MemRegion.cpp
+++ b/lib/Checker/MemRegion.cpp
@@ -14,9 +14,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Checker/PathSensitive/MemRegion.h"
+#include "clang/Checker/PathSensitive/ValueManager.h"
 #include "clang/Analysis/AnalysisContext.h"
 #include "clang/Analysis/Support/BumpVector.h"
 #include "clang/AST/CharUnits.h"
+#include "clang/AST/RecordLayout.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
@@ -29,22 +31,22 @@
 
 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;
 }
 
@@ -56,72 +58,72 @@
   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;
 }
 
@@ -171,6 +173,52 @@
 }
 
 //===----------------------------------------------------------------------===//
+// Region extents.
+//===----------------------------------------------------------------------===//
+
+DefinedOrUnknownSVal DeclRegion::getExtent(ValueManager& ValMgr) const {
+  ASTContext& Ctx = ValMgr.getContext();
+  QualType T = getDesugaredValueType();
+
+  if (isa<VariableArrayType>(T))
+    return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this));
+  if (isa<IncompleteArrayType>(T))
+    return UnknownVal();
+
+  CharUnits Size = Ctx.getTypeSizeInChars(T);
+  QualType SizeTy = Ctx.getSizeType();
+  return ValMgr.makeIntVal(Size.getQuantity(), SizeTy);
+}
+
+DefinedOrUnknownSVal FieldRegion::getExtent(ValueManager& ValMgr) const {
+  DefinedOrUnknownSVal Extent = DeclRegion::getExtent(ValMgr);
+
+  // A zero-length array at the end of a struct often stands for dynamically-
+  // allocated extra memory.
+  if (Extent.isZeroConstant()) {
+    QualType T = getDesugaredValueType();
+
+    if (isa<ConstantArrayType>(T))
+      return UnknownVal();
+  }
+
+  return Extent;
+}
+
+DefinedOrUnknownSVal AllocaRegion::getExtent(ValueManager& ValMgr) const {
+  return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this));
+}
+
+DefinedOrUnknownSVal SymbolicRegion::getExtent(ValueManager& ValMgr) const {
+  return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this));
+}
+
+DefinedOrUnknownSVal StringRegion::getExtent(ValueManager& ValMgr) const {
+  QualType SizeTy = ValMgr.getContext().getSizeType();
+  return ValMgr.makeIntVal(getStringLiteral()->getByteLength()+1, SizeTy);
+}
+
+//===----------------------------------------------------------------------===//
 // FoldingSet profiling.
 //===----------------------------------------------------------------------===//
 
@@ -183,6 +231,11 @@
   ID.AddPointer(getStackFrame());
 }
 
+void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
+  ID.AddInteger((unsigned)getKind());
+  ID.AddPointer(getCodeRegion());
+}
+
 void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
                                  const StringLiteral* Str,
                                  const MemRegion* superRegion) {
@@ -226,7 +279,7 @@
 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);
@@ -349,7 +402,6 @@
   os << "block_data{" << BC << '}';
 }
 
-
 void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
   // FIXME: More elaborate pretty-printing.
   os << "{ " << (void*) CL <<  " }";
@@ -368,6 +420,10 @@
   os << superRegion << "->" << getDecl();
 }
 
+void NonStaticGlobalSpaceRegion::dumpToStream(llvm::raw_ostream &os) const {
+  os << "NonStaticGlobalSpaceRegion";
+}
+
 void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
   os << "ivar{" << superRegion << ',' << getDecl() << '}';
 }
@@ -392,6 +448,10 @@
   os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
 }
 
+void StaticGlobalSpaceRegion::dumpToStream(llvm::raw_ostream &os) const {
+  os << "StaticGlobalsMemSpace{" << CR << '}';
+}
+
 //===----------------------------------------------------------------------===//
 // MemRegionManager methods.
 //===----------------------------------------------------------------------===//
@@ -412,7 +472,7 @@
     region = (REG*) A.Allocate<REG>();
     new (region) REG(this, a);
   }
-  
+
   return region;
 }
 
@@ -442,8 +502,18 @@
   return R;
 }
 
-const GlobalsSpaceRegion *MemRegionManager::getGlobalsRegion() {
-  return LazyAllocate(globals);
+const GlobalsSpaceRegion
+*MemRegionManager::getGlobalsRegion(const CodeTextRegion *CR) {
+  if (!CR)
+    return LazyAllocate(globals);
+
+  StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
+  if (R)
+    return R;
+
+  R = A.Allocate<StaticGlobalSpaceRegion>();
+  new (R) StaticGlobalSpaceRegion(this, CR);
+  return R;
 }
 
 const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
@@ -462,7 +532,7 @@
 // Constructing regions.
 //===----------------------------------------------------------------------===//
 
-const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
+const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){
   return getSubRegion<StringRegion>(Str, getGlobalsRegion());
 }
 
@@ -470,7 +540,9 @@
                                                 const LocationContext *LC) {
   const MemRegion *sReg = 0;
 
-  if (D->hasLocalStorage()) {    
+  if (D->hasGlobalStorage() && !D->isStaticLocal())
+    sReg = getGlobalsRegion();
+  else {
     // FIXME: Once we implement scope handling, we will need to properly lookup
     // 'D' to the proper LocationContext.
     const DeclContext *DC = D->getDeclContext();
@@ -479,15 +551,32 @@
     if (!STC)
       sReg = getUnknownRegion();
     else {
-      sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
-            ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
-            : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
+      if (D->hasLocalStorage()) {
+        sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
+               ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
+               : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
+      }
+      else {
+        assert(D->isStaticLocal());
+        const Decl *D = STC->getDecl();
+        if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+          sReg = getGlobalsRegion(getFunctionTextRegion(FD));
+        else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
+          const BlockTextRegion *BTR =
+            getBlockTextRegion(BD,
+                     C.getCanonicalType(BD->getSignatureAsWritten()->getType()),
+                     STC->getAnalysisContext());
+          sReg = getGlobalsRegion(BTR);
+        }
+        else {
+          // FIXME: For ObjC-methods, we need a new CodeTextRegion.  For now
+          // just use the main global memspace.
+          sReg = getGlobalsRegion();
+        }
+      }
     }
   }
-  else {
-    sReg = getGlobalsRegion();
-  }
-  
+
   return getSubRegion<VarRegion>(D, sReg);
 }
 
@@ -500,10 +589,10 @@
 MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
                                      const LocationContext *LC) {
   const MemRegion *sReg = 0;
-  
-  if (LC) {    
+
+  if (LC) {
     // FIXME: Once we implement scope handling, we want the parent region
-    // to be the scope.  
+    // to be the scope.
     const StackFrameContext *STC = LC->getCurrentStackFrame();
     assert(STC);
     sReg = getStackLocalsRegion(STC);
@@ -520,9 +609,9 @@
 const CompoundLiteralRegion*
 MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
                                            const LocationContext *LC) {
-  
+
   const MemRegion *sReg = 0;
-  
+
   if (CL->isFileScope())
     sReg = getGlobalsRegion();
   else {
@@ -530,7 +619,7 @@
     assert(STC);
     sReg = getStackLocalsRegion(STC);
   }
-  
+
   return getSubRegion<CompoundLiteralRegion>(CL, sReg);
 }
 
@@ -539,7 +628,7 @@
                                    const MemRegion* superRegion,
                                    ASTContext& Ctx){
 
-  QualType T = Ctx.getCanonicalType(elementType);
+  QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
 
   llvm::FoldingSetNodeID ID;
   ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
@@ -696,7 +785,7 @@
   return true;
 }
 
-RegionRawOffset ElementRegion::getAsRawOffset() const {
+RegionRawOffset ElementRegion::getAsArrayOffset() const {
   CharUnits offset = CharUnits::Zero();
   const ElementRegion *ER = this;
   const MemRegion *superR = NULL;
@@ -738,6 +827,67 @@
   return RegionRawOffset(superR, offset.getQuantity());
 }
 
+RegionOffset MemRegion::getAsOffset() const {
+  const MemRegion *R = this;
+  int64_t Offset = 0;
+
+  while (1) {
+    switch (R->getKind()) {
+    default:
+      return RegionOffset(0);
+    case SymbolicRegionKind:
+    case AllocaRegionKind:
+    case CompoundLiteralRegionKind:
+    case CXXThisRegionKind:
+    case StringRegionKind:
+    case VarRegionKind:
+    case CXXObjectRegionKind:
+      goto Finish;
+    case ElementRegionKind: {
+      const ElementRegion *ER = cast<ElementRegion>(R);
+      QualType EleTy = ER->getValueType();
+
+      if (!IsCompleteType(getContext(), EleTy))
+        return RegionOffset(0);
+
+      SVal Index = ER->getIndex();
+      if (const nonloc::ConcreteInt *CI=dyn_cast<nonloc::ConcreteInt>(&Index)) {
+        int64_t i = CI->getValue().getSExtValue();
+        CharUnits Size = getContext().getTypeSizeInChars(EleTy);
+        Offset += i * Size.getQuantity() * 8;
+      } else {
+        // We cannot compute offset for non-concrete index.
+        return RegionOffset(0);
+      }
+      R = ER->getSuperRegion();
+      break;
+    }
+    case FieldRegionKind: {
+      const FieldRegion *FR = cast<FieldRegion>(R);
+      const RecordDecl *RD = FR->getDecl()->getParent();
+      if (!RD->isDefinition())
+        // We cannot compute offset for incomplete type.
+        return RegionOffset(0);
+      // Get the field number.
+      unsigned idx = 0;
+      for (RecordDecl::field_iterator FI = RD->field_begin(), 
+             FE = RD->field_end(); FI != FE; ++FI, ++idx)
+        if (FR->getDecl() == *FI)
+          break;
+
+      const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
+      // This is offset in bits.
+      Offset += Layout.getFieldOffset(idx);
+      R = FR->getSuperRegion();
+      break;
+    }
+    }
+  }
+
+ Finish:
+  return RegionOffset(R, Offset);
+}
+
 //===----------------------------------------------------------------------===//
 // BlockDataRegion
 //===----------------------------------------------------------------------===//
@@ -749,24 +899,24 @@
   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 {
@@ -776,11 +926,11 @@
         VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
       }
     }
-    
+
     assert(VR);
     BV->push_back(VR, BC);
   }
-  
+
   ReferencedVars = BV;
 }
 
@@ -790,7 +940,7 @@
 
   BumpVector<const MemRegion*> *Vec =
     static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
-  
+
   return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
                                                    NULL : Vec->begin());
 }
@@ -801,7 +951,7 @@
 
   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/OSAtomicChecker.cpp b/lib/Checker/OSAtomicChecker.cpp
index e743528..02de0a8 100644
--- a/lib/Checker/OSAtomicChecker.cpp
+++ b/lib/Checker/OSAtomicChecker.cpp
@@ -100,13 +100,19 @@
   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.
+  // Here we should use the value type of the region as the load type, because
+  // we are simulating the semantics of the function, not the semantics of 
+  // passing argument. So the type of theValue expr is not we are loading.
+  // But usually the type of the varregion is not the type we want either,
+  // we still need to do a CastRetrievedVal in store manager. So actually this
+  // LoadTy specifying can be omitted. But we put it here to emphasize the 
+  // semantics.
   QualType LoadTy;
   if (const TypedRegion *TR =
       dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
-    LoadTy = TR->getValueType(Ctx);
+    LoadTy = TR->getValueType();
   }
-  Engine.EvalLoad(Tmp, const_cast<Expr *>(theValueExpr), C.getPredecessor(), 
+  Engine.EvalLoad(Tmp, theValueExpr, C.getPredecessor(), 
                   state, location, OSAtomicLoadTag, LoadTy);
 
   if (Tmp.empty()) {
@@ -152,10 +158,10 @@
       // Handle implicit value casts.
       if (const TypedRegion *R =
           dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
-        val = SVator.EvalCast(val,R->getValueType(Ctx),newValueExpr->getType());
+        val = SVator.EvalCast(val,R->getValueType(), newValueExpr->getType());
       }
 
-      Engine.EvalStore(TmpStore, NULL, const_cast<Expr *>(theValueExpr), N, 
+      Engine.EvalStore(TmpStore, NULL, theValueExpr, N, 
                        stateEqual, location, val, OSAtomicStoreTag);
 
       if (TmpStore.empty()) {
diff --git a/lib/Checker/ObjCUnusedIVarsChecker.cpp b/lib/Checker/ObjCUnusedIVarsChecker.cpp
index 0e47621..2523cff 100644
--- a/lib/Checker/ObjCUnusedIVarsChecker.cpp
+++ b/lib/Checker/ObjCUnusedIVarsChecker.cpp
@@ -114,7 +114,8 @@
     // (b) explicitly marked unused
     // (c) are iboutlets
     if (ID->getAccessControl() != ObjCIvarDecl::Private ||
-        ID->getAttr<UnusedAttr>() || ID->getAttr<IBOutletAttr>())
+        ID->getAttr<UnusedAttr>() || ID->getAttr<IBOutletAttr>() ||
+        ID->getAttr<IBOutletCollectionAttr>())
       continue;
 
     M[ID] = Unused;
diff --git a/lib/Checker/PathDiagnostic.cpp b/lib/Checker/PathDiagnostic.cpp
index 963923c..cf05a7d 100644
--- a/lib/Checker/PathDiagnostic.cpp
+++ b/lib/Checker/PathDiagnostic.cpp
@@ -107,7 +107,7 @@
     new PathDiagnosticEventPiece(Info.getLocation(), StrC.str());
 
   for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i)
-    P->addRange(Info.getRange(i));
+    P->addRange(Info.getRange(i).getAsRange());
   for (unsigned i = 0, e = Info.getNumFixItHints(); i != e; ++i)
     P->addFixItHint(Info.getFixItHint(i));
   D->push_front(P);
@@ -181,15 +181,8 @@
       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();
-        }
+        if (Stmt *Body = FD->getBody())
+          return Body->getSourceRange();
       }
       else {
         SourceLocation L = D->getLocation();
diff --git a/lib/Checker/PlistDiagnostics.cpp b/lib/Checker/PlistDiagnostics.cpp
new file mode 100644
index 0000000..13accbb
--- /dev/null
+++ b/lib/Checker/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/Checker/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/Checker/PointerArithChecker.cpp b/lib/Checker/PointerArithChecker.cpp
index ed60c42..cbac423 100644
--- a/lib/Checker/PointerArithChecker.cpp
+++ b/lib/Checker/PointerArithChecker.cpp
@@ -36,8 +36,7 @@
 
 void PointerArithChecker::PreVisitBinaryOperator(CheckerContext &C,
                                                  const BinaryOperator *B) {
-  if (B->getOpcode() != BinaryOperator::Sub &&
-      B->getOpcode() != BinaryOperator::Add)
+  if (B->getOpcode() != BO_Sub && B->getOpcode() != BO_Add)
     return;
 
   const GRState *state = C.getState();
diff --git a/lib/Checker/PointerSubChecker.cpp b/lib/Checker/PointerSubChecker.cpp
index bc0fd24..d64b6ae 100644
--- a/lib/Checker/PointerSubChecker.cpp
+++ b/lib/Checker/PointerSubChecker.cpp
@@ -39,7 +39,7 @@
                                                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)
+  if (B->getOpcode() != BO_Sub)
     return;
 
   const GRState *state = C.getState();
diff --git a/lib/Checker/RangeConstraintManager.cpp b/lib/Checker/RangeConstraintManager.cpp
index c904c33..697694e 100644
--- a/lib/Checker/RangeConstraintManager.cpp
+++ b/lib/Checker/RangeConstraintManager.cpp
@@ -83,7 +83,6 @@
   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(); }
@@ -105,97 +104,69 @@
     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.
+private:
+  void IntersectInRange(BasicValueFactory &BV, Factory &F,
+                        const llvm::APSInt &Lower,
+                        const llvm::APSInt &Upper,
+                        PrimRangeSet &newRanges,
+                        PrimRangeSet::iterator &i,
+                        PrimRangeSet::iterator &e) const {
+    // There are six cases for each range R in the set:
+    //   1. R is entirely before the intersection range.
+    //   2. R is entirely after the intersection range.
+    //   3. R contains the entire intersection range.
+    //   4. R starts before the intersection range and ends in the middle.
+    //   5. R starts in the middle of the intersection range and ends after it.
+    //   6. R is entirely contained in the intersection range.
+    // These correspond to each of the conditions below.
+    for (/* i = begin(), e = end() */; i != e; ++i) {
+      if (i->To() < Lower) {
+        continue;
+      }
+      if (i->From() > Upper) {
         break;
       }
-    }
 
-    return newRanges;
+      if (i->Includes(Lower)) {
+        if (i->Includes(Upper)) {
+          newRanges = F.Add(newRanges, Range(BV.getValue(Lower),
+                                             BV.getValue(Upper)));
+          break;
+        } else
+          newRanges = F.Add(newRanges, Range(BV.getValue(Lower), i->To()));
+      } else {
+        if (i->Includes(Upper)) {
+          newRanges = F.Add(newRanges, Range(i->From(), BV.getValue(Upper)));
+          break;
+        } else
+          newRanges = F.Add(newRanges, *i);
+      }
+    }
   }
 
-  /// 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) {
+public:
+  // Returns a set containing the values in the receiving set, intersected with
+  // the closed range [Lower, Upper]. Unlike the Range type, this range uses
+  // modular arithmetic, corresponding to the common treatment of C integer
+  // overflow. Thus, if the Lower bound is greater than the Upper bound, the
+  // range is taken to wrap around. This is equivalent to taking the
+  // intersection with the two ranges [Min, Upper] and [Lower, Max],
+  // or, alternatively, /removing/ all integers between Upper and Lower.
+  RangeSet Intersect(BasicValueFactory &BV, Factory &F,
+                     const llvm::APSInt &Lower,
+                     const llvm::APSInt &Upper) const {
     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);
+    PrimRangeSet::iterator i = begin(), e = end();
+    if (Lower <= Upper)
+      IntersectInRange(BV, F, Lower, Upper, newRanges, i, e);
+    else {
+      // The order of the next two statements is important!
+      // IntersectInRange() does not reset the iteration state for i and e.
+      // Therefore, the lower range most be handled first.
+      IntersectInRange(BV, F, BV.getMinValue(Upper), Upper, newRanges, i, e);
+      IntersectInRange(BV, F, Lower, BV.getMaxValue(Lower), newRanges, i, e);
     }
-
-    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;
   }
 
@@ -237,23 +208,29 @@
   RangeConstraintManager(GRSubEngine &subengine)
     : SimpleConstraintManager(subengine) {}
 
-  const GRState* AssumeSymNE(const GRState* St, SymbolRef sym,
-                             const llvm::APSInt& V);
+  const GRState* AssumeSymNE(const GRState* state, SymbolRef sym,
+                             const llvm::APSInt& Int,
+                             const llvm::APSInt& Adjustment);
 
-  const GRState* AssumeSymEQ(const GRState* St, SymbolRef sym,
-                             const llvm::APSInt& V);
+  const GRState* AssumeSymEQ(const GRState* state, SymbolRef sym,
+                             const llvm::APSInt& Int,
+                             const llvm::APSInt& Adjustment);
 
-  const GRState* AssumeSymLT(const GRState* St, SymbolRef sym,
-                             const llvm::APSInt& V);
+  const GRState* AssumeSymLT(const GRState* state, SymbolRef sym,
+                             const llvm::APSInt& Int,
+                             const llvm::APSInt& Adjustment);
 
-  const GRState* AssumeSymGT(const GRState* St, SymbolRef sym,
-                             const llvm::APSInt& V);
+  const GRState* AssumeSymGT(const GRState* state, SymbolRef sym,
+                             const llvm::APSInt& Int,
+                             const llvm::APSInt& Adjustment);
 
-  const GRState* AssumeSymGE(const GRState* St, SymbolRef sym,
-                             const llvm::APSInt& V);
+  const GRState* AssumeSymGE(const GRState* state, SymbolRef sym,
+                             const llvm::APSInt& Int,
+                             const llvm::APSInt& Adjustment);
 
-  const GRState* AssumeSymLE(const GRState* St, SymbolRef sym,
-                             const llvm::APSInt& V);
+  const GRState* AssumeSymLE(const GRState* state, SymbolRef sym,
+                             const llvm::APSInt& Int,
+                             const llvm::APSInt& Adjustment);
 
   const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) const;
 
@@ -303,10 +280,6 @@
   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))
@@ -323,20 +296,127 @@
 // 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;\
+// The syntax for ranges below is mathematical, using [x, y] for closed ranges
+// and (x, y) for open ranges. These ranges are modular, corresponding with
+// a common treatment of C integer overflow. This means that these methods
+// do not have to worry about overflow; RangeSet::Intersect can handle such a
+// "wraparound" range.
+// As an example, the range [UINT_MAX-1, 3) contains five values: UINT_MAX-1,
+// UINT_MAX, 0, 1, and 2.
+
+const GRState*
+RangeConstraintManager::AssumeSymNE(const GRState* state, SymbolRef sym,
+                                    const llvm::APSInt& Int,
+                                    const llvm::APSInt& Adjustment) {
+  BasicValueFactory &BV = state->getBasicVals();
+
+  llvm::APSInt Lower = Int-Adjustment;
+  llvm::APSInt Upper = Lower;
+  --Lower;
+  ++Upper;
+
+  // [Int-Adjustment+1, Int-Adjustment-1]
+  // Notice that the lower bound is greater than the upper bound.
+  RangeSet New = GetRange(state, sym).Intersect(BV, F, Upper, Lower);
+  return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
 }
 
-AssumeX(EQ)
-AssumeX(NE)
-AssumeX(LT)
-AssumeX(GT)
-AssumeX(LE)
-AssumeX(GE)
+const GRState*
+RangeConstraintManager::AssumeSymEQ(const GRState* state, SymbolRef sym,
+                                    const llvm::APSInt& Int,
+                                    const llvm::APSInt& Adjustment) {
+  // [Int-Adjustment, Int-Adjustment]
+  BasicValueFactory &BV = state->getBasicVals();
+  llvm::APSInt AdjInt = Int-Adjustment;
+  RangeSet New = GetRange(state, sym).Intersect(BV, F, AdjInt, AdjInt);
+  return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
+}
+
+const GRState*
+RangeConstraintManager::AssumeSymLT(const GRState* state, SymbolRef sym,
+                                    const llvm::APSInt& Int,
+                                    const llvm::APSInt& Adjustment) {
+  BasicValueFactory &BV = state->getBasicVals();
+
+  QualType T = state->getSymbolManager().getType(sym);
+  const llvm::APSInt &Min = BV.getMinValue(T);
+
+  // Special case for Int == Min. This is always false.
+  if (Int == Min)
+    return NULL;
+
+  llvm::APSInt Lower = Min-Adjustment;
+  llvm::APSInt Upper = Int-Adjustment;
+  --Upper;
+
+  RangeSet New = GetRange(state, sym).Intersect(BV, F, Lower, Upper);
+  return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
+}
+
+const GRState*
+RangeConstraintManager::AssumeSymGT(const GRState* state, SymbolRef sym,
+                                    const llvm::APSInt& Int,
+                                    const llvm::APSInt& Adjustment) {
+  BasicValueFactory &BV = state->getBasicVals();
+
+  QualType T = state->getSymbolManager().getType(sym);
+  const llvm::APSInt &Max = BV.getMaxValue(T);
+
+  // Special case for Int == Max. This is always false.
+  if (Int == Max)
+    return NULL;
+
+  llvm::APSInt Lower = Int-Adjustment;
+  llvm::APSInt Upper = Max-Adjustment;
+  ++Lower;
+
+  RangeSet New = GetRange(state, sym).Intersect(BV, F, Lower, Upper);
+  return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
+}
+
+const GRState*
+RangeConstraintManager::AssumeSymGE(const GRState* state, SymbolRef sym,
+                                    const llvm::APSInt& Int,
+                                    const llvm::APSInt& Adjustment) {
+  BasicValueFactory &BV = state->getBasicVals();
+
+  QualType T = state->getSymbolManager().getType(sym);
+  const llvm::APSInt &Min = BV.getMinValue(T);
+
+  // Special case for Int == Min. This is always feasible.
+  if (Int == Min)
+    return state;
+
+  const llvm::APSInt &Max = BV.getMaxValue(T);
+
+  llvm::APSInt Lower = Int-Adjustment;
+  llvm::APSInt Upper = Max-Adjustment;
+
+  RangeSet New = GetRange(state, sym).Intersect(BV, F, Lower, Upper);
+  return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
+}
+
+const GRState*
+RangeConstraintManager::AssumeSymLE(const GRState* state, SymbolRef sym,
+                                    const llvm::APSInt& Int,
+                                    const llvm::APSInt& Adjustment) {
+  BasicValueFactory &BV = state->getBasicVals();
+
+  QualType T = state->getSymbolManager().getType(sym);
+  const llvm::APSInt &Max = BV.getMaxValue(T);
+
+  // Special case for Int == Max. This is always feasible.
+  if (Int == Max)
+    return state;
+
+  const llvm::APSInt &Min = BV.getMinValue(T);
+
+  llvm::APSInt Lower = Min-Adjustment;
+  llvm::APSInt Upper = Int-Adjustment;
+
+  RangeSet New = GetRange(state, sym).Intersect(BV, F, Lower, Upper);
+  return New.isEmpty() ? NULL : state->set<ConstraintRange>(sym, New);
+}
 
 //===------------------------------------------------------------------------===
 // Pretty-printing.
diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp
index 1e15d43..595fb6f 100644
--- a/lib/Checker/RegionStore.cpp
+++ b/lib/Checker/RegionStore.cpp
@@ -44,10 +44,9 @@
   uint64_t Offset;
 
   explicit BindingKey(const MemRegion *r, uint64_t offset, Kind k)
-    : P(r, (unsigned) k), Offset(offset) { assert(r); }
+    : P(r, (unsigned) k), Offset(offset) {}
 public:
 
-  bool isDefault() const { return P.getInt() == Default; }
   bool isDirect() const { return P.getInt() == Direct; }
 
   const MemRegion *getRegion() const { return P.getPointer(); }
@@ -72,9 +71,26 @@
     return P.getOpaqueValue() == X.P.getOpaqueValue() &&
            Offset == X.Offset;
   }
+
+  bool isValid() const {
+    return getRegion() != NULL;
+  }
 };
 } // end anonymous namespace
 
+BindingKey BindingKey::Make(const MemRegion *R, Kind k) {
+  if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
+    const RegionRawOffset &O = ER->getAsArrayOffset();
+
+    // FIXME: There are some ElementRegions for which we cannot compute
+    // raw offsets yet, including regions with symbolic offsets. These will be
+    // ignored by the store.
+    return BindingKey(O.getRegion(), O.getByteOffset(), k);
+  }
+
+  return BindingKey(R, 0, k);
+}
+
 namespace llvm {
   static inline
   llvm::raw_ostream& operator<<(llvm::raw_ostream& os, BindingKey K) {
@@ -101,51 +117,20 @@
 
 class RegionStoreFeatures {
   bool SupportsFields;
-  bool SupportsRemaining;
-
 public:
   RegionStoreFeatures(minimal_features_tag) :
-    SupportsFields(false), SupportsRemaining(false) {}
+    SupportsFields(false) {}
 
   RegionStoreFeatures(maximal_features_tag) :
-    SupportsFields(true), SupportsRemaining(false) {}
+    SupportsFields(true) {}
 
   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.
 //===----------------------------------------------------------------------===//
 
@@ -196,6 +181,14 @@
   }
 };
 
+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);
+}
 
 class RegionStoreManager : public StoreManager {
   const RegionStoreFeatures Features;
@@ -213,7 +206,6 @@
 
   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.
@@ -242,16 +234,13 @@
   // 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);
+                          InvalidatedSymbols *IS,
+                          bool invalidateGlobals,
+                          InvalidatedRegions *Regions);
 
 public:   // Made public for helper classes.
 
@@ -274,12 +263,18 @@
     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);
 
+  // BindDefault is only used to initialize a region with a default value.
+  Store BindDefault(Store store, const MemRegion *R, SVal V) {
+    RegionBindings B = GetRegionBindings(store);
+    assert(!Lookup(B, R, BindingKey::Default));
+    assert(!Lookup(B, R, BindingKey::Direct));
+    return Add(B, R, BindingKey::Default, V).getRoot();
+  }
+
   Store BindCompoundLiteral(Store store, const CompoundLiteralExpr* CL,
                             const LocationContext *LC, SVal V);
 
@@ -295,7 +290,7 @@
   Store BindArray(Store store, const TypedRegion* R, SVal V);
 
   /// KillStruct - Set the entire struct to unknown.
-  Store KillStruct(Store store, const TypedRegion* R);
+  Store KillStruct(Store store, const TypedRegion* R, SVal DefaultVal);
 
   Store Remove(Store store, Loc LV);
 
@@ -339,6 +334,12 @@
 
   SVal RetrieveArray(Store store, const TypedRegion* R);
 
+  /// Used to lazily generate derived symbols for bindings that are defined
+  ///  implicitly by default bindings in a super region.
+  Optional<SVal> RetrieveDerivedDefaultValue(RegionBindings B,
+                                             const MemRegion *superR,
+                                             const TypedRegion *R, QualType Ty);
+
   /// Get the state and region whose binding this region R corresponds to.
   std::pair<Store, const MemRegion*>
   GetLazyBinding(RegionBindings B, const MemRegion *R);
@@ -352,19 +353,17 @@
 
   /// 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,
+  Store RemoveDeadBindings(Store store, const StackFrameContext *LCtx,
                            SymbolReaper& SymReaper,
                           llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
 
-  const GRState *EnterStackFrame(const GRState *state,
-                                 const StackFrameContext *frame);
+  Store EnterStackFrame(const GRState *state, const StackFrameContext *frame);
 
   //===------------------------------------------------------------------===//
   // Region "extents".
   //===------------------------------------------------------------------===//
 
-  const GRState *setExtent(const GRState *state,const MemRegion* R,SVal Extent);
+  // FIXME: This method will soon be eliminated; see the note in Store.h.
   DefinedOrUnknownSVal getSizeInElements(const GRState *state,
                                          const MemRegion* R, QualType EleTy);
 
@@ -380,16 +379,18 @@
              const char *sep);
 
   void iterBindings(Store store, BindingsHandler& f) {
-    // FIXME: Implement.
+    RegionBindings B = GetRegionBindings(store);
+    for (RegionBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
+      const BindingKey &K = I.getKey();
+      if (!K.isDirect())
+        continue;
+      if (const SubRegion *R = dyn_cast<SubRegion>(I.getKey().getRegion())) {
+        // FIXME: Possibly incorporate the offset?
+        if (!f.HandleBinding(*this, store, R, I.getData()))
+          return;
+      }
+    }
   }
-
-  // FIXME: Remove.
-  BasicValueFactory& getBasicVals() {
-      return StateMgr.getBasicVals();
-  }
-
-  // FIXME: Remove.
-  ASTContext& getContext() { return StateMgr.getContext(); }
 };
 
 } // end anonymous namespace
@@ -409,14 +410,6 @@
   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) {
@@ -472,12 +465,13 @@
 
   RegionBindings getRegionBindings() const { return B; }
 
-  void AddToCluster(BindingKey K) {
+  RegionCluster &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);
+    return C;
   }
 
   bool isVisited(const MemRegion *R) {
@@ -493,15 +487,20 @@
     return *CRef;
   }
 
-  void GenerateClusters() {
+  void GenerateClusters(bool includeGlobals = false) {
       // 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());
+      RegionCluster &C = 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());
       }
+      if (includeGlobals) {
+        const MemRegion *R = RI.getKey().getRegion();
+        if (isa<NonStaticGlobalSpaceRegion>(R->getMemorySpace()))
+          AddToWorkList(R, C);
+      }
     }
   }
 
@@ -568,14 +567,16 @@
   const Expr *Ex;
   unsigned Count;
   StoreManager::InvalidatedSymbols *IS;
+  StoreManager::InvalidatedRegions *Regions;
 public:
   InvalidateRegionsWorker(RegionStoreManager &rm,
                           GRStateManager &stateMgr,
                           RegionBindings b,
                           const Expr *ex, unsigned count,
-                          StoreManager::InvalidatedSymbols *is)
+                          StoreManager::InvalidatedSymbols *is,
+                          StoreManager::InvalidatedRegions *r)
     : ClusterAnalysis<InvalidateRegionsWorker>(rm, stateMgr, b),
-      Ex(ex), Count(count), IS(is) {}
+      Ex(ex), Count(count), IS(is), Regions(r) {}
 
   void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E);
   void VisitBaseRegion(const MemRegion *baseR);
@@ -604,8 +605,8 @@
     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))
+      const SubRegion *baseR = dyn_cast<SubRegion>(RI.getKey().getRegion());
+      if (baseR && baseR->isSubRegionOf(LazyR))
         VisitBinding(RI.getData());
     }
 
@@ -646,6 +647,10 @@
     return;
   }
 
+  // Otherwise, we have a normal data region. Record that we touched the region.
+  if (Regions)
+    Regions->push_back(baseR);
+
   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.
@@ -659,19 +664,12 @@
     return;
 
   const TypedRegion *TR = cast<TypedRegion>(baseR);
-  QualType T = TR->getValueType(Ctx);
+  QualType T = TR->getValueType();
 
     // 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.
+  if (T->isStructureType()) {
+    // 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);
@@ -695,13 +693,15 @@
                                             const MemRegion * const *I,
                                             const MemRegion * const *E,
                                             const Expr *Ex, unsigned Count,
-                                            InvalidatedSymbols *IS) {
+                                            InvalidatedSymbols *IS,
+                                            bool invalidateGlobals,
+                                            InvalidatedRegions *Regions) {
   InvalidateRegionsWorker W(*this, StateMgr,
                             RegionStoreManager::GetRegionBindings(store),
-                            Ex, Count, IS);
+                            Ex, Count, IS, Regions);
 
   // Scan the bindings and generate the clusters.
-  W.GenerateClusters();
+  W.GenerateClusters(invalidateGlobals);
 
   // Add I .. E to the worklist.
   for ( ; I != E; ++I)
@@ -710,7 +710,25 @@
   W.RunWorkList();
 
   // Return the new bindings.
-  return W.getRegionBindings().getRoot();
+  RegionBindings B = W.getRegionBindings();
+
+  if (invalidateGlobals) {
+    // Bind the non-static globals memory space to a new symbol that we will
+    // use to derive the bindings for all non-static globals.
+    const GlobalsSpaceRegion *GS = MRMgr.getGlobalsRegion();
+    SVal V =
+      ValMgr.getConjuredSymbolVal(/* SymbolTag = */ (void*) GS, Ex,
+                                  /* symbol type, doesn't matter */ Ctx.IntTy,
+                                  Count);
+    B = Add(B, BindingKey::Make(GS, BindingKey::Default), V);
+
+    // Even if there are no bindings in the global scope, we still need to
+    // record that we touched it.
+    if (Regions)
+      Regions->push_back(GS);
+  }
+
+  return B.getRoot();
 }
 
 //===----------------------------------------------------------------------===//
@@ -720,88 +738,19 @@
 DefinedOrUnknownSVal RegionStoreManager::getSizeInElements(const GRState *state,
                                                            const MemRegion *R,
                                                            QualType EleTy) {
+  SVal Size = cast<SubRegion>(R)->getExtent(ValMgr);
+  SValuator &SVator = ValMgr.getSValuator();
+  const llvm::APSInt *SizeInt = SVator.getKnownValue(state, Size);
+  if (!SizeInt)
+    return UnknownVal();
 
-  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();
+  CharUnits RegionSize = CharUnits::fromQuantity(SizeInt->getSExtValue());
+  CharUnits EleSize = Ctx.getTypeSizeInChars(EleTy);
 
-    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);
+  // If a variable is reinterpreted as a type that doesn't fit into a larger
+  // type evenly, round it down.
+  // This is a signed value, since it's used in arithmetic with signed indices.
+  return ValMgr.makeIntVal(RegionSize / EleSize, false);
 }
 
 //===----------------------------------------------------------------------===//
@@ -825,13 +774,12 @@
     return UnknownVal();
 
   // Strip off typedefs from the ArrayRegion's ValueType.
-  QualType T = ArrayR->getValueType(getContext()).getDesugaredType();
+  QualType T = ArrayR->getValueType().getDesugaredType();
   ArrayType *AT = cast<ArrayType>(T);
   T = AT->getElementType();
 
   SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
-  return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, ArrayR,
-                                                  getContext()));
+  return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, ArrayR, Ctx));
 }
 
 //===----------------------------------------------------------------------===//
@@ -844,6 +792,19 @@
   if (!isa<loc::MemRegionVal>(L))
     return UnknownVal();
 
+  // Special case for zero RHS.
+  if (R.isZeroConstant()) {
+    switch (Op) {
+    default:
+      // Handle it normally.
+      break;
+    case BO_Add:
+    case BO_Sub:
+      // FIXME: does this need to be casted to match resultTy?
+      return L;
+    }
+  }
+
   const MemRegion* MR = cast<loc::MemRegionVal>(L).getRegion();
   const ElementRegion *ER = 0;
 
@@ -851,7 +812,7 @@
     case MemRegion::SymbolicRegionKind: {
       const SymbolicRegion *SR = cast<SymbolicRegion>(MR);
       SymbolRef Sym = SR->getSymbol();
-      QualType T = Sym->getType(getContext());
+      QualType T = Sym->getType(Ctx);
       QualType EleTy;
 
       if (const PointerType *PT = T->getAs<PointerType>())
@@ -860,15 +821,14 @@
         EleTy = T->getAs<ObjCObjectPointerType>()->getPointeeType();
 
       SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
-      ER = MRMgr.getElementRegion(EleTy, ZeroIdx, SR, getContext());
+      ER = MRMgr.getElementRegion(EleTy, ZeroIdx, SR, Ctx);
       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();
+      QualType EleTy = Ctx.CharTy; // Create an ElementRegion of bytes.
       SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
-      ER = MRMgr.getElementRegion(EleTy, ZeroIdx, AR, getContext());
+      ER = MRMgr.getElementRegion(EleTy, ZeroIdx, AR, Ctx);
       break;
     }
 
@@ -902,7 +862,8 @@
     case MemRegion::StackLocalsSpaceRegionKind:
     case MemRegion::StackArgumentsSpaceRegionKind:
     case MemRegion::HeapSpaceRegionKind:
-    case MemRegion::GlobalsSpaceRegionKind:
+    case MemRegion::NonStaticGlobalSpaceRegionKind:
+    case MemRegion::StaticGlobalSpaceRegionKind:
     case MemRegion::UnknownSpaceRegionKind:
       assert(0 && "Cannot perform pointer arithmetic on a MemSpace");
       return UnknownVal();
@@ -922,13 +883,13 @@
                 cast<nonloc::ConcreteInt>(ValMgr.convertToArrayIndex(*Offset)));
       const MemRegion* NewER =
         MRMgr.getElementRegion(ER->getElementType(), NewIdx,
-                               ER->getSuperRegion(), getContext());
+                               ER->getSuperRegion(), Ctx);
       return ValMgr.makeLoc(NewER);
     }
     if (0 == Base->getValue()) {
       const MemRegion* NewER =
         MRMgr.getElementRegion(ER->getElementType(), R,
-                               ER->getSuperRegion(), getContext());
+                               ER->getSuperRegion(), Ctx);
       return ValMgr.makeLoc(NewER);
     }
   }
@@ -941,7 +902,8 @@
 //===----------------------------------------------------------------------===//
 
 Optional<SVal> RegionStoreManager::getDirectBinding(RegionBindings B,
-                                                 const MemRegion *R) {
+                                                    const MemRegion *R) {
+
   if (const SVal *V = Lookup(B, R, BindingKey::Direct))
     return *V;
 
@@ -952,7 +914,7 @@
                                                      const MemRegion *R) {
   if (R->isBoundable())
     if (const TypedRegion *TR = dyn_cast<TypedRegion>(R))
-      if (TR->getValueType(getContext())->isUnionType())
+      if (TR->getValueType()->isUnionType())
         return UnknownVal();
 
   if (const SVal *V = Lookup(B, R, BindingKey::Default))
@@ -961,38 +923,6 @@
   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");
@@ -1004,8 +934,13 @@
 
   const MemRegion *MR = cast<loc::MemRegionVal>(L).getRegion();
 
-  if (isa<AllocaRegion>(MR) || isa<SymbolicRegion>(MR))
+  if (isa<AllocaRegion>(MR) || isa<SymbolicRegion>(MR)) {
+    if (T.isNull()) {
+      const SymbolicRegion *SR = cast<SymbolicRegion>(MR);
+      T = SR->getSymbol()->getType(Ctx);
+    }
     MR = GetElementZeroRegion(MR, T);
+  }
 
   if (isa<CodeTextRegion>(MR)) {
     assert(0 && "Why load from a code text region?");
@@ -1015,7 +950,7 @@
   // 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());
+  QualType RTy = R->getValueType();
 
   // FIXME: We should eventually handle funny addressing.  e.g.:
   //
@@ -1026,17 +961,6 @@
   //
   // 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);
 
@@ -1146,8 +1070,7 @@
   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();
+    QualType T = Ctx.getAsArrayType(StrR->getValueType())->getElementType();
     if (T != Ctx.getCanonicalType(R->getElementType()))
       return UnknownVal();
 
@@ -1156,38 +1079,42 @@
     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];
+      // Technically, only i == byteLength is guaranteed to be null.
+      // However, such overflows should be caught before reaching this point;
+      // the only time such an access would be made is if a string literal was
+      // used to initialize a larger array.
+      char c = (i >= byteLength) ? '\0' : Str->getString()[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);
+  // Handle the case where we are indexing into a larger scalar object.
+  // For example, this handles:
+  //   int x = ...
+  //   char *y = &x;
+  //   return *y;
+  // FIXME: This is a hack, and doesn't do anything really intelligent yet.
+  const RegionRawOffset &O = R->getAsArrayOffset();
+  if (const TypedRegion *baseR = dyn_cast_or_null<TypedRegion>(O.getRegion())) {
+    QualType baseT = baseR->getValueType();
+    if (baseT->isScalarType()) {
+      QualType elemT = R->getElementType();
+      if (elemT->isScalarType()) {
+        if (Ctx.getTypeSizeInChars(baseT) >= Ctx.getTypeSizeInChars(elemT)) {
+          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);
+            if (V->isUnknownOrUndef())
+              return *V;
+            // Other cases: give up.  We are indexing into a larger object
+            // that has some value, but we don't know how to handle that yet.
+            return UnknownVal();
+          }
+        }
+      }
     }
-
-    // Other cases: give up.
-    return UnknownVal();
   }
-
   return RetrieveFieldOrElementCommon(store, R, R->getElementType(), superR);
 }
 
@@ -1199,10 +1126,32 @@
   if (const Optional<SVal> &V = getDirectBinding(B, R))
     return *V;
 
-  QualType Ty = R->getValueType(getContext());
+  QualType Ty = R->getValueType();
   return RetrieveFieldOrElementCommon(store, R, Ty, R->getSuperRegion());
 }
 
+Optional<SVal>
+RegionStoreManager::RetrieveDerivedDefaultValue(RegionBindings B,
+                                                const MemRegion *superR,
+                                                const TypedRegion *R,
+                                                QualType Ty) {
+
+  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->isUnknownOrUndef())
+      return *D;
+
+    assert(0 && "Unknown default value");
+  }
+
+  return Optional<SVal>();
+}
+
 SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store,
                                                       const TypedRegion *R,
                                                       QualType Ty,
@@ -1214,18 +1163,8 @@
   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 (const Optional<SVal> &D = RetrieveDerivedDefaultValue(B, superR, R, Ty))
+      return *D;
 
     // 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.
@@ -1254,7 +1193,7 @@
       // 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())
+        if (typedSuperR->getValueType()->isVectorType())
           return UnknownVal();
       }
     }
@@ -1306,7 +1245,7 @@
     return ValMgr.getRegionValueSymbolVal(R);
 
   if (isa<GlobalsSpaceRegion>(MS)) {
-    if (VD->isFileVarDecl()) {
+    if (isa<NonStaticGlobalSpaceRegion>(MS)) {
       // Is 'VD' declared constant?  If so, retrieve the constant value.
       QualType CT = Ctx.getCanonicalType(T);
       if (CT.isConstQualified()) {
@@ -1321,6 +1260,9 @@
           }
       }
 
+      if (const Optional<SVal> &V = RetrieveDerivedDefaultValue(B, MS, R, CT))
+        return V.getValue();
+
       return ValMgr.getRegionValueSymbolVal(R);
     }
 
@@ -1336,21 +1278,18 @@
 }
 
 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());
+  QualType T = R->getValueType();
   assert(T->isStructureOrClassType());
   return ValMgr.makeLazyCompoundVal(store, R);
 }
 
 SVal RegionStoreManager::RetrieveArray(Store store, const TypedRegion * R) {
-  assert(isa<ConstantArrayType>(R->getValueType(getContext())));
+  assert(isa<ConstantArrayType>(R->getValueType()));
   return ValMgr.makeLazyCompoundVal(store, R);
 }
 
@@ -1375,38 +1314,26 @@
 
   // Check if the region is a struct region.
   if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
-    if (TR->getValueType(getContext())->isStructureOrClassType())
+    if (TR->getValueType()->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);
-        }
+        QualType superTy = superR->getValueType();
         // For now, just invalidate the fields of the struct/union/class.
+        // This is for test rdar_test_7185607 in misc-ps-region-store.m.
         // FIXME: Precisely handle the fields of the record.
-        if (superTy->isRecordType())
-          return InvalidateRegion(store, superR, NULL, 0, NULL);
+        if (superTy->isStructureOrClassType())
+          return KillStruct(store, superR, UnknownVal());
       }
     }
   }
   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());
+    QualType T = SR->getSymbol()->getType(Ctx);
 
     // FIXME: Is this the right way to handle symbols that are references?
     if (const PointerType *PT = T->getAs<PointerType>())
@@ -1444,6 +1371,7 @@
               V);
 }
 
+
 Store RegionStoreManager::setImplicitDefaultValue(Store store,
                                                   const MemRegion *R,
                                                   QualType T) {
@@ -1457,7 +1385,7 @@
   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);
+    V = ValMgr.makeZeroVal(Ctx.IntTy);
   }
   else {
     return store;
@@ -1469,44 +1397,21 @@
 Store RegionStoreManager::BindArray(Store store, const TypedRegion* R,
                                     SVal Init) {
 
-  ASTContext &Ctx = getContext();
-  const ArrayType *AT =
-    cast<ArrayType>(Ctx.getCanonicalType(R->getValueType(Ctx)));
+  const ArrayType *AT =cast<ArrayType>(Ctx.getCanonicalType(R->getValueType()));
   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;
+  // Check if the init expr is a string literal.
+  if (loc::MemRegionVal *MRV = dyn_cast<loc::MemRegionVal>(&Init)) {
+    const StringRegion *S = cast<StringRegion>(MRV->getRegion());
 
-    // 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;
+    // Treat the string as a lazy compound value.
+    nonloc::LazyCompoundVal LCV =
+      cast<nonloc::LazyCompoundVal>(ValMgr.makeLazyCompoundVal(store, S));
+    return CopyLazyBindings(LCV, store, R);
   }
 
   // Handle lazy compound values.
@@ -1528,10 +1433,12 @@
       break;
 
     SVal Idx = ValMgr.makeArrayIndex(i);
-    const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, getContext());
+    const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx);
 
     if (ElementTy->isStructureOrClassType())
       store = BindStruct(store, ER, *VI);
+    else if (ElementTy->isArrayType())
+      store = BindArray(store, ER, *VI);
     else
       store = Bind(store, ValMgr.makeLoc(ER), *VI);
   }
@@ -1550,7 +1457,7 @@
   if (!Features.supportsFields())
     return store;
 
-  QualType T = R->getValueType(getContext());
+  QualType T = R->getValueType();
   assert(T->isStructureOrClassType());
 
   const RecordType* RT = T->getAs<RecordType>();
@@ -1563,10 +1470,13 @@
   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);
+  // We may get non-CompoundVal accidentally due to imprecise cast logic or
+  // that we are binding symbolic struct value. Kill the field values, and if
+  // the value is symbolic go and bind it as a "default" binding.
+  if (V.isUnknown() || !isa<nonloc::CompoundVal>(V)) {
+    SVal SV = isa<nonloc::SymbolVal>(V) ? V : UnknownVal();
+    return KillStruct(store, R, SV);
+  }
 
   nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
   nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
@@ -1599,14 +1509,15 @@
   return store;
 }
 
-Store RegionStoreManager::KillStruct(Store store, const TypedRegion* R) {
+Store RegionStoreManager::KillStruct(Store store, const TypedRegion* R,
+                                     SVal DefaultVal) {
   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();
+  return Add(B, R, BindingKey::Default, DefaultVal).getRoot();
 }
 
 Store RegionStoreManager::CopyLazyBindings(nonloc::LazyCompoundVal V,
@@ -1630,21 +1541,10 @@
 // "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) {
+  if (!K.isValid())
+    return B;
   return RBFactory.Add(B, K, V);
 }
 
@@ -1654,6 +1554,8 @@
 }
 
 const SVal *RegionStoreManager::Lookup(RegionBindings B, BindingKey K) {
+  if (!K.isValid())
+    return NULL;
   return B.lookup(K);
 }
 
@@ -1664,6 +1566,8 @@
 }
 
 RegionBindings RegionStoreManager::Remove(RegionBindings B, BindingKey K) {
+  if (!K.isValid())
+    return B;
   return RBFactory.Remove(B, K);
 }
 
@@ -1672,11 +1576,6 @@
   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.
 //===----------------------------------------------------------------------===//
@@ -1686,15 +1585,14 @@
   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)
+                           const StackFrameContext *LCtx)
     : ClusterAnalysis<RemoveDeadBindingsWorker>(rm, stateMgr, b),
-      SymReaper(symReaper), Loc(loc), CurrentLCtx(LCtx) {}
+      SymReaper(symReaper), CurrentLCtx(LCtx) {}
 
   // Called by ClusterAnalysis.
   void VisitAddedToCluster(const MemRegion *baseR, RegionCluster &C);
@@ -1710,7 +1608,7 @@
                                                    RegionCluster &C) {
 
   if (const VarRegion *VR = dyn_cast<VarRegion>(baseR)) {
-    if (SymReaper.isLive(Loc, VR))
+    if (SymReaper.isLive(VR))
       AddToWorkList(baseR, C);
 
     return;
@@ -1725,9 +1623,14 @@
     return;
   }
 
+  if (isa<NonStaticGlobalSpaceRegion>(baseR)) {
+    AddToWorkList(baseR, C);
+    return;
+  }
+
   // CXXThisRegion in the current or parent location context is live.
   if (const CXXThisRegion *TR = dyn_cast<CXXThisRegion>(baseR)) {
-    const StackArgumentsSpaceRegion *StackReg = 
+    const StackArgumentsSpaceRegion *StackReg =
       cast<StackArgumentsSpaceRegion>(TR->getSuperRegion());
     const StackFrameContext *RegCtx = StackReg->getStackFrame();
     if (RegCtx == CurrentLCtx || RegCtx->isParentOf(CurrentLCtx))
@@ -1749,8 +1652,8 @@
     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))
+      const SubRegion *baseR = dyn_cast<SubRegion>(RI.getKey().getRegion());
+      if (baseR && baseR->isSubRegionOf(LazyR))
         VisitBinding(RI.getData());
     }
     return;
@@ -1817,13 +1720,13 @@
   return changed;
 }
 
-Store RegionStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
+Store RegionStoreManager::RemoveDeadBindings(Store store,
                                              const StackFrameContext *LCtx,
                                              SymbolReaper& SymReaper,
                            llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
 {
   RegionBindings B = GetRegionBindings(store);
-  RemoveDeadBindingsWorker W(*this, StateMgr, B, SymReaper, Loc, LCtx);
+  RemoveDeadBindingsWorker W(*this, StateMgr, B, SymReaper, LCtx);
   W.GenerateClusters();
 
   // Enqueue the region roots onto the worklist.
@@ -1860,8 +1763,8 @@
 }
 
 
-GRState const *RegionStoreManager::EnterStackFrame(GRState const *state,
-                                               StackFrameContext const *frame) {
+Store RegionStoreManager::EnterStackFrame(const GRState *state,
+                                          const StackFrameContext *frame) {
   FunctionDecl const *FD = cast<FunctionDecl>(frame->getDecl());
   FunctionDecl::param_const_iterator PI = FD->param_begin();
   Store store = state->getStore();
@@ -1874,9 +1777,9 @@
       SVal ArgVal = state->getSVal(*AI);
       store = Bind(store, ValMgr.makeLoc(MRMgr.getVarRegion(*PI,frame)),ArgVal);
     }
-  } else if (const CXXConstructExpr *CE = 
+  } else if (const CXXConstructExpr *CE =
                dyn_cast<CXXConstructExpr>(frame->getCallSite())) {
-    CXXConstructExpr::const_arg_iterator AI = CE->arg_begin(), 
+    CXXConstructExpr::const_arg_iterator AI = CE->arg_begin(),
       AE = CE->arg_end();
 
     // Copy the arg expression value to the arg variables.
@@ -1885,9 +1788,9 @@
       store = Bind(store, ValMgr.makeLoc(MRMgr.getVarRegion(*PI,frame)),ArgVal);
     }
   } else
-    assert(0 && "Unhandled call expression.");
+    llvm_unreachable("Unhandled call expression.");
 
-  return state->makeWithStore(store);
+  return store;
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/Checker/ReturnPointerRangeChecker.cpp b/lib/Checker/ReturnPointerRangeChecker.cpp
index 14edf56..a9eb5ce 100644
--- a/lib/Checker/ReturnPointerRangeChecker.cpp
+++ b/lib/Checker/ReturnPointerRangeChecker.cpp
@@ -66,7 +66,7 @@
 
   DefinedOrUnknownSVal NumElements
     = C.getStoreManager().getSizeInElements(state, ER->getSuperRegion(),
-                                           ER->getValueType(C.getASTContext()));
+                                           ER->getValueType());
 
   const GRState *StInBound = state->AssumeInBound(Idx, NumElements, true);
   const GRState *StOutBound = state->AssumeInBound(Idx, NumElements, false);
diff --git a/lib/Checker/ReturnStackAddressChecker.cpp b/lib/Checker/ReturnStackAddressChecker.cpp
deleted file mode 100644
index 35b1cde..0000000
--- a/lib/Checker/ReturnStackAddressChecker.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-//== 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/SVals.cpp b/lib/Checker/SVals.cpp
index d756be7..97ba74e 100644
--- a/lib/Checker/SVals.cpp
+++ b/lib/Checker/SVals.cpp
@@ -62,6 +62,9 @@
 ///  wraps a symbol, return that SymbolRef.  Otherwise return 0.
 // FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
 SymbolRef SVal::getAsLocSymbol() const {
+  if (const nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(this))
+    return X->getLoc().getAsLocSymbol();
+
   if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) {
     const MemRegion *R = X->StripCasts();
     if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
@@ -200,15 +203,19 @@
   return isa<nonloc::ConcreteInt>(this) || isa<loc::ConcreteInt>(this);
 }
 
-bool SVal::isZeroConstant() const {
+bool SVal::isConstant(int I) const {
   if (isa<loc::ConcreteInt>(*this))
-    return cast<loc::ConcreteInt>(*this).getValue() == 0;
+    return cast<loc::ConcreteInt>(*this).getValue() == I;
   else if (isa<nonloc::ConcreteInt>(*this))
-    return cast<nonloc::ConcreteInt>(*this).getValue() == 0;
+    return cast<nonloc::ConcreteInt>(*this).getValue() == I;
   else
     return false;
 }
 
+bool SVal::isZeroConstant() const {
+  return isConstant(0);
+}
+
 
 //===----------------------------------------------------------------------===//
 // Transfer function dispatch for Non-Locs.
@@ -243,8 +250,8 @@
                                  BinaryOperator::Opcode Op,
                                  const loc::ConcreteInt& R) const {
 
-  assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
-          (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
+  assert (Op == BO_Add || Op == BO_Sub ||
+          (Op >= BO_LT && Op <= BO_NE));
 
   const llvm::APSInt* X = BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());
 
diff --git a/lib/Checker/SValuator.cpp b/lib/Checker/SValuator.cpp
index 542fc1b..273e574 100644
--- a/lib/Checker/SValuator.cpp
+++ b/lib/Checker/SValuator.cpp
@@ -29,15 +29,15 @@
 
   if (isa<Loc>(L)) {
     if (isa<Loc>(R))
-      return EvalBinOpLL(Op, cast<Loc>(L), cast<Loc>(R), T);
+      return EvalBinOpLL(ST, 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);
+    // Support pointer arithmetic where the addend is on the left
+    // and the pointer on the right.
+    assert(Op == BO_Add);
 
     // Commute the operands.
     return EvalBinOpLN(ST, Op, cast<Loc>(R), cast<NonLoc>(L), T);
@@ -49,7 +49,7 @@
 DefinedOrUnknownSVal SValuator::EvalEQ(const GRState *ST,
                                        DefinedOrUnknownSVal L,
                                        DefinedOrUnknownSVal R) {
-  return cast<DefinedOrUnknownSVal>(EvalBinOp(ST, BinaryOperator::EQ, L, R,
+  return cast<DefinedOrUnknownSVal>(EvalBinOp(ST, BO_EQ, L, R,
                                               ValMgr.getContext().IntTy));
 }
 
diff --git a/lib/Checker/SimpleConstraintManager.cpp b/lib/Checker/SimpleConstraintManager.cpp
index 8c423a9..04496e1 100644
--- a/lib/Checker/SimpleConstraintManager.cpp
+++ b/lib/Checker/SimpleConstraintManager.cpp
@@ -31,18 +31,17 @@
     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:
+        case BO_And:
+        case BO_Or:
+        case BO_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:
+        // We don't reason yet about these arithmetic constraints on
+        // symbolic values.
+        case BO_Mul:
+        case BO_Div:
+        case BO_Rem:
+        case BO_Shl:
+        case BO_Shr:
           return false;
         // All other cases.
         default:
@@ -90,12 +89,11 @@
     while (SubR) {
       // FIXME: now we only find the first symbolic region.
       if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR)) {
+        const llvm::APSInt &zero = BasicVals.getZeroWithPtrWidth();
         if (Assumption)
-          return AssumeSymNE(state, SymR->getSymbol(),
-                             BasicVals.getZeroWithPtrWidth());
+          return AssumeSymNE(state, SymR->getSymbol(), zero, zero);
         else
-          return AssumeSymEQ(state, SymR->getSymbol(),
-                             BasicVals.getZeroWithPtrWidth());
+          return AssumeSymEQ(state, SymR->getSymbol(), zero, zero);
       }
       SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
     }
@@ -121,11 +119,27 @@
   return SU.ProcessAssume(state, cond, assumption);
 }
 
+static BinaryOperator::Opcode NegateComparison(BinaryOperator::Opcode op) {
+  // FIXME: This should probably be part of BinaryOperator, since this isn't
+  // the only place it's used. (This code was copied from SimpleSValuator.cpp.)
+  switch (op) {
+  default:
+    assert(false && "Invalid opcode.");
+  case BO_LT: return BO_GE;
+  case BO_GT: return BO_LE;
+  case BO_LE: return BO_GT;
+  case BO_GE: return BO_LT;
+  case BO_EQ: return BO_NE;
+  case BO_NE: return BO_EQ;
+  }
+}
+
 const GRState *SimpleConstraintManager::AssumeAux(const GRState *state,
                                                   NonLoc Cond,
                                                   bool Assumption) {
 
-  // We cannot reason about SymIntExpr and SymSymExpr.
+  // We cannot reason about SymSymExprs,
+  // and can only reason about some SymIntExprs.
   if (!canReasonAbout(Cond)) {
     // Just return the current state indicating that the path is feasible.
     // This may be an over-approximation of what is possible.
@@ -144,30 +158,35 @@
     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);
+    if (Assumption)
+      return AssumeSymNE(state, sym, zero, zero);
+    else
+      return AssumeSymEQ(state, sym, zero, 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 now, we only handle expressions whose RHS is an integer.
+    // All other expressions are assumed to be feasible.
+    const SymIntExpr *SE = dyn_cast<SymIntExpr>(V.getSymbolicExpression());
+    if (!SE)
+      return state;
+
+    BinaryOperator::Opcode op = SE->getOpcode();
+    // Implicitly compare non-comparison expressions to 0.
+    if (!BinaryOperator::isComparisonOp(op)) {
+      QualType T = SymMgr.getType(SE);
+      const llvm::APSInt &zero = BasicVals.getValue(0, T);
+      op = (Assumption ? BO_NE : BO_EQ);
+      return AssumeSymRel(state, SE, op, zero);
     }
 
-    // For all other symbolic expressions, over-approximate and consider
-    // the constraint feasible.
-    return state;
+    // From here on out, op is the real comparison we'll be testing.
+    if (!Assumption)
+      op = NegateComparison(op);
+  
+    return AssumeSymRel(state, SE->getLHS(), op, SE->getRHS());
   }
 
   case nonloc::ConcreteIntKind: {
@@ -182,68 +201,99 @@
   } // end switch
 }
 
-const GRState *SimpleConstraintManager::AssumeSymInt(const GRState *state,
-                                                     bool Assumption,
-                                                     const SymIntExpr *SE) {
+const GRState *SimpleConstraintManager::AssumeSymRel(const GRState *state,
+                                                     const SymExpr *LHS,
+                                                     BinaryOperator::Opcode op,
+                                                     const llvm::APSInt& Int) {
+  assert(BinaryOperator::isComparisonOp(op) &&
+         "Non-comparison ops should be rewritten as comparisons to zero.");
 
+   // We only handle simple comparisons of the form "$sym == constant"
+   // or "($sym+constant1) == constant2".
+   // The adjustment is "constant1" in the above expression. It's used to
+   // "slide" the solution range around for modular arithmetic. For example,
+   // x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which
+   // in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to
+   // the subclasses of SimpleConstraintManager to handle the adjustment.
+   llvm::APSInt Adjustment;
 
-  // 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();
+  // First check if the LHS is a simple symbol reference.
+  SymbolRef Sym = dyn_cast<SymbolData>(LHS);
+  if (Sym) {
+    Adjustment = 0;
+  } else {
+    // Next, see if it's a "($sym+constant1)" expression.
+    const SymIntExpr *SE = dyn_cast<SymIntExpr>(LHS);
 
-  switch (SE->getOpcode()) {
+    // We don't handle "($sym1+$sym2)".
+    // Give up and assume the constraint is feasible.
+    if (!SE)
+      return state;
+
+    // We don't handle "(<expr>+constant1)".
+    // Give up and assume the constraint is feasible.
+    Sym = dyn_cast<SymbolData>(SE->getLHS());
+    if (!Sym)
+      return state;
+
+    // Get the constant out of the expression "($sym+constant1)".
+    switch (SE->getOpcode()) {
+    case BO_Add:
+      Adjustment = SE->getRHS();
+      break;
+    case BO_Sub:
+      Adjustment = -SE->getRHS();
+      break;
+    default:
+      // We don't handle non-additive operators.
+      // Give up and assume the constraint is feasible.
+      return state;
+    }
+  }
+
+  // FIXME: This next section is a hack. It silently converts the integers to
+  // be of the same type as the symbol, which is not always correct. Really the
+  // comparisons should be performed using the Int's type, then mapped back to
+  // the symbol's range of values.
+  GRStateManager &StateMgr = state->getStateManager();
+  ASTContext &Ctx = StateMgr.getContext();
+
+  QualType T = Sym->getType(Ctx);
+  assert(T->isIntegerType() || Loc::IsLocType(T));
+  unsigned bitwidth = Ctx.getTypeSize(T);
+  bool isSymUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
+
+  // Convert the adjustment.
+  Adjustment.setIsUnsigned(isSymUnsigned);
+  Adjustment.extOrTrunc(bitwidth);
+
+  // Convert the right-hand side integer.
+  llvm::APSInt ConvertedInt(Int, isSymUnsigned);
+  ConvertedInt.extOrTrunc(bitwidth);
+
+  switch (op) {
   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 BO_EQ:
+    return AssumeSymEQ(state, Sym, ConvertedInt, Adjustment);
 
-  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 BO_NE:
+    return AssumeSymNE(state, Sym, ConvertedInt, Adjustment);
 
-  case BinaryOperator::GE:
-    return Assumption ? AssumeSymGE(state, Sym, Int)
-                      : AssumeSymLT(state, Sym, Int);
+  case BO_GT:
+    return AssumeSymGT(state, Sym, ConvertedInt, Adjustment);
 
-  case BinaryOperator::LT:
-    return Assumption ? AssumeSymLT(state, Sym, Int)
-                      : AssumeSymGE(state, Sym, Int);
+  case BO_GE:
+    return AssumeSymGE(state, Sym, ConvertedInt, Adjustment);
 
-  case BinaryOperator::LE:
-    return Assumption ? AssumeSymLE(state, Sym, Int)
-                      : AssumeSymGT(state, Sym, Int);
+  case BO_LT:
+    return AssumeSymLT(state, Sym, ConvertedInt, Adjustment);
+
+  case BO_LE:
+    return AssumeSymLE(state, Sym, ConvertedInt, Adjustment);
   } // 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
index 5f20e00..96811b3 100644
--- a/lib/Checker/SimpleConstraintManager.h
+++ b/lib/Checker/SimpleConstraintManager.h
@@ -38,12 +38,10 @@
 
   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);
+  const GRState *AssumeSymRel(const GRState *state,
+                              const SymExpr *LHS,
+                              BinaryOperator::Opcode op,
+                              const llvm::APSInt& Int);
 
 protected:
 
@@ -51,23 +49,31 @@
   // Interface that subclasses must implement.
   //===------------------------------------------------------------------===//
 
+  // Each of these is of the form "$sym+Adj <> V", where "<>" is the comparison
+  // operation for the method being invoked.
   virtual const GRState *AssumeSymNE(const GRState *state, SymbolRef sym,
-                                     const llvm::APSInt& V) = 0;
+                                     const llvm::APSInt& V,
+                                     const llvm::APSInt& Adjustment) = 0;
 
   virtual const GRState *AssumeSymEQ(const GRState *state, SymbolRef sym,
-                                     const llvm::APSInt& V) = 0;
+                                     const llvm::APSInt& V,
+                                     const llvm::APSInt& Adjustment) = 0;
 
   virtual const GRState *AssumeSymLT(const GRState *state, SymbolRef sym,
-                                     const llvm::APSInt& V) = 0;
+                                     const llvm::APSInt& V,
+                                     const llvm::APSInt& Adjustment) = 0;
 
   virtual const GRState *AssumeSymGT(const GRState *state, SymbolRef sym,
-                                     const llvm::APSInt& V) = 0;
+                                     const llvm::APSInt& V,
+                                     const llvm::APSInt& Adjustment) = 0;
 
   virtual const GRState *AssumeSymLE(const GRState *state, SymbolRef sym,
-                                     const llvm::APSInt& V) = 0;
+                                     const llvm::APSInt& V,
+                                     const llvm::APSInt& Adjustment) = 0;
 
   virtual const GRState *AssumeSymGE(const GRState *state, SymbolRef sym,
-                                     const llvm::APSInt& V) = 0;
+                                     const llvm::APSInt& V,
+                                     const llvm::APSInt& Adjustment) = 0;
 
   //===------------------------------------------------------------------===//
   // Internal implementation.
diff --git a/lib/Checker/SimpleSValuator.cpp b/lib/Checker/SimpleSValuator.cpp
index dd38a43..7650f09 100644
--- a/lib/Checker/SimpleSValuator.cpp
+++ b/lib/Checker/SimpleSValuator.cpp
@@ -30,10 +30,17 @@
   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 EvalBinOpLL(const GRState *state, BinaryOperator::Opcode op,
+                           Loc lhs, Loc rhs, QualType resultTy);
   virtual SVal EvalBinOpLN(const GRState *state, BinaryOperator::Opcode op,
                            Loc lhs, NonLoc rhs, QualType resultTy);
+
+  /// getKnownValue - Evaluates a given SVal. If the SVal has only one possible
+  ///  (integer) value, that value is returned. Otherwise, returns NULL.
+  virtual const llvm::APSInt *getKnownValue(const GRState *state, SVal V);
+  
+  SVal MakeSymIntVal(const SymExpr *LHS, BinaryOperator::Opcode op,
+                     const llvm::APSInt &RHS, QualType resultTy);
 };
 } // end anonymous namespace
 
@@ -161,54 +168,102 @@
   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;
+  case BO_LT: return BO_GE;
+  case BO_GT: return BO_LE;
+  case BO_LE: return BO_GT;
+  case BO_GE: return BO_LT;
+  case BO_EQ: return BO_NE;
+  case BO_NE: return BO_EQ;
   }
 }
 
-// Equality operators for Locs.
-// FIXME: All this logic will be revamped when we have MemRegion::getLocation()
-// implemented.
+static BinaryOperator::Opcode ReverseComparison(BinaryOperator::Opcode op) {
+  switch (op) {
+  default:
+    assert(false && "Invalid opcode.");
+  case BO_LT: return BO_GT;
+  case BO_GT: return BO_LT;
+  case BO_LE: return BO_GE;
+  case BO_GE: return BO_LE;
+  case BO_EQ:
+  case BO_NE:
+    return op;
+  }
+}
 
-static SVal EvalEquality(ValueManager &ValMgr, Loc lhs, Loc rhs, bool isEqual,
-                         QualType resultTy) {
+SVal SimpleSValuator::MakeSymIntVal(const SymExpr *LHS,
+                                    BinaryOperator::Opcode op,
+                                    const llvm::APSInt &RHS,
+                                    QualType resultTy) {
+  bool isIdempotent = false;
 
-  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;
+  // Check for a few special cases with known reductions first.
+  switch (op) {
+  default:
+    // We can't reduce this case; just treat it normally.
+    break;
+  case BO_Mul:
+    // a*0 and a*1
+    if (RHS == 0)
+      return ValMgr.makeIntVal(0, resultTy);
+    else if (RHS == 1)
+      isIdempotent = true;
+    break;
+  case BO_Div:
+    // a/0 and a/1
+    if (RHS == 0)
+      // This is also handled elsewhere.
+      return UndefinedVal();
+    else if (RHS == 1)
+      isIdempotent = true;
+    break;
+  case BO_Rem:
+    // a%0 and a%1
+    if (RHS == 0)
+      // This is also handled elsewhere.
+      return UndefinedVal();
+    else if (RHS == 1)
+      return ValMgr.makeIntVal(0, resultTy);
+    break;
+  case BO_Add:
+  case BO_Sub:
+  case BO_Shl:
+  case BO_Shr:
+  case BO_Xor:
+    // a+0, a-0, a<<0, a>>0, a^0
+    if (RHS == 0)
+      isIdempotent = true;
+    break;
+  case BO_And:
+    // a&0 and a&(~0)
+    if (RHS == 0)
+      return ValMgr.makeIntVal(0, resultTy);
+    else if (RHS.isAllOnesValue())
+      isIdempotent = true;
+    break;
+  case BO_Or:
+    // a|0 and a|(~0)
+    if (RHS == 0)
+      isIdempotent = true;
+    else if (RHS.isAllOnesValue()) {
+      BasicValueFactory &BVF = ValMgr.getBasicValueFactory();
+      const llvm::APSInt &Result = BVF.Convert(resultTy, RHS);
+      return nonloc::ConcreteInt(Result);
     }
-    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;
+    break;
   }
 
-  return ValMgr.makeTruthVal(isEqual ? lhs == rhs : lhs != rhs, resultTy);
+  // Idempotent ops (like a*1) can still change the type of an expression.
+  // Wrap the LHS up in a NonLoc again and let EvalCastNL do the dirty work.
+  if (isIdempotent) {
+    if (SymbolRef LHSSym = dyn_cast<SymbolData>(LHS))
+      return EvalCastNL(nonloc::SymbolVal(LHSSym), resultTy);
+    return EvalCastNL(nonloc::SymExprVal(LHS), resultTy);
+  }
+
+  // If we reach this point, the expression cannot be simplified.
+  // Make a SymExprVal for the entire thing.
+  return ValMgr.makeNonLoc(LHS, op, RHS, resultTy);
 }
 
 SVal SimpleSValuator::EvalBinOpNN(const GRState *state,
@@ -220,14 +275,20 @@
     switch (op) {
       default:
         break;
-      case BinaryOperator::EQ:
-      case BinaryOperator::LE:
-      case BinaryOperator::GE:
+      case BO_EQ:
+      case BO_LE:
+      case BO_GE:
         return ValMgr.makeTruthVal(true, resultTy);
-      case BinaryOperator::LT:
-      case BinaryOperator::GT:
-      case BinaryOperator::NE:
+      case BO_LT:
+      case BO_GT:
+      case BO_NE:
         return ValMgr.makeTruthVal(false, resultTy);
+      case BO_Xor:
+      case BO_Sub:
+        return ValMgr.makeIntVal(0, resultTy);
+      case BO_Or:
+      case BO_And:
+        return EvalCastNL(lhs, resultTy);
     }
 
   while (1) {
@@ -238,7 +299,8 @@
       Loc lhsL = cast<nonloc::LocAsInteger>(lhs).getLoc();
       switch (rhs.getSubKind()) {
         case nonloc::LocAsIntegerKind:
-          return EvalBinOpLL(op, lhsL, cast<nonloc::LocAsInteger>(rhs).getLoc(),
+          return EvalBinOpLL(state, op, lhsL,
+                             cast<nonloc::LocAsInteger>(rhs).getLoc(),
                              resultTy);
         case nonloc::ConcreteIntKind: {
           // Transform the integer into a location and compare.
@@ -246,13 +308,13 @@
           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);
+          return EvalBinOpLL(state, op, lhsL, ValMgr.makeLoc(i), resultTy);
         }
         default:
           switch (op) {
-            case BinaryOperator::EQ:
+            case BO_EQ:
               return ValMgr.makeTruthVal(false, resultTy);
-            case BinaryOperator::NE:
+            case BO_NE:
               return ValMgr.makeTruthVal(true, resultTy);
             default:
               // This case also handles pointer arithmetic.
@@ -261,87 +323,136 @@
       }
     }
     case nonloc::SymExprValKind: {
-      // Logical not?
-      if (!(op == BinaryOperator::EQ && rhs.isZeroConstant()))
+      nonloc::SymExprVal *selhs = cast<nonloc::SymExprVal>(&lhs);
+
+      // Only handle LHS of the form "$sym op constant", at least for now.
+      const SymIntExpr *symIntExpr =
+        dyn_cast<SymIntExpr>(selhs->getSymbolicExpression());
+
+      if (!symIntExpr)
         return UnknownVal();
 
-      const SymExpr *symExpr =
-        cast<nonloc::SymExprVal>(lhs).getSymbolicExpression();
+      // Is this a logical not? (!x is represented as x == 0.)
+      if (op == BO_EQ && rhs.isZeroConstant()) {
+        // We know how to negate certain expressions. Simplify them here.
 
-      // 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);
+        default:
+          // We don't know how to negate this operation.
+          // Just handle it as if it were a normal comparison to 0.
+          break;
+        case BO_LAnd:
+        case BO_LOr:
+          assert(false && "Logical operators handled by branching logic.");
+          return UnknownVal();
+        case BO_Assign:
+        case BO_MulAssign:
+        case BO_DivAssign:
+        case BO_RemAssign:
+        case BO_AddAssign:
+        case BO_SubAssign:
+        case BO_ShlAssign:
+        case BO_ShrAssign:
+        case BO_AndAssign:
+        case BO_XorAssign:
+        case BO_OrAssign:
+        case BO_Comma:
+          assert(false && "'=' and ',' operators handled by GRExprEngine.");
+          return UnknownVal();
+        case BO_PtrMemD:
+        case BO_PtrMemI:
+          assert(false && "Pointer arithmetic not handled here.");
+          return UnknownVal();
+        case BO_LT:
+        case BO_GT:
+        case BO_LE:
+        case BO_GE:
+        case BO_EQ:
+        case BO_NE:
+          // Negate the comparison and make a value.
+          opc = NegateComparison(opc);
+          assert(symIntExpr->getType(ValMgr.getContext()) == resultTy);
+          return ValMgr.makeNonLoc(symIntExpr->getLHS(), opc,
+                                   symIntExpr->getRHS(), resultTy);
         }
       }
+
+      // For now, only handle expressions whose RHS is a constant.
+      const nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs);
+      if (!rhsInt)
+        return UnknownVal();
+
+      // If both the LHS and the current expression are additive,
+      // fold their constants.
+      if (BinaryOperator::isAdditiveOp(op)) {
+        BinaryOperator::Opcode lop = symIntExpr->getOpcode();
+        if (BinaryOperator::isAdditiveOp(lop)) {
+          BasicValueFactory &BVF = ValMgr.getBasicValueFactory();
+
+          // resultTy may not be the best type to convert to, but it's
+          // probably the best choice in expressions with mixed type
+          // (such as x+1U+2LL). The rules for implicit conversions should
+          // choose a reasonable type to preserve the expression, and will
+          // at least match how the value is going to be used.
+          const llvm::APSInt &first =
+            BVF.Convert(resultTy, symIntExpr->getRHS());
+          const llvm::APSInt &second =
+            BVF.Convert(resultTy, rhsInt->getValue());
+
+          const llvm::APSInt *newRHS;
+          if (lop == op)
+            newRHS = BVF.EvaluateAPSInt(BO_Add, first, second);
+          else
+            newRHS = BVF.EvaluateAPSInt(BO_Sub, first, second);
+          return MakeSymIntVal(symIntExpr->getLHS(), lop, *newRHS, resultTy);
+        }
+      }
+
+      // Otherwise, make a SymExprVal out of the expression.
+      return MakeSymIntVal(symIntExpr, op, rhsInt->getValue(), resultTy);
     }
     case nonloc::ConcreteIntKind: {
+      const nonloc::ConcreteInt& lhsInt = cast<nonloc::ConcreteInt>(lhs);
+
       if (isa<nonloc::ConcreteInt>(rhs)) {
-        const nonloc::ConcreteInt& lhsInt = cast<nonloc::ConcreteInt>(lhs);
         return lhsInt.evalBinOp(ValMgr, op, cast<nonloc::ConcreteInt>(rhs));
-      }
-      else {
+      } else {
+        const llvm::APSInt& lhsValue = lhsInt.getValue();
+        
         // 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).
+        // While we're at it, catch some special cases for non-commutative ops.
         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:
+          case BO_LT:
+          case BO_GT:
+          case BO_LE:
+          case BO_GE:
+            op = ReverseComparison(op);
             continue;
+          case BO_EQ:
+          case BO_NE:
+          case BO_Add:
+          case BO_Mul:
+          case BO_And:
+          case BO_Xor:
+          case BO_Or:
+            continue;
+          case BO_Shr:
+            if (lhsValue.isAllOnesValue() && lhsValue.isSigned())
+              // At this point lhs and rhs have been swapped.
+              return rhs;
+            // FALL-THROUGH
+          case BO_Shl:
+            if (lhsValue == 0)
+              // At this point lhs and rhs have been swapped.
+              return rhs;
+            return UnknownVal();
           default:
             return UnknownVal();
         }
@@ -350,10 +461,12 @@
     case nonloc::SymbolValKind: {
       nonloc::SymbolVal *slhs = cast<nonloc::SymbolVal>(&lhs);
       SymbolRef Sym = slhs->getSymbol();
-      
+
+      ASTContext& Ctx = ValMgr.getContext();
+
       // 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 (Sym->getType(Ctx)->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.
@@ -363,7 +476,7 @@
           
           // Also promote the RHS (if necessary).
 
-          // For shifts, it necessary promote the RHS to the result type.
+          // For shifts, it is not necessary to promote the RHS.
           if (BinaryOperator::isShiftOp(op))
             continue;
           
@@ -375,11 +488,24 @@
           
           continue;
         }
-      
+
+      // Is the RHS a symbol we can simplify?
+      if (const nonloc::SymbolVal *srhs = dyn_cast<nonloc::SymbolVal>(&rhs)) {
+        SymbolRef RSym = srhs->getSymbol();
+        if (RSym->getType(Ctx)->isIntegerType()) {
+          if (const llvm::APSInt *Constant = state->getSymVal(RSym)) {
+            // The symbol evaluates to a constant.
+            BasicValueFactory &BVF = ValMgr.getBasicValueFactory();
+            const llvm::APSInt &rhs_I = BVF.Convert(resultTy, *Constant);
+            rhs = nonloc::ConcreteInt(rhs_I);
+          }
+        }
+      }
+
       if (isa<nonloc::ConcreteInt>(rhs)) {
-        return ValMgr.makeNonLoc(slhs->getSymbol(), op,
-                                 cast<nonloc::ConcreteInt>(rhs).getValue(),
-                                 resultTy);
+        return MakeSymIntVal(slhs->getSymbol(), op,
+                             cast<nonloc::ConcreteInt>(rhs).getValue(),
+                             resultTy);
       }
 
       return UnknownVal();
@@ -388,21 +514,301 @@
   }
 }
 
-SVal SimpleSValuator::EvalBinOpLL(BinaryOperator::Opcode op, Loc lhs, Loc rhs,
+// FIXME: all this logic will change if/when we have MemRegion::getLocation().
+SVal SimpleSValuator::EvalBinOpLL(const GRState *state,
+                                  BinaryOperator::Opcode op,
+                                  Loc lhs, Loc rhs,
                                   QualType resultTy) {
-  switch (op) {
+  // Only comparisons and subtractions are valid operations on two pointers.
+  // See [C99 6.5.5 through 6.5.14] or [C++0x 5.6 through 5.15].
+  // However, if a pointer is casted to an integer, EvalBinOpNN may end up
+  // calling this function with another operation (PR7527). We don't attempt to
+  // model this for now, but it could be useful, particularly when the
+  // "location" is actually an integer value that's been passed through a void*.
+  if (!(BinaryOperator::isComparisonOp(op) || op == BO_Sub))
+    return UnknownVal();
+
+  // Special cases for when both sides are identical.
+  if (lhs == rhs) {
+    switch (op) {
     default:
+      assert(false && "Unimplemented operation for two identical values");
       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)
+    case BO_Sub:
+      return ValMgr.makeZeroVal(resultTy);
+    case BO_EQ:
+    case BO_LE:
+    case BO_GE:
+      return ValMgr.makeTruthVal(true, resultTy);
+    case BO_NE:
+    case BO_LT:
+    case BO_GT:
+      return ValMgr.makeTruthVal(false, resultTy);
+    }
+  }
+
+  switch (lhs.getSubKind()) {
+  default:
+    assert(false && "Ordering not implemented for this Loc.");
+    return UnknownVal();
+
+  case loc::GotoLabelKind:
+    // The only thing we know about labels is that they're non-null.
+    if (rhs.isZeroConstant()) {
+      switch (op) {
+      default:
+        break;
+      case BO_Sub:
+        return EvalCastL(lhs, resultTy);
+      case BO_EQ:
+      case BO_LE:
+      case BO_LT:
         return ValMgr.makeTruthVal(false, resultTy);
+      case BO_NE:
+      case BO_GT:
+      case BO_GE:
+        return ValMgr.makeTruthVal(true, resultTy);
+      }
+    }
+    // There may be two labels for the same location, and a function region may
+    // have the same address as a label at the start of the function (depending
+    // on the ABI).
+    // FIXME: we can probably do a comparison against other MemRegions, though.
+    // FIXME: is there a way to tell if two labels refer to the same location?
+    return UnknownVal(); 
+
+  case loc::ConcreteIntKind: {
+    // If one of the operands is a symbol and the other is a constant,
+    // build an expression for use by the constraint manager.
+    if (SymbolRef rSym = rhs.getAsLocSymbol()) {
+      // We can only build expressions with symbols on the left,
+      // so we need a reversible operator.
+      if (!BinaryOperator::isComparisonOp(op))
+        return UnknownVal();
+
+      const llvm::APSInt &lVal = cast<loc::ConcreteInt>(lhs).getValue();
+      return ValMgr.makeNonLoc(rSym, ReverseComparison(op), lVal, resultTy);
+    }
+
+    // If both operands are constants, just perform the operation.
+    if (loc::ConcreteInt *rInt = dyn_cast<loc::ConcreteInt>(&rhs)) {
+      BasicValueFactory &BVF = ValMgr.getBasicValueFactory();
+      SVal ResultVal = cast<loc::ConcreteInt>(lhs).EvalBinOp(BVF, op, *rInt);
+      if (Loc *Result = dyn_cast<Loc>(&ResultVal))
+        return EvalCastL(*Result, resultTy);
+      else
+        return UnknownVal();
+    }
+
+    // Special case comparisons against NULL.
+    // This must come after the test if the RHS is a symbol, which is used to
+    // build constraints. The address of any non-symbolic region is guaranteed
+    // to be non-NULL, as is any label.
+    assert(isa<loc::MemRegionVal>(rhs) || isa<loc::GotoLabel>(rhs));
+    if (lhs.isZeroConstant()) {
+      switch (op) {
+      default:
+        break;
+      case BO_EQ:
+      case BO_GT:
+      case BO_GE:
+        return ValMgr.makeTruthVal(false, resultTy);
+      case BO_NE:
+      case BO_LT:
+      case BO_LE:
+        return ValMgr.makeTruthVal(true, resultTy);
+      }
+    }
+
+    // Comparing an arbitrary integer to a region or label address is
+    // completely unknowable.
+    return UnknownVal();
+  }
+  case loc::MemRegionKind: {
+    if (loc::ConcreteInt *rInt = dyn_cast<loc::ConcreteInt>(&rhs)) {
+      // If one of the operands is a symbol and the other is a constant,
+      // build an expression for use by the constraint manager.
+      if (SymbolRef lSym = lhs.getAsLocSymbol())
+        return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
+
+      // Special case comparisons to NULL.
+      // This must come after the test if the LHS is a symbol, which is used to
+      // build constraints. The address of any non-symbolic region is guaranteed
+      // to be non-NULL.
+      if (rInt->isZeroConstant()) {
+        switch (op) {
+        default:
+          break;
+        case BO_Sub:
+          return EvalCastL(lhs, resultTy);
+        case BO_EQ:
+        case BO_LT:
+        case BO_LE:
+          return ValMgr.makeTruthVal(false, resultTy);
+        case BO_NE:
+        case BO_GT:
+        case BO_GE:
+          return ValMgr.makeTruthVal(true, resultTy);
+        }
+      }
+
+      // Comparing a region to an arbitrary integer is completely unknowable.
       return UnknownVal();
+    }
+
+    // Get both values as regions, if possible.
+    const MemRegion *LeftMR = lhs.getAsRegion();
+    assert(LeftMR && "MemRegionKind SVal doesn't have a region!");
+
+    const MemRegion *RightMR = rhs.getAsRegion();
+    if (!RightMR)
+      // The RHS is probably a label, which in theory could address a region.
+      // FIXME: we can probably make a more useful statement about non-code
+      // regions, though.
+      return UnknownVal();
+
+    // If both values wrap regions, see if they're from different base regions.
+    const MemRegion *LeftBase = LeftMR->getBaseRegion();
+    const MemRegion *RightBase = RightMR->getBaseRegion();
+    if (LeftBase != RightBase &&
+        !isa<SymbolicRegion>(LeftBase) && !isa<SymbolicRegion>(RightBase)) {
+      switch (op) {
+      default:
+        return UnknownVal();
+      case BO_EQ:
+        return ValMgr.makeTruthVal(false, resultTy);
+      case BO_NE:
+        return ValMgr.makeTruthVal(true, resultTy);
+      }
+    }
+
+    // The two regions are from the same base region. See if they're both a
+    // type of region we know how to compare.
+
+    // FIXME: If/when there is a getAsRawOffset() for FieldRegions, this
+    // ElementRegion path and the FieldRegion path below should be unified.
+    if (const ElementRegion *LeftER = dyn_cast<ElementRegion>(LeftMR)) {
+      // First see if the right region is also an ElementRegion.
+      const ElementRegion *RightER = dyn_cast<ElementRegion>(RightMR);
+      if (!RightER)
+        return UnknownVal();
+
+      // Next, see if the two ERs have the same super-region and matching types.
+      // FIXME: This should do something useful even if the types don't match,
+      // though if both indexes are constant the RegionRawOffset path will
+      // give the correct answer.
+      if (LeftER->getSuperRegion() == RightER->getSuperRegion() &&
+          LeftER->getElementType() == RightER->getElementType()) {
+        // Get the left index and cast it to the correct type.
+        // If the index is unknown or undefined, bail out here.
+        SVal LeftIndexVal = LeftER->getIndex();
+        NonLoc *LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal);
+        if (!LeftIndex)
+          return UnknownVal();
+        LeftIndexVal = EvalCastNL(*LeftIndex, resultTy);
+        LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal);
+        if (!LeftIndex)
+          return UnknownVal();
+
+        // Do the same for the right index.
+        SVal RightIndexVal = RightER->getIndex();
+        NonLoc *RightIndex = dyn_cast<NonLoc>(&RightIndexVal);
+        if (!RightIndex)
+          return UnknownVal();
+        RightIndexVal = EvalCastNL(*RightIndex, resultTy);
+        RightIndex = dyn_cast<NonLoc>(&RightIndexVal);
+        if (!RightIndex)
+          return UnknownVal();
+
+        // Actually perform the operation.
+        // EvalBinOpNN expects the two indexes to already be the right type.
+        return EvalBinOpNN(state, op, *LeftIndex, *RightIndex, resultTy);
+      }
+
+      // If the element indexes aren't comparable, see if the raw offsets are.
+      RegionRawOffset LeftOffset = LeftER->getAsArrayOffset();
+      RegionRawOffset RightOffset = RightER->getAsArrayOffset();
+
+      if (LeftOffset.getRegion() != NULL &&
+          LeftOffset.getRegion() == RightOffset.getRegion()) {
+        int64_t left = LeftOffset.getByteOffset();
+        int64_t right = RightOffset.getByteOffset();
+
+        switch (op) {
+        default:
+          return UnknownVal();
+        case BO_LT:
+          return ValMgr.makeTruthVal(left < right, resultTy);
+        case BO_GT:
+          return ValMgr.makeTruthVal(left > right, resultTy);
+        case BO_LE:
+          return ValMgr.makeTruthVal(left <= right, resultTy);
+        case BO_GE:
+          return ValMgr.makeTruthVal(left >= right, resultTy);
+        case BO_EQ:
+          return ValMgr.makeTruthVal(left == right, resultTy);
+        case BO_NE:
+          return ValMgr.makeTruthVal(left != right, resultTy);
+        }
+      }
+
+      // If we get here, we have no way of comparing the ElementRegions.
+      return UnknownVal();
+    }
+
+    // See if both regions are fields of the same structure.
+    // FIXME: This doesn't handle nesting, inheritance, or Objective-C ivars.
+    if (const FieldRegion *LeftFR = dyn_cast<FieldRegion>(LeftMR)) {
+      // Only comparisons are meaningful here!
+      if (!BinaryOperator::isComparisonOp(op))
+        return UnknownVal();
+
+      // First see if the right region is also a FieldRegion.
+      const FieldRegion *RightFR = dyn_cast<FieldRegion>(RightMR);
+      if (!RightFR)
+        return UnknownVal();
+
+      // Next, see if the two FRs have the same super-region.
+      // FIXME: This doesn't handle casts yet, and simply stripping the casts
+      // doesn't help.
+      if (LeftFR->getSuperRegion() != RightFR->getSuperRegion())
+        return UnknownVal();
+
+      const FieldDecl *LeftFD = LeftFR->getDecl();
+      const FieldDecl *RightFD = RightFR->getDecl();
+      const RecordDecl *RD = LeftFD->getParent();
+
+      // Make sure the two FRs are from the same kind of record. Just in case!
+      // FIXME: This is probably where inheritance would be a problem.
+      if (RD != RightFD->getParent())
+        return UnknownVal();
+
+      // We know for sure that the two fields are not the same, since that
+      // would have given us the same SVal.
+      if (op == BO_EQ)
+        return ValMgr.makeTruthVal(false, resultTy);
+      if (op == BO_NE)
+        return ValMgr.makeTruthVal(true, resultTy);
+
+      // Iterate through the fields and see which one comes first.
+      // [C99 6.7.2.1.13] "Within a structure object, the non-bit-field
+      // members and the units in which bit-fields reside have addresses that
+      // increase in the order in which they are declared."
+      bool leftFirst = (op == BO_LT || op == BO_LE);
+      for (RecordDecl::field_iterator I = RD->field_begin(),
+           E = RD->field_end(); I!=E; ++I) {
+        if (*I == LeftFD)
+          return ValMgr.makeTruthVal(leftFirst, resultTy);
+        if (*I == RightFD)
+          return ValMgr.makeTruthVal(!leftFirst, resultTy);
+      }
+
+      assert(false && "Fields not found in parent record's definition");
+    }
+
+    // If we get here, we have no way of comparing the regions.
+    return UnknownVal();
+  }
   }
 }
 
@@ -414,7 +820,7 @@
   // 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 (BinaryOperator::isComparisonOp(op)) {
     if (nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs)) {
       const llvm::APSInt *x = &rhsInt->getValue();
       ASTContext &ctx = ValMgr.getContext();
@@ -423,7 +829,7 @@
         if (x->isSigned())
           x = &ValMgr.getBasicValueFactory().getValue(*x, true);
 
-        return EvalBinOpLL(op, lhs, loc::ConcreteInt(*x), resultTy);
+        return EvalBinOpLL(state, op, lhs, loc::ConcreteInt(*x), resultTy);
       }
     }
   }
@@ -432,3 +838,21 @@
   return state->getStateManager().getStoreManager().EvalBinOp(op, lhs,
                                                               rhs, resultTy);
 }
+
+const llvm::APSInt *SimpleSValuator::getKnownValue(const GRState *state,
+                                                   SVal V) {
+  if (V.isUnknownOrUndef())
+    return NULL;
+
+  if (loc::ConcreteInt* X = dyn_cast<loc::ConcreteInt>(&V))
+    return &X->getValue();
+
+  if (nonloc::ConcreteInt* X = dyn_cast<nonloc::ConcreteInt>(&V))
+    return &X->getValue();
+
+  if (SymbolRef Sym = V.getAsSymbol())
+    return state->getSymVal(Sym);
+
+  // FIXME: Add support for SymExprs.
+  return NULL;
+}
diff --git a/lib/Checker/StackAddrLeakChecker.cpp b/lib/Checker/StackAddrLeakChecker.cpp
new file mode 100644
index 0000000..c67a81d
--- /dev/null
+++ b/lib/Checker/StackAddrLeakChecker.cpp
@@ -0,0 +1,204 @@
+//=== StackAddrLeakChecker.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 stack address leak checker, which checks if an invalid 
+// stack address is stored into a global or heap location. See CERT DCL30-C.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GRExprEngineInternalChecks.h"
+#include "clang/Checker/BugReporter/BugType.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/SmallString.h"
+using namespace clang;
+
+namespace {
+class StackAddrLeakChecker : public CheckerVisitor<StackAddrLeakChecker> {
+  BuiltinBug *BT_stackleak;
+  BuiltinBug *BT_returnstack;
+
+public:
+  StackAddrLeakChecker() : BT_stackleak(0), BT_returnstack(0) {}
+  static void *getTag() {
+    static int x;
+    return &x;
+  }
+  void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *RS);
+  void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
+private:
+  void EmitStackError(CheckerContext &C, const MemRegion *R, const Expr *RetE);
+  SourceRange GenName(llvm::raw_ostream &os, const MemRegion *R,
+                      SourceManager &SM);
+};
+}
+
+void clang::RegisterStackAddrLeakChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new StackAddrLeakChecker());
+}
+
+SourceRange StackAddrLeakChecker::GenName(llvm::raw_ostream &os,
+                                          const MemRegion *R,
+                                          SourceManager &SM) {
+    // Get the base region, stripping away fields and elements.
+  R = R->getBaseRegion();
+  SourceRange range;
+  os << "Address of ";
+  
+  // Check if the region is a compound literal.
+  if (const CompoundLiteralRegion* CR = dyn_cast<CompoundLiteralRegion>(R)) { 
+    const CompoundLiteralExpr* CL = CR->getLiteralExpr();
+    os << "stack memory associated with a compound literal "
+          "declared on line "
+        << SM.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 << "stack memory allocated by call to alloca() on line "
+       << SM.getInstantiationLineNumber(L);
+  }
+  else if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(R)) {
+    const BlockDecl *BD = BR->getCodeRegion()->getDecl();
+    SourceLocation L = BD->getLocStart();
+    range = BD->getSourceRange();
+    os << "stack-allocated block declared on line "
+       << SM.getInstantiationLineNumber(L);
+  }
+  else if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
+    os << "stack memory associated with local variable '"
+       << VR->getString() << '\'';
+    range = VR->getDecl()->getSourceRange();
+  }
+  else {
+    assert(false && "Invalid region in ReturnStackAddressChecker.");
+  } 
+  
+  return range;
+}
+
+void StackAddrLeakChecker::EmitStackError(CheckerContext &C, const MemRegion *R,
+                                          const Expr *RetE) {
+  ExplodedNode *N = C.GenerateSink();
+
+  if (!N)
+    return;
+
+  if (!BT_returnstack)
+   BT_returnstack=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 = GenName(os, R, C.getSourceManager());
+  os << " returned to caller";
+  RangedBugReport *report = new RangedBugReport(*BT_returnstack, os.str(), N);
+  report->addRange(RetE->getSourceRange());
+  if (range.isValid())
+    report->addRange(range);
+
+  C.EmitReport(report);
+}
+
+void StackAddrLeakChecker::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;
+  }
+}
+
+void StackAddrLeakChecker::EvalEndPath(GREndPathNodeBuilder &B, void *tag,
+                                       GRExprEngine &Eng) {
+  SaveAndRestore<bool> OldHasGen(B.HasGeneratedNode);
+  const GRState *state = B.getState();
+
+  // Iterate over all bindings to global variables and see if it contains
+  // a memory region in the stack space.
+  class CallBack : public StoreManager::BindingsHandler {
+  private:
+    const StackFrameContext *CurSFC;
+  public:
+    llvm::SmallVector<std::pair<const MemRegion*, const MemRegion*>, 10> V;
+
+    CallBack(const LocationContext *LCtx)
+      : CurSFC(LCtx->getCurrentStackFrame()) {}
+    
+    bool HandleBinding(StoreManager &SMgr, Store store,
+                       const MemRegion *region, SVal val) {
+      
+      if (!isa<GlobalsSpaceRegion>(region->getMemorySpace()))
+        return true;
+      
+      const MemRegion *vR = val.getAsRegion();
+      if (!vR)
+        return true;
+      
+      if (const StackSpaceRegion *SSR = 
+          dyn_cast<StackSpaceRegion>(vR->getMemorySpace())) {
+        // If the global variable holds a location in the current stack frame,
+        // record the binding to emit a warning.
+        if (SSR->getStackFrame() == CurSFC)
+          V.push_back(std::make_pair(region, vR));
+      }
+      
+      return true;
+    }
+  };
+    
+  CallBack cb(B.getPredecessor()->getLocationContext());
+  state->getStateManager().getStoreManager().iterBindings(state->getStore(),cb);
+
+  if (cb.V.empty())
+    return;
+
+  // Generate an error node.
+  ExplodedNode *N = B.generateNode(state, tag, B.getPredecessor());
+  if (!N)
+    return;
+
+  if (!BT_stackleak)
+    BT_stackleak =
+      new BuiltinBug("Stack address stored into global variable",
+                     "Stack address was saved into a global variable. "
+                     "This is dangerous because the address will become "
+                     "invalid after returning from the function");
+  
+  for (unsigned i = 0, e = cb.V.size(); i != e; ++i) {
+    // Generate a report for this bug.
+    llvm::SmallString<512> buf;
+    llvm::raw_svector_ostream os(buf);
+    SourceRange range = GenName(os, cb.V[i].second,
+                                Eng.getContext().getSourceManager());
+    os << " is still referred to by the global variable '";
+    const VarRegion *VR = cast<VarRegion>(cb.V[i].first->getBaseRegion());
+    os << VR->getDecl()->getNameAsString() 
+       << "' upon returning to the caller.  This will be a dangling reference";
+    RangedBugReport *report = new RangedBugReport(*BT_stackleak, os.str(), N);
+    if (range.isValid())
+      report->addRange(range);
+
+    Eng.getBugReporter().EmitReport(report);
+  }
+}
diff --git a/lib/Checker/Store.cpp b/lib/Checker/Store.cpp
index c12065b..7c80eed 100644
--- a/lib/Checker/Store.cpp
+++ b/lib/Checker/Store.cpp
@@ -21,6 +21,11 @@
   : ValMgr(stateMgr.getValueManager()), StateMgr(stateMgr),
     MRMgr(ValMgr.getRegionManager()), Ctx(stateMgr.getContext()) {}
 
+Store StoreManager::EnterStackFrame(const GRState *state,
+                                    const StackFrameContext *frame) {
+  return state->getStore();
+}
+
 const MemRegion *StoreManager::MakeElementRegion(const MemRegion *Base,
                                               QualType EleTy, uint64_t index) {
   SVal idx = ValMgr.makeArrayIndex(index);
@@ -78,7 +83,7 @@
   // Handle casts from compatible types.
   if (R->isBoundable())
     if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
-      QualType ObjTy = Ctx.getCanonicalType(TR->getValueType(Ctx));
+      QualType ObjTy = Ctx.getCanonicalType(TR->getValueType());
       if (CanonPointeeTy == ObjTy)
         return R;
     }
@@ -91,7 +96,8 @@
     case MemRegion::StackArgumentsSpaceRegionKind:
     case MemRegion::HeapSpaceRegionKind:
     case MemRegion::UnknownSpaceRegionKind:
-    case MemRegion::GlobalsSpaceRegionKind: {
+    case MemRegion::NonStaticGlobalSpaceRegionKind:
+    case MemRegion::StaticGlobalSpaceRegionKind: {
       assert(0 && "Invalid region cast");
       break;
     }
@@ -138,7 +144,7 @@
       // FIXME: Handle symbolic raw offsets.
 
       const ElementRegion *elementR = cast<ElementRegion>(R);
-      const RegionRawOffset &rawOff = elementR->getAsRawOffset();
+      const RegionRawOffset &rawOff = elementR->getAsArrayOffset();
       const MemRegion *baseR = rawOff.getRegion();
 
       // If we cannot compute a raw offset, throw up our hands and return
@@ -153,7 +159,7 @@
         // 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 ObjTy = Ctx.getCanonicalType(TR->getValueType());
           QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy);
           if (CanonPointeeTy == ObjTy)
             return baseR;
@@ -216,7 +222,7 @@
 
   if (performTestOnly) {  
     // Automatically translate references to pointers.
-    QualType T = R->getValueType(Ctx);
+    QualType T = R->getValueType();
     if (const ReferenceType *RT = T->getAs<ReferenceType>())
       T = Ctx.getPointerType(RT->getPointeeType());
     
@@ -232,17 +238,6 @@
   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;
@@ -289,10 +284,6 @@
   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.
@@ -321,6 +312,19 @@
     return UnknownVal();
 
   const llvm::APSInt& BaseIdxI = cast<nonloc::ConcreteInt>(BaseIdx).getValue();
+
+  // Only allow non-integer offsets if the base region has no offset itself.
+  // FIXME: This is a somewhat arbitrary restriction. We should be using
+  // SValuator here to add the two offsets without checking their types.
+  if (!isa<nonloc::ConcreteInt>(Offset)) {
+    if (isa<ElementRegion>(BaseRegion->StripCasts()))
+      return UnknownVal();
+
+    return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
+                                                    ElemR->getSuperRegion(),
+                                                    Ctx));
+  }
+
   const llvm::APSInt& OffI = cast<nonloc::ConcreteInt>(Offset).getValue();
   assert(BaseIdxI.isSigned());
 
diff --git a/lib/Checker/StreamChecker.cpp b/lib/Checker/StreamChecker.cpp
new file mode 100644
index 0000000..87874e3
--- /dev/null
+++ b/lib/Checker/StreamChecker.cpp
@@ -0,0 +1,466 @@
+//===-- StreamChecker.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 checkers that model and check stream handling functions.
+//
+//===----------------------------------------------------------------------===//
+
+#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 {
+
+struct StreamState {
+  enum Kind { Opened, Closed, OpenFailed, Escaped } K;
+  const Stmt *S;
+
+  StreamState(Kind k, const Stmt *s) : K(k), S(s) {}
+
+  bool isOpened() const { return K == Opened; }
+  bool isClosed() const { return K == Closed; }
+  bool isOpenFailed() const { return K == OpenFailed; }
+  bool isEscaped() const { return K == Escaped; }
+
+  bool operator==(const StreamState &X) const {
+    return K == X.K && S == X.S;
+  }
+
+  static StreamState getOpened(const Stmt *s) { return StreamState(Opened, s); }
+  static StreamState getClosed(const Stmt *s) { return StreamState(Closed, s); }
+  static StreamState getOpenFailed(const Stmt *s) { 
+    return StreamState(OpenFailed, s); 
+  }
+  static StreamState getEscaped(const Stmt *s) {
+    return StreamState(Escaped, s);
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddInteger(K);
+    ID.AddPointer(S);
+  }
+};
+
+class StreamChecker : public CheckerVisitor<StreamChecker> {
+  IdentifierInfo *II_fopen, *II_tmpfile, *II_fclose, *II_fread, *II_fwrite, 
+                 *II_fseek, *II_ftell, *II_rewind, *II_fgetpos, *II_fsetpos,  
+                 *II_clearerr, *II_feof, *II_ferror, *II_fileno;
+  BuiltinBug *BT_nullfp, *BT_illegalwhence, *BT_doubleclose, *BT_ResourceLeak;
+
+public:
+  StreamChecker() 
+    : II_fopen(0), II_tmpfile(0) ,II_fclose(0), II_fread(0), II_fwrite(0), 
+      II_fseek(0), II_ftell(0), II_rewind(0), II_fgetpos(0), II_fsetpos(0), 
+      II_clearerr(0), II_feof(0), II_ferror(0), II_fileno(0), 
+      BT_nullfp(0), BT_illegalwhence(0), BT_doubleclose(0), 
+      BT_ResourceLeak(0) {}
+
+  static void *getTag() {
+    static int x;
+    return &x;
+  }
+
+  virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
+  void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper);
+  void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
+  void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S);
+
+private:
+  void Fopen(CheckerContext &C, const CallExpr *CE);
+  void Tmpfile(CheckerContext &C, const CallExpr *CE);
+  void Fclose(CheckerContext &C, const CallExpr *CE);
+  void Fread(CheckerContext &C, const CallExpr *CE);
+  void Fwrite(CheckerContext &C, const CallExpr *CE);
+  void Fseek(CheckerContext &C, const CallExpr *CE);
+  void Ftell(CheckerContext &C, const CallExpr *CE);
+  void Rewind(CheckerContext &C, const CallExpr *CE);
+  void Fgetpos(CheckerContext &C, const CallExpr *CE);
+  void Fsetpos(CheckerContext &C, const CallExpr *CE);
+  void Clearerr(CheckerContext &C, const CallExpr *CE);
+  void Feof(CheckerContext &C, const CallExpr *CE);
+  void Ferror(CheckerContext &C, const CallExpr *CE);
+  void Fileno(CheckerContext &C, const CallExpr *CE);
+
+  void OpenFileAux(CheckerContext &C, const CallExpr *CE);
+  
+  const GRState *CheckNullStream(SVal SV, const GRState *state, 
+                                 CheckerContext &C);
+  const GRState *CheckDoubleClose(const CallExpr *CE, const GRState *state, 
+                                 CheckerContext &C);
+};
+
+} // end anonymous namespace
+
+namespace clang {
+  template <>
+  struct GRStateTrait<StreamState> 
+    : public GRStatePartialTrait<llvm::ImmutableMap<SymbolRef, StreamState> > {
+    static void *GDMIndex() { return StreamChecker::getTag(); }
+  };
+}
+
+void clang::RegisterStreamChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new StreamChecker());
+}
+
+bool StreamChecker::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_fopen)
+    II_fopen = &Ctx.Idents.get("fopen");
+  if (!II_tmpfile)
+    II_tmpfile = &Ctx.Idents.get("tmpfile");
+  if (!II_fclose)
+    II_fclose = &Ctx.Idents.get("fclose");
+  if (!II_fread)
+    II_fread = &Ctx.Idents.get("fread");
+  if (!II_fwrite)
+    II_fwrite = &Ctx.Idents.get("fwrite");
+  if (!II_fseek)
+    II_fseek = &Ctx.Idents.get("fseek");
+  if (!II_ftell)
+    II_ftell = &Ctx.Idents.get("ftell");
+  if (!II_rewind)
+    II_rewind = &Ctx.Idents.get("rewind");
+  if (!II_fgetpos)
+    II_fgetpos = &Ctx.Idents.get("fgetpos");
+  if (!II_fsetpos)
+    II_fsetpos = &Ctx.Idents.get("fsetpos");
+  if (!II_clearerr)
+    II_clearerr = &Ctx.Idents.get("clearerr");
+  if (!II_feof)
+    II_feof = &Ctx.Idents.get("feof");
+  if (!II_ferror)
+    II_ferror = &Ctx.Idents.get("ferror");
+  if (!II_fileno)
+    II_fileno = &Ctx.Idents.get("fileno");
+
+  if (FD->getIdentifier() == II_fopen) {
+    Fopen(C, CE);
+    return true;
+  }
+  if (FD->getIdentifier() == II_tmpfile) {
+    Tmpfile(C, CE);
+    return true;
+  }
+  if (FD->getIdentifier() == II_fclose) {
+    Fclose(C, CE);
+    return true;
+  }
+  if (FD->getIdentifier() == II_fread) {
+    Fread(C, CE);
+    return true;
+  }
+  if (FD->getIdentifier() == II_fwrite) {
+    Fwrite(C, CE);
+    return true;
+  }
+  if (FD->getIdentifier() == II_fseek) {
+    Fseek(C, CE);
+    return true;
+  }
+  if (FD->getIdentifier() == II_ftell) {
+    Ftell(C, CE);
+    return true;
+  }
+  if (FD->getIdentifier() == II_rewind) {
+    Rewind(C, CE);
+    return true;
+  }
+  if (FD->getIdentifier() == II_fgetpos) {
+    Fgetpos(C, CE);
+    return true;
+  }
+  if (FD->getIdentifier() == II_fsetpos) {
+    Fsetpos(C, CE);
+    return true;
+  }
+  if (FD->getIdentifier() == II_clearerr) {
+    Clearerr(C, CE);
+    return true;
+  }
+  if (FD->getIdentifier() == II_feof) {
+    Feof(C, CE);
+    return true;
+  }
+  if (FD->getIdentifier() == II_ferror) {
+    Ferror(C, CE);
+    return true;
+  }
+  if (FD->getIdentifier() == II_fileno) {
+    Fileno(C, CE);
+    return true;
+  }
+
+  return false;
+}
+
+void StreamChecker::Fopen(CheckerContext &C, const CallExpr *CE) {
+  OpenFileAux(C, CE);
+}
+
+void StreamChecker::Tmpfile(CheckerContext &C, const CallExpr *CE) {
+  OpenFileAux(C, CE);
+}
+
+void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
+  ValueManager &ValMgr = C.getValueManager();
+  DefinedSVal RetVal = cast<DefinedSVal>(ValMgr.getConjuredSymbolVal(0, CE, 
+                                                                     Count));
+  state = state->BindExpr(CE, RetVal);
+  
+  ConstraintManager &CM = C.getConstraintManager();
+  // Bifurcate the state into two: one with a valid FILE* pointer, the other
+  // with a NULL.
+  const GRState *stateNotNull, *stateNull;
+  llvm::tie(stateNotNull, stateNull) = CM.AssumeDual(state, RetVal);
+  
+  SymbolRef Sym = RetVal.getAsSymbol();
+  assert(Sym);
+
+  // if RetVal is not NULL, set the symbol's state to Opened.
+  stateNotNull = stateNotNull->set<StreamState>(Sym,StreamState::getOpened(CE));
+  stateNull = stateNull->set<StreamState>(Sym, StreamState::getOpenFailed(CE));
+
+  C.addTransition(stateNotNull);
+  C.addTransition(stateNull);
+}
+
+void StreamChecker::Fclose(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = CheckDoubleClose(CE, C.getState(), C);
+  if (state)
+    C.addTransition(state);
+}
+
+void StreamChecker::Fread(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  if (!CheckNullStream(state->getSVal(CE->getArg(3)), state, C))
+    return;
+}
+
+void StreamChecker::Fwrite(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  if (!CheckNullStream(state->getSVal(CE->getArg(3)), state, C))
+    return;
+}
+
+void StreamChecker::Fseek(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  if (!(state = CheckNullStream(state->getSVal(CE->getArg(0)), state, C)))
+    return;
+  // Check the legality of the 'whence' argument of 'fseek'.
+  SVal Whence = state->getSVal(CE->getArg(2));
+  bool WhenceIsLegal = true;
+  const nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Whence);
+  if (!CI)
+    WhenceIsLegal = false;
+
+  int64_t x = CI->getValue().getSExtValue();
+  if (!(x == 0 || x == 1 || x == 2))
+    WhenceIsLegal = false;
+
+  if (!WhenceIsLegal) {
+    if (ExplodedNode *N = C.GenerateSink(state)) {
+      if (!BT_illegalwhence)
+        BT_illegalwhence = new BuiltinBug("Illegal whence argument",
+                                     "The whence argument to fseek() should be "
+                                          "SEEK_SET, SEEK_END, or SEEK_CUR.");
+      BugReport *R = new BugReport(*BT_illegalwhence, 
+                                   BT_illegalwhence->getDescription(), N);
+      C.EmitReport(R);
+    }
+    return;
+  }
+
+  C.addTransition(state);
+}
+
+void StreamChecker::Ftell(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+    return;
+}
+
+void StreamChecker::Rewind(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+    return;
+}
+
+void StreamChecker::Fgetpos(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+    return;
+}
+
+void StreamChecker::Fsetpos(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+    return;
+}
+
+void StreamChecker::Clearerr(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+    return;
+}
+
+void StreamChecker::Feof(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+    return;
+}
+
+void StreamChecker::Ferror(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+    return;
+}
+
+void StreamChecker::Fileno(CheckerContext &C, const CallExpr *CE) {
+  const GRState *state = C.getState();
+  if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+    return;
+}
+
+const GRState *StreamChecker::CheckNullStream(SVal SV, const GRState *state,
+                                    CheckerContext &C) {
+  const DefinedSVal *DV = dyn_cast<DefinedSVal>(&SV);
+  if (!DV)
+    return 0;
+
+  ConstraintManager &CM = C.getConstraintManager();
+  const GRState *stateNotNull, *stateNull;
+  llvm::tie(stateNotNull, stateNull) = CM.AssumeDual(state, *DV);
+
+  if (!stateNotNull && stateNull) {
+    if (ExplodedNode *N = C.GenerateSink(stateNull)) {
+      if (!BT_nullfp)
+        BT_nullfp = new BuiltinBug("NULL stream pointer",
+                                     "Stream pointer might be NULL.");
+      BugReport *R =new BugReport(*BT_nullfp, BT_nullfp->getDescription(), N);
+      C.EmitReport(R);
+    }
+    return 0;
+  }
+  return stateNotNull;
+}
+
+const GRState *StreamChecker::CheckDoubleClose(const CallExpr *CE,
+                                               const GRState *state,
+                                               CheckerContext &C) {
+  SymbolRef Sym = state->getSVal(CE->getArg(0)).getAsSymbol();
+  assert(Sym);
+  
+  const StreamState *SS = state->get<StreamState>(Sym);
+
+  // If the file stream is not tracked, return.
+  if (!SS)
+    return state;
+  
+  // Check: Double close a File Descriptor could cause undefined behaviour.
+  // Conforming to man-pages
+  if (SS->isClosed()) {
+    ExplodedNode *N = C.GenerateSink();
+    if (N) {
+      if (!BT_doubleclose)
+        BT_doubleclose = new BuiltinBug("Double fclose",
+                                        "Try to close a file Descriptor already"
+                                        " closed. Cause undefined behaviour.");
+      BugReport *R = new BugReport(*BT_doubleclose,
+                                   BT_doubleclose->getDescription(), N);
+      C.EmitReport(R);
+    }
+    return NULL;
+  }
+  
+  // Close the File Descriptor.
+  return state->set<StreamState>(Sym, StreamState::getClosed(CE));
+}
+
+void StreamChecker::EvalDeadSymbols(CheckerContext &C,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 StreamState *SS = state->get<StreamState>(Sym);
+    if (!SS)
+      return;
+
+    if (SS->isOpened()) {
+      ExplodedNode *N = C.GenerateSink();
+      if (N) {
+        if (!BT_ResourceLeak)
+          BT_ResourceLeak = new BuiltinBug("Resource Leak", 
+                          "Opened File never closed. Potential Resource leak.");
+        BugReport *R = new BugReport(*BT_ResourceLeak, 
+                                     BT_ResourceLeak->getDescription(), N);
+        C.EmitReport(R);
+      }
+    }
+  }
+}
+
+void StreamChecker::EvalEndPath(GREndPathNodeBuilder &B, void *tag,
+                                GRExprEngine &Eng) {
+  SaveAndRestore<bool> OldHasGen(B.HasGeneratedNode);
+  const GRState *state = B.getState();
+  typedef llvm::ImmutableMap<SymbolRef, StreamState> SymMap;
+  SymMap M = state->get<StreamState>();
+  
+  for (SymMap::iterator I = M.begin(), E = M.end(); I != E; ++I) {
+    StreamState SS = I->second;
+    if (SS.isOpened()) {
+      ExplodedNode *N = B.generateNode(state, tag, B.getPredecessor());
+      if (N) {
+        if (!BT_ResourceLeak)
+          BT_ResourceLeak = new BuiltinBug("Resource Leak", 
+                          "Opened File never closed. Potential Resource leak.");
+        BugReport *R = new BugReport(*BT_ResourceLeak, 
+                                     BT_ResourceLeak->getDescription(), N);
+        Eng.getBugReporter().EmitReport(R);
+      }
+    }
+  }
+}
+
+void StreamChecker::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 StreamState *SS = state->get<StreamState>(Sym);
+  if(!SS)
+    return;
+
+  if (SS->isOpened())
+    state = state->set<StreamState>(Sym, StreamState::getEscaped(S));
+
+  C.addTransition(state);
+}
diff --git a/lib/Checker/SymbolManager.cpp b/lib/Checker/SymbolManager.cpp
index f3a803c..3b1bb6d 100644
--- a/lib/Checker/SymbolManager.cpp
+++ b/lib/Checker/SymbolManager.cpp
@@ -28,22 +28,22 @@
     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;
+    case BO_Mul: os << '*'  ; break;
+    case BO_Div: os << '/'  ; break;
+    case BO_Rem: os << '%'  ; break;
+    case BO_Add: os << '+'  ; break;
+    case BO_Sub: os << '-'  ; break;
+    case BO_Shl: os << "<<" ; break;
+    case BO_Shr: os << ">>" ; break;
+    case BO_LT:  os << "<"  ; break;
+    case BO_GT:  os << '>'  ; break;
+    case BO_LE:  os << "<=" ; break;
+    case BO_GE:  os << ">=" ; break;
+    case BO_EQ:  os << "==" ; break;
+    case BO_NE:  os << "!=" ; break;
+    case BO_And: os << '&'  ; break;
+    case BO_Xor: os << '^'  ; break;
+    case BO_Or:  os << '|'  ; break;
   }
 }
 
@@ -74,6 +74,15 @@
      << getParentSymbol() << ',' << getRegion() << '}';
 }
 
+void SymbolExtent::dumpToStream(llvm::raw_ostream& os) const {
+  os << "extent_$" << getSymbolID() << '{' << getRegion() << '}';
+}
+
+void SymbolMetadata::dumpToStream(llvm::raw_ostream& os) const {
+  os << "meta_$" << getSymbolID() << '{'
+     << getRegion() << ',' << T.getAsString() << '}';
+}
+
 void SymbolRegionValue::dumpToStream(llvm::raw_ostream& os) const {
   os << "reg_$" << getSymbolID() << "<" << R << ">";
 }
@@ -130,6 +139,40 @@
   return cast<SymbolDerived>(SD);
 }
 
+const SymbolExtent*
+SymbolManager::getExtentSymbol(const SubRegion *R) {
+  llvm::FoldingSetNodeID profile;
+  SymbolExtent::Profile(profile, R);
+  void* InsertPos;
+  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
+  if (!SD) {
+    SD = (SymExpr*) BPAlloc.Allocate<SymbolExtent>();
+    new (SD) SymbolExtent(SymbolCounter, R);
+    DataSet.InsertNode(SD, InsertPos);
+    ++SymbolCounter;
+  }
+
+  return cast<SymbolExtent>(SD);
+}
+
+const SymbolMetadata*
+SymbolManager::getMetadataSymbol(const MemRegion* R, const Stmt* S, QualType T,
+                                 unsigned Count, const void* SymbolTag) {
+
+  llvm::FoldingSetNodeID profile;
+  SymbolMetadata::Profile(profile, R, S, T, Count, SymbolTag);
+  void* InsertPos;
+  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
+  if (!SD) {
+    SD = (SymExpr*) BPAlloc.Allocate<SymbolMetadata>();
+    new (SD) SymbolMetadata(SymbolCounter, R, S, T, Count, SymbolTag);
+    DataSet.InsertNode(SD, InsertPos);
+    ++SymbolCounter;
+  }
+
+  return cast<SymbolMetadata>(SD);
+}
+
 const SymIntExpr *SymbolManager::getSymIntExpr(const SymExpr *lhs,
                                                BinaryOperator::Opcode op,
                                                const llvm::APSInt& v,
@@ -170,19 +213,35 @@
   return T;
 }
 
-
 QualType SymbolDerived::getType(ASTContext& Ctx) const {
-  return R->getValueType(Ctx);
+  return R->getValueType();
+}
+
+QualType SymbolExtent::getType(ASTContext& Ctx) const {
+  return Ctx.getSizeType();
+}
+
+QualType SymbolMetadata::getType(ASTContext&) const {
+  return T;
 }
 
 QualType SymbolRegionValue::getType(ASTContext& C) const {
-  return R->getValueType(C);
+  return R->getValueType();
 }
 
 SymbolManager::~SymbolManager() {}
 
 bool SymbolManager::canSymbolicate(QualType T) {
-  return Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType());
+  if (Loc::IsLocType(T))
+    return true;
+
+  if (T->isIntegerType())
+    return T->isScalarType();
+
+  if (T->isRecordType())
+    return true;
+
+  return false;
 }
 
 void SymbolReaper::markLive(SymbolRef sym) {
@@ -190,6 +249,11 @@
   TheDead.erase(sym);
 }
 
+void SymbolReaper::markInUse(SymbolRef sym) {
+  if (isa<SymbolMetadata>(sym))
+    MetadataInUse.insert(sym);
+}
+
 bool SymbolReaper::maybeDead(SymbolRef sym) {
   if (isLive(sym))
     return false;
@@ -198,6 +262,31 @@
   return true;
 }
 
+static bool IsLiveRegion(SymbolReaper &Reaper, const MemRegion *MR) {
+  MR = MR->getBaseRegion();
+
+  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
+    return Reaper.isLive(SR->getSymbol());
+
+  if (const VarRegion *VR = dyn_cast<VarRegion>(MR))
+    return Reaper.isLive(VR);
+
+  // FIXME: This is a gross over-approximation. What we really need is a way to
+  // tell if anything still refers to this region. Unlike SymbolicRegions,
+  // AllocaRegions don't have associated symbols, though, so we don't actually
+  // have a way to track their liveness.
+  if (isa<AllocaRegion>(MR))
+    return true;
+
+  if (isa<CXXThisRegion>(MR))
+    return true;
+
+  if (isa<MemSpaceRegion>(MR))
+    return true;
+
+  return false;
+}
+
 bool SymbolReaper::isLive(SymbolRef sym) {
   if (TheLiving.count(sym))
     return true;
@@ -210,22 +299,44 @@
     return false;
   }
 
+  if (const SymbolExtent *extent = dyn_cast<SymbolExtent>(sym)) {
+    if (IsLiveRegion(*this, extent->getRegion())) {
+      markLive(sym);
+      return true;
+    }
+    return false;
+  }
+
+  if (const SymbolMetadata *metadata = dyn_cast<SymbolMetadata>(sym)) {
+    if (MetadataInUse.count(sym)) {
+      if (IsLiveRegion(*this, metadata->getRegion())) {
+        markLive(sym);
+        MetadataInUse.erase(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* ExprVal) const {
+  return LCtx->getAnalysisContext()->getRelaxedLiveVariables()->
+      isLive(Loc, ExprVal);
 }
 
-bool SymbolReaper::isLive(const Stmt *Loc, const VarRegion *VR) const {
-  const StackFrameContext *SFC = VR->getStackFrame();
+bool SymbolReaper::isLive(const VarRegion *VR) const {
+  const StackFrameContext *VarContext = VR->getStackFrame();
+  const StackFrameContext *CurrentContext = LCtx->getCurrentStackFrame();
 
-  if (SFC == LCtx->getCurrentStackFrame())
-    return LCtx->getLiveVariables()->isLive(Loc, VR->getDecl());
-  else
-    return SFC->isParentOf(LCtx->getCurrentStackFrame());
+  if (VarContext == CurrentContext)
+    return LCtx->getAnalysisContext()->getRelaxedLiveVariables()->
+        isLive(Loc, VR->getDecl());
+
+  return VarContext->isParentOf(CurrentContext);
 }
 
 SymbolVisitor::~SymbolVisitor() {}
diff --git a/lib/Checker/UndefBranchChecker.cpp b/lib/Checker/UndefBranchChecker.cpp
index 9088345..1ff0641 100644
--- a/lib/Checker/UndefBranchChecker.cpp
+++ b/lib/Checker/UndefBranchChecker.cpp
@@ -29,27 +29,28 @@
 
     FindUndefExpr(GRStateManager& V, const GRState* S) : VM(V), St(S) {}
 
-    Expr* FindExpr(Expr* Ex) {
+    const Expr* FindExpr(const 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);
+      for (Stmt::const_child_iterator I = Ex->child_begin(), 
+                                      E = Ex->child_end();I!=E;++I)
+        if (const Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
+          const Expr* E2 = FindExpr(ExI);
           if (E2) return E2;
         }
 
       return Ex;
     }
 
-    bool MatchesCriteria(Expr* Ex) { return St->getSVal(Ex).isUndef(); }
+    bool MatchesCriteria(const Expr* Ex) { return St->getSVal(Ex).isUndef(); }
   };
 
 public:
   UndefBranchChecker() : BT(0) {}
   static void *getTag();
   void VisitBranchCondition(GRBranchNodeBuilder &Builder, GRExprEngine &Eng,
-                            Stmt *Condition, void *tag);
+                            const Stmt *Condition, void *tag);
 };
 
 }
@@ -65,7 +66,7 @@
 
 void UndefBranchChecker::VisitBranchCondition(GRBranchNodeBuilder &Builder, 
                                               GRExprEngine &Eng,
-                                              Stmt *Condition, void *tag) {
+                                              const Stmt *Condition, void *tag){
   const GRState *state = Builder.getState();
   SVal X = state->getSVal(Condition);
   if (X.isUndef()) {
@@ -81,7 +82,7 @@
       // 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());
+      const 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
diff --git a/lib/Checker/UnixAPIChecker.cpp b/lib/Checker/UnixAPIChecker.cpp
index e9b8f09..de7346d 100644
--- a/lib/Checker/UnixAPIChecker.cpp
+++ b/lib/Checker/UnixAPIChecker.cpp
@@ -100,7 +100,7 @@
   NonLoc ocreateFlag =
     cast<NonLoc>(C.getValueManager().makeIntVal(UC.Val_O_CREAT.getValue(),
                                                 oflagsEx->getType()));
-  SVal maskedFlagsUC = C.getSValuator().EvalBinOpNN(state, BinaryOperator::And,
+  SVal maskedFlagsUC = C.getSValuator().EvalBinOpNN(state, BO_And,
                                                     oflags, ocreateFlag,
                                                     oflagsEx->getType());
   if (maskedFlagsUC.isUnknownOrUndef())
diff --git a/lib/Checker/UnreachableCodeChecker.cpp b/lib/Checker/UnreachableCodeChecker.cpp
new file mode 100644
index 0000000..7a56c7f
--- /dev/null
+++ b/lib/Checker/UnreachableCodeChecker.cpp
@@ -0,0 +1,226 @@
+//==- UnreachableCodeChecker.cpp - Generalized dead code 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 implements a generalized unreachable code checker using a
+// path-sensitive analysis. We mark any path visited, and then walk the CFG as a
+// post-analysis to determine what was never visited.
+//
+// A similar flow-sensitive only check exists in Analysis/ReachableCode.cpp
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ParentMap.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Checker/PathSensitive/CheckerVisitor.h"
+#include "clang/Checker/PathSensitive/ExplodedGraph.h"
+#include "clang/Checker/PathSensitive/SVals.h"
+#include "clang/Checker/PathSensitive/CheckerHelpers.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "GRExprEngineExperimentalChecks.h"
+#include "llvm/ADT/SmallPtrSet.h"
+
+// The number of CFGBlock pointers we want to reserve memory for. This is used
+// once for each function we analyze.
+#define DEFAULT_CFGBLOCKS 256
+
+using namespace clang;
+
+namespace {
+class UnreachableCodeChecker : public CheckerVisitor<UnreachableCodeChecker> {
+public:
+  static void *getTag();
+  void VisitEndAnalysis(ExplodedGraph &G,
+                        BugReporter &B,
+                        GRExprEngine &Eng);
+private:
+  static inline const Stmt *getUnreachableStmt(const CFGBlock *CB);
+  void FindUnreachableEntryPoints(const CFGBlock *CB);
+  static bool isInvalidPath(const CFGBlock *CB, const ParentMap &PM);
+  static inline bool isEmptyCFGBlock(const CFGBlock *CB);
+
+  llvm::SmallSet<unsigned, DEFAULT_CFGBLOCKS> reachable;
+  llvm::SmallSet<unsigned, DEFAULT_CFGBLOCKS> visited;
+};
+}
+
+void *UnreachableCodeChecker::getTag() {
+  static int x = 0;
+  return &x;
+}
+
+void clang::RegisterUnreachableCodeChecker(GRExprEngine &Eng) {
+  Eng.registerCheck(new UnreachableCodeChecker());
+}
+
+void UnreachableCodeChecker::VisitEndAnalysis(ExplodedGraph &G,
+                                              BugReporter &B,
+                                              GRExprEngine &Eng) {
+  // Bail out if we didn't cover all paths
+  if (Eng.hasWorkRemaining())
+    return;
+
+  CFG *C = 0;
+  ParentMap *PM = 0;
+  // Iterate over ExplodedGraph
+  for (ExplodedGraph::node_iterator I = G.nodes_begin(), E = G.nodes_end();
+      I != E; ++I) {
+    const ProgramPoint &P = I->getLocation();
+    const LocationContext *LC = P.getLocationContext();
+
+    // Save the CFG if we don't have it already
+    if (!C)
+      C = LC->getAnalysisContext()->getUnoptimizedCFG();
+    if (!PM)
+      PM = &LC->getParentMap();
+
+    if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
+      const CFGBlock *CB = BE->getBlock();
+      reachable.insert(CB->getBlockID());
+    }
+  }
+
+  // Bail out if we didn't get the CFG or the ParentMap.
+  if (!C || !PM)
+    return;
+
+  ASTContext &Ctx = B.getContext();
+
+  // Find CFGBlocks that were not covered by any node
+  for (CFG::const_iterator I = C->begin(); I != C->end(); ++I) {
+    const CFGBlock *CB = *I;
+    // Check if the block is unreachable
+    if (reachable.count(CB->getBlockID()))
+      continue;
+
+    // Check if the block is empty (an artificial block)
+    if (isEmptyCFGBlock(CB))
+      continue;
+
+    // Find the entry points for this block
+    FindUnreachableEntryPoints(CB);
+
+    // This block may have been pruned; check if we still want to report it
+    if (reachable.count(CB->getBlockID()))
+      continue;
+
+    // Check for false positives
+    if (CB->size() > 0 && isInvalidPath(CB, *PM))
+      continue;
+
+    // Special case for __builtin_unreachable.
+    // FIXME: This should be extended to include other unreachable markers,
+    // such as llvm_unreachable.
+    if (!CB->empty()) {
+      const Stmt *First = CB->front();
+      if (const CallExpr *CE = dyn_cast<CallExpr>(First)) {
+        if (CE->isBuiltinCall(Ctx) == Builtin::BI__builtin_unreachable)
+          continue;
+      }
+    }
+
+    // We found a block that wasn't covered - find the statement to report
+    SourceRange SR;
+    SourceLocation SL;
+    if (const Stmt *S = getUnreachableStmt(CB)) {
+      SR = S->getSourceRange();
+      SL = S->getLocStart();
+      if (SR.isInvalid() || SL.isInvalid())
+        continue;
+    }
+    else
+      continue;
+
+    // Check if the SourceLocation is in a system header
+    const SourceManager &SM = B.getSourceManager();
+    if (SM.isInSystemHeader(SL) || SM.isInExternCSystemHeader(SL))
+      continue;
+
+    B.EmitBasicReport("Unreachable code", "Dead code", "This statement is never"
+        " executed", SL, SR);
+  }
+}
+
+// Recursively finds the entry point(s) for this dead CFGBlock.
+void UnreachableCodeChecker::FindUnreachableEntryPoints(const CFGBlock *CB) {
+  bool allPredecessorsReachable = true;
+
+  visited.insert(CB->getBlockID());
+
+  for (CFGBlock::const_pred_iterator I = CB->pred_begin(); I != CB->pred_end();
+      ++I) {
+    // Recurse over all unreachable blocks
+    if (!reachable.count((*I)->getBlockID())) {
+      // At least one predeccessor was unreachable
+      allPredecessorsReachable = false;
+
+      // Only visit the block once
+      if (!visited.count((*I)->getBlockID()))
+        FindUnreachableEntryPoints(*I);
+    }
+  }
+
+  // If at least one predecessor is unreachable, mark this block as reachable
+  // so we don't report this block.
+  if (!allPredecessorsReachable) {
+    reachable.insert(CB->getBlockID());
+  }
+}
+
+// Find the Stmt* in a CFGBlock for reporting a warning
+const Stmt *UnreachableCodeChecker::getUnreachableStmt(const CFGBlock *CB) {
+  if (CB->size() > 0)
+    return CB->front().getStmt();
+  else if (const Stmt *S = CB->getTerminator())
+    return S;
+  else
+    return 0;
+}
+
+// Determines if the path to this CFGBlock contained an element that infers this
+// block is a false positive. We assume that FindUnreachableEntryPoints has
+// already marked only the entry points to any dead code, so we need only to
+// find the condition that led to this block (the predecessor of this block.)
+// There will never be more than one predecessor.
+bool UnreachableCodeChecker::isInvalidPath(const CFGBlock *CB,
+                                           const ParentMap &PM) {
+  // We only expect a predecessor size of 0 or 1. If it is >1, then an external
+  // condition has broken our assumption (for example, a sink being placed by
+  // another check). In these cases, we choose not to report.
+  if (CB->pred_size() > 1)
+    return true;
+
+  // If there are no predecessors, then this block is trivially unreachable
+  if (CB->pred_size() == 0)
+    return false;
+
+  const CFGBlock *pred = *CB->pred_begin();
+
+  // Get the predecessor block's terminator conditon
+  const Stmt *cond = pred->getTerminatorCondition();
+
+  //assert(cond && "CFGBlock's predecessor has a terminator condition");
+  // The previous assertion is invalid in some cases (eg do/while). Leaving
+  // reporting of these situations on at the moment to help triage these cases.
+  if (!cond)
+    return false;
+
+  // Run each of the checks on the conditions
+  if (containsMacro(cond) || containsEnum(cond)
+      || containsStaticLocal(cond) || containsBuiltinOffsetOf(cond)
+      || containsStmt<SizeOfAlignOfExpr>(cond))
+    return true;
+
+  return false;
+}
+
+// Returns true if the given CFGBlock is empty
+bool UnreachableCodeChecker::isEmptyCFGBlock(const CFGBlock *CB) {
+  return CB->getLabel() == 0       // No labels
+      && CB->size() == 0           // No statements
+      && CB->getTerminator() == 0; // No terminator
+}
diff --git a/lib/Checker/VLASizeChecker.cpp b/lib/Checker/VLASizeChecker.cpp
index cea9d19..0800b8b 100644
--- a/lib/Checker/VLASizeChecker.cpp
+++ b/lib/Checker/VLASizeChecker.cpp
@@ -9,10 +9,13 @@
 //
 // This defines VLASizeChecker, a builtin check in GRExprEngine that 
 // performs checks for declaration of VLA of undefined or zero size.
+// In addition, VLASizeChecker is responsible for defining the extent
+// of the MemRegion that represents a VLA.
 //
 //===----------------------------------------------------------------------===//
 
 #include "GRExprEngineInternalChecks.h"
+#include "clang/AST/CharUnits.h"
 #include "clang/Checker/BugReporter/BugType.h"
 #include "clang/Checker/PathSensitive/CheckerVisitor.h"
 #include "clang/Checker/PathSensitive/GRExprEngine.h"
@@ -42,9 +45,9 @@
   const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
   if (!VD)
     return;
-  
-  const VariableArrayType *VLA
-    = C.getASTContext().getAsVariableArrayType(VD->getType());
+
+  ASTContext &Ctx = C.getASTContext();
+  const VariableArrayType *VLA = Ctx.getAsVariableArrayType(VD->getType());
   if (!VLA)
     return;
 
@@ -70,9 +73,14 @@
     C.EmitReport(report);
     return;
   }
+
+  // See if the size value is known. It can't be undefined because we would have
+  // warned about that already.
+  if (sizeV.isUnknown())
+    return;
   
   // Check if the size is zero.
-  DefinedOrUnknownSVal sizeD = cast<DefinedOrUnknownSVal>(sizeV);
+  DefinedSVal sizeD = cast<DefinedSVal>(sizeV);
 
   const GRState *stateNotZero, *stateZero;
   llvm::tie(stateNotZero, stateZero) = state->Assume(sizeD);
@@ -92,5 +100,36 @@
   }
  
   // From this point on, assume that the size is not zero.
-  C.addTransition(stateNotZero);
+  state = stateNotZero;
+
+  // VLASizeChecker is responsible for defining the extent of the array being
+  // declared. We do this by multiplying the array length by the element size,
+  // then matching that with the array region's extent symbol.
+
+  // Convert the array length to size_t.
+  ValueManager &ValMgr = C.getValueManager();
+  SValuator &SV = ValMgr.getSValuator();
+  QualType SizeTy = Ctx.getSizeType();
+  NonLoc ArrayLength = cast<NonLoc>(SV.EvalCast(sizeD, SizeTy, SE->getType()));
+
+  // Get the element size.
+  CharUnits EleSize = Ctx.getTypeSizeInChars(VLA->getElementType());
+  SVal EleSizeVal = ValMgr.makeIntVal(EleSize.getQuantity(), SizeTy);
+
+  // Multiply the array length by the element size.
+  SVal ArraySizeVal = SV.EvalBinOpNN(state, BO_Mul, ArrayLength,
+                                     cast<NonLoc>(EleSizeVal), SizeTy);
+
+  // Finally, Assume that the array's extent matches the given size.
+  const LocationContext *LC = C.getPredecessor()->getLocationContext();
+  DefinedOrUnknownSVal Extent = state->getRegion(VD, LC)->getExtent(ValMgr);
+  DefinedOrUnknownSVal ArraySize = cast<DefinedOrUnknownSVal>(ArraySizeVal);
+  DefinedOrUnknownSVal SizeIsKnown = SV.EvalEQ(state, Extent, ArraySize);
+  state = state->Assume(SizeIsKnown, true);
+
+  // Assume should not fail at this point.
+  assert(state);
+
+  // Remember our assumptions!
+  C.addTransition(state);
 }
diff --git a/lib/Checker/ValueManager.cpp b/lib/Checker/ValueManager.cpp
index aa0c3c8..8b7cd7b 100644
--- a/lib/Checker/ValueManager.cpp
+++ b/lib/Checker/ValueManager.cpp
@@ -72,7 +72,7 @@
 
 DefinedOrUnknownSVal 
 ValueManager::getRegionValueSymbolVal(const TypedRegion* R) {
-  QualType T = R->getValueType(SymMgr.getContext());
+  QualType T = R->getValueType();
 
   if (!SymbolManager::canSymbolicate(T))
     return UnknownVal();
@@ -117,11 +117,24 @@
   return nonloc::SymbolVal(sym);
 }
 
+DefinedSVal ValueManager::getMetadataSymbolVal(const void *SymbolTag,
+                                               const MemRegion *MR,
+                                               const Expr *E, QualType T,
+                                               unsigned Count) {
+  assert(SymbolManager::canSymbolicate(T) && "Invalid metadata symbol type");
+
+  SymbolRef sym = SymMgr.getMetadataSymbol(MR, 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());
+  QualType T = R->getValueType();
 
   if (!SymbolManager::canSymbolicate(T))
     return UnknownVal();
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h
index 1ab2f55..91b7742 100644
--- a/lib/CodeGen/ABIInfo.h
+++ b/lib/CodeGen/ABIInfo.h
@@ -11,66 +11,64 @@
 #define CLANG_CODEGEN_ABIINFO_H
 
 #include "clang/AST/Type.h"
-
-#include <cassert>
+#include "llvm/Type.h"
 
 namespace llvm {
-  class Type;
   class Value;
   class LLVMContext;
+  class TargetData;
 }
 
 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;
+    class CodeGenTypes;
   }
 
-  /* 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.
-  */
+  // 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.
+      /// Direct - Pass the argument directly using the normal converted LLVM
+      /// type, or by coercing to another specified type stored in
+      /// 'CoerceToType').  If an offset is specified (in UIntData), then the
+      /// argument passed is offset by some number of bytes in the memory
+      /// representation.
+      Direct,
 
-      Extend,    /// Valid only for integer argument types. Same as 'direct'
-                 /// but also emit a zero/sign extension attribute.
+      /// Extend - Valid only for integer argument types. Same as 'direct'
+      /// but also emit a zero/sign extension attribute.
+      Extend,
 
-      Indirect,  /// Pass the argument indirectly via a hidden pointer
-                 /// with the specified alignment (0 indicates default
-                 /// alignment).
+      /// Indirect - Pass the argument indirectly via a hidden pointer
+      /// with the specified alignment (0 indicates default alignment).
+      Indirect,
 
-      Ignore,    /// Ignore the argument (treat as void). Useful for
-                 /// void and empty structs.
+      /// Ignore - Ignore the argument (treat as void). Useful for void and
+      /// empty structs.
+      Ignore,
 
-      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.
+      /// 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.
+      Expand,
 
       KindFirst=Direct, KindLast=Expand
     };
 
   private:
     Kind TheKind;
-    const llvm::Type *TypeData;
+    llvm::PATypeHolder TypeData;
     unsigned UIntData;
     bool BoolData;
 
@@ -81,18 +79,15 @@
   public:
     ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
 
-    static ABIArgInfo getDirect() {
-      return ABIArgInfo(Direct);
+    static ABIArgInfo getDirect(const llvm::Type *T = 0, unsigned Offset = 0) {
+      return ABIArgInfo(Direct, T, Offset);
     }
-    static ABIArgInfo getExtend() {
-      return ABIArgInfo(Extend);
+    static ABIArgInfo getExtend(const llvm::Type *T = 0) {
+      return ABIArgInfo(Extend, T, 0);
     }
     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);
     }
@@ -104,16 +99,28 @@
     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
+    bool canHaveCoerceToType() const {
+      return TheKind == Direct || TheKind == Extend;
+    }
+    
+    // Direct/Extend accessors
+    unsigned getDirectOffset() const {
+      assert((isDirect() || isExtend()) && "Not a direct or extend kind");
+      return UIntData;
+    }
     const llvm::Type *getCoerceToType() const {
-      assert(TheKind == Coerce && "Invalid kind!");
+      assert(canHaveCoerceToType() && "Invalid kind!");
       return TypeData;
     }
-
+    
+    void setCoerceToType(const llvm::Type *T) {
+      assert(canHaveCoerceToType() && "Invalid kind!");
+      TypeData = T;
+    }
+    
     // Indirect accessors
     unsigned getIndirectAlign() const {
       assert(TheKind == Indirect && "Invalid kind!");
@@ -132,11 +139,16 @@
   /// passed or returned from functions.
   class ABIInfo {
   public:
+    CodeGen::CodeGenTypes &CGT;
+    
+    ABIInfo(CodeGen::CodeGenTypes &cgt) : CGT(cgt) {}
     virtual ~ABIInfo();
+    
+    ASTContext &getContext() const;
+    llvm::LLVMContext &getVMContext() const;
+    const llvm::TargetData &getTargetData() const;
 
-    virtual void computeInfo(CodeGen::CGFunctionInfo &FI,
-                             ASTContext &Ctx,
-                             llvm::LLVMContext &VMContext) const = 0;
+    virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0;
 
     /// EmitVAArg - Emit the target dependent code to load a value of
     /// \arg Ty from the va_list pointed to by \arg VAListAddr.
diff --git a/lib/CodeGen/Android.mk b/lib/CodeGen/Android.mk
index e590f71..4a8d40e 100644
--- a/lib/CodeGen/Android.mk
+++ b/lib/CodeGen/Android.mk
@@ -6,9 +6,16 @@
 include $(CLEAR_TBLGEN_VARS)
 
 TBLGEN_TABLES :=    \
-    DiagnosticCommonKinds.inc
+	AttrList.inc	\
+	Attrs.inc	\
+	DeclNodes.inc	\
+	DiagnosticCommonKinds.inc	\
+	DiagnosticFrontendKinds.inc	\
+	StmtNodes.inc	\
+	arm_neon.inc
 
 clang_codegen_SRC_FILES :=	\
+	BackendUtil.cpp	\
 	CGBlocks.cpp	\
 	CGBuiltin.cpp	\
 	CGCXX.cpp	\
@@ -33,10 +40,13 @@
 	CGTemporaries.cpp	\
 	CGVTT.cpp	\
 	CGVTables.cpp	\
+	CodeGenAction.cpp	\
 	CodeGenFunction.cpp	\
 	CodeGenModule.cpp	\
 	CodeGenTypes.cpp	\
+	ItaniumCXXABI.cpp	\
 	Mangle.cpp	\
+	MicrosoftCXXABI.cpp	\
 	ModuleBuilder.cpp	\
 	TargetInfo.cpp
 
@@ -45,6 +55,7 @@
 LOCAL_MODULE:= libclangCodeGen
 
 include $(CLANG_HOST_BUILD_MK)
+include $(CLANG_VERSION_INC_MK)
 include $(CLANG_TBLGEN_RULES_MK)
 include $(LLVM_GEN_INTRINSICS_MK)
 include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
new file mode 100644
index 0000000..69efe43
--- /dev/null
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -0,0 +1,339 @@
+//===--- BackendUtil.cpp - LLVM Backend Utilities -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CodeGen/BackendUtil.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/Frontend/CodeGenOptions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Assembly/PrintModulePass.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/CodeGen/RegAllocRegistry.h"
+#include "llvm/CodeGen/SchedulerRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/StandardPasses.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.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 {
+
+class EmitAssemblyHelper {
+  Diagnostic &Diags;
+  const CodeGenOptions &CodeGenOpts;
+  const TargetOptions &TargetOpts;
+  Module *TheModule;
+
+  Timer CodeGenerationTime;
+
+  mutable FunctionPassManager *CodeGenPasses;
+  mutable PassManager *PerModulePasses;
+  mutable FunctionPassManager *PerFunctionPasses;
+
+private:
+  FunctionPassManager *getCodeGenPasses() const {
+    if (!CodeGenPasses) {
+      CodeGenPasses = new FunctionPassManager(TheModule);
+      CodeGenPasses->add(new TargetData(TheModule));
+    }
+    return CodeGenPasses;
+  }
+
+  PassManager *getPerModulePasses() const {
+    if (!PerModulePasses) {
+      PerModulePasses = new PassManager();
+      PerModulePasses->add(new TargetData(TheModule));
+    }
+    return PerModulePasses;
+  }
+
+  FunctionPassManager *getPerFunctionPasses() const {
+    if (!PerFunctionPasses) {
+      PerFunctionPasses = new FunctionPassManager(TheModule);
+      PerFunctionPasses->add(new TargetData(TheModule));
+    }
+    return PerFunctionPasses;
+  }
+
+  void CreatePasses();
+
+  /// AddEmitPasses - Add passes necessary to emit assembly or LLVM IR.
+  ///
+  /// \return True on success.
+  bool AddEmitPasses(BackendAction Action, formatted_raw_ostream &OS);
+
+public:
+  EmitAssemblyHelper(Diagnostic &_Diags,
+                     const CodeGenOptions &CGOpts, const TargetOptions &TOpts,
+                     Module *M)
+    : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts),
+      TheModule(M), CodeGenerationTime("Code Generation Time"),
+      CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {}
+
+  ~EmitAssemblyHelper() {
+    delete CodeGenPasses;
+    delete PerModulePasses;
+    delete PerFunctionPasses;
+  }
+
+  void EmitAssembly(BackendAction Action, raw_ostream *OS);
+};
+
+}
+
+void EmitAssemblyHelper::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.
+  llvm::createStandardModulePasses(getPerModulePasses(), OptLevel,
+                                   CodeGenOpts.OptimizeSize,
+                                   CodeGenOpts.UnitAtATime,
+                                   CodeGenOpts.UnrollLoops,
+                                   CodeGenOpts.SimplifyLibCalls,
+                                   /*HaveExceptions=*/true,
+                                   InliningPass);
+}
+
+bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action,
+                                       formatted_raw_ostream &OS) {
+  // 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.
+
+  // Set frame pointer elimination mode.
+  if (!CodeGenOpts.DisableFPElim) {
+    llvm::NoFramePointerElim = false;
+    llvm::NoFramePointerElimNonLeaf = false;
+  } else if (CodeGenOpts.OmitLeafFramePointer) {
+    llvm::NoFramePointerElim = false;
+    llvm::NoFramePointerElimNonLeaf = true;
+  } else {
+    llvm::NoFramePointerElim = true;
+    llvm::NoFramePointerElimNonLeaf = true;
+  }
+
+  // Set float ABI type.
+  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);
+
+  if (CodeGenOpts.RelaxAll)
+    TM->setMCRelaxAll(true);
+
+  // Create the code generator passes.
+  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;
+  }
+
+  // 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;
+  else if (Action == Backend_EmitMCNull)
+    CGFT = TargetMachine::CGFT_Null;
+  else
+    assert(Action == Backend_EmitAssembly && "Invalid action!");
+  if (TM->addPassesToEmitFile(*PM, OS, CGFT, OptLevel,
+                              /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
+    Diags.Report(diag::err_fe_unable_to_interface_with_target);
+    return false;
+  }
+
+  return true;
+}
+
+void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) {
+  TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : 0);
+  llvm::formatted_raw_ostream FormattedOS;
+
+  CreatePasses();
+  switch (Action) {
+  case Backend_EmitNothing:
+    break;
+
+  case Backend_EmitBC:
+    getPerModulePasses()->add(createBitcodeWriterPass(*OS));
+    break;
+
+  case Backend_EmitLL:
+    FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM);
+    getPerModulePasses()->add(createPrintModulePass(&FormattedOS));
+    break;
+
+  default:
+    FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM);
+    if (!AddEmitPasses(Action, FormattedOS))
+      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 = TheModule->begin(),
+           E = TheModule->end(); I != E; ++I)
+      if (!I->isDeclaration())
+        PerFunctionPasses->run(*I);
+    PerFunctionPasses->doFinalization();
+  }
+
+  if (PerModulePasses) {
+    PrettyStackTraceString CrashInfo("Per-module optimization passes");
+    PerModulePasses->run(*TheModule);
+  }
+
+  if (CodeGenPasses) {
+    PrettyStackTraceString CrashInfo("Code generation");
+
+    CodeGenPasses->doInitialization();
+    for (Module::iterator I = TheModule->begin(),
+           E = TheModule->end(); I != E; ++I)
+      if (!I->isDeclaration())
+        CodeGenPasses->run(*I);
+    CodeGenPasses->doFinalization();
+  }
+}
+
+void clang::EmitBackendOutput(Diagnostic &Diags, const CodeGenOptions &CGOpts,
+                              const TargetOptions &TOpts, Module *M,
+                              BackendAction Action, raw_ostream *OS) {
+  EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, M);
+
+  AsmHelper.EmitAssembly(Action, OS);
+}
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 2997b21..04f1ef2 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -24,10 +24,22 @@
 using namespace clang;
 using namespace CodeGen;
 
+CGBlockInfo::CGBlockInfo(const char *N)
+  : Name(N), CXXThisRef(0), NeedsObjCSelf(false) {
+    
+  // Skip asm prefix, if any.
+  if (Name && Name[0] == '\01')
+    ++Name;
+}
+
+
 llvm::Constant *CodeGenFunction::
-BuildDescriptorBlockDecl(const BlockExpr *BE, bool BlockHasCopyDispose, CharUnits Size,
+BuildDescriptorBlockDecl(const BlockExpr *BE, const CGBlockInfo &Info,
                          const llvm::StructType* Ty,
+                         llvm::Constant *BlockVarLayout,
                          std::vector<HelperInfo> *NoteForHelper) {
+  bool BlockHasCopyDispose = Info.BlockHasCopyDispose;
+  CharUnits Size = Info.BlockSize;
   const llvm::Type *UnsignedLongTy
     = CGM.getTypes().ConvertType(getContext().UnsignedLongTy);
   llvm::Constant *C;
@@ -61,7 +73,8 @@
           CGM.GetAddrOfConstantCString(BlockTypeEncoding), PtrToInt8Ty));
   
   // Layout.
-  C = llvm::ConstantInt::get(UnsignedLongTy, 0);
+  C = BlockVarLayout;
+    
   Elts.push_back(C);
 
   C = llvm::ConstantStruct::get(VMContext, Elts, false);
@@ -72,72 +85,101 @@
   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) {
+static void CollectBlockDeclRefInfo(const Stmt *S, CGBlockInfo &Info) {
   for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
        I != E; ++I)
     if (*I)
-      CollectBlockDeclRefInfo(*I, Info, InnerContexts);
+      CollectBlockDeclRefInfo(*I, Info);
 
   // 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);
+    Info.InnerBlocks.insert(BE->getBlockDecl());
+    CollectBlockDeclRefInfo(BE->getBody(), Info);
   }
 
-  if (const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {
+  else if (const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {
+    const ValueDecl *D = BDRE->getDecl();
     // FIXME: Handle enums.
-    if (isa<FunctionDecl>(BDRE->getDecl()))
+    if (isa<FunctionDecl>(D))
       return;
 
+    if (isa<ImplicitParamDecl>(D) &&
+        isa<ObjCMethodDecl>(D->getDeclContext()) &&
+        cast<ObjCMethodDecl>(D->getDeclContext())->getSelfDecl() == D) {
+      Info.NeedsObjCSelf = true;
+      return;
+    }
+
     // Only Decls that escape are added.
-    if (!InnerContexts.count(BDRE->getDecl()->getDeclContext()))
+    if (!Info.InnerBlocks.count(D->getDeclContext()))
       Info.DeclRefs.push_back(BDRE);
   }
+
+  // Make sure to capture implicit 'self' references due to super calls.
+  else if (const ObjCMessageExpr *E = dyn_cast<ObjCMessageExpr>(S)) {
+    if (E->getReceiverKind() == ObjCMessageExpr::SuperClass || 
+        E->getReceiverKind() == ObjCMessageExpr::SuperInstance)
+      Info.NeedsObjCSelf = true;
+  }
+
+  // Getter/setter uses may also cause implicit super references,
+  // which we can check for with:
+  else if (isa<ObjCSuperExpr>(S))
+    Info.NeedsObjCSelf = true;
+
+  else if (isa<CXXThisExpr>(S))
+    Info.CXXThisRef = cast<CXXThisExpr>(S);
 }
 
-/// CanBlockBeGlobal - Given a BlockInfo struct, determines if a block can be
+/// CanBlockBeGlobal - Given a CGBlockInfo struct, determines if a block can be
 /// declared as a global variable instead of on the stack.
-static bool CanBlockBeGlobal(const CodeGenFunction::BlockInfo &Info) {
+static bool CanBlockBeGlobal(const CGBlockInfo &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.
+static void AllocateAllBlockDeclRefs(CodeGenFunction &CGF, CGBlockInfo &Info) {
+  if (Info.CXXThisRef)
+    CGF.AllocateBlockCXXThisPointer(Info.CXXThisRef);
 
   for (size_t i = 0; i < Info.DeclRefs.size(); ++i)
-    CGF->AllocateBlockDecl(Info.DeclRefs[i]);
+    CGF.AllocateBlockDecl(Info.DeclRefs[i]);
+
+  if (Info.NeedsObjCSelf) {
+    ValueDecl *Self = cast<ObjCMethodDecl>(CGF.CurFuncDecl)->getSelfDecl();
+    BlockDeclRefExpr *BDRE =
+      new (CGF.getContext()) BlockDeclRefExpr(Self, Self->getType(),
+                                              SourceLocation(), false);
+    Info.DeclRefs.push_back(BDRE);
+    CGF.AllocateBlockDecl(BDRE);
+  }
+}
+
+static unsigned computeBlockFlag(CodeGenModule &CGM,
+                                 const BlockExpr *BE, unsigned 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 |= CodeGenFunction::BLOCK_USE_STRET;
+  return flags;
 }
 
 // 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);
+  CGBlockInfo Info(Name.c_str());
+  Info.InnerBlocks.insert(BE->getBlockDecl());
+  CollectBlockDeclRefInfo(BE->getBody(), Info);
 
   // Check if the block can be global.
   // FIXME: This test doesn't work for nested blocks yet.  Longer term, I'd like
@@ -154,29 +196,23 @@
   llvm::Value *V;
 
   {
+    llvm::Constant *BlockVarLayout;
     // 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;
+      = CodeGenFunction(CGM).GenerateBlockFunction(CurGD, BE, Info, CurFuncDecl,
+                                                   BlockVarLayout,
+                                                   LocalDeclMap);
+    BlockHasCopyDispose |= Info.BlockHasCopyDispose;
     Elts[3] = Fn;
 
     // FIXME: Don't use BlockHasCopyDispose, it is set more often then
     // necessary, for example: { ^{ __block int i; ^{ i = 1; }(); }(); }
-    if (subBlockHasCopyDispose)
+    if (Info.BlockHasCopyDispose)
       flags |= BLOCK_HAS_COPY_DISPOSE;
 
     // __isa
@@ -185,18 +221,7 @@
     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;
-    }
+    flags = computeBlockFlag(CGM, BE, flags);
     const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
       CGM.getTypes().ConvertType(CGM.getContext().IntTy));
     C = llvm::ConstantInt::get(IntTy, flags);
@@ -206,10 +231,10 @@
     C = llvm::ConstantInt::get(IntTy, 0);
     Elts[2] = C;
 
-    if (subBlockDeclRefDecls.size() == 0) {
+    if (Info.BlockLayout.empty()) {
       // __descriptor
-      Elts[4] = BuildDescriptorBlockDecl(BE, subBlockHasCopyDispose, subBlockSize,
-                                         0, 0);
+      C = llvm::Constant::getNullValue(PtrToInt8Ty);
+      Elts[4] = BuildDescriptorBlockDecl(BE, Info, 0, C, 0);
 
       // Optimize to being a global block.
       Elts[0] = CGM.getNSConcreteGlobalBlock();
@@ -227,123 +252,144 @@
       return C;
     }
 
-    std::vector<const llvm::Type *> Types(BlockFields+subBlockDeclRefDecls.size());
+    std::vector<const llvm::Type *> Types(BlockFields+Info.BlockLayout.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];
+    for (unsigned i = 0, n = Info.BlockLayout.size(); i != n; ++i) {
+      const Expr *E = Info.BlockLayout[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] = 
+          llvm::PointerType::get(BuildByRefType(BDRE->getDecl()), 0);
+      } else if (BDRE && BDRE->getDecl()->getType()->isReferenceType()) {
+         Types[i+BlockFields] = llvm::PointerType::get(ConvertType(Ty), 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());
+    A->setAlignment(Info.BlockAlign.getQuantity());
     V = A;
 
-    std::vector<HelperInfo> NoteForHelper(subBlockDeclRefDecls.size());
-    int helpersize = 0;
+    // Build layout / cleanup information for all the data entries in the
+    // layout, and write the enclosing fields into the type.
+    std::vector<HelperInfo> NoteForHelper(Info.BlockLayout.size());
+    unsigned NumHelpers = 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;
+    for (unsigned i=0; i < Info.BlockLayout.size(); ++i) {
+      const Expr *E = Info.BlockLayout[i];
 
-        DR = dyn_cast<DeclRefExpr>(E);
-        // Skip padding.
-        if (DR) continue;
+      // Skip padding.
+      if (isa<DeclRefExpr>(E)) continue;
 
-        BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
-        VD = BDRE->getDecl();
+      llvm::Value* Addr = Builder.CreateStructGEP(V, i+BlockFields, "tmp");
+      HelperInfo &Note = NoteForHelper[NumHelpers++];
 
-        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);
+      Note.index = i+5;
 
-        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;
+      if (isa<CXXThisExpr>(E)) {
+        Note.RequiresCopying = false;
+        Note.flag = BLOCK_FIELD_IS_OBJECT;
 
-        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.
+        Builder.CreateStore(LoadCXXThis(), Addr);
+        continue;
       }
-    NoteForHelper.resize(helpersize);
+
+      const BlockDeclRefExpr *BDRE = cast<BlockDeclRefExpr>(E);
+      const ValueDecl *VD = BDRE->getDecl();
+      QualType T = VD->getType();
+
+      Note.RequiresCopying = BlockRequiresCopying(T);
+
+      if (BDRE->isByRef()) {
+        Note.flag = BLOCK_FIELD_IS_BYREF;
+        if (T.isObjCGCWeak())
+          Note.flag |= BLOCK_FIELD_IS_WEAK;
+      } else if (T->isBlockPointerType()) {
+        Note.flag = BLOCK_FIELD_IS_BLOCK;
+      } else {
+        Note.flag = BLOCK_FIELD_IS_OBJECT;
+      }
+
+      if (LocalDeclMap[VD]) {
+        if (BDRE->isByRef()) {
+          llvm::Value *Loc = LocalDeclMap[VD];
+          Loc = Builder.CreateStructGEP(Loc, 1, "forwarding");
+          Loc = Builder.CreateLoad(Loc);
+          Builder.CreateStore(Loc, Addr);
+          continue;
+        } else {
+          if (BDRE->getCopyConstructorExpr()) {
+            E = BDRE->getCopyConstructorExpr();
+            PushDestructorCleanup(E->getType(), Addr);
+          }
+            else {
+              E = new (getContext()) DeclRefExpr(const_cast<ValueDecl*>(VD),
+                                            VD->getType().getNonReferenceType(),
+                                            SourceLocation());
+              if (VD->getType()->isReferenceType()) {
+                E = new (getContext())
+                    UnaryOperator(const_cast<Expr*>(E), UO_AddrOf,
+                                getContext().getPointerType(E->getType()),
+                                SourceLocation());
+              } 
+            }
+          }
+        }
+
+      if (BDRE->isByRef()) {
+        E = new (getContext())
+          UnaryOperator(const_cast<Expr*>(E), UO_AddrOf,
+                        getContext().getPointerType(E->getType()),
+                        SourceLocation());
+      }
+
+      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(Int64Ty, 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(NumHelpers);
 
     // __descriptor
-    llvm::Value *Descriptor = BuildDescriptorBlockDecl(BE,
-                                                       subBlockHasCopyDispose,
-                                                       subBlockSize, Ty,
+    llvm::Value *Descriptor = BuildDescriptorBlockDecl(BE, Info, Ty,
+                                                       BlockVarLayout,
                                                        &NoteForHelper);
     Descriptor = Builder.CreateBitCast(Descriptor, PtrToInt8Ty);
     Builder.CreateStore(Descriptor, Builder.CreateStructGEP(V, 4, "block.tmp"));
@@ -487,13 +533,25 @@
   return EmitCall(FnInfo, Func, ReturnValue, Args);
 }
 
-CharUnits CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) {
+void CodeGenFunction::AllocateBlockCXXThisPointer(const CXXThisExpr *E) {
+  assert(BlockCXXThisOffset.isZero() && "already computed 'this' pointer");
+
+  // Figure out what the offset is.
+  QualType T = E->getType();
+  std::pair<CharUnits,CharUnits> TypeInfo = getContext().getTypeInfoInChars(T);
+  CharUnits Offset = getBlockOffset(TypeInfo.first, TypeInfo.second);
+
+  BlockCXXThisOffset = Offset;
+  BlockLayout.push_back(E);
+}
+
+void CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) {
   const ValueDecl *VD = E->getDecl();
-  CharUnits &offset = BlockDecls[VD];
+  CharUnits &Offset = BlockDecls[VD];
 
   // See if we have already allocated an offset for this variable.
-  if (offset.isPositive())
-    return offset;
+  if (!Offset.isZero())
+    return;
 
   // Don't run the expensive check, unless we have to.
   if (!BlockHasCopyDispose)
@@ -501,23 +559,34 @@
         || BlockRequiresCopying(E->getType()))
       BlockHasCopyDispose = true;
 
-  // if not, allocate one now.
-  offset = getBlockOffset(E);
+  const ValueDecl *D = cast<ValueDecl>(E->getDecl());
 
-  return offset;
+  CharUnits Size;
+  CharUnits Align;
+
+  if (E->isByRef()) {
+    llvm::tie(Size,Align) =
+      getContext().getTypeInfoInChars(getContext().VoidPtrTy);
+  } else {
+    Size = getContext().getTypeSizeInChars(D->getType());
+    Align = getContext().getDeclAlign(D);
+  }
+
+  Offset = getBlockOffset(Size, Align);
+  BlockLayout.push_back(E);
 }
 
-llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) {
-  const ValueDecl *VD = E->getDecl();
-  CharUnits offset = AllocateBlockDecl(E);
+llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const ValueDecl *VD,
+                                                 bool IsByRef) {
   
+  CharUnits offset = BlockDecls[VD];
+  assert(!offset.isZero() && "getting address of unallocated decl");
 
   llvm::Value *BlockLiteral = LoadBlockStruct();
   llvm::Value *V = Builder.CreateGEP(BlockLiteral,
-                       llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
-                                                         offset.getQuantity()),
+                       llvm::ConstantInt::get(Int64Ty, offset.getQuantity()),
                                      "block.literal");
-  if (E->isByRef()) {
+  if (IsByRef) {
     const llvm::Type *PtrStructTy
       = llvm::PointerType::get(BuildByRefType(VD), 0);
     // The block literal will need a copy/destroy helper.
@@ -532,28 +601,18 @@
     V = Builder.CreateBitCast(V, PtrStructTy);
     V = Builder.CreateStructGEP(V, getByRefValueLLVMField(VD), 
                                 VD->getNameAsString());
+    if (VD->getType()->isReferenceType())
+      V = Builder.CreateLoad(V);
   } else {
     const llvm::Type *Ty = CGM.getTypes().ConvertType(VD->getType());
-
     Ty = llvm::PointerType::get(Ty, 0);
     V = Builder.CreateBitCast(V, Ty);
+    if (VD->getType()->isReferenceType())
+      V = Builder.CreateLoad(V, "ref.tmp");
   }
   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.
@@ -598,27 +657,24 @@
 
   std::vector<llvm::Constant*> LiteralFields(FieldCount);
 
-  CodeGenFunction::BlockInfo Info(0, n);
-  CharUnits subBlockSize; 
-  CharUnits subBlockAlign;
-  llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls;
-  bool subBlockHasCopyDispose = false;
+  CGBlockInfo Info(n);
+  llvm::Constant *BlockVarLayout;
   llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
   llvm::Function *Fn
-    = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, 0, LocalDeclMap,
-                                                 subBlockSize,
-                                                 subBlockAlign,
-                                                 subBlockDeclRefDecls,
-                                                 subBlockHasCopyDispose);
-  assert(subBlockSize == BlockLiteralSize
+    = CodeGenFunction(CGM).GenerateBlockFunction(GlobalDecl(), BE, 
+                                                 Info, 0, BlockVarLayout,
+                                                 LocalDeclMap);
+  assert(Info.BlockSize == BlockLiteralSize
          && "no imports allowed for global block");
 
   // isa
-  LiteralFields[0] = getNSConcreteGlobalBlock();
+  LiteralFields[0] = CGM.getNSConcreteGlobalBlock();
 
-  // Flags
+  // __flags
+  unsigned flags = computeBlockFlag(CGM, BE,
+                                    (BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE));
   LiteralFields[1] =
-    llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE);
+    llvm::ConstantInt::get(IntTy, flags);
 
   // Reserved
   LiteralFields[2] = llvm::Constant::getNullValue(IntTy);
@@ -648,14 +704,11 @@
 }
 
 llvm::Function *
-CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr,
-                                       const BlockInfo& Info,
+CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, const BlockExpr *BExpr,
+                                       CGBlockInfo &Info,
                                        const Decl *OuterFuncDecl,
-                                  llvm::DenseMap<const Decl*, llvm::Value*> ldm,
-                                       CharUnits &Size,
-                                       CharUnits &Align,
-                       llvm::SmallVector<const Expr *, 8> &subBlockDeclRefDecls,
-                                       bool &subBlockHasCopyDispose) {
+                                       llvm::Constant *& BlockVarLayout,
+                                  llvm::DenseMap<const Decl*, llvm::Value*> ldm) {
 
   // Check if we should generate debug info for this block.
   if (CGM.getDebugInfo())
@@ -669,7 +722,7 @@
        ++i) {
     const VarDecl *VD = dyn_cast<VarDecl>(i->first);
 
-    if (VD->getStorageClass() == VarDecl::Static || VD->hasExternalStorage())
+    if (VD->getStorageClass() == SC_Static || VD->hasExternalStorage())
       LocalDeclMap[VD] = i->second;
   }
 
@@ -699,14 +752,21 @@
 
   IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor");
 
-  // Allocate all BlockDeclRefDecls, so we can calculate the right ParmTy below.
-  AllocateAllBlockDeclRefs(Info, this);
+  // Build the block struct now.
+  AllocateAllBlockDeclRefs(*this, Info);
 
+  // Capture block layout info. here.
+  if (CGM.getContext().getLangOptions().ObjC1)
+    BlockVarLayout = CGM.getObjCRuntime().GCBlockLayout(*this, Info.DeclRefs);
+  else
+    BlockVarLayout = llvm::Constant::getNullValue(PtrToInt8Ty);
+  
   QualType ParmTy = getContext().getBlockParmType(BlockHasCopyDispose,
-                                                  BlockDeclRefDecls);
+                                                  BlockLayout);
+
   // FIXME: This leaks
   ImplicitParamDecl *SelfDecl =
-    ImplicitParamDecl::Create(getContext(), 0,
+    ImplicitParamDecl::Create(getContext(), const_cast<BlockDecl*>(BD),
                               SourceLocation(), II,
                               ParmTy);
 
@@ -723,18 +783,69 @@
   CodeGenTypes &Types = CGM.getTypes();
   const llvm::FunctionType *LTy = Types.GetFunctionType(FI, IsVariadic);
 
+  MangleBuffer Name;
+  CGM.getMangledName(GD, Name, BD);
   llvm::Function *Fn =
-    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
-                           llvm::Twine("__") + Info.Name + "_block_invoke_",
-                           &CGM.getModule());
+    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, 
+                           Name.getString(), &CGM.getModule());
 
   CGM.SetInternalFunctionAttributes(BD, Fn, FI);
-
   StartFunction(BD, ResultType, Fn, Args,
                 BExpr->getBody()->getLocEnd());
-
+  
   CurFuncDecl = OuterFuncDecl;
-  CurCodeDecl = BD;
+  
+  QualType FnType(BlockFunctionType, 0);
+  bool HasPrototype = isa<FunctionProtoType>(BlockFunctionType);
+  
+  IdentifierInfo *ID = &getContext().Idents.get(Name.getString());
+  CurCodeDecl = FunctionDecl::Create(getContext(),
+                                     getContext().getTranslationUnitDecl(),
+                                     SourceLocation(), ID, FnType, 
+                                     0,
+                                     SC_Static,
+                                     SC_None,
+                                     false, HasPrototype);
+  if (FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FnType)) {
+    const FunctionDecl *CFD = dyn_cast<FunctionDecl>(CurCodeDecl);
+    FunctionDecl *FD = const_cast<FunctionDecl *>(CFD);
+    llvm::SmallVector<ParmVarDecl*, 16> Params;
+    for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i)
+      Params.push_back(ParmVarDecl::Create(getContext(), FD, 
+                                           SourceLocation(), 0,
+                                           FT->getArgType(i), /*TInfo=*/0,
+                                           SC_None, SC_None, 0));
+    FD->setParams(Params.data(), Params.size());
+  }
+  
+  
+  // If we have a C++ 'this' reference, go ahead and force it into
+  // existence now.
+  if (Info.CXXThisRef) {
+    assert(!BlockCXXThisOffset.isZero() &&
+           "haven't yet allocated 'this' reference");
+
+    // TODO: I have a dream that one day this will be typed.
+    llvm::Value *BlockLiteral = LoadBlockStruct();
+    llvm::Value *ThisPtrRaw =
+      Builder.CreateConstInBoundsGEP1_64(BlockLiteral,
+                                         BlockCXXThisOffset.getQuantity(),
+                                         "this.ptr.raw");
+
+    const llvm::Type *Ty =
+      CGM.getTypes().ConvertType(Info.CXXThisRef->getType());
+    Ty = llvm::PointerType::get(Ty, 0);  
+    llvm::Value *ThisPtr = Builder.CreateBitCast(ThisPtrRaw, Ty, "this.ptr");
+
+    CXXThisValue = Builder.CreateLoad(ThisPtr, "this");
+  }
+
+  // If we have an Objective C 'self' reference, go ahead and force it
+  // into existence now.
+  if (Info.NeedsObjCSelf) {
+    ValueDecl *Self = cast<ObjCMethodDecl>(CurFuncDecl)->getSelfDecl();
+    LocalDeclMap[Self] = GetAddrOfBlockDecl(Self, false);
+  }
 
   // Save a spot to insert the debug information for all the BlockDeclRefDecls.
   llvm::BasicBlock *entry = Builder.GetInsertBlock();
@@ -752,9 +863,10 @@
 
   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])) {
+    // FIXME: also for 'this'
+    for (unsigned i = 0, e = BlockLayout.size(); i != e; ++i) {
+      if (const BlockDeclRefExpr *BDRE =
+            dyn_cast<BlockDeclRefExpr>(BlockLayout[i])) {
         const ValueDecl *D = BDRE->getDecl();
         DI->setLocation(D->getLocation());
         DI->EmitDeclareOfBlockDeclRefVariable(BDRE,
@@ -777,25 +889,15 @@
       llvm::RoundUpToAlignment(BlockOffset.getQuantity(), 
                                MinAlign.getQuantity()));
 
-  Size = BlockOffset;
-  Align = BlockAlign;
-  subBlockDeclRefDecls = BlockDeclRefDecls;
-  subBlockHasCopyDispose |= BlockHasCopyDispose;
+  Info.BlockSize = BlockOffset;
+  Info.BlockAlign = BlockAlign;
+  Info.BlockLayout = BlockLayout;
+  Info.BlockHasCopyDispose = 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 BlockFunction::getBlockOffset(CharUnits Size, CharUnits Align) {
+  assert((Align.isPositive()) && "alignment must be 1 byte or more");
 
   CharUnits OldOffset = BlockOffset;
 
@@ -806,23 +908,22 @@
 
   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(),
+    ValueDecl *PadDecl = VarDecl::Create(getContext(), 
+                                         getContext().getTranslationUnitDecl(),
+                                         SourceLocation(),
                                          0, QualType(PadTy), 0,
-                                         VarDecl::None, VarDecl::None);
-    Expr *E;
-    E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(),
-                                       SourceLocation());
-    BlockDeclRefDecls.push_back(E);
+                                         SC_None, SC_None);
+    Expr *E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(),
+                                             SourceLocation());
+    BlockLayout.push_back(E);
   }
-  BlockDeclRefDecls.push_back(BDRE);
 
   BlockOffset += Size;
-  return BlockOffset-Size;
+  return BlockOffset - Size;
 }
 
 llvm::Constant *BlockFunction::
@@ -861,8 +962,8 @@
   FunctionDecl *FD = FunctionDecl::Create(getContext(),
                                           getContext().getTranslationUnitDecl(),
                                           SourceLocation(), II, R, 0,
-                                          FunctionDecl::Static,
-                                          FunctionDecl::None,
+                                          SC_Static,
+                                          SC_None,
                                           false,
                                           true);
   CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
@@ -898,9 +999,8 @@
         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();
+        llvm::Value *N = llvm::ConstantInt::get(CGF.Int32Ty, flag);
+        llvm::Value *F = CGM.getBlockObjectAssign();
         Builder.CreateCall3(F, Dstv, Srcv, N);
       }
     }
@@ -944,8 +1044,8 @@
   FunctionDecl *FD = FunctionDecl::Create(getContext(),
                                           getContext().getTranslationUnitDecl(),
                                           SourceLocation(), II, R, 0,
-                                          FunctionDecl::Static,
-                                          FunctionDecl::None,
+                                          SC_Static,
+                                          SC_None,
                                           false, true);
   CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
 
@@ -1029,8 +1129,8 @@
   FunctionDecl *FD = FunctionDecl::Create(getContext(),
                                           getContext().getTranslationUnitDecl(),
                                           SourceLocation(), II, R, 0,
-                                          FunctionDecl::Static,
-                                          FunctionDecl::None,
+                                          SC_Static,
+                                          SC_None,
                                           false, true);
   CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
 
@@ -1051,9 +1151,8 @@
 
   flag |= BLOCK_BYREF_CALLER;
 
-  llvm::Value *N = llvm::ConstantInt::get(
-          llvm::Type::getInt32Ty(T->getContext()), flag);
-  llvm::Value *F = getBlockObjectAssign();
+  llvm::Value *N = llvm::ConstantInt::get(CGF.Int32Ty, flag);
+  llvm::Value *F = CGM.getBlockObjectAssign();
   Builder.CreateCall3(F, DstObj, SrcObj, N);
 
   CGF.FinishFunction();
@@ -1094,8 +1193,8 @@
   FunctionDecl *FD = FunctionDecl::Create(getContext(),
                                           getContext().getTranslationUnitDecl(),
                                           SourceLocation(), II, R, 0,
-                                          FunctionDecl::Static,
-                                          FunctionDecl::None,
+                                          SC_Static,
+                                          SC_None,
                                           false, true);
   CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
 
@@ -1148,40 +1247,11 @@
   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 *F = CGM.getBlockObjectDispose();
   llvm::Value *N;
   V = Builder.CreateBitCast(V, PtrToInt8Ty);
-  N = llvm::ConstantInt::get(llvm::Type::getInt32Ty(V->getContext()), flag);
+  N = llvm::ConstantInt::get(CGF.Int32Ty, flag);
   Builder.CreateCall2(F, V, N);
 }
 
@@ -1189,7 +1259,7 @@
 
 BlockFunction::BlockFunction(CodeGenModule &cgm, CodeGenFunction &cgf,
                              CGBuilderTy &B)
-  : CGM(cgm), CGF(cgf), VMContext(cgm.getLLVMContext()), Builder(B) {
+  : CGM(cgm), VMContext(cgm.getLLVMContext()), CGF(cgf), Builder(B) {
   PtrToInt8Ty = llvm::PointerType::getUnqual(
             llvm::Type::getInt8Ty(VMContext));
 
diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h
index 5646d00..743e3c8 100644
--- a/lib/CodeGen/CGBlocks.h
+++ b/lib/CodeGen/CGBlocks.h
@@ -73,8 +73,6 @@
   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();
 
@@ -82,14 +80,6 @@
 
   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;
 
@@ -97,9 +87,7 @@
     int GlobalUniqueCount;
   } Block;
 
-  llvm::Value *BlockObjectAssign;
-  llvm::Value *BlockObjectDispose;
-  const llvm::Type *PtrToInt8Ty;
+  const llvm::PointerType *PtrToInt8Ty;
 
   std::map<uint64_t, llvm::Constant *> AssignCache;
   std::map<uint64_t, llvm::Constant *> DestroyCache;
@@ -108,9 +96,7 @@
               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) {
+      BlockDescriptorType(0), GenericBlockLiteralType(0) {
     Block.GlobalUniqueCount = 0;
     PtrToInt8Ty = llvm::Type::getInt8PtrTy(M.getContext());
   }
@@ -121,13 +107,14 @@
 
 class BlockFunction : public BlockBase {
   CodeGenModule &CGM;
-  CodeGenFunction &CGF;
   ASTContext &getContext() const;
 
 protected:
   llvm::LLVMContext &VMContext;
 
 public:
+  CodeGenFunction &CGF;
+
   const llvm::PointerType *PtrToInt8Ty;
   struct HelperInfo {
     int index;
@@ -148,26 +135,6 @@
     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);
@@ -179,19 +146,31 @@
   /// characters.
   CharUnits BlockAlign;
 
-  /// getBlockOffset - Allocate an offset for the ValueDecl from a
-  /// BlockDeclRefExpr in a block literal (BlockExpr).
-  CharUnits getBlockOffset(const BlockDeclRefExpr *E);
+  /// getBlockOffset - Allocate a location within the block's storage
+  /// for a value with the given size and alignment requirements.
+  CharUnits getBlockOffset(CharUnits Size, CharUnits Align);
 
   /// 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;
+  /// BlockLayout - The layout of the block's storage, represented as
+  /// a sequence of expressions which require such storage.  The
+  /// expressions can be:
+  /// - a BlockDeclRefExpr, indicating that the given declaration
+  ///   from an enclosing scope is needed by the block;
+  /// - a DeclRefExpr, which always wraps an anonymous VarDecl with
+  ///   array type, used to insert padding into the block; or
+  /// - a CXXThisExpr, indicating that the C++ 'this' value should
+  ///   propagate from the parent to the block.
+  /// This is a really silly representation.
+  llvm::SmallVector<const Expr *, 8> BlockLayout;
 
   /// BlockDecls - Offsets for all Decls in BlockDeclRefExprs.
-  std::map<const Decl*, CharUnits> BlockDecls;
+  llvm::DenseMap<const Decl*, CharUnits> BlockDecls;
+  
+  /// BlockCXXThisOffset - The offset of the C++ 'this' value within
+  /// the block structure.
+  CharUnits BlockCXXThisOffset;
 
   ImplicitParamDecl *BlockStructDecl;
   ImplicitParamDecl *getBlockStructDecl() { return BlockStructDecl; }
@@ -214,8 +193,6 @@
   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)
diff --git a/lib/CodeGen/CGBuilder.h b/lib/CodeGen/CGBuilder.h
index ed56bd9..8120217 100644
--- a/lib/CodeGen/CGBuilder.h
+++ b/lib/CodeGen/CGBuilder.h
@@ -14,12 +14,14 @@
 
 namespace clang {
 namespace CodeGen {
-  // Don't preserve names on values in an optimized build.
+
+// Don't preserve names on values in an optimized build.
 #ifdef NDEBUG
-  typedef llvm::IRBuilder<false> CGBuilderTy;
+typedef llvm::IRBuilder<false> CGBuilderTy;
 #else
-  typedef llvm::IRBuilder<> CGBuilderTy;
+typedef llvm::IRBuilder<> CGBuilderTy;
 #endif
+
 }  // end namespace CodeGen
 }  // end namespace clang
 
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 95c41db..3a4d0fa 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -14,6 +14,7 @@
 #include "TargetInfo.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "CGObjCRuntime.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTContext.h"
@@ -40,6 +41,31 @@
                          C, C + 5);
 }
 
+static Value *EmitCastToInt(CodeGenFunction &CGF,
+                            const llvm::Type *ToType, Value *Val) {
+  if (Val->getType()->isPointerTy()) {
+    return CGF.Builder.CreatePtrToInt(Val, ToType);
+  }
+  assert(Val->getType()->isIntegerTy() &&
+         "Used a non-integer and non-pointer type with atomic builtin");
+  assert(Val->getType()->getScalarSizeInBits() <=
+         ToType->getScalarSizeInBits() && "Integer type too small");
+  return CGF.Builder.CreateSExtOrBitCast(Val, ToType);
+}
+
+static Value *EmitCastFromInt(CodeGenFunction &CGF, QualType ToQualType,
+                              Value *Val) {
+  const llvm::Type *ToType = CGF.ConvertType(ToQualType);
+  if (ToType->isPointerTy()) {
+    return CGF.Builder.CreateIntToPtr(Val, ToType);
+  }
+  assert(Val->getType()->isIntegerTy() &&
+         "Used a non-integer and non-pointer type with atomic builtin");
+  assert(Val->getType()->getScalarSizeInBits() >=
+         ToType->getScalarSizeInBits() && "Integer type too small");
+  return CGF.Builder.CreateTruncOrBitCast(Val, ToType);
+}
+
 // 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,
@@ -59,33 +85,66 @@
 /// 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));
+  const llvm::Type *ValueType =
+    llvm::IntegerType::get(CGF.getLLVMContext(),
+                           CGF.getContext().getTypeSize(E->getType()));
+  const llvm::Type *PtrType = ValueType->getPointerTo();
+  const llvm::Type *IntrinsicTypes[2] = { ValueType, PtrType };
+  Value *AtomF = CGF.CGM.getIntrinsic(Id, IntrinsicTypes, 2);
+
+  Value *Args[2] = { CGF.Builder.CreateBitCast(CGF.EmitScalarExpr(E->getArg(0)),
+                                               PtrType),
+                     EmitCastToInt(CGF, ValueType,
+                                   CGF.EmitScalarExpr(E->getArg(1))) };
+  return RValue::get(EmitCastFromInt(CGF, E->getType(),
+                                     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,
+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)) };
+  const llvm::Type *ValueType =
+    llvm::IntegerType::get(CGF.getLLVMContext(),
+                           CGF.getContext().getTypeSize(E->getType()));
+  const llvm::Type *PtrType = ValueType->getPointerTo();
+  const llvm::Type *IntrinsicTypes[2] = { ValueType, PtrType };
+  Value *AtomF = CGF.CGM.getIntrinsic(Id, IntrinsicTypes, 2);
+
+  Value *Args[2] = { CGF.Builder.CreateBitCast(CGF.EmitScalarExpr(E->getArg(0)),
+                                               PtrType),
+                     EmitCastToInt(CGF, ValueType,
+                                   CGF.EmitScalarExpr(E->getArg(1))) };
   Value *Result = EmitCallWithBarrier(CGF, AtomF, Args, Args + 2);
-  return RValue::get(CGF.Builder.CreateBinOp(Op, Result, Args[1]));
+  return RValue::get(EmitCastFromInt(CGF, E->getType(),
+                                     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);
+/// EmitFAbs - Emit a call to fabs/fabsf/fabsl, depending on the type of ValTy,
+/// which must be a scalar floating point type.
+static Value *EmitFAbs(CodeGenFunction &CGF, Value *V, QualType ValTy) {
+  const BuiltinType *ValTyP = ValTy->getAs<BuiltinType>();
+  assert(ValTyP && "isn't scalar fp type!");
+  
+  StringRef FnName;
+  switch (ValTyP->getKind()) {
+  default: assert(0 && "Isn't a scalar fp type!");
+  case BuiltinType::Float:      FnName = "fabsf"; break;
+  case BuiltinType::Double:     FnName = "fabs"; break;
+  case BuiltinType::LongDouble: FnName = "fabsl"; break;
+  }
+  
+  // The prototype is something that takes and returns whatever V's type is.
+  std::vector<const llvm::Type*> Args;
+  Args.push_back(V->getType());
+  llvm::FunctionType *FT = llvm::FunctionType::get(V->getType(), Args, false);
+  llvm::Value *Fn = CGF.CGM.CreateRuntimeFunction(FT, FnName);
+
+  return CGF.Builder.CreateCall(Fn, V, "abs");
 }
 
 RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
@@ -225,9 +284,12 @@
                                      "cast");
     return RValue::get(Result);
   }
-  case Builtin::BI__builtin_expect:
+  case Builtin::BI__builtin_expect: {
     // FIXME: pass expect through to LLVM
+    if (E->getArg(1)->HasSideEffects(getContext()))
+      (void)EmitScalarExpr(E->getArg(1));
     return RValue::get(EmitScalarExpr(E->getArg(0)));
+  }
   case Builtin::BI__builtin_bswap32:
   case Builtin::BI__builtin_bswap64: {
     Value *ArgValue = EmitScalarExpr(E->getArg(0));
@@ -259,9 +321,9 @@
     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);
+      llvm::ConstantInt::get(Int32Ty, 0);
     Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) :
-      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 3);
+      llvm::ConstantInt::get(Int32Ty, 3);
     Value *F = CGM.getIntrinsic(Intrinsic::prefetch, 0, 0);
     return RValue::get(Builder.CreateCall3(F, Address, RW, Locality));
   }
@@ -328,11 +390,111 @@
     V = Builder.CreateFCmpUNO(V, V, "cmp");
     return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()), "tmp"));
   }
+  
+  case Builtin::BI__builtin_isinf: {
+    // isinf(x) --> fabs(x) == infinity
+    Value *V = EmitScalarExpr(E->getArg(0));
+    V = EmitFAbs(*this, V, E->getArg(0)->getType());
+    
+    V = Builder.CreateFCmpOEQ(V, ConstantFP::getInfinity(V->getType()),"isinf");
+    return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()), "tmp"));
+  }
+      
+  // TODO: BI__builtin_isinf_sign
+  //   isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0
+
+  case Builtin::BI__builtin_isnormal: {
+    // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min
+    Value *V = EmitScalarExpr(E->getArg(0));
+    Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq");
+
+    Value *Abs = EmitFAbs(*this, V, E->getArg(0)->getType());
+    Value *IsLessThanInf =
+      Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf");
+    APFloat Smallest = APFloat::getSmallestNormalized(
+                   getContext().getFloatTypeSemantics(E->getArg(0)->getType()));
+    Value *IsNormal =
+      Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest),
+                            "isnormal");
+    V = Builder.CreateAnd(Eq, IsLessThanInf, "and");
+    V = Builder.CreateAnd(V, IsNormal, "and");
+    return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
+  }
+
+  case Builtin::BI__builtin_isfinite: {
+    // isfinite(x) --> x == x && fabs(x) != infinity; }
+    Value *V = EmitScalarExpr(E->getArg(0));
+    Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq");
+    
+    Value *Abs = EmitFAbs(*this, V, E->getArg(0)->getType());
+    Value *IsNotInf =
+      Builder.CreateFCmpUNE(Abs, ConstantFP::getInfinity(V->getType()),"isinf");
+    
+    V = Builder.CreateAnd(Eq, IsNotInf, "and");
+    return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
+  }
+
+  case Builtin::BI__builtin_fpclassify: {
+    Value *V = EmitScalarExpr(E->getArg(5));
+    const llvm::Type *Ty = ConvertType(E->getArg(5)->getType());
+
+    // Create Result
+    BasicBlock *Begin = Builder.GetInsertBlock();
+    BasicBlock *End = createBasicBlock("fpclassify_end", this->CurFn);
+    Builder.SetInsertPoint(End);
+    PHINode *Result =
+      Builder.CreatePHI(ConvertType(E->getArg(0)->getType()),
+                        "fpclassify_result");
+
+    // if (V==0) return FP_ZERO
+    Builder.SetInsertPoint(Begin);
+    Value *IsZero = Builder.CreateFCmpOEQ(V, Constant::getNullValue(Ty),
+                                          "iszero");
+    Value *ZeroLiteral = EmitScalarExpr(E->getArg(4));
+    BasicBlock *NotZero = createBasicBlock("fpclassify_not_zero", this->CurFn);
+    Builder.CreateCondBr(IsZero, End, NotZero);
+    Result->addIncoming(ZeroLiteral, Begin);
+
+    // if (V != V) return FP_NAN
+    Builder.SetInsertPoint(NotZero);
+    Value *IsNan = Builder.CreateFCmpUNO(V, V, "cmp");
+    Value *NanLiteral = EmitScalarExpr(E->getArg(0));
+    BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", this->CurFn);
+    Builder.CreateCondBr(IsNan, End, NotNan);
+    Result->addIncoming(NanLiteral, NotZero);
+
+    // if (fabs(V) == infinity) return FP_INFINITY
+    Builder.SetInsertPoint(NotNan);
+    Value *VAbs = EmitFAbs(*this, V, E->getArg(5)->getType());
+    Value *IsInf =
+      Builder.CreateFCmpOEQ(VAbs, ConstantFP::getInfinity(V->getType()),
+                            "isinf");
+    Value *InfLiteral = EmitScalarExpr(E->getArg(1));
+    BasicBlock *NotInf = createBasicBlock("fpclassify_not_inf", this->CurFn);
+    Builder.CreateCondBr(IsInf, End, NotInf);
+    Result->addIncoming(InfLiteral, NotNan);
+
+    // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL
+    Builder.SetInsertPoint(NotInf);
+    APFloat Smallest = APFloat::getSmallestNormalized(
+        getContext().getFloatTypeSemantics(E->getArg(5)->getType()));
+    Value *IsNormal =
+      Builder.CreateFCmpUGE(VAbs, ConstantFP::get(V->getContext(), Smallest),
+                            "isnormal");
+    Value *NormalResult =
+      Builder.CreateSelect(IsNormal, EmitScalarExpr(E->getArg(2)),
+                           EmitScalarExpr(E->getArg(3)));
+    Builder.CreateBr(End);
+    Result->addIncoming(NormalResult, NotInf);
+
+    // return Result
+    Builder.SetInsertPoint(End);
+    return RValue::get(Result);
+  }
+      
   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:
@@ -343,7 +505,7 @@
                    Address,
                    llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0),
                    SizeVal,
-                   llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1),
+                   llvm::ConstantInt::get(Int32Ty, 1),
                    llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
     return RValue::get(Address);
   }
@@ -355,10 +517,20 @@
     Builder.CreateCall5(CGM.getMemCpyFn(Address->getType(), SrcAddr->getType(),
                                         SizeVal->getType()),
                   Address, SrcAddr, SizeVal, 
-                  llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1),
+                  llvm::ConstantInt::get(Int32Ty, 1),
                   llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
     return RValue::get(Address);
   }
+      
+  case Builtin::BI__builtin_objc_memmove_collectable: {
+    Value *Address = EmitScalarExpr(E->getArg(0));
+    Value *SrcAddr = EmitScalarExpr(E->getArg(1));
+    Value *SizeVal = EmitScalarExpr(E->getArg(2));
+    CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, 
+                                                  Address, SrcAddr, SizeVal);
+    return RValue::get(Address);
+  }
+      
   case Builtin::BImemmove:
   case Builtin::BI__builtin_memmove: {
     Value *Address = EmitScalarExpr(E->getArg(0));
@@ -367,7 +539,7 @@
     Builder.CreateCall5(CGM.getMemMoveFn(Address->getType(), SrcAddr->getType(),
                                          SizeVal->getType()),
                   Address, SrcAddr, SizeVal, 
-                  llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1),
+                  llvm::ConstantInt::get(Int32Ty, 1),
                   llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
     return RValue::get(Address);
   }
@@ -380,7 +552,7 @@
                   Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
                                       llvm::Type::getInt8Ty(VMContext)),
                   SizeVal,
-                  llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1),
+                  llvm::ConstantInt::get(Int32Ty, 1),
                   llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
     return RValue::get(Address);
   }
@@ -396,21 +568,18 @@
     int32_t Offset = 0;
 
     Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa, 0, 0);
-    return RValue::get(Builder.CreateCall(F, getInt32(VMContext, Offset)));
+    return RValue::get(Builder.CreateCall(F, 
+                                      llvm::ConstantInt::get(Int32Ty, Offset)));
   }
   case Builtin::BI__builtin_return_address: {
     Value *Depth = EmitScalarExpr(E->getArg(0));
-    Depth = Builder.CreateIntCast(Depth,
-                                  llvm::Type::getInt32Ty(VMContext),
-                                  false, "tmp");
+    Depth = Builder.CreateIntCast(Depth, Int32Ty, 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");
+    Depth = Builder.CreateIntCast(Depth, Int32Ty, false, "tmp");
     Value *F = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0);
     return RValue::get(Builder.CreateCall(F, Depth));
   }
@@ -483,36 +652,45 @@
       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: {
+    // Buffer is a void**.
     Value *Buf = EmitScalarExpr(E->getArg(0));
-    // Store the frame pointer to the buffer
-    Value *FrameAddrF = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0);
+
+    // Store the frame pointer to the setjmp buffer.
     Value *FrameAddr =
-        Builder.CreateCall(FrameAddrF,
-                           Constant::getNullValue(llvm::Type::getInt32Ty(VMContext)));
+      Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
+                         ConstantInt::get(Int32Ty, 0));
     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);
+
+    // Store the stack pointer to the setjmp buffer.
+    Value *StackAddr =
+      Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave));
+    Value *StackSaveSlot =
+      Builder.CreateGEP(Buf, ConstantInt::get(Int32Ty, 2));
+    Builder.CreateStore(StackAddr, StackSaveSlot);
+
+    // Call LLVM's EH setjmp, which is lightweight.
+    Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp);
+    Buf = Builder.CreateBitCast(Buf, llvm::Type::getInt8PtrTy(VMContext));
     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));
+    Buf = Builder.CreateBitCast(Buf, llvm::Type::getInt8PtrTy(VMContext));
+
+    // Call LLVM's EH longjmp, which is lightweight.
+    Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf);
+
+    // longjmp doesn't return; mark this as unreachable
+    Value *V = Builder.CreateUnreachable();
+    Builder.ClearInsertionPoint();
+    return RValue::get(V);
   }
-#endif
   case Builtin::BI__sync_fetch_and_add:
   case Builtin::BI__sync_fetch_and_sub:
   case Builtin::BI__sync_fetch_and_or:
@@ -610,14 +788,23 @@
   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));
+    const llvm::Type *ValueType =
+      llvm::IntegerType::get(CGF.getLLVMContext(),
+                             CGF.getContext().getTypeSize(E->getType()));
+    const llvm::Type *PtrType = ValueType->getPointerTo();
+    const llvm::Type *IntrinsicTypes[2] = { ValueType, PtrType };
+    Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap,
+                                    IntrinsicTypes, 2);
+
+    Value *Args[3] = { Builder.CreateBitCast(CGF.EmitScalarExpr(E->getArg(0)),
+                                             PtrType),
+                       EmitCastToInt(CGF, ValueType,
+                                     CGF.EmitScalarExpr(E->getArg(1))),
+                       EmitCastToInt(CGF, ValueType,
+                                     CGF.EmitScalarExpr(E->getArg(2))) };
+    return RValue::get(EmitCastFromInt(CGF, E->getType(),
+                                       EmitCallWithBarrier(CGF, AtomF, Args,
+                                                           Args + 3)));
   }
 
   case Builtin::BI__sync_bool_compare_and_swap_1:
@@ -625,14 +812,22 @@
   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)) };
+    const llvm::Type *ValueType =
+      llvm::IntegerType::get(
+        CGF.getLLVMContext(),
+        CGF.getContext().getTypeSize(E->getArg(1)->getType()));
+    const llvm::Type *PtrType = ValueType->getPointerTo();
+    const llvm::Type *IntrinsicTypes[2] = { ValueType, PtrType };
+    Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap,
+                                    IntrinsicTypes, 2);
+
+    Value *Args[3] = { Builder.CreateBitCast(CGF.EmitScalarExpr(E->getArg(0)),
+                                             PtrType),
+                       EmitCastToInt(CGF, ValueType,
+                                     CGF.EmitScalarExpr(E->getArg(1))),
+                       EmitCastToInt(CGF, ValueType,
+                                     CGF.EmitScalarExpr(E->getArg(2))) };
+    Value *OldVal = Args[1];
     Value *PrevVal = EmitCallWithBarrier(*this, AtomF, Args, Args + 3);
     Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal);
     // zext bool to int.
@@ -802,14 +997,765 @@
   }
 }
 
+const llvm::VectorType *GetNeonType(LLVMContext &C, unsigned type, bool q) {
+  switch (type) {
+    default: break;
+    case 0: 
+    case 5: return llvm::VectorType::get(llvm::Type::getInt8Ty(C), 8 << (int)q);
+    case 6:
+    case 7:
+    case 1: return llvm::VectorType::get(llvm::Type::getInt16Ty(C),4 << (int)q);
+    case 2: return llvm::VectorType::get(llvm::Type::getInt32Ty(C),2 << (int)q);
+    case 3: return llvm::VectorType::get(llvm::Type::getInt64Ty(C),1 << (int)q);
+    case 4: return llvm::VectorType::get(llvm::Type::getFloatTy(C),2 << (int)q);
+  };
+  return 0;
+}
+
+Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C, bool widen) {
+  unsigned nElts = cast<llvm::VectorType>(V->getType())->getNumElements();
+  if (widen)
+    nElts <<= 1;
+  SmallVector<Constant*, 16> Indices(nElts, C);
+  Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size());
+  return Builder.CreateShuffleVector(V, V, SV, "lane");
+}
+
+Value *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops,
+                                     const char *name, bool splat,
+                                     unsigned shift, bool rightshift) {
+  unsigned j = 0;
+  for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
+       ai != ae; ++ai, ++j)
+    if (shift > 0 && shift == j)
+      Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift);
+    else
+      Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name);
+
+  if (splat) {
+    Ops[j-1] = EmitNeonSplat(Ops[j-1], cast<Constant>(Ops[j]));
+    Ops.resize(j);
+  }
+  return Builder.CreateCall(F, Ops.begin(), Ops.end(), name);
+}
+
+Value *CodeGenFunction::EmitNeonShiftVector(Value *V, const llvm::Type *Ty, 
+                                            bool neg) {
+  ConstantInt *CI = cast<ConstantInt>(V);
+  int SV = CI->getSExtValue();
+  
+  const llvm::VectorType *VTy = cast<llvm::VectorType>(Ty);
+  llvm::Constant *C = ConstantInt::get(VTy->getElementType(), neg ? -SV : SV);
+  SmallVector<llvm::Constant*, 16> CV(VTy->getNumElements(), C);
+  return llvm::ConstantVector::get(CV.begin(), CV.size());
+}
+
+/// GetPointeeAlignment - Given an expression with a pointer type, find the
+/// alignment of the type referenced by the pointer.  Skip over implicit
+/// casts.
+static Value *GetPointeeAlignment(CodeGenFunction &CGF, const Expr *Addr) {
+  unsigned Align = 1;
+  // Check if the type is a pointer.  The implicit cast operand might not be.
+  while (Addr->getType()->isPointerType()) {
+    QualType PtTy = Addr->getType()->getPointeeType();
+    unsigned NewA = CGF.getContext().getTypeAlignInChars(PtTy).getQuantity();
+    if (NewA > Align)
+      Align = NewA;
+
+    // If the address is an implicit cast, repeat with the cast operand.
+    if (const ImplicitCastExpr *CastAddr = dyn_cast<ImplicitCastExpr>(Addr)) {
+      Addr = CastAddr->getSubExpr();
+      continue;
+    }
+    break;
+  }
+  return llvm::ConstantInt::get(CGF.Int32Ty, Align);
+}
+
 Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
                                            const CallExpr *E) {
+  if (BuiltinID == ARM::BI__clear_cache) {
+    const FunctionDecl *FD = E->getDirectCallee();
+    Value *a = EmitScalarExpr(E->getArg(0));
+    Value *b = EmitScalarExpr(E->getArg(1));
+    const llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
+    const llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
+    llvm::StringRef Name = FD->getName();
+    return Builder.CreateCall2(CGM.CreateRuntimeFunction(FTy, Name),
+                               a, b);
+  }
+
+  llvm::SmallVector<Value*, 4> Ops;
+  for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++)
+    Ops.push_back(EmitScalarExpr(E->getArg(i)));
+
+  llvm::APSInt Result;
+  const Expr *Arg = E->getArg(E->getNumArgs()-1);
+  if (!Arg->isIntegerConstantExpr(Result, getContext()))
+    return 0;
+
+  if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f ||
+      BuiltinID == ARM::BI__builtin_arm_vcvtr_d) {
+    // Determine the overloaded type of this builtin.
+    const llvm::Type *Ty;
+    if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f)
+      Ty = llvm::Type::getFloatTy(VMContext);
+    else
+      Ty = llvm::Type::getDoubleTy(VMContext);
+    
+    // Determine whether this is an unsigned conversion or not.
+    bool usgn = Result.getZExtValue() == 1;
+    unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr;
+
+    // Call the appropriate intrinsic.
+    Function *F = CGM.getIntrinsic(Int, &Ty, 1);
+    return Builder.CreateCall(F, Ops.begin(), Ops.end(), "vcvtr");
+  }
+  
+  // Determine the type of this overloaded NEON intrinsic.
+  unsigned type = Result.getZExtValue();
+  bool usgn = type & 0x08;
+  bool quad = type & 0x10;
+  bool poly = (type & 0x7) == 5 || (type & 0x7) == 6;
+  bool splat = false;
+
+  const llvm::VectorType *VTy = GetNeonType(VMContext, type & 0x7, quad);
+  const llvm::Type *Ty = VTy;
+  if (!Ty)
+    return 0;
+
+  unsigned Int;
   switch (BuiltinID) {
   default: return 0;
+  case ARM::BI__builtin_neon_vaba_v:
+  case ARM::BI__builtin_neon_vabaq_v:
+    Int = usgn ? Intrinsic::arm_neon_vabau : Intrinsic::arm_neon_vabas;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vaba");
+  case ARM::BI__builtin_neon_vabal_v:
+    Int = usgn ? Intrinsic::arm_neon_vabalu : Intrinsic::arm_neon_vabals;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vabal");
+  case ARM::BI__builtin_neon_vabd_v:
+  case ARM::BI__builtin_neon_vabdq_v:
+    Int = usgn ? Intrinsic::arm_neon_vabdu : Intrinsic::arm_neon_vabds;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vabd");
+  case ARM::BI__builtin_neon_vabdl_v:
+    Int = usgn ? Intrinsic::arm_neon_vabdlu : Intrinsic::arm_neon_vabdls;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vabdl");
+  case ARM::BI__builtin_neon_vabs_v:
+  case ARM::BI__builtin_neon_vabsq_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vabs, &Ty, 1),
+                        Ops, "vabs");
+  case ARM::BI__builtin_neon_vaddhn_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vaddhn, &Ty, 1),
+                        Ops, "vaddhn");
+  case ARM::BI__builtin_neon_vaddl_v:
+    Int = usgn ? Intrinsic::arm_neon_vaddlu : Intrinsic::arm_neon_vaddls;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vaddl");
+  case ARM::BI__builtin_neon_vaddw_v:
+    Int = usgn ? Intrinsic::arm_neon_vaddws : Intrinsic::arm_neon_vaddwu;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vaddw");
+  case ARM::BI__builtin_neon_vcale_v:
+    std::swap(Ops[0], Ops[1]);
+  case ARM::BI__builtin_neon_vcage_v: {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacged, &Ty, 1);
+    return EmitNeonCall(F, Ops, "vcage");
+  }
+  case ARM::BI__builtin_neon_vcaleq_v:
+    std::swap(Ops[0], Ops[1]);
+  case ARM::BI__builtin_neon_vcageq_v: {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgeq, &Ty, 1);
+    return EmitNeonCall(F, Ops, "vcage");
+  }
+  case ARM::BI__builtin_neon_vcalt_v:
+    std::swap(Ops[0], Ops[1]);
+  case ARM::BI__builtin_neon_vcagt_v: {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtd, &Ty, 1);
+    return EmitNeonCall(F, Ops, "vcagt");
+  }
+  case ARM::BI__builtin_neon_vcaltq_v:
+    std::swap(Ops[0], Ops[1]);
+  case ARM::BI__builtin_neon_vcagtq_v: {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtq, &Ty, 1);
+    return EmitNeonCall(F, Ops, "vcagt");
+  }
+  case ARM::BI__builtin_neon_vcls_v:
+  case ARM::BI__builtin_neon_vclsq_v: {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcls, &Ty, 1);
+    return EmitNeonCall(F, Ops, "vcls");
+  }
+  case ARM::BI__builtin_neon_vclz_v:
+  case ARM::BI__builtin_neon_vclzq_v: {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vclz, &Ty, 1);
+    return EmitNeonCall(F, Ops, "vclz");
+  }
+  case ARM::BI__builtin_neon_vcnt_v:
+  case ARM::BI__builtin_neon_vcntq_v: {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcnt, &Ty, 1);
+    return EmitNeonCall(F, Ops, "vcnt");
+  }
+  // FIXME: intrinsics for f16<->f32 convert missing from ARM target.
+  case ARM::BI__builtin_neon_vcvt_f32_v:
+  case ARM::BI__builtin_neon_vcvtq_f32_v: {
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ty = GetNeonType(VMContext, 4, quad);
+    return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 
+                : Builder.CreateSIToFP(Ops[0], Ty, "vcvt");
+  }
+  case ARM::BI__builtin_neon_vcvt_s32_v:
+  case ARM::BI__builtin_neon_vcvt_u32_v:
+  case ARM::BI__builtin_neon_vcvtq_s32_v:
+  case ARM::BI__builtin_neon_vcvtq_u32_v: {
+    Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(VMContext, 4, quad));
+    return usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 
+                : Builder.CreateFPToSI(Ops[0], Ty, "vcvt");
+  }
+  case ARM::BI__builtin_neon_vcvt_n_f32_v:
+  case ARM::BI__builtin_neon_vcvtq_n_f32_v: {
+    const llvm::Type *Tys[2] = { GetNeonType(VMContext, 4, quad), Ty };
+    Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp : Intrinsic::arm_neon_vcvtfxs2fp;
+    Function *F = CGM.getIntrinsic(Int, Tys, 2);
+    return EmitNeonCall(F, Ops, "vcvt_n");
+  }
+  case ARM::BI__builtin_neon_vcvt_n_s32_v:
+  case ARM::BI__builtin_neon_vcvt_n_u32_v:
+  case ARM::BI__builtin_neon_vcvtq_n_s32_v:
+  case ARM::BI__builtin_neon_vcvtq_n_u32_v: {
+    const llvm::Type *Tys[2] = { Ty, GetNeonType(VMContext, 4, quad) };
+    Int = usgn ? Intrinsic::arm_neon_vcvtfp2fxu : Intrinsic::arm_neon_vcvtfp2fxs;
+    Function *F = CGM.getIntrinsic(Int, Tys, 2);
+    return EmitNeonCall(F, Ops, "vcvt_n");
+  }
+  case ARM::BI__builtin_neon_vdup_lane_v: 
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return EmitNeonSplat(Ops[0], cast<Constant>(Ops[1]));
+  case ARM::BI__builtin_neon_vdupq_lane_v:
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return EmitNeonSplat(Ops[0], cast<Constant>(Ops[1]), true);
+  case ARM::BI__builtin_neon_vext_v:
+  case ARM::BI__builtin_neon_vextq_v: {
+    ConstantInt *C = dyn_cast<ConstantInt>(Ops[2]);
+    int CV = C->getSExtValue();
+    SmallVector<Constant*, 16> Indices;
+    for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
+      Indices.push_back(ConstantInt::get(Int32Ty, i+CV));
+    
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size());
+    return Builder.CreateShuffleVector(Ops[0], Ops[1], SV, "vext");
+  }
+  case ARM::BI__builtin_neon_vget_lane_i8:
+  case ARM::BI__builtin_neon_vget_lane_i16:
+  case ARM::BI__builtin_neon_vget_lane_i32:
+  case ARM::BI__builtin_neon_vget_lane_i64:
+  case ARM::BI__builtin_neon_vget_lane_f32:
+  case ARM::BI__builtin_neon_vgetq_lane_i8:
+  case ARM::BI__builtin_neon_vgetq_lane_i16:
+  case ARM::BI__builtin_neon_vgetq_lane_i32:
+  case ARM::BI__builtin_neon_vgetq_lane_i64:
+  case ARM::BI__builtin_neon_vgetq_lane_f32:
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vget_lane");
+  case ARM::BI__builtin_neon_vhadd_v:
+  case ARM::BI__builtin_neon_vhaddq_v:
+    Int = usgn ? Intrinsic::arm_neon_vhaddu : Intrinsic::arm_neon_vhadds;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vhadd");
+  case ARM::BI__builtin_neon_vhsub_v:
+  case ARM::BI__builtin_neon_vhsubq_v:
+    Int = usgn ? Intrinsic::arm_neon_vhsubu : Intrinsic::arm_neon_vhsubs;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vhsub");
+  case ARM::BI__builtin_neon_vld1_v:
+  case ARM::BI__builtin_neon_vld1q_v:
+    Ops.push_back(GetPointeeAlignment(*this, E->getArg(0)));
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vld1, &Ty, 1),
+                        Ops, "vld1");
+  case ARM::BI__builtin_neon_vld1_lane_v:
+  case ARM::BI__builtin_neon_vld1q_lane_v:
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ty = llvm::PointerType::getUnqual(VTy->getElementType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[0] = Builder.CreateLoad(Ops[0]);
+    return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vld1_lane");
+  case ARM::BI__builtin_neon_vld1_dup_v:
+  case ARM::BI__builtin_neon_vld1q_dup_v: {
+    Value *V = UndefValue::get(Ty);
+    Ty = llvm::PointerType::getUnqual(VTy->getElementType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[0] = Builder.CreateLoad(Ops[0]);
+    llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
+    Ops[0] = Builder.CreateInsertElement(V, Ops[0], CI);
+    return EmitNeonSplat(Ops[0], CI);
+  }
+  case ARM::BI__builtin_neon_vld2_v:
+  case ARM::BI__builtin_neon_vld2q_v: {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2, &Ty, 1);
+    Value *Align = GetPointeeAlignment(*this, E->getArg(1));
+    Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld2");
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case ARM::BI__builtin_neon_vld3_v:
+  case ARM::BI__builtin_neon_vld3q_v: {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3, &Ty, 1);
+    Value *Align = GetPointeeAlignment(*this, E->getArg(1));
+    Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld3");
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case ARM::BI__builtin_neon_vld4_v:
+  case ARM::BI__builtin_neon_vld4q_v: {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4, &Ty, 1);
+    Value *Align = GetPointeeAlignment(*this, E->getArg(1));
+    Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld4");
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case ARM::BI__builtin_neon_vld2_lane_v:
+  case ARM::BI__builtin_neon_vld2q_lane_v: {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2lane, &Ty, 1);
+    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
+    Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
+    Ops.push_back(GetPointeeAlignment(*this, E->getArg(1)));
+    Ops[1] = Builder.CreateCall(F, Ops.begin() + 1, Ops.end(), "vld2_lane");
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case ARM::BI__builtin_neon_vld3_lane_v:
+  case ARM::BI__builtin_neon_vld3q_lane_v: {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3lane, &Ty, 1);
+    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
+    Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
+    Ops[4] = Builder.CreateBitCast(Ops[4], Ty);
+    Ops.push_back(GetPointeeAlignment(*this, E->getArg(1)));
+    Ops[1] = Builder.CreateCall(F, Ops.begin() + 1, Ops.end(), "vld3_lane");
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case ARM::BI__builtin_neon_vld4_lane_v:
+  case ARM::BI__builtin_neon_vld4q_lane_v: {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4lane, &Ty, 1);
+    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
+    Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
+    Ops[4] = Builder.CreateBitCast(Ops[4], Ty);
+    Ops[5] = Builder.CreateBitCast(Ops[5], Ty);
+    Ops.push_back(GetPointeeAlignment(*this, E->getArg(1)));
+    Ops[1] = Builder.CreateCall(F, Ops.begin() + 1, Ops.end(), "vld3_lane");
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case ARM::BI__builtin_neon_vld2_dup_v:
+  case ARM::BI__builtin_neon_vld3_dup_v:
+  case ARM::BI__builtin_neon_vld4_dup_v: {
+    switch (BuiltinID) {
+    case ARM::BI__builtin_neon_vld2_dup_v: 
+      Int = Intrinsic::arm_neon_vld2lane; 
+      break;
+    case ARM::BI__builtin_neon_vld3_dup_v:
+      Int = Intrinsic::arm_neon_vld2lane; 
+      break;
+    case ARM::BI__builtin_neon_vld4_dup_v:
+      Int = Intrinsic::arm_neon_vld2lane; 
+      break;
+    default: assert(0 && "unknown vld_dup intrinsic?");
+    }
+    Function *F = CGM.getIntrinsic(Int, &Ty, 1);
+    const llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType());
+    
+    SmallVector<Value*, 6> Args;
+    Args.push_back(Ops[1]);
+    Args.append(STy->getNumElements(), UndefValue::get(Ty));
 
-  case ARM::BI__builtin_thread_pointer: {
-    Value *AtomF = CGM.getIntrinsic(Intrinsic::arm_thread_pointer, 0, 0);
-    return Builder.CreateCall(AtomF);
+    llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
+    Args.push_back(CI);
+    Args.push_back(GetPointeeAlignment(*this, E->getArg(1)));
+    
+    Ops[1] = Builder.CreateCall(F, Args.begin(), Args.end(), "vld_dup");
+    // splat lane 0 to all elts in each vector of the result.
+    for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+      Value *Val = Builder.CreateExtractValue(Ops[1], i);
+      Value *Elt = Builder.CreateBitCast(Val, Ty);
+      Elt = EmitNeonSplat(Elt, CI);
+      Elt = Builder.CreateBitCast(Elt, Val->getType());
+      Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i);
+    }
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case ARM::BI__builtin_neon_vmax_v:
+  case ARM::BI__builtin_neon_vmaxq_v:
+    Int = usgn ? Intrinsic::arm_neon_vmaxu : Intrinsic::arm_neon_vmaxs;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmax");
+  case ARM::BI__builtin_neon_vmin_v:
+  case ARM::BI__builtin_neon_vminq_v:
+    Int = usgn ? Intrinsic::arm_neon_vminu : Intrinsic::arm_neon_vmins;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmin");
+  case ARM::BI__builtin_neon_vmlal_lane_v:
+    splat = true;
+  case ARM::BI__builtin_neon_vmlal_v:
+    Int = usgn ? Intrinsic::arm_neon_vmlalu : Intrinsic::arm_neon_vmlals;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmlal", splat);
+  case ARM::BI__builtin_neon_vmlsl_lane_v:
+    splat = true;
+  case ARM::BI__builtin_neon_vmlsl_v:
+    Int = usgn ? Intrinsic::arm_neon_vmlslu : Intrinsic::arm_neon_vmlsls;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmlsl", splat);
+  case ARM::BI__builtin_neon_vmovl_v:
+    if (usgn)
+      return Builder.CreateZExt(Ops[0], Ty, "vmovl");
+    return Builder.CreateSExt(Ops[0], Ty, "vmovl");
+  case ARM::BI__builtin_neon_vmovn_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vmovn, &Ty, 1),
+                        Ops, "vmovn");
+  case ARM::BI__builtin_neon_vmull_lane_v:
+    splat = true;
+  case ARM::BI__builtin_neon_vmull_v:
+    Int = usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls;
+    Int = poly ? (unsigned)Intrinsic::arm_neon_vmullp : Int;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmlal", splat);
+  case ARM::BI__builtin_neon_vpadal_v:
+  case ARM::BI__builtin_neon_vpadalq_v:
+    Int = usgn ? Intrinsic::arm_neon_vpadalu : Intrinsic::arm_neon_vpadals;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vpadal");
+  case ARM::BI__builtin_neon_vpadd_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vpadd, &Ty, 1),
+                        Ops, "vpadd");
+  case ARM::BI__builtin_neon_vpaddl_v:
+  case ARM::BI__builtin_neon_vpaddlq_v:
+    Int = usgn ? Intrinsic::arm_neon_vpaddlu : Intrinsic::arm_neon_vpaddls;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vpaddl");
+  case ARM::BI__builtin_neon_vpmax_v:
+    Int = usgn ? Intrinsic::arm_neon_vpmaxu : Intrinsic::arm_neon_vpmaxs;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vpmax");
+  case ARM::BI__builtin_neon_vpmin_v:
+    Int = usgn ? Intrinsic::arm_neon_vpminu : Intrinsic::arm_neon_vpmins;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vpmin");
+  case ARM::BI__builtin_neon_vqabs_v:
+  case ARM::BI__builtin_neon_vqabsq_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqabs, &Ty, 1),
+                        Ops, "vqabs");
+  case ARM::BI__builtin_neon_vqadd_v:
+  case ARM::BI__builtin_neon_vqaddq_v:
+    Int = usgn ? Intrinsic::arm_neon_vqaddu : Intrinsic::arm_neon_vqadds;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqadd");
+  case ARM::BI__builtin_neon_vqdmlal_lane_v:
+    splat = true;
+  case ARM::BI__builtin_neon_vqdmlal_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmlal, &Ty, 1),
+                        Ops, "vqdmlal", splat);
+  case ARM::BI__builtin_neon_vqdmlsl_lane_v:
+    splat = true;
+  case ARM::BI__builtin_neon_vqdmlsl_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmlsl, &Ty, 1),
+                        Ops, "vqdmlsl", splat);
+  case ARM::BI__builtin_neon_vqdmulh_lane_v:
+  case ARM::BI__builtin_neon_vqdmulhq_lane_v:
+    splat = true;
+  case ARM::BI__builtin_neon_vqdmulh_v:
+  case ARM::BI__builtin_neon_vqdmulhq_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmulh, &Ty, 1),
+                        Ops, "vqdmulh", splat);
+  case ARM::BI__builtin_neon_vqdmull_lane_v:
+    splat = true;
+  case ARM::BI__builtin_neon_vqdmull_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, &Ty, 1),
+                        Ops, "vqdmull", splat);
+  case ARM::BI__builtin_neon_vqmovn_v:
+    Int = usgn ? Intrinsic::arm_neon_vqmovnu : Intrinsic::arm_neon_vqmovns;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqmovn");
+  case ARM::BI__builtin_neon_vqmovun_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqmovnsu, &Ty, 1),
+                        Ops, "vqdmull");
+  case ARM::BI__builtin_neon_vqneg_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqneg, &Ty, 1),
+                        Ops, "vqneg");
+  case ARM::BI__builtin_neon_vqrdmulh_lane_v:
+  case ARM::BI__builtin_neon_vqrdmulhq_lane_v:
+    splat = true;
+  case ARM::BI__builtin_neon_vqrdmulh_v:
+  case ARM::BI__builtin_neon_vqrdmulhq_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrdmulh, &Ty, 1),
+                        Ops, "vqrdmulh", splat);
+  case ARM::BI__builtin_neon_vqrshl_v:
+  case ARM::BI__builtin_neon_vqrshlq_v:
+    Int = usgn ? Intrinsic::arm_neon_vqrshiftu : Intrinsic::arm_neon_vqrshifts;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqrshl");
+  case ARM::BI__builtin_neon_vqrshrn_n_v:
+    Int = usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqrshrn_n", false,
+                        1, true);
+  case ARM::BI__builtin_neon_vqrshrun_n_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, &Ty, 1),
+                        Ops, "vqrshrun_n", false, 1, true);
+  case ARM::BI__builtin_neon_vqshl_v:
+  case ARM::BI__builtin_neon_vqshlq_v:
+    Int = usgn ? Intrinsic::arm_neon_vqshiftu : Intrinsic::arm_neon_vqshifts;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqshl");
+  case ARM::BI__builtin_neon_vqshl_n_v:
+  case ARM::BI__builtin_neon_vqshlq_n_v:
+    Int = usgn ? Intrinsic::arm_neon_vqshiftu : Intrinsic::arm_neon_vqshifts;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqshl_n", false,
+                        1, false);
+  case ARM::BI__builtin_neon_vqshlu_n_v:
+  case ARM::BI__builtin_neon_vqshluq_n_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftsu, &Ty, 1),
+                        Ops, "vqshlu", 1, false);
+  case ARM::BI__builtin_neon_vqshrn_n_v:
+    Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqshrn_n", false,
+                        1, true);
+  case ARM::BI__builtin_neon_vqshrun_n_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, &Ty, 1),
+                        Ops, "vqshrun_n", false, 1, true);
+  case ARM::BI__builtin_neon_vqsub_v:
+  case ARM::BI__builtin_neon_vqsubq_v:
+    Int = usgn ? Intrinsic::arm_neon_vqsubu : Intrinsic::arm_neon_vqsubs;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqsub");
+  case ARM::BI__builtin_neon_vraddhn_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vraddhn, &Ty, 1),
+                        Ops, "vraddhn");
+  case ARM::BI__builtin_neon_vrecpe_v:
+  case ARM::BI__builtin_neon_vrecpeq_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, &Ty, 1),
+                        Ops, "vrecpe");
+  case ARM::BI__builtin_neon_vrecps_v:
+  case ARM::BI__builtin_neon_vrecpsq_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecps, &Ty, 1),
+                        Ops, "vrecps");
+  case ARM::BI__builtin_neon_vrhadd_v:
+  case ARM::BI__builtin_neon_vrhaddq_v:
+    Int = usgn ? Intrinsic::arm_neon_vrhaddu : Intrinsic::arm_neon_vrhadds;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vrhadd");
+  case ARM::BI__builtin_neon_vrshl_v:
+  case ARM::BI__builtin_neon_vrshlq_v:
+    Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vrshl");
+  case ARM::BI__builtin_neon_vrshrn_n_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, &Ty, 1),
+                        Ops, "vrshrn_n", false, 1, true);
+  case ARM::BI__builtin_neon_vrshr_n_v:
+  case ARM::BI__builtin_neon_vrshrq_n_v:
+    Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vrshr_n", false,
+                        1, true);
+  case ARM::BI__builtin_neon_vrsqrte_v:
+  case ARM::BI__builtin_neon_vrsqrteq_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrte, &Ty, 1),
+                        Ops, "vrsqrte");
+  case ARM::BI__builtin_neon_vrsqrts_v:
+  case ARM::BI__builtin_neon_vrsqrtsq_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrts, &Ty, 1),
+                        Ops, "vrsqrts");
+  case ARM::BI__builtin_neon_vrsra_n_v:
+  case ARM::BI__builtin_neon_vrsraq_n_v:
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true);
+    Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts;
+    Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, &Ty, 1), Ops[1], Ops[2]); 
+    return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n");
+  case ARM::BI__builtin_neon_vrsubhn_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsubhn, &Ty, 1),
+                        Ops, "vrsubhn");
+  case ARM::BI__builtin_neon_vset_lane_i8:
+  case ARM::BI__builtin_neon_vset_lane_i16:
+  case ARM::BI__builtin_neon_vset_lane_i32:
+  case ARM::BI__builtin_neon_vset_lane_i64:
+  case ARM::BI__builtin_neon_vset_lane_f32:
+  case ARM::BI__builtin_neon_vsetq_lane_i8:
+  case ARM::BI__builtin_neon_vsetq_lane_i16:
+  case ARM::BI__builtin_neon_vsetq_lane_i32:
+  case ARM::BI__builtin_neon_vsetq_lane_i64:
+  case ARM::BI__builtin_neon_vsetq_lane_f32:
+    Ops.push_back(EmitScalarExpr(E->getArg(2)));
+    return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
+  case ARM::BI__builtin_neon_vshl_v:
+  case ARM::BI__builtin_neon_vshlq_v:
+    Int = usgn ? Intrinsic::arm_neon_vshiftu : Intrinsic::arm_neon_vshifts;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vshl");
+  case ARM::BI__builtin_neon_vshll_n_v:
+    Int = usgn ? Intrinsic::arm_neon_vshiftlu : Intrinsic::arm_neon_vshiftls;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vshll", false, 1);
+  case ARM::BI__builtin_neon_vshl_n_v:
+  case ARM::BI__builtin_neon_vshlq_n_v:
+    Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false);
+    return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1], "vshl_n");
+  case ARM::BI__builtin_neon_vshrn_n_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftn, &Ty, 1),
+                        Ops, "vshrn_n", false, 1, true);
+  case ARM::BI__builtin_neon_vshr_n_v:
+  case ARM::BI__builtin_neon_vshrq_n_v:
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false);
+    if (usgn)
+      return Builder.CreateLShr(Ops[0], Ops[1], "vshr_n");
+    else
+      return Builder.CreateAShr(Ops[0], Ops[1], "vshr_n");
+  case ARM::BI__builtin_neon_vsri_n_v:
+  case ARM::BI__builtin_neon_vsriq_n_v:
+    poly = true;
+  case ARM::BI__builtin_neon_vsli_n_v:
+  case ARM::BI__builtin_neon_vsliq_n_v:
+    Ops[2] = EmitNeonShiftVector(Ops[2], Ty, poly);
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, &Ty, 1),
+                        Ops, "vsli_n");
+  case ARM::BI__builtin_neon_vsra_n_v:
+  case ARM::BI__builtin_neon_vsraq_n_v:
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[2] = EmitNeonShiftVector(Ops[2], Ty, false);
+    if (usgn)
+      Ops[1] = Builder.CreateLShr(Ops[1], Ops[2], "vsra_n");
+    else
+      Ops[1] = Builder.CreateAShr(Ops[1], Ops[2], "vsra_n");
+    return Builder.CreateAdd(Ops[0], Ops[1]);
+  case ARM::BI__builtin_neon_vst1_v:
+  case ARM::BI__builtin_neon_vst1q_v:
+    Ops.push_back(GetPointeeAlignment(*this, E->getArg(0)));
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, &Ty, 1),
+                        Ops, "");
+  case ARM::BI__builtin_neon_vst1_lane_v:
+  case ARM::BI__builtin_neon_vst1q_lane_v:
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]);
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    return Builder.CreateStore(Ops[1], Builder.CreateBitCast(Ops[0], Ty));
+  case ARM::BI__builtin_neon_vst2_v:
+  case ARM::BI__builtin_neon_vst2q_v:
+    Ops.push_back(GetPointeeAlignment(*this, E->getArg(0)));
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2, &Ty, 1),
+                        Ops, "");
+  case ARM::BI__builtin_neon_vst2_lane_v:
+  case ARM::BI__builtin_neon_vst2q_lane_v:
+    Ops.push_back(GetPointeeAlignment(*this, E->getArg(0)));
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2lane, &Ty, 1),
+                        Ops, "");
+  case ARM::BI__builtin_neon_vst3_v:
+  case ARM::BI__builtin_neon_vst3q_v:
+    Ops.push_back(GetPointeeAlignment(*this, E->getArg(0)));
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3, &Ty, 1),
+                        Ops, "");
+  case ARM::BI__builtin_neon_vst3_lane_v:
+  case ARM::BI__builtin_neon_vst3q_lane_v:
+    Ops.push_back(GetPointeeAlignment(*this, E->getArg(0)));
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3lane, &Ty, 1),
+                        Ops, "");
+  case ARM::BI__builtin_neon_vst4_v:
+  case ARM::BI__builtin_neon_vst4q_v:
+    Ops.push_back(GetPointeeAlignment(*this, E->getArg(0)));
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4, &Ty, 1),
+                        Ops, "");
+  case ARM::BI__builtin_neon_vst4_lane_v:
+  case ARM::BI__builtin_neon_vst4q_lane_v:
+    Ops.push_back(GetPointeeAlignment(*this, E->getArg(0)));
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4lane, &Ty, 1),
+                        Ops, "");
+  case ARM::BI__builtin_neon_vsubhn_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vsubhn, &Ty, 1),
+                        Ops, "vsubhn");
+  case ARM::BI__builtin_neon_vsubl_v:
+    Int = usgn ? Intrinsic::arm_neon_vsublu : Intrinsic::arm_neon_vsubls;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vsubl");
+  case ARM::BI__builtin_neon_vsubw_v:
+    Int = usgn ? Intrinsic::arm_neon_vsubws : Intrinsic::arm_neon_vsubwu;
+    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vsubw");
+  case ARM::BI__builtin_neon_vtbl1_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1),
+                        Ops, "vtbl1");
+  case ARM::BI__builtin_neon_vtbl2_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2),
+                        Ops, "vtbl2");
+  case ARM::BI__builtin_neon_vtbl3_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3),
+                        Ops, "vtbl3");
+  case ARM::BI__builtin_neon_vtbl4_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4),
+                        Ops, "vtbl4");
+  case ARM::BI__builtin_neon_vtbx1_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1),
+                        Ops, "vtbx1");
+  case ARM::BI__builtin_neon_vtbx2_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2),
+                        Ops, "vtbx2");
+  case ARM::BI__builtin_neon_vtbx3_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3),
+                        Ops, "vtbx3");
+  case ARM::BI__builtin_neon_vtbx4_v:
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4),
+                        Ops, "vtbx4");
+  case ARM::BI__builtin_neon_vtst_v:
+  case ARM::BI__builtin_neon_vtstq_v: {
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]);
+    Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 
+                                ConstantAggregateZero::get(Ty));
+    return Builder.CreateSExt(Ops[0], Ty, "vtst");
+  }
+  case ARM::BI__builtin_neon_vtrn_v:
+  case ARM::BI__builtin_neon_vtrnq_v: {
+    Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
+    Value *SV;
+
+    for (unsigned vi = 0; vi != 2; ++vi) {
+      SmallVector<Constant*, 16> Indices;
+      for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
+        Indices.push_back(ConstantInt::get(Int32Ty, i+vi));
+        Indices.push_back(ConstantInt::get(Int32Ty, i+e+vi));
+      }
+      Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi);
+      SV = llvm::ConstantVector::get(Indices.begin(), Indices.size());
+      SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vtrn");
+      SV = Builder.CreateStore(SV, Addr);
+    }
+    return SV;
+  }
+  case ARM::BI__builtin_neon_vuzp_v:
+  case ARM::BI__builtin_neon_vuzpq_v: {
+    Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
+    Value *SV;
+    
+    for (unsigned vi = 0; vi != 2; ++vi) {
+      SmallVector<Constant*, 16> Indices;
+      for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
+        Indices.push_back(ConstantInt::get(Int32Ty, 2*i+vi));
+
+      Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi);
+      SV = llvm::ConstantVector::get(Indices.begin(), Indices.size());
+      SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vuzp");
+      SV = Builder.CreateStore(SV, Addr);
+    }
+    return SV;
+  }
+  case ARM::BI__builtin_neon_vzip_v: 
+  case ARM::BI__builtin_neon_vzipq_v: {
+    Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
+    Value *SV;
+    
+    for (unsigned vi = 0; vi != 2; ++vi) {
+      SmallVector<Constant*, 16> Indices;
+      for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
+        Indices.push_back(ConstantInt::get(Int32Ty, (i + vi*e) >> 1));
+        Indices.push_back(ConstantInt::get(Int32Ty, ((i + vi*e) >> 1)+e));
+      }
+      Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi);
+      SV = llvm::ConstantVector::get(Indices.begin(), Indices.size());
+      SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vzip");
+      SV = Builder.CreateStore(SV, Addr);
+    }
+    return SV;
   }
   }
 }
@@ -832,9 +1778,9 @@
   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.CreateZExt(Ops[1], Int64Ty, "zext");
+    const llvm::Type *Ty = llvm::VectorType::get(Int64Ty, 2);
+    llvm::Value *Zero = llvm::ConstantInt::get(Int32Ty, 0);
     Ops[1] = Builder.CreateInsertElement(llvm::UndefValue::get(Ty),
                                          Ops[1], Zero, "insert");
     Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType(), "bitcast");
@@ -887,8 +1833,8 @@
   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.CreateZExt(Ops[1], Int64Ty, "zext");
+    const llvm::Type *Ty = llvm::VectorType::get(Int64Ty, 1);
     Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast");
     const char *name = 0;
     Intrinsic::ID ID = Intrinsic::not_intrinsic;
@@ -941,16 +1887,16 @@
   }
   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");
+    Value *One = llvm::ConstantInt::get(Int32Ty, 1);
+    Value *Tmp = Builder.CreateAlloca(Int32Ty, 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");
+    Value *One = llvm::ConstantInt::get(Int32Ty, 1);
+    Value *Tmp = Builder.CreateAlloca(Int32Ty, One, "tmp");
     One = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr),
                              Builder.CreateBitCast(Tmp, PtrTy));
     return Builder.CreateLoad(Tmp, "stmxcsr");
@@ -965,16 +1911,15 @@
   }
   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);
+    llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty);
+    llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 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);
+    llvm::Value *Idx = llvm::ConstantInt::get(Int32Ty, Index);
     Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract");
 
     // cast pointer to i64 & store
@@ -987,11 +1932,9 @@
     // 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));
+        Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i));
       
       Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size());
       return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr");
@@ -1001,8 +1944,7 @@
     // 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);
+      const llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 1);
       
       Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast");
       Ops[1] = llvm::ConstantInt::get(VecTy, (shiftVal-8) * 8);
@@ -1021,11 +1963,9 @@
     // 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));
+        Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i));
       
       Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size());
       return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr");
@@ -1034,12 +1974,10 @@
     // 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);
+      const llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2);
       
       Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast");
-      Ops[1] = llvm::ConstantInt::get(IntTy, (shiftVal-16) * 8);
+      Ops[1] = llvm::ConstantInt::get(Int32Ty, (shiftVal-16) * 8);
       
       // create i32 constant
       llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_psrl_dq);
@@ -1064,6 +2002,48 @@
   switch (BuiltinID) {
   default: return 0;
 
+  // vec_ld, vec_lvsl, vec_lvsr
+  case PPC::BI__builtin_altivec_lvx:
+  case PPC::BI__builtin_altivec_lvxl:
+  case PPC::BI__builtin_altivec_lvebx:
+  case PPC::BI__builtin_altivec_lvehx:
+  case PPC::BI__builtin_altivec_lvewx:
+  case PPC::BI__builtin_altivec_lvsl:
+  case PPC::BI__builtin_altivec_lvsr:
+  {
+    Ops[1] = Builder.CreateBitCast(Ops[1], llvm::Type::getInt8PtrTy(VMContext));
+
+    Ops[0] = Builder.CreateGEP(Ops[1], Ops[0], "tmp");
+    Ops.pop_back();
+
+    switch (BuiltinID) {
+    default: assert(0 && "Unsupported ld/lvsl/lvsr intrinsic!");
+    case PPC::BI__builtin_altivec_lvx:
+      ID = Intrinsic::ppc_altivec_lvx;
+      break;
+    case PPC::BI__builtin_altivec_lvxl:
+      ID = Intrinsic::ppc_altivec_lvxl;
+      break;
+    case PPC::BI__builtin_altivec_lvebx:
+      ID = Intrinsic::ppc_altivec_lvebx;
+      break;
+    case PPC::BI__builtin_altivec_lvehx:
+      ID = Intrinsic::ppc_altivec_lvehx;
+      break;
+    case PPC::BI__builtin_altivec_lvewx:
+      ID = Intrinsic::ppc_altivec_lvewx;
+      break;
+    case PPC::BI__builtin_altivec_lvsl:
+      ID = Intrinsic::ppc_altivec_lvsl;
+      break;
+    case PPC::BI__builtin_altivec_lvsr:
+      ID = Intrinsic::ppc_altivec_lvsr;
+      break;
+    }
+    llvm::Function *F = CGM.getIntrinsic(ID);
+    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "");
+  }
+
   // vec_st
   case PPC::BI__builtin_altivec_stvx:
   case PPC::BI__builtin_altivec_stvxl:
@@ -1072,12 +2052,11 @@
   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[1] = Builder.CreateGEP(Ops[2], Ops[1], "tmp");
     Ops.pop_back();
 
     switch (BuiltinID) {
-    default: assert(0 && "Unsupported vavg intrinsic!");
+    default: assert(0 && "Unsupported st intrinsic!");
     case PPC::BI__builtin_altivec_stvx:
       ID = Intrinsic::ppc_altivec_stvx;
       break;
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 74cf113..94378b7 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -13,6 +13,7 @@
 
 // We might split this into multiple files if it gets too unwieldy
 
+#include "CGCXXABI.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "Mangle.h"
@@ -22,7 +23,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/StmtCXX.h"
-#include "clang/CodeGen/CodeGenOptions.h"
+#include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/ADT/StringExtras.h"
 using namespace clang;
 using namespace CodeGen;
@@ -96,8 +97,8 @@
   /// 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())
+  const CXXDestructorDecl *BaseD = UniqueBase->getDestructor();
+  if (!BaseD->isImplicit() && !BaseD->hasBody())
     return true;
 
   // If the base is at a non-zero offset, give up.
@@ -165,8 +166,7 @@
     new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule());
 
   // Switch any previous uses to the alias.
-  MangleBuffer MangledName;
-  getMangledName(MangledName, AliasDecl);
+  llvm::StringRef MangledName = getMangledName(AliasDecl);
   llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
   if (Entry) {
     assert(Entry->isDeclaration() && "definition already exists for alias");
@@ -176,7 +176,7 @@
     Entry->replaceAllUsesWith(Alias);
     Entry->eraseFromParent();
   } else {
-    Alias->setName(MangledName.getString());
+    Alias->setName(MangledName);
   }
 
   // Finally, set up the alias with its proper name and attributes.
@@ -206,6 +206,7 @@
     return;
 
   llvm::Function *Fn = cast<llvm::Function>(GetAddrOfCXXConstructor(D, Type));
+  setFunctionLinkage(D, Fn);
 
   CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn);
 
@@ -216,8 +217,9 @@
 llvm::GlobalValue *
 CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
                                        CXXCtorType Type) {
-  MangleBuffer Name;
-  getMangledCXXCtorName(Name, D, Type);
+  GlobalDecl GD(D, Type);
+  
+  llvm::StringRef Name = getMangledName(GD);
   if (llvm::GlobalValue *V = GetGlobalValue(Name))
     return V;
 
@@ -225,14 +227,7 @@
   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());
+  return cast<llvm::Function>(GetOrCreateLLVMFunction(Name, FTy, GD));
 }
 
 void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
@@ -269,6 +264,7 @@
     return;
 
   llvm::Function *Fn = cast<llvm::Function>(GetAddrOfCXXDestructor(D, Type));
+  setFunctionLinkage(D, Fn);
 
   CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn);
 
@@ -279,22 +275,16 @@
 llvm::GlobalValue *
 CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
                                       CXXDtorType Type) {
-  MangleBuffer Name;
-  getMangledCXXDtorName(Name, D, Type);
+  GlobalDecl GD(D, Type);
+
+  llvm::StringRef Name = getMangledName(GD);
   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());
+  return cast<llvm::Function>(GetOrCreateLLVMFunction(Name, FTy, GD));
 }
 
 static llvm::Value *BuildVirtualCall(CodeGenFunction &CGF, uint64_t VTableIndex, 
@@ -327,3 +317,96 @@
 
   return ::BuildVirtualCall(*this, VTableIndex, This, Ty);
 }
+
+/// Implementation for CGCXXABI.  Possibly this should be moved into
+/// the incomplete ABI implementations?
+
+CGCXXABI::~CGCXXABI() {}
+
+static void ErrorUnsupportedABI(CodeGenFunction &CGF,
+                                llvm::StringRef S) {
+  Diagnostic &Diags = CGF.CGM.getDiags();
+  unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Error,
+                                          "cannot yet compile %s in this ABI");
+  Diags.Report(CGF.getContext().getFullLoc(CGF.CurCodeDecl->getLocation()),
+               DiagID)
+    << S;
+}
+
+static llvm::Constant *GetBogusMemberPointer(CodeGenModule &CGM,
+                                             QualType T) {
+  return llvm::Constant::getNullValue(CGM.getTypes().ConvertType(T));
+}
+
+const llvm::Type *
+CGCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
+  return CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
+}
+
+llvm::Value *CGCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
+                                                       llvm::Value *&This,
+                                                       llvm::Value *MemPtr,
+                                                 const MemberPointerType *MPT) {
+  ErrorUnsupportedABI(CGF, "calls through member pointers");
+
+  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());
+  return llvm::Constant::getNullValue(FTy->getPointerTo());
+}
+
+llvm::Value *CGCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
+                                                   const CastExpr *E,
+                                                   llvm::Value *Src) {
+  ErrorUnsupportedABI(CGF, "member function pointer conversions");
+  return GetBogusMemberPointer(CGM, E->getType());
+}
+
+llvm::Value *
+CGCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
+                                      llvm::Value *L,
+                                      llvm::Value *R,
+                                      const MemberPointerType *MPT,
+                                      bool Inequality) {
+  ErrorUnsupportedABI(CGF, "member function pointer comparison");
+  return CGF.Builder.getFalse();
+}
+
+llvm::Value *
+CGCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
+                                     llvm::Value *MemPtr,
+                                     const MemberPointerType *MPT) {
+  ErrorUnsupportedABI(CGF, "member function pointer null testing");
+  return CGF.Builder.getFalse();
+}
+
+llvm::Constant *
+CGCXXABI::EmitMemberPointerConversion(llvm::Constant *C, const CastExpr *E) {
+  return GetBogusMemberPointer(CGM, E->getType());
+}
+
+llvm::Constant *
+CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
+  return GetBogusMemberPointer(CGM, QualType(MPT, 0));
+}
+
+llvm::Constant *CGCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
+  return GetBogusMemberPointer(CGM,
+                         CGM.getContext().getMemberPointerType(MD->getType(),
+                                         MD->getParent()->getTypeForDecl()));
+}
+
+llvm::Constant *CGCXXABI::EmitMemberPointer(const FieldDecl *FD) {
+  return GetBogusMemberPointer(CGM,
+                         CGM.getContext().getMemberPointerType(FD->getType(),
+                                         FD->getParent()->getTypeForDecl()));
+}
+
+bool CGCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
+  // Fake answer.
+  return true;
+}
diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h
new file mode 100644
index 0000000..25110eb
--- /dev/null
+++ b/lib/CodeGen/CGCXXABI.h
@@ -0,0 +1,112 @@
+//===----- CGCXXABI.h - Interface to C++ ABIs -------------------*- 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 C++ code generation. Concrete subclasses
+// of this implement code generation for specific C++ ABIs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CXXABI_H
+#define CLANG_CODEGEN_CXXABI_H
+
+namespace llvm {
+  class Constant;
+  class Type;
+  class Value;
+}
+
+namespace clang {
+  class CastExpr;
+  class CXXMethodDecl;
+  class CXXRecordDecl;
+  class FieldDecl;
+  class MemberPointerType;
+  class QualType;
+
+namespace CodeGen {
+  class CodeGenFunction;
+  class CodeGenModule;
+  class MangleContext;
+
+/// Implements C++ ABI-specific code generation functions.
+class CGCXXABI {
+protected:
+  CodeGenModule &CGM;
+
+  CGCXXABI(CodeGenModule &CGM) : CGM(CGM) {}
+
+public:
+
+  virtual ~CGCXXABI();
+
+  /// Gets the mangle context.
+  virtual MangleContext &getMangleContext() = 0;
+
+  /// Find the LLVM type used to represent the given member pointer
+  /// type.
+  virtual const llvm::Type *
+  ConvertMemberPointerType(const MemberPointerType *MPT);
+
+  /// Load a member function from an object and a member function
+  /// pointer.  Apply the this-adjustment and set 'This' to the
+  /// adjusted value.
+  virtual llvm::Value *
+  EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
+                                  llvm::Value *&This,
+                                  llvm::Value *MemPtr,
+                                  const MemberPointerType *MPT);
+
+  /// Perform a derived-to-base or base-to-derived member pointer
+  /// conversion.
+  virtual llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
+                                                   const CastExpr *E,
+                                                   llvm::Value *Src);
+
+  /// Perform a derived-to-base or base-to-derived member pointer
+  /// conversion on a constant member pointer.
+  virtual llvm::Constant *EmitMemberPointerConversion(llvm::Constant *C,
+                                                      const CastExpr *E);
+
+  /// Return true if the given member pointer can be zero-initialized
+  /// (in the C++ sense) with an LLVM zeroinitializer.
+  virtual bool isZeroInitializable(const MemberPointerType *MPT);
+
+  /// Create a null member pointer of the given type.
+  virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
+
+  /// Create a member pointer for the given method.
+  virtual llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD);
+
+  /// Create a member pointer for the given field.
+  virtual llvm::Constant *EmitMemberPointer(const FieldDecl *FD);
+
+  /// Emit a comparison between two member pointers.  Returns an i1.
+  virtual llvm::Value *
+  EmitMemberPointerComparison(CodeGenFunction &CGF,
+                              llvm::Value *L,
+                              llvm::Value *R,
+                              const MemberPointerType *MPT,
+                              bool Inequality);
+
+  /// Determine if a member pointer is non-null.  Returns an i1.
+  virtual llvm::Value *
+  EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
+                             llvm::Value *MemPtr,
+                             const MemberPointerType *MPT);
+};
+
+/// Creates an instance of a C++ ABI class.
+CGCXXABI *CreateARMCXXABI(CodeGenModule &CGM);
+CGCXXABI *CreateItaniumCXXABI(CodeGenModule &CGM);
+CGCXXABI *CreateMicrosoftCXXABI(CodeGenModule &CGM);
+
+}
+}
+
+#endif
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 8b5c3a0..4c48d63 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -13,31 +13,28 @@
 //===----------------------------------------------------------------------===//
 
 #include "CGCall.h"
+#include "ABIInfo.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 "clang/Frontend/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;
+  case CC_X86ThisCall: return llvm::CallingConv::X86_ThisCall;
   }
 }
 
@@ -64,29 +61,31 @@
 }
 
 const CGFunctionInfo &
-CodeGenTypes::getFunctionInfo(CanQual<FunctionNoProtoType> FTNP) {
+CodeGenTypes::getFunctionInfo(CanQual<FunctionNoProtoType> FTNP,
+                              bool IsRecursive) {
   return getFunctionInfo(FTNP->getResultType().getUnqualifiedType(),
                          llvm::SmallVector<CanQualType, 16>(),
-                         FTNP->getExtInfo());
+                         FTNP->getExtInfo(), IsRecursive);
 }
 
 /// \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) {
+                                             CanQual<FunctionProtoType> FTP,
+                                             bool IsRecursive = false) {
   // 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());
+  return CGT.getFunctionInfo(ResTy, ArgTys, FTP->getExtInfo(), IsRecursive);
 }
 
 const CGFunctionInfo &
-CodeGenTypes::getFunctionInfo(CanQual<FunctionProtoType> FTP) {
+CodeGenTypes::getFunctionInfo(CanQual<FunctionProtoType> FTP,
+                              bool IsRecursive) {
   llvm::SmallVector<CanQualType, 16> ArgTys;
-  return ::getFunctionInfo(*this, ArgTys, FTP);
+  return ::getFunctionInfo(*this, ArgTys, FTP, IsRecursive);
 }
 
 static CallingConv getCallingConventionForDecl(const Decl *D) {
@@ -97,6 +96,9 @@
   if (D->hasAttr<FastCallAttr>())
     return CC_X86FastCall;
 
+  if (D->hasAttr<ThisCallAttr>())
+    return CC_X86ThisCall;
+
   return CC_C;
 }
 
@@ -216,7 +218,8 @@
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(CanQualType ResTy,
                            const llvm::SmallVectorImpl<CanQualType> &ArgTys,
-                                            const FunctionType::ExtInfo &Info) {
+                                            const FunctionType::ExtInfo &Info,
+                                                    bool IsRecursive) {
 #ifndef NDEBUG
   for (llvm::SmallVectorImpl<CanQualType>::const_iterator
          I = ArgTys.begin(), E = ArgTys.end(); I != E; ++I)
@@ -236,35 +239,57 @@
     return *FI;
 
   // Construct the function info.
-  FI = new CGFunctionInfo(CC, Info.getNoReturn(), Info.getRegParm(), ResTy, ArgTys);
+  FI = new CGFunctionInfo(CC, Info.getNoReturn(), Info.getRegParm(), ResTy,
+                          ArgTys.data(), ArgTys.size());
   FunctionInfos.InsertNode(FI, InsertPos);
 
   // Compute ABI information.
-  getABIInfo().computeInfo(*FI, getContext(), TheModule.getContext());
+  getABIInfo().computeInfo(*FI);
+  
+  // Loop over all of the computed argument and return value info.  If any of
+  // them are direct or extend without a specified coerce type, specify the
+  // default now.
+  ABIArgInfo &RetInfo = FI->getReturnInfo();
+  if (RetInfo.canHaveCoerceToType() && RetInfo.getCoerceToType() == 0)
+    RetInfo.setCoerceToType(ConvertTypeRecursive(FI->getReturnType()));
+  
+  for (CGFunctionInfo::arg_iterator I = FI->arg_begin(), E = FI->arg_end();
+       I != E; ++I)
+    if (I->info.canHaveCoerceToType() && I->info.getCoerceToType() == 0)
+      I->info.setCoerceToType(ConvertTypeRecursive(I->type));
 
+  // If this is a top-level call and ConvertTypeRecursive hit unresolved pointer
+  // types, resolve them now.  These pointers may point to this function, which
+  // we *just* filled in the FunctionInfo for.
+  if (!IsRecursive && !PointersToResolve.empty())
+    HandleLateResolvedPointers();
+  
   return *FI;
 }
 
 CGFunctionInfo::CGFunctionInfo(unsigned _CallingConvention,
-                               bool _NoReturn,
-                               unsigned _RegParm,
+                               bool _NoReturn, unsigned _RegParm,
                                CanQualType ResTy,
-                               const llvm::SmallVectorImpl<CanQualType> &ArgTys)
+                               const CanQualType *ArgTys,
+                               unsigned NumArgTys)
   : CallingConvention(_CallingConvention),
     EffectiveCallingConvention(_CallingConvention),
     NoReturn(_NoReturn), RegParm(_RegParm)
 {
-  NumArgs = ArgTys.size();
-  Args = new ArgInfo[1 + NumArgs];
+  NumArgs = NumArgTys;
+  
+  // FIXME: Coallocate with the CGFunctionInfo object.
+  Args = new ArgInfo[1 + NumArgTys];
   Args[0].type = ResTy;
-  for (unsigned i = 0; i < NumArgs; ++i)
+  for (unsigned i = 0; i != NumArgTys; ++i)
     Args[1 + i].type = ArgTys[i];
 }
 
 /***/
 
 void CodeGenTypes::GetExpandedTypes(QualType Ty,
-                                    std::vector<const llvm::Type*> &ArgTys) {
+                                    std::vector<const llvm::Type*> &ArgTys,
+                                    bool IsRecursive) {
   const RecordType *RT = Ty->getAsStructureType();
   assert(RT && "Can only expand structure types.");
   const RecordDecl *RD = RT->getDecl();
@@ -278,11 +303,10 @@
            "Cannot expand structure with bit-field members.");
 
     QualType FT = FD->getType();
-    if (CodeGenFunction::hasAggregateLLVMType(FT)) {
-      GetExpandedTypes(FT, ArgTys);
-    } else {
-      ArgTys.push_back(ConvertType(FT));
-    }
+    if (CodeGenFunction::hasAggregateLLVMType(FT))
+      GetExpandedTypes(FT, ArgTys, IsRecursive);
+    else
+      ArgTys.push_back(ConvertType(FT, IsRecursive));
   }
 }
 
@@ -341,6 +365,71 @@
   }
 }
 
+/// EnterStructPointerForCoercedAccess - Given a struct pointer that we are
+/// accessing some number of bytes out of it, try to gep into the struct to get
+/// at its inner goodness.  Dive as deep as possible without entering an element
+/// with an in-memory size smaller than DstSize.
+static llvm::Value *
+EnterStructPointerForCoercedAccess(llvm::Value *SrcPtr,
+                                   const llvm::StructType *SrcSTy,
+                                   uint64_t DstSize, CodeGenFunction &CGF) {
+  // We can't dive into a zero-element struct.
+  if (SrcSTy->getNumElements() == 0) return SrcPtr;
+  
+  const llvm::Type *FirstElt = SrcSTy->getElementType(0);
+  
+  // If the first elt is at least as large as what we're looking for, or if the
+  // first element is the same size as the whole struct, we can enter it.
+  uint64_t FirstEltSize = 
+    CGF.CGM.getTargetData().getTypeAllocSize(FirstElt);
+  if (FirstEltSize < DstSize && 
+      FirstEltSize < CGF.CGM.getTargetData().getTypeAllocSize(SrcSTy))
+    return SrcPtr;
+  
+  // GEP into the first element.
+  SrcPtr = CGF.Builder.CreateConstGEP2_32(SrcPtr, 0, 0, "coerce.dive");
+  
+  // If the first element is a struct, recurse.
+  const llvm::Type *SrcTy =
+    cast<llvm::PointerType>(SrcPtr->getType())->getElementType();
+  if (const llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy))
+    return EnterStructPointerForCoercedAccess(SrcPtr, SrcSTy, DstSize, CGF);
+
+  return SrcPtr;
+}
+
+/// CoerceIntOrPtrToIntOrPtr - Convert a value Val to the specific Ty where both
+/// are either integers or pointers.  This does a truncation of the value if it
+/// is too large or a zero extension if it is too small.
+static llvm::Value *CoerceIntOrPtrToIntOrPtr(llvm::Value *Val,
+                                             const llvm::Type *Ty,
+                                             CodeGenFunction &CGF) {
+  if (Val->getType() == Ty)
+    return Val;
+  
+  if (isa<llvm::PointerType>(Val->getType())) {
+    // If this is Pointer->Pointer avoid conversion to and from int.
+    if (isa<llvm::PointerType>(Ty))
+      return CGF.Builder.CreateBitCast(Val, Ty, "coerce.val");
+  
+    // Convert the pointer to an integer so we can play with its width.
+    Val = CGF.Builder.CreatePtrToInt(Val, CGF.IntPtrTy, "coerce.val.pi");
+  }
+  
+  const llvm::Type *DestIntTy = Ty;
+  if (isa<llvm::PointerType>(DestIntTy))
+    DestIntTy = CGF.IntPtrTy;
+  
+  if (Val->getType() != DestIntTy)
+    Val = CGF.Builder.CreateIntCast(Val, DestIntTy, false, "coerce.val.ii");
+  
+  if (isa<llvm::PointerType>(Ty))
+    Val = CGF.Builder.CreateIntToPtr(Val, Ty, "coerce.val.ip");
+  return Val;
+}
+
+
+
 /// CreateCoercedLoad - Create a load from \arg SrcPtr interpreted as
 /// a pointer to an object of type \arg Ty.
 ///
@@ -352,9 +441,28 @@
                                       CodeGenFunction &CGF) {
   const llvm::Type *SrcTy =
     cast<llvm::PointerType>(SrcPtr->getType())->getElementType();
-  uint64_t SrcSize = CGF.CGM.getTargetData().getTypeAllocSize(SrcTy);
+  
+  // If SrcTy and Ty are the same, just do a load.
+  if (SrcTy == Ty)
+    return CGF.Builder.CreateLoad(SrcPtr);
+  
   uint64_t DstSize = CGF.CGM.getTargetData().getTypeAllocSize(Ty);
+  
+  if (const llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy)) {
+    SrcPtr = EnterStructPointerForCoercedAccess(SrcPtr, SrcSTy, DstSize, CGF);
+    SrcTy = cast<llvm::PointerType>(SrcPtr->getType())->getElementType();
+  }
+  
+  uint64_t SrcSize = CGF.CGM.getTargetData().getTypeAllocSize(SrcTy);
 
+  // If the source and destination are integer or pointer types, just do an
+  // extension or truncation to the desired type.
+  if ((isa<llvm::IntegerType>(Ty) || isa<llvm::PointerType>(Ty)) &&
+      (isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy))) {
+    llvm::LoadInst *Load = CGF.Builder.CreateLoad(SrcPtr);
+    return CoerceIntOrPtrToIntOrPtr(Load, Ty, CGF);
+  }
+  
   // If load is legal, just bitcast the src pointer.
   if (SrcSize >= DstSize) {
     // Generally SrcSize is never greater than DstSize, since this means we are
@@ -369,18 +477,18 @@
     // 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);
   }
+  
+  // 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,
@@ -395,8 +503,27 @@
   const llvm::Type *SrcTy = Src->getType();
   const llvm::Type *DstTy =
     cast<llvm::PointerType>(DstPtr->getType())->getElementType();
-
+  if (SrcTy == DstTy) {
+    CGF.Builder.CreateStore(Src, DstPtr, DstIsVolatile);
+    return;
+  }
+  
   uint64_t SrcSize = CGF.CGM.getTargetData().getTypeAllocSize(SrcTy);
+  
+  if (const llvm::StructType *DstSTy = dyn_cast<llvm::StructType>(DstTy)) {
+    DstPtr = EnterStructPointerForCoercedAccess(DstPtr, DstSTy, SrcSize, CGF);
+    DstTy = cast<llvm::PointerType>(DstPtr->getType())->getElementType();
+  }
+  
+  // If the source and destination are integer or pointer types, just do an
+  // extension or truncation to the desired type.
+  if ((isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy)) &&
+      (isa<llvm::IntegerType>(DstTy) || isa<llvm::PointerType>(DstTy))) {
+    Src = CoerceIntOrPtrToIntOrPtr(Src, DstTy, CGF);
+    CGF.Builder.CreateStore(Src, DstPtr, DstIsVolatile);
+    return;
+  }
+  
   uint64_t DstSize = CGF.CGM.getTargetData().getTypeAllocSize(DstTy);
 
   // If store is legal, just bitcast the src pointer.
@@ -428,10 +555,28 @@
 
 /***/
 
-bool CodeGenModule::ReturnTypeUsesSret(const CGFunctionInfo &FI) {
+bool CodeGenModule::ReturnTypeUsesSRet(const CGFunctionInfo &FI) {
   return FI.getReturnInfo().isIndirect();
 }
 
+bool CodeGenModule::ReturnTypeUsesFPRet(QualType ResultType) {
+  if (const BuiltinType *BT = ResultType->getAs<BuiltinType>()) {
+    switch (BT->getKind()) {
+    default:
+      return false;
+    case BuiltinType::Float:
+      return getContext().Target.useObjCFPRetForRealType(TargetInfo::Float);
+    case BuiltinType::Double:
+      return getContext().Target.useObjCFPRetForRealType(TargetInfo::Double);
+    case BuiltinType::LongDouble:
+      return getContext().Target.useObjCFPRetForRealType(
+        TargetInfo::LongDouble);
+    }
+  }
+
+  return false;
+}
+
 const llvm::FunctionType *CodeGenTypes::GetFunctionType(GlobalDecl GD) {
   const CGFunctionInfo &FI = getFunctionInfo(GD);
   
@@ -441,11 +586,12 @@
         cast<FunctionDecl>(GD.getDecl())->getType()->getAs<FunctionProtoType>())
     Variadic = FPT->isVariadic();
 
-  return GetFunctionType(FI, Variadic);
+  return GetFunctionType(FI, Variadic, false);
 }
 
 const llvm::FunctionType *
-CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) {
+CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic,
+                              bool IsRecursive) {
   std::vector<const llvm::Type*> ArgTys;
 
   const llvm::Type *ResultType = 0;
@@ -458,13 +604,13 @@
 
   case ABIArgInfo::Extend:
   case ABIArgInfo::Direct:
-    ResultType = ConvertType(RetTy);
+    ResultType = RetAI.getCoerceToType();
     break;
 
   case ABIArgInfo::Indirect: {
     assert(!RetAI.getIndirectAlign() && "Align unused on indirect return.");
     ResultType = llvm::Type::getVoidTy(getLLVMContext());
-    const llvm::Type *STy = ConvertType(RetTy);
+    const llvm::Type *STy = ConvertType(RetTy, IsRecursive);
     ArgTys.push_back(llvm::PointerType::get(STy, RetTy.getAddressSpace()));
     break;
   }
@@ -472,10 +618,6 @@
   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(),
@@ -486,24 +628,30 @@
     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);
+      const llvm::Type *LTy = ConvertTypeForMem(it->type, IsRecursive);
       ArgTys.push_back(llvm::PointerType::getUnqual(LTy));
       break;
     }
 
     case ABIArgInfo::Extend:
-    case ABIArgInfo::Direct:
-      ArgTys.push_back(ConvertType(it->type));
+    case ABIArgInfo::Direct: {
+      // If the coerce-to type is a first class aggregate, flatten it.  Either
+      // way is semantically identical, but fast-isel and the optimizer
+      // generally likes scalar values better than FCAs.
+      const llvm::Type *ArgTy = AI.getCoerceToType();
+      if (const llvm::StructType *STy = dyn_cast<llvm::StructType>(ArgTy)) {
+        for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
+          ArgTys.push_back(STy->getElementType(i));
+      } else {
+        ArgTys.push_back(ArgTy);
+      }
       break;
+    }
 
     case ABIArgInfo::Expand:
-      GetExpandedTypes(it->type, ArgTys);
+      GetExpandedTypes(it->type, ArgTys, IsRecursive);
       break;
     }
   }
@@ -511,28 +659,12 @@
   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());
+  if (!VerifyFuncTypeComplete(FPT))
+    return GetFunctionType(getFunctionInfo(MD), FPT->isVariadic(), false);
 
   return llvm::OpaqueType::get(getLLVMContext());
 }
@@ -553,6 +685,12 @@
   if (TargetDecl) {
     if (TargetDecl->hasAttr<NoThrowAttr>())
       FuncAttrs |= llvm::Attribute::NoUnwind;
+    else if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
+      const FunctionProtoType *FPT = Fn->getType()->getAs<FunctionProtoType>();
+      if (FPT && FPT->hasEmptyExceptionSpec())
+        FuncAttrs |= llvm::Attribute::NoUnwind;
+    }
+
     if (TargetDecl->hasAttr<NoReturnAttr>())
       FuncAttrs |= llvm::Attribute::NoReturn;
     if (TargetDecl->hasAttr<ConstAttr>())
@@ -575,13 +713,13 @@
   const ABIArgInfo &RetAI = FI.getReturnInfo();
   switch (RetAI.getKind()) {
   case ABIArgInfo::Extend:
-   if (RetTy->isSignedIntegerType()) {
+   if (RetTy->hasSignedIntegerRepresentation())
      RetAttrs |= llvm::Attribute::SExt;
-   } else if (RetTy->isUnsignedIntegerType()) {
+   else if (RetTy->hasUnsignedIntegerRepresentation())
      RetAttrs |= llvm::Attribute::ZExt;
-   }
-   // FALLTHROUGH
+    break;
   case ABIArgInfo::Direct:
+  case ABIArgInfo::Ignore:
     break;
 
   case ABIArgInfo::Indirect:
@@ -593,10 +731,6 @@
                    llvm::Attribute::ReadNone);
     break;
 
-  case ABIArgInfo::Ignore:
-  case ABIArgInfo::Coerce:
-    break;
-
   case ABIArgInfo::Expand:
     assert(0 && "Invalid ABI kind for return argument");
   }
@@ -604,7 +738,7 @@
   if (RetAttrs)
     PAL.push_back(llvm::AttributeWithIndex::get(0, RetAttrs));
 
-  // FIXME: we need to honour command line settings also...
+  // FIXME: we need to honor command line settings also.
   // FIXME: RegParm should be reduced in case of nested functions and/or global
   // register variable.
   signed RegParm = FI.getRegParm();
@@ -619,9 +753,26 @@
     // '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:
+    case ABIArgInfo::Extend:
+      if (ParamType->isSignedIntegerType())
+        Attributes |= llvm::Attribute::SExt;
+      else if (ParamType->isUnsignedIntegerType())
+        Attributes |= llvm::Attribute::ZExt;
+      // FALL 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...
+        
+      if (const llvm::StructType *STy =
+            dyn_cast<llvm::StructType>(AI.getCoerceToType()))
+        Index += STy->getNumElements()-1;  // 1 will be added below.
       break;
 
     case ABIArgInfo::Indirect:
@@ -635,24 +786,6 @@
                      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;
@@ -662,7 +795,7 @@
       // 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);
+      getTypes().GetExpandedTypes(ParamType, Tys, false);
       Index += Tys.size();
       continue;
     }
@@ -683,7 +816,7 @@
   // 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 (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);
@@ -699,7 +832,7 @@
   llvm::Function::arg_iterator AI = Fn->arg_begin();
 
   // Name the struct return argument.
-  if (CGM.ReturnTypeUsesSret(FI)) {
+  if (CGM.ReturnTypeUsesSRet(FI)) {
     AI->setName("agg.result");
     ++AI;
   }
@@ -715,13 +848,14 @@
 
     switch (ArgI.getKind()) {
     case ABIArgInfo::Indirect: {
-      llvm::Value* V = AI;
+      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);
+        unsigned Alignment = getContext().getTypeAlignInChars(Ty).getQuantity();
+        V = EmitLoadOfScalar(V, false, Alignment, Ty);
         if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
           // This must be a promotion, for something like
           // "void a(x) short x; {..."
@@ -734,15 +868,13 @@
 
     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 we have the trivial case, handle it with no muss and fuss.
+      if (!isa<llvm::StructType>(ArgI.getCoerceToType()) &&
+          ArgI.getCoerceToType() == ConvertType(Ty) &&
+          ArgI.getDirectOffset() == 0) {
+        assert(AI != Fn->arg_end() && "Argument mismatch!");
+        llvm::Value *V = AI;
+        
         if (Arg->getType().isRestrictQualified())
           AI->addAttr(llvm::Attribute::NoAlias);
 
@@ -751,9 +883,63 @@
           // "void a(x) short x; {..."
           V = EmitScalarConversion(V, Ty, Arg->getType());
         }
+        EmitParmDecl(*Arg, V);
+        break;
+      }
+
+      llvm::AllocaInst *Alloca = CreateMemTemp(Ty, "coerce");
+      
+      // The alignment we need to use is the max of the requested alignment for
+      // the argument plus the alignment required by our access code below.
+      unsigned AlignmentToUse = 
+        CGF.CGM.getTargetData().getABITypeAlignment(ArgI.getCoerceToType());
+      AlignmentToUse = std::max(AlignmentToUse,
+                        (unsigned)getContext().getDeclAlign(Arg).getQuantity());
+      
+      Alloca->setAlignment(AlignmentToUse);
+      llvm::Value *V = Alloca;
+      llvm::Value *Ptr = V;    // Pointer to store into.
+      
+      // If the value is offset in memory, apply the offset now.
+      if (unsigned Offs = ArgI.getDirectOffset()) {
+        Ptr = Builder.CreateBitCast(Ptr, Builder.getInt8PtrTy());
+        Ptr = Builder.CreateConstGEP1_32(Ptr, Offs);
+        Ptr = Builder.CreateBitCast(Ptr, 
+                          llvm::PointerType::getUnqual(ArgI.getCoerceToType()));
+      }
+      
+      // If the coerce-to type is a first class aggregate, we flatten it and
+      // pass the elements. Either way is semantically identical, but fast-isel
+      // and the optimizer generally likes scalar values better than FCAs.
+      if (const llvm::StructType *STy =
+            dyn_cast<llvm::StructType>(ArgI.getCoerceToType())) {
+        Ptr = Builder.CreateBitCast(Ptr, llvm::PointerType::getUnqual(STy));
+        
+        for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+          assert(AI != Fn->arg_end() && "Argument mismatch!");
+          AI->setName(Arg->getName() + ".coerce" + llvm::Twine(i));
+          llvm::Value *EltPtr = Builder.CreateConstGEP2_32(Ptr, 0, i);
+          Builder.CreateStore(AI++, EltPtr);
+        }
+      } else {
+        // Simple case, just do a coerced store of the argument into the alloca.
+        assert(AI != Fn->arg_end() && "Argument mismatch!");
+        AI->setName(Arg->getName() + ".coerce");
+        CreateCoercedStore(AI++, Ptr, /*DestIsVolatile=*/false, *this);
+      }
+      
+      
+      // Match to what EmitParmDecl is expecting for this type.
+      if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
+        V = EmitLoadOfScalar(V, false, AlignmentToUse, 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;
+      continue;  // Skip ++AI increment, already done.
     }
 
     case ABIArgInfo::Expand: {
@@ -761,9 +947,8 @@
       // 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);
+        ExpandTypeFromArgs(Ty, MakeAddrLValue(Temp, Ty), AI);
       EmitParmDecl(*Arg, Temp);
 
       // Name the arguments used in expansion and increment AI.
@@ -775,34 +960,13 @@
 
     case ABIArgInfo::Ignore:
       // Initialize the local variable appropriately.
-      if (hasAggregateLLVMType(Ty)) {
+      if (hasAggregateLLVMType(Ty))
         EmitParmDecl(*Arg, CreateMemTemp(Ty));
-      } else {
+      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;
@@ -810,66 +974,149 @@
   assert(AI == Fn->arg_end() && "Argument mismatch!");
 }
 
-void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
-                                         llvm::Value *ReturnValue) {
-  llvm::Value *RV = 0;
-
+void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI) {
   // 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 {
+  if (ReturnValue == 0) {
     Builder.CreateRetVoid();
+    return;
   }
+
+  llvm::DebugLoc RetDbgLoc;
+  llvm::Value *RV = 0;
+  QualType RetTy = FI.getReturnType();
+  const ABIArgInfo &RetAI = FI.getReturnInfo();
+
+  switch (RetAI.getKind()) {
+  case ABIArgInfo::Indirect: {
+    unsigned Alignment = getContext().getTypeAlignInChars(RetTy).getQuantity();
+    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, Alignment, RetTy);
+    }
+    break;
+  }
+
+  case ABIArgInfo::Extend:
+  case ABIArgInfo::Direct:
+    if (RetAI.getCoerceToType() == ConvertType(RetTy) &&
+        RetAI.getDirectOffset() == 0) {
+      // The internal return value temp always will have pointer-to-return-type
+      // type, just do a load.
+        
+      // If the instruction right before the insertion point is a store to the
+      // return value, we can elide the load, zap the store, and usually zap the
+      // alloca.
+      llvm::BasicBlock *InsertBB = Builder.GetInsertBlock();
+      llvm::StoreInst *SI = 0;
+      if (InsertBB->empty() || 
+          !(SI = dyn_cast<llvm::StoreInst>(&InsertBB->back())) ||
+          SI->getPointerOperand() != ReturnValue || SI->isVolatile()) {
+        RV = Builder.CreateLoad(ReturnValue);
+      } else {
+        // Get the stored value and nuke the now-dead store.
+        RetDbgLoc = SI->getDebugLoc();
+        RV = SI->getValueOperand();
+        SI->eraseFromParent();
+        
+        // If that was the only use of the return value, nuke it as well now.
+        if (ReturnValue->use_empty() && isa<llvm::AllocaInst>(ReturnValue)) {
+          cast<llvm::AllocaInst>(ReturnValue)->eraseFromParent();
+          ReturnValue = 0;
+        }
+      }
+    } else {
+      llvm::Value *V = ReturnValue;
+      // If the value is offset in memory, apply the offset now.
+      if (unsigned Offs = RetAI.getDirectOffset()) {
+        V = Builder.CreateBitCast(V, Builder.getInt8PtrTy());
+        V = Builder.CreateConstGEP1_32(V, Offs);
+        V = Builder.CreateBitCast(V, 
+                         llvm::PointerType::getUnqual(RetAI.getCoerceToType()));
+      }
+      
+      RV = CreateCoercedLoad(V, RetAI.getCoerceToType(), *this);
+    }
+    break;
+
+  case ABIArgInfo::Ignore:
+    break;
+
+  case ABIArgInfo::Expand:
+    assert(0 && "Invalid ABI kind for return argument");
+  }
+
+  llvm::Instruction *Ret = RV ? Builder.CreateRet(RV) : Builder.CreateRetVoid();
+  if (!RetDbgLoc.isUnknown())
+    Ret->setDebugLoc(RetDbgLoc);
+}
+
+RValue CodeGenFunction::EmitDelegateCallArg(const VarDecl *Param) {
+  // 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);
+
+  QualType ArgType = Param->getType();
+ 
+  // 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 (const ReferenceType *RefType = ArgType->getAs<ReferenceType>()) {
+    if (hasAggregateLLVMType(RefType->getPointeeType()))
+      return RValue::getAggregate(Local);
+
+    // Locals which are references to scalars are represented
+    // with allocas holding the pointer.
+    return RValue::get(Builder.CreateLoad(Local));
+  }
+
+  if (ArgType->isAnyComplexType())
+    return RValue::getComplex(LoadComplexFromAddr(Local, /*volatile*/ false));
+
+  if (hasAggregateLLVMType(ArgType))
+    return RValue::getAggregate(Local);
+
+  unsigned Alignment = getContext().getDeclAlign(Param).getQuantity();
+  return RValue::get(EmitLoadOfScalar(Local, false, Alignment, ArgType));
 }
 
 RValue CodeGenFunction::EmitCallArg(const Expr *E, QualType ArgType) {
   if (ArgType->isReferenceType())
-    return EmitReferenceBindingToExpr(E);
+    return EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0);
 
   return EmitAnyExprToTemp(E);
 }
 
+/// Emits a call or invoke instruction to the given function, depending
+/// on the current state of the EH stack.
+llvm::CallSite
+CodeGenFunction::EmitCallOrInvoke(llvm::Value *Callee,
+                                  llvm::Value * const *ArgBegin,
+                                  llvm::Value * const *ArgEnd,
+                                  const llvm::Twine &Name) {
+  llvm::BasicBlock *InvokeDest = getInvokeDest();
+  if (!InvokeDest)
+    return Builder.CreateCall(Callee, ArgBegin, ArgEnd, Name);
+
+  llvm::BasicBlock *ContBB = createBasicBlock("invoke.cont");
+  llvm::InvokeInst *Invoke = Builder.CreateInvoke(Callee, ContBB, InvokeDest,
+                                                  ArgBegin, ArgEnd, Name);
+  EmitBlock(ContBB);
+  return Invoke;
+}
+
 RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
                                  llvm::Value *Callee,
                                  ReturnValueSlot ReturnValue,
                                  const CallArgList &CallArgs,
-                                 const Decl *TargetDecl) {
+                                 const Decl *TargetDecl,
+                                 llvm::Instruction **callOrInvoke) {
   // FIXME: We no longer need the types from CallArgs; lift up and simplify.
   llvm::SmallVector<llvm::Value*, 16> Args;
 
@@ -881,7 +1128,7 @@
 
   // 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)) {
+  if (CGM.ReturnTypeUsesSRet(CallInfo)) {
     llvm::Value *Value = ReturnValue.getValue();
     if (!Value)
       Value = CreateMemTemp(RetTy);
@@ -896,50 +1143,80 @@
     const ABIArgInfo &ArgInfo = info_it->info;
     RValue RV = I->first;
 
+    unsigned Alignment =
+      getContext().getTypeAlignInChars(I->second).getQuantity();
     switch (ArgInfo.getKind()) {
-    case ABIArgInfo::Indirect:
+    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);
+          EmitStoreOfScalar(RV.getScalarVal(), Args.back(), false,
+                            Alignment, 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::Extend:
+    case ABIArgInfo::Direct: {
+      if (!isa<llvm::StructType>(ArgInfo.getCoerceToType()) &&
+          ArgInfo.getCoerceToType() == ConvertType(info_it->type) &&
+          ArgInfo.getDirectOffset() == 0) {
+        if (RV.isScalar())
+          Args.push_back(RV.getScalarVal());
+        else
+          Args.push_back(Builder.CreateLoad(RV.getAggregateAddr()));
+        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);
+        EmitStoreOfScalar(RV.getScalarVal(), SrcPtr, false, Alignment,
+                          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));
+      
+      // If the value is offset in memory, apply the offset now.
+      if (unsigned Offs = ArgInfo.getDirectOffset()) {
+        SrcPtr = Builder.CreateBitCast(SrcPtr, Builder.getInt8PtrTy());
+        SrcPtr = Builder.CreateConstGEP1_32(SrcPtr, Offs);
+        SrcPtr = Builder.CreateBitCast(SrcPtr, 
+                       llvm::PointerType::getUnqual(ArgInfo.getCoerceToType()));
+
+      }
+      
+      // If the coerce-to type is a first class aggregate, we flatten it and
+      // pass the elements. Either way is semantically identical, but fast-isel
+      // and the optimizer generally likes scalar values better than FCAs.
+      if (const llvm::StructType *STy =
+            dyn_cast<llvm::StructType>(ArgInfo.getCoerceToType())) {
+        SrcPtr = Builder.CreateBitCast(SrcPtr,
+                                       llvm::PointerType::getUnqual(STy));
+        for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+          llvm::Value *EltPtr = Builder.CreateConstGEP2_32(SrcPtr, 0, i);
+          llvm::LoadInst *LI = Builder.CreateLoad(EltPtr);
+          // We don't know what we're loading from.
+          LI->setAlignment(1);
+          Args.push_back(LI);
+        }
+      } else {
+        // In the simple case, just pass the coerced loaded value.
+        Args.push_back(CreateCoercedLoad(SrcPtr, ArgInfo.getCoerceToType(),
+                                         *this));
+      }
+      
       break;
     }
 
@@ -979,15 +1256,18 @@
     }
 
 
-  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::BasicBlock *InvokeDest = 0;
+  if (!(Attrs.getFnAttributes() & llvm::Attribute::NoUnwind))
+    InvokeDest = getInvokeDest();
+
   llvm::CallSite CS;
-  if (!InvokeDest || (Attrs.getFnAttributes() & llvm::Attribute::NoUnwind)) {
+  if (!InvokeDest) {
     CS = Builder.CreateCall(Callee, Args.data(), Args.data()+Args.size());
   } else {
     llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
@@ -995,6 +1275,8 @@
                               Args.data(), Args.data()+Args.size());
     EmitBlock(Cont);
   }
+  if (callOrInvoke)
+    *callOrInvoke = CS.getInstruction();
 
   CS.setAttributes(Attrs);
   CS.setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
@@ -1020,39 +1302,43 @@
     CI->setName("call");
 
   switch (RetAI.getKind()) {
-  case ABIArgInfo::Indirect:
+  case ABIArgInfo::Indirect: {
+    unsigned Alignment = getContext().getTypeAlignInChars(RetTy).getQuantity();
     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);
+    return RValue::get(EmitLoadOfScalar(Args[0], false, Alignment, RetTy));
+  }
 
   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::Extend:
+  case ABIArgInfo::Direct: {
+    if (RetAI.getCoerceToType() == ConvertType(RetTy) &&
+        RetAI.getDirectOffset() == 0) {
+      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();
 
-  case ABIArgInfo::Coerce: {
+        if (!DestPtr) {
+          DestPtr = CreateMemTemp(RetTy, "agg.tmp");
+          DestIsVolatile = false;
+        }
+        Builder.CreateStore(CI, DestPtr, DestIsVolatile);
+        return RValue::getAggregate(DestPtr);
+      }
+      return RValue::get(CI);
+    }
+      
     llvm::Value *DestPtr = ReturnValue.getValue();
     bool DestIsVolatile = ReturnValue.isVolatile();
     
@@ -1061,12 +1347,22 @@
       DestIsVolatile = false;
     }
     
-    CreateCoercedStore(CI, DestPtr, DestIsVolatile, *this);
+    // If the value is offset in memory, apply the offset now.
+    llvm::Value *StorePtr = DestPtr;
+    if (unsigned Offs = RetAI.getDirectOffset()) {
+      StorePtr = Builder.CreateBitCast(StorePtr, Builder.getInt8PtrTy());
+      StorePtr = Builder.CreateConstGEP1_32(StorePtr, Offs);
+      StorePtr = Builder.CreateBitCast(StorePtr, 
+                         llvm::PointerType::getUnqual(RetAI.getCoerceToType()));
+    }
+    CreateCoercedStore(CI, StorePtr, DestIsVolatile, *this);
+    
+    unsigned Alignment = getContext().getTypeAlignInChars(RetTy).getQuantity();
     if (RetTy->isAnyComplexType())
       return RValue::getComplex(LoadComplexFromAddr(DestPtr, false));
     if (CodeGenFunction::hasAggregateLLVMType(RetTy))
       return RValue::getAggregate(DestPtr);
-    return RValue::get(EmitLoadOfScalar(DestPtr, false, RetTy));
+    return RValue::get(EmitLoadOfScalar(DestPtr, false, Alignment, RetTy));
   }
 
   case ABIArgInfo::Expand:
diff --git a/lib/CodeGen/CGCall.h b/lib/CodeGen/CGCall.h
index 31c8aac..41e707a 100644
--- a/lib/CodeGen/CGCall.h
+++ b/lib/CodeGen/CGCall.h
@@ -83,11 +83,9 @@
     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(unsigned CallingConvention, bool NoReturn,
+                   unsigned RegParm, CanQualType ResTy,
+                   const CanQualType *ArgTys, unsigned NumArgTys);
     ~CGFunctionInfo() { delete[] Args; }
 
     const_arg_iterator arg_begin() const { return Args + 1; }
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index bfaa54e..bf26799 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "CGDebugInfo.h"
 #include "CodeGenFunction.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/RecordLayout.h"
@@ -22,13 +23,13 @@
 static uint64_t 
 ComputeNonVirtualBaseClassOffset(ASTContext &Context, 
                                  const CXXRecordDecl *DerivedClass,
-                                 CXXBaseSpecifierArray::iterator Start,
-                                 CXXBaseSpecifierArray::iterator End) {
+                                 CastExpr::path_const_iterator Start,
+                                 CastExpr::path_const_iterator End) {
   uint64_t Offset = 0;
   
   const CXXRecordDecl *RD = DerivedClass;
   
-  for (CXXBaseSpecifierArray::iterator I = Start; I != End; ++I) {
+  for (CastExpr::path_const_iterator I = Start; I != End; ++I) {
     const CXXBaseSpecifier *Base = *I;
     assert(!Base->isVirtual() && "Should not see virtual bases here!");
 
@@ -47,40 +48,16 @@
   // 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!");
+                                   CastExpr::path_const_iterator PathBegin,
+                                   CastExpr::path_const_iterator PathEnd) {
+  assert(PathBegin != PathEnd && "Base path should not be empty!");
 
   uint64_t Offset = 
-    ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, 
-                                     BasePath.begin(), BasePath.end());
+    ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl,
+                                     PathBegin, PathEnd);
   if (!Offset)
     return 0;
   
@@ -156,11 +133,12 @@
 llvm::Value *
 CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, 
                                        const CXXRecordDecl *Derived,
-                                       const CXXBaseSpecifierArray &BasePath, 
+                                       CastExpr::path_const_iterator PathBegin,
+                                       CastExpr::path_const_iterator PathEnd,
                                        bool NullCheckValue) {
-  assert(!BasePath.empty() && "Base path should not be empty!");
+  assert(PathBegin != PathEnd && "Base path should not be empty!");
 
-  CXXBaseSpecifierArray::iterator Start = BasePath.begin();
+  CastExpr::path_const_iterator Start = PathBegin;
   const CXXRecordDecl *VBase = 0;
   
   // Get the virtual base.
@@ -172,11 +150,11 @@
   
   uint64_t NonVirtualOffset = 
     ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : Derived,
-                                     Start, BasePath.end());
+                                     Start, PathEnd);
 
   // Get the base pointer type.
   const llvm::Type *BasePtrTy = 
-    ConvertType((BasePath.end()[-1])->getType())->getPointerTo();
+    ConvertType((PathEnd[-1])->getType())->getPointerTo();
   
   if (!NonVirtualOffset && !VBase) {
     // Just cast back.
@@ -229,84 +207,19 @@
 }
 
 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,
+                                        CastExpr::path_const_iterator PathBegin,
+                                          CastExpr::path_const_iterator PathEnd,
                                           bool NullCheckValue) {
-  assert(!BasePath.empty() && "Base path should not be empty!");
+  assert(PathBegin != PathEnd && "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);
+    CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd);
   
   if (!NonVirtualOffset) {
     // No offset, we can just cast back.
@@ -353,204 +266,11 @@
   
   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) {
+static llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD,
+                                    bool ForVirtualBase) {
   if (!CodeGenVTables::needsVTTParameter(GD)) {
     // This constructor/destructor does not need a VTT parameter.
     return 0;
@@ -568,9 +288,16 @@
   if (RD == Base) {
     assert(!CodeGenVTables::needsVTTParameter(CGF.CurGD) &&
            "doing no-op VTT offset in base dtor/ctor?");
+    assert(!ForVirtualBase && "Can't have same class as virtual base!");
     SubVTTIndex = 0;
   } else {
-    SubVTTIndex = CGF.CGM.getVTables().getSubVTTIndex(RD, Base);
+    const ASTRecordLayout &Layout = 
+      CGF.getContext().getASTRecordLayout(RD);
+    uint64_t BaseOffset = ForVirtualBase ? 
+      Layout.getVBaseClassOffset(Base) : Layout.getBaseClassOffset(Base);
+
+    SubVTTIndex = 
+      CGF.CGM.getVTables().getSubVTTIndex(RD, BaseSubobject(Base, BaseOffset));
     assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!");
   }
   
@@ -587,254 +314,26 @@
   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);
+namespace {
+  /// Call the destructor for a direct base class.
+  struct CallBaseDtor : EHScopeStack::Cleanup {
+    const CXXRecordDecl *BaseClass;
+    bool BaseIsVirtual;
+    CallBaseDtor(const CXXRecordDecl *Base, bool BaseIsVirtual)
+      : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {}
 
-    // We want to call the base constructor.
-    CtorType = Ctor_Base;
-  }
-  if (BaseClassDecl->hasTrivialCopyConstructor()) {
-    EmitAggregateCopy(Dest, Src, Ty);
-    return;
-  }
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      const CXXRecordDecl *DerivedClass =
+        cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent();
 
-  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;
+      const CXXDestructorDecl *D = BaseClass->getDestructor();
+      llvm::Value *Addr = 
+        CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThis(),
+                                                  DerivedClass, BaseClass,
+                                                  BaseIsVirtual);
+      CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual, Addr);
     }
-    
-    // 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, 
@@ -860,23 +359,126 @@
   // virtual bases, and we only do virtual bases for complete ctors.
   llvm::Value *V = 
     CGF.GetAddressOfDirectBaseInCompleteClass(ThisPtr, ClassDecl,
-                                              BaseClassDecl, 
-                                              BaseInit->isBaseVirtual());
+                                              BaseClassDecl,
+                                              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);
-  }
+  if (CGF.Exceptions && !BaseClassDecl->hasTrivialDestructor())
+    CGF.EHStack.pushCleanup<CallBaseDtor>(EHCleanup, BaseClassDecl,
+                                          isBaseVirtual);
 }
 
+static void EmitAggMemberInitializer(CodeGenFunction &CGF,
+                                     LValue LHS,
+                                     llvm::Value *ArrayIndexVar,
+                                     CXXBaseOrMemberInitializer *MemberInit,
+                                     QualType T,
+                                     unsigned Index) {
+  if (Index == MemberInit->getNumArrayIndices()) {
+    CodeGenFunction::RunCleanupsScope Cleanups(CGF);
+    
+    llvm::Value *Dest = LHS.getAddress();
+    if (ArrayIndexVar) {
+      // If we have an array index variable, load it and use it as an offset.
+      // Then, increment the value.
+      llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar);
+      Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress");
+      llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1);
+      Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc");
+      CGF.Builder.CreateStore(Next, ArrayIndexVar);      
+    }
+    
+    CGF.EmitAggExpr(MemberInit->getInit(), Dest, 
+                    LHS.isVolatileQualified(),
+                    /*IgnoreResult*/ false,
+                    /*IsInitializer*/ true);
+    
+    return;
+  }
+  
+  const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T);
+  assert(Array && "Array initialization without the array type?");
+  llvm::Value *IndexVar
+    = CGF.GetAddrOfLocalVar(MemberInit->getArrayIndex(Index));
+  assert(IndexVar && "Array index variable not loaded");
+  
+  // Initialize this index variable to zero.
+  llvm::Value* Zero
+    = llvm::Constant::getNullValue(
+                              CGF.ConvertType(CGF.getContext().getSizeType()));
+  CGF.Builder.CreateStore(Zero, IndexVar);
+                                   
+  // Start the loop with a block that tests the condition.
+  llvm::BasicBlock *CondBlock = CGF.createBasicBlock("for.cond");
+  llvm::BasicBlock *AfterFor = CGF.createBasicBlock("for.end");
+  
+  CGF.EmitBlock(CondBlock);
+
+  llvm::BasicBlock *ForBody = CGF.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 = Array->getSize().getZExtValue();
+  llvm::Value *Counter = CGF.Builder.CreateLoad(IndexVar);
+  llvm::Value *NumElementsPtr =
+    llvm::ConstantInt::get(Counter->getType(), NumElements);
+  llvm::Value *IsLess = CGF.Builder.CreateICmpULT(Counter, NumElementsPtr,
+                                                  "isless");
+                                   
+  // If the condition is true, execute the body.
+  CGF.Builder.CreateCondBr(IsLess, ForBody, AfterFor);
+
+  CGF.EmitBlock(ForBody);
+  llvm::BasicBlock *ContinueBlock = CGF.createBasicBlock("for.inc");
+  
+  {
+    CodeGenFunction::RunCleanupsScope Cleanups(CGF);
+    
+    // Inside the loop body recurse to emit the inner loop or, eventually, the
+    // constructor call.
+    EmitAggMemberInitializer(CGF, LHS, ArrayIndexVar, MemberInit, 
+                             Array->getElementType(), Index + 1);
+  }
+  
+  CGF.EmitBlock(ContinueBlock);
+
+  // Emit the increment of the loop counter.
+  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
+  Counter = CGF.Builder.CreateLoad(IndexVar);
+  NextVal = CGF.Builder.CreateAdd(Counter, NextVal, "inc");
+  CGF.Builder.CreateStore(NextVal, IndexVar);
+
+  // Finally, branch back up to the condition for the next iteration.
+  CGF.EmitBranch(CondBlock);
+
+  // Emit the fall-through block.
+  CGF.EmitBlock(AfterFor, true);
+}
+
+namespace {
+  struct CallMemberDtor : EHScopeStack::Cleanup {
+    FieldDecl *Field;
+    CXXDestructorDecl *Dtor;
+
+    CallMemberDtor(FieldDecl *Field, CXXDestructorDecl *Dtor)
+      : Field(Field), Dtor(Dtor) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      // FIXME: Is this OK for C++0x delegating constructors?
+      llvm::Value *ThisPtr = CGF.LoadCXXThis();
+      LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0);
+
+      CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false,
+                                LHS.getAddress());
+    }
+  };
+}
+  
 static void EmitMemberInitializer(CodeGenFunction &CGF,
                                   const CXXRecordDecl *ClassDecl,
-                                  CXXBaseOrMemberInitializer *MemberInit) {
+                                  CXXBaseOrMemberInitializer *MemberInit,
+                                  const CXXConstructorDecl *Constructor,
+                                  FunctionArgList &Args) {
   assert(MemberInit->isMemberInitializer() &&
          "Must have member initializer!");
   
@@ -885,52 +487,95 @@
   QualType FieldType = CGF.getContext().getCanonicalType(Field->getType());
 
   llvm::Value *ThisPtr = CGF.LoadCXXThis();
-  LValue LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0);
+  LValue LHS;
   
   // 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);
+    LHS = CGF.EmitLValueForAnonRecordField(ThisPtr, Field, 0);
     FieldType = Field->getType();
+  } else {
+    LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0);
   }
 
   // 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);
+    RHS = CGF.EmitReferenceBindingToExpr(MemberInit->getInit(), Field);
     CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
   } else if (FieldType->isArrayType() && !MemberInit->getInit()) {
-    CGF.EmitMemSetToZero(LHS.getAddress(), Field->getType());
+    CGF.EmitNullInitialization(LHS.getAddress(), Field->getType());
   } else if (!CGF.hasAggregateLLVMType(Field->getType())) {
-    RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit(), true));
+    RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit()));
     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);
+    llvm::Value *ArrayIndexVar = 0;
+    const ConstantArrayType *Array
+      = CGF.getContext().getAsConstantArrayType(FieldType);
+    if (Array && Constructor->isImplicit() && 
+        Constructor->isCopyConstructor()) {
+      const llvm::Type *SizeTy
+        = CGF.ConvertType(CGF.getContext().getSizeType());
+      
+      // The LHS is a pointer to the first object we'll be constructing, as
+      // a flat array.
+      QualType BaseElementTy = CGF.getContext().getBaseElementType(Array);
+      const llvm::Type *BasePtr = CGF.ConvertType(BaseElementTy);
+      BasePtr = llvm::PointerType::getUnqual(BasePtr);
+      llvm::Value *BaseAddrPtr = CGF.Builder.CreateBitCast(LHS.getAddress(), 
+                                                           BasePtr);
+      LHS = CGF.MakeAddrLValue(BaseAddrPtr, BaseElementTy);
+      
+      // Create an array index that will be used to walk over all of the
+      // objects we're constructing.
+      ArrayIndexVar = CGF.CreateTempAlloca(SizeTy, "object.index");
+      llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy);
+      CGF.Builder.CreateStore(Zero, ArrayIndexVar);
+      
+      // If we are copying an array of scalars or classes with trivial copy 
+      // constructors, perform a single aggregate copy.
+      const RecordType *Record = BaseElementTy->getAs<RecordType>();
+      if (!Record || 
+          cast<CXXRecordDecl>(Record->getDecl())->hasTrivialCopyConstructor()) {
+        // Find the source pointer. We knows it's the last argument because
+        // we know we're in a copy constructor.
+        unsigned SrcArgIndex = Args.size() - 1;
+        llvm::Value *SrcPtr
+          = CGF.Builder.CreateLoad(
+                               CGF.GetAddrOfLocalVar(Args[SrcArgIndex].first));
+        LValue Src = CGF.EmitLValueForFieldInitialization(SrcPtr, Field, 0);
+        
+        // Copy the aggregate.
+        CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType,
+                              LHS.isVolatileQualified());
+        return;
+      }
+      
+      // Emit the block variables for the array indices, if any.
+      for (unsigned I = 0, N = MemberInit->getNumArrayIndices(); I != N; ++I)
+        CGF.EmitLocalBlockVarDecl(*MemberInit->getArrayIndex(I));
+    }
+    
+    EmitAggMemberInitializer(CGF, LHS, ArrayIndexVar, MemberInit, FieldType, 0);
     
     if (!CGF.Exceptions)
       return;
 
+    // FIXME: If we have an array of classes w/ non-trivial destructors, 
+    // we need to destroy in reverse order of construction along the exception
+    // path.
     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());
-    }
+    if (!RD->hasTrivialDestructor())
+      CGF.EHStack.pushCleanup<CallMemberDtor>(EHCleanup, Field,
+                                              RD->getDestructor());
   }
 }
 
@@ -986,6 +631,8 @@
   // Before we go any further, try the complete->base constructor
   // delegation optimization.
   if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor)) {
+    if (CGDebugInfo *DI = getDebugInfo()) 
+      DI->EmitStopPoint(Builder);
     EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args);
     return;
   }
@@ -994,45 +641,37 @@
 
   // 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));
+    EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true);
 
-  unsigned CleanupStackSize = CleanupEntries.size();
+  EHScopeStack::stable_iterator CleanupDepth = EHStack.stable_begin();
 
   // Emit the constructor prologue, i.e. the base and member
   // initializers.
-  EmitCtorPrologue(Ctor, CtorType);
+  EmitCtorPrologue(Ctor, CtorType, Args);
 
   // 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);
+  PopCleanupBlocks(CleanupDepth);
 
   if (IsTryBody)
-    ExitCXXTryStmt(*cast<CXXTryStmt>(Body), TryInfo);
+    ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true);
 }
 
 /// 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) {
+                                       CXXCtorType CtorType,
+                                       FunctionArgList &Args) {
   const CXXRecordDecl *ClassDecl = CD->getParent();
 
   llvm::SmallVector<CXXBaseOrMemberInitializer *, 8> MemberInitializers;
@@ -1042,9 +681,6 @@
        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
@@ -1053,12 +689,8 @@
 
   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]);
-  }
+  for (unsigned I = 0, E = MemberInitializers.size(); I != E; ++I)
+    EmitMemberInitializer(*this, ClassDecl, MemberInitializers[I], CD, Args);
 }
 
 /// EmitDestructorBody - Emits the body of the current destructor.
@@ -1066,107 +698,158 @@
   const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl());
   CXXDtorType DtorType = CurGD.getDtorType();
 
+  // The call to operator delete in a deleting destructor happens
+  // outside of the function-try-block, which means it's always
+  // possible to delegate the destructor body to the complete
+  // destructor.  Do so.
+  if (DtorType == Dtor_Deleting) {
+    EnterDtorCleanups(Dtor, Dtor_Deleting);
+    EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false,
+                          LoadCXXThis());
+    PopCleanupBlock();
+    return;
+  }
+
   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));
+  // anything else.
+  bool isTryBody = (Body && isa<CXXTryStmt>(Body));
   if (isTryBody)
-    TryInfo = EnterCXXTryStmt(*cast<CXXTryStmt>(Body));
+    EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true);
 
-  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;
-
+  // Enter the epilogue cleanups.
+  RunCleanupsScope DtorEpilogue(*this);
+  
   // 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;
+  switch (DtorType) {
+  case Dtor_Deleting: llvm_unreachable("already handled deleting case");
+
+  case Dtor_Complete:
+    // Enter the cleanup scopes for virtual bases.
+    EnterDtorCleanups(Dtor, Dtor_Complete);
+
+    if (!isTryBody) {
+      EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false,
+                            LoadCXXThis());
+      break;
+    }
+    // Fallthrough: act like we're in the base variant.
       
-  // Otherwise, we're in the base variant, so we need to ensure the
-  // vtable ptrs are right before emitting the body.
-  } else {
+  case Dtor_Base:
+    // Enter the cleanup scopes for fields and non-virtual bases.
+    EnterDtorCleanups(Dtor, Dtor_Base);
+
+    // Initialize the vtable pointers before entering the body.
     InitializeVTablePointers(Dtor->getParent());
+
+    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
+    }
+    break;
   }
 
-  // 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);
+  // Jump out through the epilogue cleanups.
+  DtorEpilogue.ForceCleanup();
 
   // Exit the try if applicable.
   if (isTryBody)
-    ExitCXXTryStmt(*cast<CXXTryStmt>(Body), TryInfo);
+    ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true);
+}
+
+namespace {
+  /// Call the operator delete associated with the current destructor.
+  struct CallDtorDelete : EHScopeStack::Cleanup {
+    CallDtorDelete() {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl);
+      const CXXRecordDecl *ClassDecl = Dtor->getParent();
+      CGF.EmitDeleteCall(Dtor->getOperatorDelete(), CGF.LoadCXXThis(),
+                         CGF.getContext().getTagDeclType(ClassDecl));
+    }
+  };
+
+  struct CallArrayFieldDtor : EHScopeStack::Cleanup {
+    const FieldDecl *Field;
+    CallArrayFieldDtor(const FieldDecl *Field) : Field(Field) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      QualType FieldType = Field->getType();
+      const ConstantArrayType *Array =
+        CGF.getContext().getAsConstantArrayType(FieldType);
+      
+      QualType BaseType =
+        CGF.getContext().getBaseElementType(Array->getElementType());
+      const CXXRecordDecl *FieldClassDecl = BaseType->getAsCXXRecordDecl();
+
+      llvm::Value *ThisPtr = CGF.LoadCXXThis();
+      LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 
+                                          // FIXME: Qualifiers?
+                                          /*CVRQualifiers=*/0);
+
+      const llvm::Type *BasePtr = CGF.ConvertType(BaseType)->getPointerTo();
+      llvm::Value *BaseAddrPtr =
+        CGF.Builder.CreateBitCast(LHS.getAddress(), BasePtr);
+      CGF.EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(),
+                                    Array, BaseAddrPtr);
+    }
+  };
+
+  struct CallFieldDtor : EHScopeStack::Cleanup {
+    const FieldDecl *Field;
+    CallFieldDtor(const FieldDecl *Field) : Field(Field) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      const CXXRecordDecl *FieldClassDecl =
+        Field->getType()->getAsCXXRecordDecl();
+
+      llvm::Value *ThisPtr = CGF.LoadCXXThis();
+      LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 
+                                          // FIXME: Qualifiers?
+                                          /*CVRQualifiers=*/0);
+
+      CGF.EmitCXXDestructorCall(FieldClassDecl->getDestructor(),
+                                Dtor_Complete, /*ForVirtualBase=*/false,
+                                LHS.getAddress());
+    }
+  };
 }
 
 /// 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) {
+void CodeGenFunction::EnterDtorCleanups(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.
+  // The deleting-destructor phase just needs to call the appropriate
+  // operator delete that Sema picked up.
   if (DtorType == Dtor_Deleting) {
     assert(DD->getOperatorDelete() && 
            "operator delete missing - EmitDtorEpilogue");
-    EmitDeleteCall(DD->getOperatorDelete(), LoadCXXThis(),
-                   getContext().getTagDeclType(ClassDecl));
+    EHStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup);
     return;
   }
 
-  // For complete destructors, we've already called the base
-  // destructor (in GenerateBody), so we just need to destruct all the
-  // virtual bases.
+  const CXXRecordDecl *ClassDecl = DD->getParent();
+
+  // The complete-destructor phase just destructs 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();
+
+    // We push them in the forward order so that they'll be popped in
+    // the reverse order.
+    for (CXXRecordDecl::base_class_const_iterator I = 
+           ClassDecl->vbases_begin(), E = ClassDecl->vbases_end();
               I != E; ++I) {
       const CXXBaseSpecifier &Base = *I;
       CXXRecordDecl *BaseClassDecl
@@ -1175,26 +858,48 @@
       // 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);
+
+      EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup,
+                                        BaseClassDecl,
+                                        /*BaseIsVirtual*/ true);
     }
+
     return;
   }
 
   assert(DtorType == Dtor_Base);
+  
+  // Destroy non-virtual bases.
+  for (CXXRecordDecl::base_class_const_iterator I = 
+        ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) {
+    const CXXBaseSpecifier &Base = *I;
+    
+    // Ignore virtual bases.
+    if (Base.isVirtual())
+      continue;
+    
+    CXXRecordDecl *BaseClassDecl = Base.getType()->getAsCXXRecordDecl();
+    
+    // Ignore trivial destructors.
+    if (BaseClassDecl->hasTrivialDestructor())
+      continue;
 
-  // Collect the fields.
+    EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup,
+                                      BaseClassDecl,
+                                      /*BaseIsVirtual*/ false);
+  }
+
+  // Destroy direct 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 ConstantArrayType *Array = 
+      getContext().getAsConstantArrayType(FieldType);
+    if (Array)
+      FieldType = getContext().getBaseElementType(Array->getElementType());
     
     const RecordType *RT = FieldType->getAs<RecordType>();
     if (!RT)
@@ -1203,60 +908,11 @@
     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);
+      EHStack.pushCleanup<CallArrayFieldDtor>(NormalAndEHCleanup, Field);
+    else
+      EHStack.pushCleanup<CallFieldDtor>(NormalAndEHCleanup, Field);
   }
 }
 
@@ -1266,19 +922,24 @@
 /// '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.
+///
+/// \param ZeroInitialization True if each element should be zero-initialized
+/// before it is constructed.
 void
 CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
-                                          const ConstantArrayType *ArrayTy,
-                                          llvm::Value *ArrayPtr,
-                                          CallExpr::const_arg_iterator ArgBeg,
-                                          CallExpr::const_arg_iterator ArgEnd) {
+                                            const ConstantArrayType *ArrayTy,
+                                            llvm::Value *ArrayPtr,
+                                            CallExpr::const_arg_iterator ArgBeg,
+                                            CallExpr::const_arg_iterator ArgEnd,
+                                            bool ZeroInitialization) {
 
   const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
   llvm::Value * NumElements =
     llvm::ConstantInt::get(SizeTy, 
                            getContext().getConstantArrayElementCount(ArrayTy));
 
-  EmitCXXAggrConstructorCall(D, NumElements, ArrayPtr, ArgBeg, ArgEnd);
+  EmitCXXAggrConstructorCall(D, NumElements, ArrayPtr, ArgBeg, ArgEnd,
+                             ZeroInitialization);
 }
 
 void
@@ -1286,7 +947,8 @@
                                           llvm::Value *NumElements,
                                           llvm::Value *ArrayPtr,
                                           CallExpr::const_arg_iterator ArgBeg,
-                                          CallExpr::const_arg_iterator ArgEnd) {
+                                          CallExpr::const_arg_iterator ArgEnd,
+                                            bool ZeroInitialization) {
   const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
 
   // Create a temporary for the loop index and initialize it with 0.
@@ -1317,6 +979,11 @@
   llvm::Value *Address = Builder.CreateInBoundsGEP(ArrayPtr, Counter, 
                                                    "arrayidx");
 
+  // Zero initialize the storage, if requested.
+  if (ZeroInitialization)
+    EmitNullInitialization(Address, 
+                           getContext().getTypeDeclType(D->getParent()));
+  
   // 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
@@ -1327,9 +994,10 @@
   
   // Keep track of the current number of live temporaries.
   {
-    CXXTemporariesCleanupScope Scope(*this);
+    RunCleanupsScope Scope(*this);
 
-    EmitCXXConstructorCall(D, Ctor_Complete, Address, ArgBeg, ArgEnd);
+    EmitCXXConstructorCall(D, Ctor_Complete, /*ForVirtualBase=*/false, Address,
+                           ArgBeg, ArgEnd);
   }
 
   EmitBlock(ContinueBlock);
@@ -1403,7 +1071,7 @@
   Counter = Builder.CreateLoad(IndexPtr);
   Counter = Builder.CreateSub(Counter, One);
   llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
-  EmitCXXDestructorCall(D, Dtor_Complete, Address);
+  EmitCXXDestructorCall(D, Dtor_Complete, /*ForVirtualBase=*/false, Address);
 
   EmitBlock(ContinueBlock);
 
@@ -1419,54 +1087,9 @@
   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,
+                                        CXXCtorType Type, bool ForVirtualBase,
                                         llvm::Value *This,
                                         CallExpr::const_arg_iterator ArgBeg,
                                         CallExpr::const_arg_iterator ArgEnd) {
@@ -1488,7 +1111,7 @@
     return;
   }
 
-  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type));
+  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type), ForVirtualBase);
   llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
 
   EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, ArgBeg, ArgEnd);
@@ -1509,7 +1132,8 @@
   ++I;
 
   // vtt
-  if (llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(Ctor, CtorType))) {
+  if (llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(Ctor, CtorType),
+                                         /*ForVirtualBase=*/false)) {
     QualType VoidPP = getContext().getPointerType(getContext().VoidPtrTy);
     DelegateArgs.push_back(std::make_pair(RValue::get(VTT), VoidPP));
 
@@ -1522,34 +1146,9 @@
 
   // 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));
-    }
+    RValue Arg = EmitDelegateCallArg(Param);
 
     DelegateArgs.push_back(std::make_pair(Arg, ArgType));
   }
@@ -1561,13 +1160,44 @@
 
 void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
                                             CXXDtorType Type,
+                                            bool ForVirtualBase,
                                             llvm::Value *This) {
-  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type));
+  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type), 
+                                     ForVirtualBase);
   llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(DD, Type);
   
   EmitCXXMemberCall(DD, Callee, ReturnValueSlot(), This, VTT, 0, 0);
 }
 
+namespace {
+  struct CallLocalDtor : EHScopeStack::Cleanup {
+    const CXXDestructorDecl *Dtor;
+    llvm::Value *Addr;
+
+    CallLocalDtor(const CXXDestructorDecl *D, llvm::Value *Addr)
+      : Dtor(D), Addr(Addr) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
+                                /*ForVirtualBase=*/false, Addr);
+    }
+  };
+}
+
+void CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D,
+                                            llvm::Value *Addr) {
+  EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr);
+}
+
+void CodeGenFunction::PushDestructorCleanup(QualType T, llvm::Value *Addr) {
+  CXXRecordDecl *ClassDecl = T->getAsCXXRecordDecl();
+  if (!ClassDecl) return;
+  if (ClassDecl->hasTrivialDestructor()) return;
+
+  const CXXDestructorDecl *D = ClassDecl->getDestructor();
+  PushDestructorCleanup(D, Addr);
+}
+
 llvm::Value *
 CodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This,
                                            const CXXRecordDecl *ClassDecl,
@@ -1598,6 +1228,7 @@
 void
 CodeGenFunction::InitializeVTablePointer(BaseSubobject Base, 
                                          const CXXRecordDecl *NearestVBase,
+                                         uint64_t OffsetFromNearestVBase,
                                          llvm::Constant *VTable,
                                          const CXXRecordDecl *VTableClass) {
   const CXXRecordDecl *RD = Base.getBase();
@@ -1626,19 +1257,27 @@
   }
 
   // Compute where to store the address point.
-  llvm::Value *VTableField;
+  llvm::Value *VirtualOffset = 0;
+  uint64_t NonVirtualOffset = 0;
   
   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);
+    VirtualOffset = GetVirtualBaseClassOffset(LoadCXXThis(), VTableClass, 
+                                              NearestVBase);
+    NonVirtualOffset = OffsetFromNearestVBase / 8;
   } else {
-    const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
-
-    VTableField = Builder.CreateBitCast(LoadCXXThis(), Int8PtrTy);
-    VTableField = 
-      Builder.CreateConstInBoundsGEP1_64(VTableField, Base.getBaseOffset() / 8);  
+    // We can just use the base offset in the complete class.
+    NonVirtualOffset = Base.getBaseOffset() / 8;
   }
+  
+  // Apply the offsets.
+  llvm::Value *VTableField = LoadCXXThis();
+  
+  if (NonVirtualOffset || VirtualOffset)
+    VTableField = ApplyNonVirtualAndVirtualOffset(*this, VTableField, 
+                                                  NonVirtualOffset,
+                                                  VirtualOffset);
 
   // Finally, store the address point.
   const llvm::Type *AddressPointPtrTy =
@@ -1650,6 +1289,7 @@
 void
 CodeGenFunction::InitializeVTablePointers(BaseSubobject Base, 
                                           const CXXRecordDecl *NearestVBase,
+                                          uint64_t OffsetFromNearestVBase,
                                           bool BaseIsNonVirtualPrimaryBase,
                                           llvm::Constant *VTable,
                                           const CXXRecordDecl *VTableClass,
@@ -1658,7 +1298,8 @@
   // been set.
   if (!BaseIsNonVirtualPrimaryBase) {
     // Initialize the vtable pointer for this base.
-    InitializeVTablePointer(Base, NearestVBase, VTable, VTableClass);
+    InitializeVTablePointer(Base, NearestVBase, OffsetFromNearestVBase,
+                            VTable, VTableClass);
   }
   
   const CXXRecordDecl *RD = Base.getBase();
@@ -1674,6 +1315,7 @@
       continue;
 
     uint64_t BaseOffset;
+    uint64_t BaseOffsetFromNearestVBase;
     bool BaseDeclIsNonVirtualPrimaryBase;
 
     if (I->isVirtual()) {
@@ -1685,16 +1327,20 @@
         getContext().getASTRecordLayout(VTableClass);
 
       BaseOffset = Layout.getVBaseClassOffset(BaseDecl);
+      BaseOffsetFromNearestVBase = 0;
       BaseDeclIsNonVirtualPrimaryBase = false;
     } else {
       const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
 
       BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl);
+      BaseOffsetFromNearestVBase = 
+        OffsetFromNearestVBase + Layout.getBaseClassOffset(BaseDecl);
       BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl;
     }
     
     InitializeVTablePointers(BaseSubobject(BaseDecl, BaseOffset), 
                              I->isVirtual() ? BaseDecl : NearestVBase,
+                             BaseOffsetFromNearestVBase,
                              BaseDeclIsNonVirtualPrimaryBase, 
                              VTable, VTableClass, VBases);
   }
@@ -1711,6 +1357,7 @@
   // Initialize the vtable pointers for this class and all of its bases.
   VisitedVirtualBasesSetTy VBases;
   InitializeVTablePointers(BaseSubobject(RD, 0), /*NearestVBase=*/0, 
+                           /*OffsetFromNearestVBase=*/0,
                            /*BaseIsNonVirtualPrimaryBase=*/false, 
                            VTable, RD, VBases);
 }
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 4991c0f..939b6f7 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -15,13 +15,15 @@
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.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 "clang/Frontend/CodeGenOptions.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Instructions.h"
@@ -37,7 +39,7 @@
 
 CGDebugInfo::CGDebugInfo(CodeGenModule &CGM)
   : CGM(CGM), DebugFactory(CGM.getModule()),
-    FwdDeclCount(0), BlockLiteralGenericSet(false) {
+    BlockLiteralGenericSet(false) {
   CreateCompileUnit();
 }
 
@@ -64,7 +66,14 @@
   // Check namespace.
   if (const NamespaceDecl *NSDecl = dyn_cast<NamespaceDecl>(Context))
     return llvm::DIDescriptor(getOrCreateNameSpace(NSDecl, CompileUnit));
-  
+
+  if (const RecordDecl *RDecl = dyn_cast<RecordDecl>(Context)) {
+    if (!RDecl->isDependentType()) {
+      llvm::DIType Ty = getOrCreateType(CGM.getContext().getTypeDeclType(RDecl), 
+                                        llvm::DIFile(CompileUnit));
+      return llvm::DIDescriptor(Ty);
+    }
+  }
   return CompileUnit;
 }
 
@@ -86,6 +95,40 @@
   return llvm::StringRef(StrPtr, NS.length());
 }
 
+/// getClassName - Get class name including template argument list.
+llvm::StringRef 
+CGDebugInfo::getClassName(RecordDecl *RD) {
+  ClassTemplateSpecializationDecl *Spec
+    = dyn_cast<ClassTemplateSpecializationDecl>(RD);
+  if (!Spec)
+    return RD->getName();
+
+  const TemplateArgument *Args;
+  unsigned NumArgs;
+  std::string Buffer;
+  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 = RD->getIdentifier()->getNameStart();
+  PrintingPolicy Policy(CGM.getLangOptions());
+  Buffer += TemplateSpecializationType::PrintTemplateArgumentList(Args,
+                                                                  NumArgs,
+                                                                  Policy);
+
+  // Copy this name on the side and use its reference.
+  char *StrPtr = DebugInfoNames.Allocate<char>(Buffer.length());
+  memcpy(StrPtr, Buffer.data(), Buffer.length());
+  return llvm::StringRef(StrPtr, Buffer.length());
+
+}
+
 /// getOrCreateFile - Get the file debug info descriptor for the input location.
 llvm::DIFile CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
   if (!Loc.isValid())
@@ -106,18 +149,42 @@
       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(PLoc.getFilename(),
+                                           getCurrentDirname(), TheCU);
 
-  llvm::DIFile F = DebugFactory.CreateFile(AbsFileName.getLast(),
-                                           AbsFileName.getDirname(), TheCU);
-
-  DIFileCache[fname] = F.getNode();
+  DIFileCache[fname] = F;
   return F;
 
 }
+
+/// getLineNumber - Get line number for the location. If location is invalid
+/// then use current location.
+unsigned CGDebugInfo::getLineNumber(SourceLocation Loc) {
+  assert (CurLoc.isValid() && "Invalid current location!");
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  PresumedLoc PLoc = SM.getPresumedLoc(Loc.isValid() ? Loc : CurLoc);
+  return PLoc.getLine();
+}
+
+/// getColumnNumber - Get column number for the location. If location is 
+/// invalid then use current location.
+unsigned CGDebugInfo::getColumnNumber(SourceLocation Loc) {
+  assert (CurLoc.isValid() && "Invalid current location!");
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  PresumedLoc PLoc = SM.getPresumedLoc(Loc.isValid() ? Loc : CurLoc);
+  return PLoc.getColumn();
+}
+
+llvm::StringRef CGDebugInfo::getCurrentDirname() {
+  if (!CWDName.empty())
+    return CWDName;
+  char *CompDirnamePtr = NULL;
+  llvm::sys::Path CWD = llvm::sys::Path::GetCurrentDirectory();
+  CompDirnamePtr = DebugInfoNames.Allocate<char>(CWD.size());
+  memcpy(CompDirnamePtr, CWD.c_str(), CWD.size());
+  return CWDName = llvm::StringRef(CompDirnamePtr, CWD.size());
+}
+
 /// CreateCompileUnit - Create new compile unit.
 void CGDebugInfo::CreateCompileUnit() {
 
@@ -127,19 +194,22 @@
   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()))
+  if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
     MainFileDir = MainFile->getDir()->getName();
-  else
-    MainFileDir = AbsFileName.getDirname();
+    if (MainFileDir != ".")
+      MainFileName = MainFileDir + "/" + MainFileName;
+  }
 
+  // Save filename string.
+  char *FilenamePtr = DebugInfoNames.Allocate<char>(MainFileName.length());
+  memcpy(FilenamePtr, MainFileName.c_str(), MainFileName.length());
+  llvm::StringRef Filename(FilenamePtr, MainFileName.length());
+  
   unsigned LangTag;
   const LangOptions &LO = CGM.getLangOptions();
   if (LO.CPlusPlus) {
@@ -155,11 +225,7 @@
     LangTag = llvm::dwarf::DW_LANG_C89;
   }
 
-  const char *Producer =
-#ifdef CLANG_VENDOR
-    CLANG_VENDOR
-#endif
-    "clang " CLANG_VERSION_STRING;
+  std::string Producer = getClangFullVersion();
 
   // Figure out which version of the ObjC runtime we have.
   unsigned RuntimeVers = 0;
@@ -168,7 +234,8 @@
 
   // Create new compile unit.
   TheCU = DebugFactory.CreateCompileUnit(
-    LangTag, AbsFileName.getLast(), MainFileDir, Producer, true,
+    LangTag, Filename, getCurrentDirname(),
+    Producer, true,
     LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers);
 }
 
@@ -177,10 +244,49 @@
 llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT,
                                      llvm::DIFile Unit) {
   unsigned Encoding = 0;
+  const char *BTName = NULL;
   switch (BT->getKind()) {
   default:
   case BuiltinType::Void:
     return llvm::DIType();
+  case BuiltinType::ObjCClass:
+    return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_structure_type,
+                                            Unit, "objc_class", Unit, 0, 0, 0, 0,
+                                            llvm::DIType::FlagFwdDecl, 
+                                            llvm::DIType(), llvm::DIArray());
+  case BuiltinType::ObjCId: {
+    // typedef struct objc_class *Class;
+    // typedef struct objc_object {
+    //  Class isa;
+    // } *id;
+
+    llvm::DIType OCTy = 
+      DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_structure_type,
+                                       Unit, "objc_class", Unit, 0, 0, 0, 0,
+                                       llvm::DIType::FlagFwdDecl, 
+                                       llvm::DIType(), llvm::DIArray());
+    unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
+    
+    llvm::DIType ISATy = 
+      DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
+                                     Unit, "", Unit,
+                                     0, Size, 0, 0, 0, OCTy);
+
+    llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
+
+    llvm::DIType FieldTy = 
+      DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+                                     "isa", Unit,
+                                     0,Size, 0, 0, 0, ISATy);
+    EltTys.push_back(FieldTy);
+    llvm::DIArray Elements =
+      DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
+    
+    return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_structure_type,
+                                            Unit, "objc_object", Unit, 0, 0, 0, 0,
+                                            0,
+                                            llvm::DIType(), Elements);
+  }
   case BuiltinType::UChar:
   case BuiltinType::Char_U: Encoding = llvm::dwarf::DW_ATE_unsigned_char; break;
   case BuiltinType::Char_S:
@@ -198,14 +304,23 @@
   case BuiltinType::LongDouble:
   case BuiltinType::Double:    Encoding = llvm::dwarf::DW_ATE_float; break;
   }
+
+  switch (BT->getKind()) {
+  case BuiltinType::Long:      BTName = "long int"; break;
+  case BuiltinType::LongLong:  BTName = "long long int"; break;
+  case BuiltinType::ULong:     BTName = "long unsigned int"; break;
+  case BuiltinType::ULongLong: BTName = "long long unsigned int"; break;
+  default:
+    BTName = BT->getName(CGM.getContext().getLangOptions());
+    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()),
+    DebugFactory.CreateBasicType(Unit, BTName,
                                  Unit, 0, Size, Align,
                                  Offset, /*flags*/ 0, Encoding);
   return DbgTy;
@@ -327,10 +442,11 @@
   EltTys.clear();
 
   unsigned Flags = llvm::DIType::FlagAppleBlock;
+  unsigned LineNo = getLineNumber(CurLoc);
 
   EltTy = DebugFactory.CreateCompositeType(Tag, Unit, "__block_descriptor",
-                                           Unit, 0, FieldOffset, 0, 0, Flags,
-                                           llvm::DIType(), Elements);
+                                           Unit, LineNo, FieldOffset, 0, 0, 
+                                           Flags, llvm::DIType(), Elements);
 
   // Bit size, align and offset of the type.
   uint64_t Size = CGM.getContext().getTypeSize(Ty);
@@ -338,7 +454,7 @@
 
   DescTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
                                           Unit, "", Unit,
-                                          0, Size, Align, 0, 0, EltTy);
+                                          LineNo, Size, Align, 0, 0, EltTy);
 
   FieldOffset = 0;
   FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
@@ -355,7 +471,7 @@
   FieldAlign = CGM.getContext().getTypeAlign(Ty);
   FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
                                            "__descriptor", Unit,
-                                           0, FieldSize, FieldAlign,
+                                           LineNo, FieldSize, FieldAlign,
                                            FieldOffset, 0, FieldTy);
   EltTys.push_back(FieldTy);
 
@@ -363,14 +479,14 @@
   Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
 
   EltTy = DebugFactory.CreateCompositeType(Tag, Unit, "__block_literal_generic",
-                                           Unit, 0, FieldOffset, 0, 0, Flags,
-                                           llvm::DIType(), Elements);
+                                           Unit, LineNo, 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);
+                                     LineNo, Size, Align, 0, 0, EltTy);
   return BlockLiteralGeneric;
 }
 
@@ -382,9 +498,7 @@
 
   // 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();
+  unsigned Line = getLineNumber(Ty->getDecl()->getLocation());
 
   llvm::DIDescriptor TyContext 
     = getContextDescriptor(dyn_cast<Decl>(Ty->getDecl()->getDeclContext()),
@@ -430,14 +544,12 @@
 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.
@@ -445,16 +557,8 @@
       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();
-    }
-
+    llvm::DIFile FieldDefUnit = getOrCreateFile(Field->getLocation());
+    unsigned FieldLine = getLineNumber(Field->getLocation());
     QualType FType = Field->getType();
     uint64_t FieldSize = 0;
     unsigned FieldAlign = 0;
@@ -465,7 +569,6 @@
       Expr *BitWidth = Field->getBitWidth();
       if (BitWidth)
         FieldSize = BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
-
       FieldAlign =  CGM.getContext().getTypeAlign(FType);
     }
 
@@ -495,15 +598,21 @@
 llvm::DIType
 CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
                                    llvm::DIFile Unit) {
-  llvm::DIType FnTy = getOrCreateType(Method->getType(), Unit);
+  llvm::DIType FnTy
+    = getOrCreateType(QualType(Method->getType()->getAs<FunctionProtoType>(),
+                               0),
+                      Unit);
   
-  // Static methods do not need "this" pointer argument.
-  if (Method->isStatic())
-    return FnTy;
+  unsigned BFlags=0;
+  AccessSpecifier Access = Method->getAccess();
+  if (Access == clang::AS_private)
+    BFlags |= llvm::DIType::FlagPrivate;
+  else if (Access == clang::AS_protected)
+    BFlags |= llvm::DIType::FlagProtected;
 
   // Add "this" pointer.
 
-  llvm::DIArray Args = llvm::DICompositeType(FnTy.getNode()).getTypeArray();
+  llvm::DIArray Args = llvm::DICompositeType(FnTy).getTypeArray();
   assert (Args.getNumElements() && "Invalid number of arguments!");
 
   llvm::SmallVector<llvm::DIDescriptor, 16> Elts;
@@ -511,14 +620,18 @@
   // 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);
+  if (!Method->isStatic())
+  {
+        // "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;
+        Elts.push_back(ThisPtrType);
+    }
 
   // Copy rest of the arguments.
   for (unsigned i = 1, e = Args.getNumElements(); i != e; ++i)
@@ -539,7 +652,7 @@
 llvm::DISubprogram
 CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,
                                      llvm::DIFile Unit,
-                                     llvm::DICompositeType &RecordTy) {
+                                     llvm::DIType RecordTy) {
   bool IsCtorOrDtor = 
     isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
   
@@ -548,22 +661,13 @@
   
   // 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;
+  llvm::StringRef MethodLinkageName;
   if (!IsCtorOrDtor)
-    CGM.getMangledName(MethodLinkageName, Method);
-
-  SourceManager &SM = CGM.getContext().getSourceManager();
+    MethodLinkageName = CGM.getMangledName(Method);
 
   // 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();
-  }
+  llvm::DIFile MethodDefUnit = getOrCreateFile(Method->getLocation());
+  unsigned MethodLine = getLineNumber(Method->getLocation());
 
   // Collect virtual method info.
   llvm::DIType ContainingType;
@@ -588,13 +692,15 @@
                                   MethodLinkageName,
                                   MethodDefUnit, MethodLine,
                                   MethodTy, /*isLocalToUnit=*/false, 
-                                  Method->isThisDeclarationADefinition(),
-                                  Virtuality, VIndex, ContainingType);
+                                  /* isDefintion=*/ false,
+                                  Virtuality, VIndex, ContainingType,
+                                  Method->isImplicit(),
+                                  CGM.getLangOptions().Optimize);
   
   // 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());
+    SPCache[Method] = llvm::WeakVH(SP);
 
   return SP;
 }
@@ -605,7 +711,7 @@
 void CGDebugInfo::
 CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit,
                           llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys,
-                          llvm::DICompositeType &RecordTy) {
+                          llvm::DIType RecordTy) {
   for(CXXRecordDecl::method_iterator I = RD->method_begin(),
         E = RD->method_end(); I != E; ++I) {
     const CXXMethodDecl *Method = *I;
@@ -617,13 +723,41 @@
   }
 }                                 
 
+/// CollectCXXFriends - A helper function to collect debug info for
+/// C++ base classes. This is used while creating debug info entry for
+/// a Record.
+void CGDebugInfo::
+CollectCXXFriends(const CXXRecordDecl *RD, llvm::DIFile Unit,
+                llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys,
+                llvm::DIType RecordTy) {
+
+  for (CXXRecordDecl::friend_iterator BI =  RD->friend_begin(),
+         BE = RD->friend_end(); BI != BE; ++BI) {
+
+    TypeSourceInfo *TInfo = (*BI)->getFriendType();
+    if(TInfo)
+    {
+        llvm::DIType Ty = getOrCreateType(TInfo->getType(), Unit);
+
+            llvm::DIType DTy =
+          DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_friend,
+                                         RecordTy, llvm::StringRef(),
+                                         Unit, 0, 0, 0,
+                                         0, 0, Ty);
+
+        EltTys.push_back(DTy);
+    }
+
+  }
+}
+
 /// 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) {
+                llvm::DIType RecordTy) {
 
   const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
   for (CXXRecordDecl::base_class_const_iterator BI = RD->bases_begin(),
@@ -738,16 +872,9 @@
     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();
-  }
+  llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());
+  unsigned Line = getLineNumber(RD->getLocation());
 
   // 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.
@@ -755,29 +882,31 @@
   // 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 = 
+  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;
+  // If this is just a forward declaration, construct an appropriately
+  // marked node and just return it.
+  if (!RD->getDefinition()) {
+    llvm::DICompositeType FwdDecl =
+      DebugFactory.CreateCompositeType(Tag, FDContext, RD->getName(),
+                                       DefUnit, Line, 0, 0, 0,
+                                       llvm::DIType::FlagFwdDecl,
+                                       llvm::DIType(), llvm::DIArray());
 
-  llvm::TrackingVH<llvm::MDNode> FwdDeclNode = FwdDecl.getNode();
+      return FwdDecl;
+  }
+
+  llvm::DIType FwdDecl = DebugFactory.CreateTemporaryType();
+
+  llvm::MDNode *MN = FwdDecl;
+  llvm::TrackingVH<llvm::MDNode> FwdDeclNode = MN;
   // Otherwise, insert it into the TypeCache so that recursive uses will find
   // it.
-  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl.getNode();
+  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
   // Push the struct on region stack.
-  RegionStack.push_back(FwdDecl.getNode());
-  RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl.getNode());
+  RegionStack.push_back(FwdDeclNode);
+  RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);
 
   // Convert all the elements.
   llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
@@ -787,18 +916,44 @@
     CollectCXXBases(CXXDecl, Unit, EltTys, FwdDecl);
     CollectVTableInfo(CXXDecl, Unit, EltTys);
   }
+  
+  // Collect static variables with initializers.
+  for (RecordDecl::decl_iterator I = RD->decls_begin(), E = RD->decls_end();
+       I != E; ++I)
+    if (const VarDecl *V = dyn_cast<VarDecl>(*I)) {
+      if (const Expr *Init = V->getInit()) {
+        Expr::EvalResult Result;
+        if (Init->Evaluate(Result, CGM.getContext()) && Result.Val.isInt()) {
+          llvm::ConstantInt *CI 
+            = llvm::ConstantInt::get(CGM.getLLVMContext(), Result.Val.getInt());
+          
+          // Create the descriptor for static variable.
+          llvm::DIFile VUnit = getOrCreateFile(V->getLocation());
+          llvm::StringRef VName = V->getName();
+          llvm::DIType VTy = getOrCreateType(V->getType(), VUnit);
+          // Do not use DIGlobalVariable for enums.
+          if (VTy.getTag() != llvm::dwarf::DW_TAG_enumeration_type) {
+            DebugFactory.CreateGlobalVariable(FwdDecl, VName, VName, VName, VUnit,
+                                              getLineNumber(V->getLocation()),
+                                              VTy, true, true, CI);
+          }
+        }
+      }
+    }
+
   CollectRecordFields(RD, Unit, EltTys);
   llvm::MDNode *ContainingType = NULL;
   if (CXXDecl) {
     CollectCXXMemberFunctions(CXXDecl, Unit, EltTys, FwdDecl);
+    CollectCXXFriends(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();
+        getOrCreateType(QualType(PBase->getTypeForDecl(), 0), Unit);
     else if (CXXDecl->isDynamicClass()) 
-      ContainingType = FwdDecl.getNode();
+      ContainingType = FwdDecl;
   }
 
   llvm::DIArray Elements =
@@ -816,59 +971,71 @@
 
   llvm::DIDescriptor RDContext =  
     getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()), Unit);
+
+  llvm::StringRef RDName = RD->getName();
+  // If this is a class, include the template arguments also.
+  if (Tag == llvm::dwarf::DW_TAG_class_type) 
+    RDName = getClassName(RD);
+  
   llvm::DICompositeType RealDecl =
     DebugFactory.CreateCompositeType(Tag, RDContext,
-                                     RD->getName(),
+                                     RDName,
                                      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());
+  llvm::DIType(FwdDeclNode).replaceAllUsesWith(RealDecl);
+  RegionMap[RD] = llvm::WeakVH(RealDecl);
   return RealDecl;
 }
 
+/// CreateType - get objective-c object type.
+llvm::DIType CGDebugInfo::CreateType(const ObjCObjectType *Ty,
+                                     llvm::DIFile Unit) {
+  // Ignore protocols.
+  return getOrCreateType(Ty->getBaseType(), Unit);
+}
+
 /// 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 Line = getLineNumber(ID->getLocation());
   unsigned RuntimeLang = TheCU.getLanguage();
 
+  // If this is just a forward declaration, return a special forward-declaration
+  // debug type.
+  if (ID->isForwardDecl()) {
+    llvm::DICompositeType FwdDecl =
+      DebugFactory.CreateCompositeType(Tag, Unit, ID->getName(),
+                                       DefUnit, Line, 0, 0, 0, 0,
+                                       llvm::DIType(), llvm::DIArray(),
+                                       RuntimeLang);
+    return FwdDecl;
+  }
+
   // 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);
+  llvm::DIType FwdDecl = DebugFactory.CreateTemporaryType();
 
-  // If this is just a forward declaration, return it.
-  if (ID->isForwardDecl())
-    return FwdDecl;
-
-  llvm::TrackingVH<llvm::MDNode> FwdDeclNode = FwdDecl.getNode();
+  llvm::MDNode *MN = FwdDecl;
+  llvm::TrackingVH<llvm::MDNode> FwdDeclNode = MN;
   // Otherwise, insert it into the TypeCache so that recursive uses will find
   // it.
-  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl.getNode();
+  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
   // Push the struct on region stack.
-  RegionStack.push_back(FwdDecl.getNode());
-  RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl.getNode());
+  RegionStack.push_back(FwdDeclNode);
+  RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);
 
   // Convert all the elements.
   llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
@@ -899,12 +1066,8 @@
       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();
-
-
+    llvm::DIFile FieldDefUnit = getOrCreateFile(Field->getLocation());
+    unsigned FieldLine = getLineNumber(Field->getLocation());
     QualType FType = Field->getType();
     uint64_t FieldSize = 0;
     unsigned FieldAlign = 0;
@@ -958,51 +1121,16 @@
 
   // 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());
+  llvm::DIType(FwdDeclNode).replaceAllUsesWith(RealDecl);
+  RegionMap[ID] = llvm::WeakVH(RealDecl);
 
   return RealDecl;
 }
 
 llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,
                                      llvm::DIFile Unit) {
-  EnumDecl *ED = Ty->getDecl();
+  return CreateEnumType(Ty->getDecl(), Unit);
 
-  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,
@@ -1016,7 +1144,7 @@
 }
 
 llvm::DIType CGDebugInfo::CreateType(const VectorType *Ty,
-				     llvm::DIFile Unit) {
+                                     llvm::DIFile Unit) {
   llvm::DIType ElementTy = getOrCreateType(Ty->getElementType(), Unit);
   uint64_t NumElems = Ty->getNumElements();
   if (NumElems > 0)
@@ -1032,7 +1160,7 @@
     DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_vector_type,
                                      Unit, "", Unit,
                                      0, Size, Align, 0, 0,
-				     ElementTy,  SubscriptArray);
+                                     ElementTy,  SubscriptArray);
 }
 
 llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,
@@ -1129,6 +1257,38 @@
                                           0, 0, 0, llvm::DIType(), Elements);
 }
 
+/// CreateEnumType - get enumeration type.
+llvm::DIType CGDebugInfo::CreateEnumType(const EnumDecl *ED, llvm::DIFile Unit){
+  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());
+
+  llvm::DIFile DefUnit = getOrCreateFile(ED->getLocation());
+  unsigned Line = getLineNumber(ED->getLocation());
+  uint64_t Size = 0;
+  uint64_t Align = 0;
+  if (!ED->getTypeForDecl()->isIncompleteType()) {
+    Size = CGM.getContext().getTypeSize(ED->getTypeForDecl());
+    Align = CGM.getContext().getTypeAlign(ED->getTypeForDecl());
+  }
+  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;
+}
+
 static QualType UnwrapTypeForDebugInfo(QualType T) {
   do {
     QualType LastT = T;
@@ -1149,15 +1309,12 @@
     case Type::Decltype:
       T = cast<DecltypeType>(T)->getUnderlyingType();
       break;
-    case Type::QualifiedName:
-      T = cast<QualifiedNameType>(T)->getNamedType();
+    case Type::Elaborated:
+      T = cast<ElaboratedType>(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!");
@@ -1191,7 +1348,7 @@
   llvm::DIType Res = CreateTypeNode(Ty, Unit);
 
   // And update the type cache.
-  TypeCache[Ty.getAsOpaquePtr()] = Res.getNode();  
+  TypeCache[Ty.getAsOpaquePtr()] = Res;  
   return Res;
 }
 
@@ -1221,6 +1378,8 @@
     return CreateType(cast<VectorType>(Ty), Unit);
   case Type::ObjCObjectPointer:
     return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
+  case Type::ObjCObject:
+    return CreateType(cast<ObjCObjectType>(Ty), Unit);
   case Type::ObjCInterface:
     return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
   case Type::Builtin: return CreateType(cast<BuiltinType>(Ty), Unit);
@@ -1248,7 +1407,6 @@
 
   case Type::TemplateSpecialization:
   case Type::Elaborated:
-  case Type::QualifiedName:
   case Type::SubstTemplateTypeParm:
   case Type::TypeOfExpr:
   case Type::TypeOf:
@@ -1292,7 +1450,9 @@
                                     CGBuilderTy &Builder) {
 
   llvm::StringRef Name;
-  MangleBuffer LinkageName;
+  llvm::StringRef LinkageName;
+
+  FnBeginRegionCount.push_back(RegionStack.size());
 
   const Decl *D = GD.getDecl();
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
@@ -1301,19 +1461,20 @@
       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());
+      if (SP.isSubprogram() && llvm::DISubprogram(SP).isDefinition()) {
+        llvm::MDNode *SPN = SP;
+        RegionStack.push_back(SPN);
+        RegionMap[D] = llvm::WeakVH(SP);
         return;
       }
     }
     Name = getFunctionName(FD);
     // Use mangled name as linkage name for c/c++ functions.
-    CGM.getMangledName(LinkageName, GD);
+    LinkageName = CGM.getMangledName(GD);
   } else {
     // Use llvm function name as linkage name.
     Name = Fn->getName();
-    LinkageName.setString(Name);
+    LinkageName = Name;
   }
   if (!Name.empty() && Name[0] == '\01')
     Name = Name.substr(1);
@@ -1322,21 +1483,27 @@
   // 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();
+  unsigned LineNo = getLineNumber(CurLoc);
 
   llvm::DISubprogram SP =
     DebugFactory.CreateSubprogram(Unit, Name, Name, LinkageName, Unit, LineNo,
                                   getOrCreateType(FnType, Unit),
-                                  Fn->hasInternalLinkage(), true/*definition*/);
+                                  Fn->hasInternalLinkage(), true/*definition*/,
+                                  0, 0, llvm::DIType(),
+                                  D->isImplicit(),
+                                  CGM.getLangOptions().Optimize, Fn);
 
   // Push function on region stack.
-  RegionStack.push_back(SP.getNode());
-  RegionMap[D] = llvm::WeakVH(SP.getNode());
+  llvm::MDNode *SPN = SP;
+  RegionStack.push_back(SPN);
+  RegionMap[D] = llvm::WeakVH(SP);
+
+  // Clear stack used to keep track of #line directives.
+  LineDirectiveFiles.clear();
 }
 
 
-void CGDebugInfo::EmitStopPoint(llvm::Function *Fn, CGBuilderTy &Builder) {
+void CGDebugInfo::EmitStopPoint(CGBuilderTy &Builder) {
   if (CurLoc.isInvalid() || CurLoc.isMacroID()) return;
 
   // Don't bother if things are the same as last time.
@@ -1352,40 +1519,98 @@
   // 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(),
+  Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(getLineNumber(CurLoc),
+                                                      getColumnNumber(CurLoc),
                                                       Scope));
 }
 
+/// UpdateLineDirectiveRegion - Update region stack only if #line directive
+/// has introduced scope change.
+void CGDebugInfo::UpdateLineDirectiveRegion(CGBuilderTy &Builder) {
+  if (CurLoc.isInvalid() || CurLoc.isMacroID() ||
+      PrevLoc.isInvalid() || PrevLoc.isMacroID())
+    return;
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  PresumedLoc PCLoc = SM.getPresumedLoc(CurLoc);
+  PresumedLoc PPLoc = SM.getPresumedLoc(PrevLoc);
+
+  if (!strcmp(PPLoc.getFilename(), PCLoc.getFilename()))
+    return;
+
+  // If #line directive stack is empty then we are entering a new scope.
+  if (LineDirectiveFiles.empty()) {
+    EmitRegionStart(Builder);
+    LineDirectiveFiles.push_back(PCLoc.getFilename());
+    return;
+  }
+
+  assert (RegionStack.size() >= LineDirectiveFiles.size()
+          && "error handling  #line regions!");
+
+  bool SeenThisFile = false;
+  for(std::vector<const char *>::iterator I = LineDirectiveFiles.begin(),
+        E = LineDirectiveFiles.end(); I != E; ++I)
+    if (!strcmp(PPLoc.getFilename(), *I)) {
+      SeenThisFile = true;
+      break;
+    }
+
+  // If #line for this file is seen earlier then pop out #line regions.
+  if (SeenThisFile) {
+    while (!LineDirectiveFiles.empty()) {
+      const char *LastFile = LineDirectiveFiles.back();
+      RegionStack.pop_back();
+      LineDirectiveFiles.pop_back();
+      if (!strcmp(PPLoc.getFilename(), LastFile))
+        break;
+    }
+    return;
+  } 
+
+  // .. otherwise insert new #line region.
+  EmitRegionStart(Builder);
+  LineDirectiveFiles.push_back(PCLoc.getFilename());
+
+  return;
+}
 /// 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);
+void CGDebugInfo::EmitRegionStart(CGBuilderTy &Builder) {
   llvm::DIDescriptor D =
     DebugFactory.CreateLexicalBlock(RegionStack.empty() ? 
                                     llvm::DIDescriptor() : 
                                     llvm::DIDescriptor(RegionStack.back()),
-                                    PLoc.getLine(), PLoc.getColumn());
-  RegionStack.push_back(D.getNode());
+                                    getOrCreateFile(CurLoc),
+                                    getLineNumber(CurLoc), 
+                                    getColumnNumber(CurLoc));
+  llvm::MDNode *DN = D;
+  RegionStack.push_back(DN);
 }
 
 /// EmitRegionEnd - Constructs the debug code for exiting a declarative
 /// region - "llvm.dbg.region.end."
-void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, CGBuilderTy &Builder) {
+void CGDebugInfo::EmitRegionEnd(CGBuilderTy &Builder) {
   assert(!RegionStack.empty() && "Region stack mismatch, stack empty!");
 
   // Provide an region stop point.
-  EmitStopPoint(Fn, Builder);
+  EmitStopPoint(Builder);
 
   RegionStack.pop_back();
 }
 
+/// EmitFunctionEnd - Constructs the debug code for exiting a function.
+void CGDebugInfo::EmitFunctionEnd(CGBuilderTy &Builder) {
+  assert(!RegionStack.empty() && "Region stack mismatch, stack empty!");
+  unsigned RCount = FnBeginRegionCount.back();
+  assert(RCount <= RegionStack.size() && "Region stack mismatch");
+
+  // Pop all regions for this function.
+  while (RegionStack.size() != RCount)
+    EmitRegionEnd(Builder);
+  FnBeginRegionCount.pop_back();
+}
+
 // EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.  
 // See BuildByRefType.
 llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD,
@@ -1470,26 +1695,20 @@
   else 
     Ty = getOrCreateType(VD->getType(), Unit);
 
+  // If there is not any debug info for type then do not emit debug info
+  // for this variable.
+  if (!Ty)
+    return;
+
   // 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();
-  }
+  unsigned Line = getLineNumber(VD->getLocation());
+  unsigned Column = getColumnNumber(VD->getLocation());
 
   // Create the descriptor for the variable.
   llvm::DIVariable D =
     DebugFactory.CreateVariable(Tag, llvm::DIDescriptor(RegionStack.back()),
                                 VD->getName(),
-                                Unit, Line, Ty);
+                                Unit, Line, Ty, CGM.getLangOptions().Optimize);
   // Insert an llvm.dbg.declare into the current block.
   llvm::Instruction *Call =
     DebugFactory.InsertDeclare(Storage, D, Builder.GetInsertBlock());
@@ -1517,13 +1736,8 @@
     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();
+  unsigned Line = getLineNumber(VD->getLocation());
+  unsigned Column = getColumnNumber(VD->getLocation());
 
   CharUnits offset = CGF->BlockDecls[VD];
   llvm::SmallVector<llvm::Value *, 9> addr;
@@ -1555,7 +1769,7 @@
     DebugFactory.InsertDeclare(Storage, D, Builder.GetInsertBlock());
   
   llvm::MDNode *Scope = RegionStack.back();
-  Call->setDebugLoc(llvm::DebugLoc::get(Line, PLoc.getColumn(), Scope));
+  Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));
 }
 
 void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD,
@@ -1585,9 +1799,7 @@
   
   // 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();
+  unsigned LineNo = getLineNumber(D->getLocation());
 
   QualType T = D->getType();
   if (T->isIncompleteArrayType()) {
@@ -1601,12 +1813,14 @@
     T = CGM.getContext().getConstantArrayType(ET, ConstVal,
                                            ArrayType::Normal, 0);
   }
-  llvm::StringRef DeclName = Var->getName();
+  llvm::StringRef DeclName = D->getName();
+  llvm::StringRef LinkageName;
+  if (D->getDeclContext() && !isa<FunctionDecl>(D->getDeclContext()))
+    LinkageName = Var->getName();
   llvm::DIDescriptor DContext = 
     getContextDescriptor(dyn_cast<Decl>(D->getDeclContext()), Unit);
-  DebugFactory.CreateGlobalVariable(DContext, DeclName,
-                                    DeclName, llvm::StringRef(), Unit, LineNo,
-                                    getOrCreateType(T, Unit),
+  DebugFactory.CreateGlobalVariable(DContext, DeclName, DeclName, LinkageName,
+                                    Unit, LineNo, getOrCreateType(T, Unit),
                                     Var->hasInternalLinkage(),
                                     true/*definition*/, Var);
 }
@@ -1616,9 +1830,7 @@
                                      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();
+  unsigned LineNo = getLineNumber(ID->getLocation());
 
   llvm::StringRef Name = ID->getName();
 
@@ -1641,6 +1853,26 @@
                                     true/*definition*/, Var);
 }
 
+/// EmitGlobalVariable - Emit global variable's debug info.
+void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, 
+                                     llvm::ConstantInt *Init,
+                                     CGBuilderTy &Builder) {
+  // Create the descriptor for the variable.
+  llvm::DIFile Unit = getOrCreateFile(VD->getLocation());
+  llvm::StringRef Name = VD->getName();
+  llvm::DIType Ty = getOrCreateType(VD->getType(), Unit);
+  if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(VD)) {
+    if (const EnumDecl *ED = dyn_cast<EnumDecl>(ECD->getDeclContext()))
+      Ty = CreateEnumType(ED, Unit);
+  }
+  // Do not use DIGlobalVariable for enums.
+  if (Ty.getTag() == llvm::dwarf::DW_TAG_enumeration_type)
+    return;
+  DebugFactory.CreateGlobalVariable(Unit, Name, Name, Name, Unit,
+                                    getLineNumber(VD->getLocation()),
+                                    Ty, true, true, Init);
+}
+
 /// getOrCreateNamesSpace - Return namespace descriptor for the given
 /// namespace decl.
 llvm::DINameSpace 
@@ -1651,15 +1883,13 @@
   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();
+  unsigned LineNo = getLineNumber(NSDecl->getLocation());
 
   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());
+                                 llvm::DIFile(Unit), LineNo);
+  NameSpaceCache[NSDecl] = llvm::WeakVH(NS);
   return NS;
 }
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index c16379a..fce66b2 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -46,9 +46,6 @@
   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;
@@ -58,10 +55,19 @@
 
   std::vector<llvm::TrackingVH<llvm::MDNode> > RegionStack;
   llvm::DenseMap<const Decl *, llvm::WeakVH> RegionMap;
+  // FnBeginRegionCount - Keep track of RegionStack counter at the beginning
+  // of a function. This is used to pop unbalanced regions at the end of a
+  // function.
+  std::vector<unsigned> FnBeginRegionCount;
+
+  /// LineDirectiveFiles - This stack is used to keep track of 
+  /// scopes introduced by #line directives.
+  std::vector<const char *> LineDirectiveFiles;
 
   /// DebugInfoNames - This is a storage for names that are
   /// constructed on demand. For example, C++ destructors, C++ operators etc..
   llvm::BumpPtrAllocator DebugInfoNames;
+  llvm::StringRef CWDName;
 
   llvm::DenseMap<const char *, llvm::WeakVH> DIFileCache;
   llvm::DenseMap<const FunctionDecl *, llvm::WeakVH> SPCache;
@@ -80,11 +86,13 @@
   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 ObjCObjectType *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 CreateEnumType(const EnumDecl *ED, llvm::DIFile Unit);
   llvm::DIType getOrCreateMethodType(const CXXMethodDecl *Method,
                                      llvm::DIFile F);
   llvm::DIType getOrCreateVTablePtrType(llvm::DIFile F);
@@ -97,16 +105,22 @@
   
   llvm::DISubprogram CreateCXXMemberFunction(const CXXMethodDecl *Method,
                                              llvm::DIFile F,
-                                             llvm::DICompositeType &RecordTy);
+                                             llvm::DIType RecordTy);
   
   void CollectCXXMemberFunctions(const CXXRecordDecl *Decl,
                                  llvm::DIFile F,
                                  llvm::SmallVectorImpl<llvm::DIDescriptor> &E,
-                                 llvm::DICompositeType &T);
+                                 llvm::DIType T);
+
+  void CollectCXXFriends(const CXXRecordDecl *Decl,
+                       llvm::DIFile F,
+                       llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys,
+                       llvm::DIType RecordTy);
+
   void CollectCXXBases(const CXXRecordDecl *Decl,
                        llvm::DIFile F,
                        llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys,
-                       llvm::DICompositeType &RecordTy);
+                       llvm::DIType RecordTy);
 
 
   void CollectRecordFields(const RecordDecl *Decl, llvm::DIFile F,
@@ -126,20 +140,27 @@
 
   /// EmitStopPoint - Emit a call to llvm.dbg.stoppoint to indicate a change of
   /// source line.
-  void EmitStopPoint(llvm::Function *Fn, CGBuilderTy &Builder);
+  void EmitStopPoint(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);
 
+  /// EmitFunctionEnd - Constructs the debug code for exiting a function.
+  void EmitFunctionEnd(CGBuilderTy &Builder);
+
+  /// UpdateLineDirectiveRegion - Update region stack only if #line directive
+  /// has introduced scope change.
+  void UpdateLineDirectiveRegion(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);
+  void EmitRegionStart(CGBuilderTy &Builder);
 
   /// EmitRegionEnd - Emit call to llvm.dbg.region.end to indicate end of a
   /// block.
-  void EmitRegionEnd(llvm::Function *Fn, CGBuilderTy &Builder);
+  void EmitRegionEnd(CGBuilderTy &Builder);
 
   /// EmitDeclareOfAutoVariable - Emit call to llvm.dbg.declare for an automatic
   /// variable declaration.
@@ -164,6 +185,10 @@
   /// EmitGlobalVariable - Emit information about an objective-c interface.
   void EmitGlobalVariable(llvm::GlobalVariable *GV, ObjCInterfaceDecl *Decl);
 
+  /// EmitGlobalVariable - Emit global variable's debug info.
+  void EmitGlobalVariable(const ValueDecl *VD, llvm::ConstantInt *Init, 
+                          CGBuilderTy &Builder);
+
 private:
   /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
   void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,
@@ -182,6 +207,9 @@
   llvm::DIDescriptor getContextDescriptor(const Decl *Decl,
                                           llvm::DIDescriptor &CU);
 
+  /// getCurrentDirname - Return current directory name.
+  llvm::StringRef getCurrentDirname();
+
   /// CreateCompileUnit - Create new compile unit.
   void CreateCompileUnit();
 
@@ -205,9 +233,19 @@
   /// is stored on the side.
   llvm::StringRef getFunctionName(const FunctionDecl *FD);
 
+  /// getClassName - Get class name including template argument list.
+  llvm::StringRef getClassName(RecordDecl *RD);
+
   /// getVTableName - Get vtable name for the given Class.
   llvm::StringRef getVTableName(const CXXRecordDecl *Decl);
 
+  /// getLineNumber - Get line number for the location. If location is invalid
+  /// then use current location.
+  unsigned getLineNumber(SourceLocation Loc);
+
+  /// getColumnNumber - Get column number for the location. If location is 
+  /// invalid then use current location.
+  unsigned getColumnNumber(SourceLocation Loc);
 };
 } // namespace CodeGen
 } // namespace clang
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 331ae7a..8ce196b 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -20,7 +20,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
-#include "clang/CodeGen/CodeGenOptions.h"
+#include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/GlobalVariable.h"
 #include "llvm/Intrinsics.h"
 #include "llvm/Target/TargetData.h"
@@ -38,7 +38,7 @@
   case Decl::ClassTemplatePartialSpecialization:
   case Decl::TemplateTypeParm:
   case Decl::UnresolvedUsingValue:
-    case Decl::NonTypeTemplateParm:
+  case Decl::NonTypeTemplateParm:
   case Decl::CXXMethod:
   case Decl::CXXConstructor:
   case Decl::CXXDestructor:
@@ -59,6 +59,7 @@
   case Decl::ObjCImplementation:
   case Decl::ObjCProperty:
   case Decl::ObjCCompatibleAlias:
+  case Decl::AccessSpec:
   case Decl::LinkageSpec:
   case Decl::ObjCPropertyImpl:
   case Decl::ObjCClass:
@@ -106,27 +107,27 @@
     CGM.ErrorUnsupported(&D, "__asm__");
 
   switch (D.getStorageClass()) {
-  case VarDecl::None:
-  case VarDecl::Auto:
-  case VarDecl::Register:
+  case SC_None:
+  case SC_Auto:
+  case SC_Register:
     return EmitLocalBlockVarDecl(D);
-  case VarDecl::Static: {
+  case SC_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;
-      }
-    }
+    // If the function definition has some sort of weak linkage, its
+    // static variables should also be weak so that they get properly
+    // uniqued.  We can't do this in C, though, because there's no
+    // standard way to agree on which variables are the same (i.e.
+    // there's no mangling).
+    if (getContext().getLangOptions().CPlusPlus)
+      if (llvm::GlobalValue::isWeakForLinker(CurFn->getLinkage()))
+        Linkage = CurFn->getLinkage();
     
     return EmitStaticBlockVarDecl(D, Linkage);
   }
-  case VarDecl::Extern:
-  case VarDecl::PrivateExtern:
+  case SC_Extern:
+  case SC_PrivateExtern:
     // Don't emit it now, allow it to be emitted lazily on its first use.
     return;
   }
@@ -138,16 +139,14 @@
                                      const char *Separator) {
   CodeGenModule &CGM = CGF.CGM;
   if (CGF.getContext().getLangOptions().CPlusPlus) {
-    MangleBuffer Name;
-    CGM.getMangledName(Name, &D);
-    return Name.getString().str();
+    llvm::StringRef Name = CGM.getMangledName(&D);
+    return Name.str();
   }
   
   std::string ContextName;
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl)) {
-    MangleBuffer Name;
-    CGM.getMangledName(Name, FD);
-    ContextName = Name.getString().str();
+    llvm::StringRef Name = CGM.getMangledName(FD);
+    ContextName = Name.str();
   } else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl))
     ContextName = CGF.CurFn->getName();
   else
@@ -184,7 +183,7 @@
 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) {
@@ -199,7 +198,7 @@
     }
     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
@@ -239,12 +238,10 @@
   // Store into LocalDeclMap before generating initializer to handle
   // circular references.
   DMEntry = GV;
-  if (getContext().getLangOptions().CPlusPlus)
-    CGM.setStaticLocalDeclAddress(&D, GV);
 
+  // We can't have a VLA here, but we can have a pointer to a VLA,
+  // even though that doesn't really make any sense.
   // 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());
 
@@ -269,6 +266,9 @@
   if (D.hasAttr<UsedAttr>())
     CGM.AddUsedGlobal(GV);
 
+  if (getContext().getLangOptions().CPlusPlus)
+    CGM.setStaticLocalDeclAddress(&D, GV);
+  
   // We may have to cast the constant because of the initializer
   // mismatch above.
   //
@@ -327,10 +327,10 @@
   Types.push_back(llvm::PointerType::getUnqual(ByRefTypeHolder));
   
   // int32_t __flags;
-  Types.push_back(llvm::Type::getInt32Ty(VMContext));
+  Types.push_back(Int32Ty);
     
   // int32_t __size;
-  Types.push_back(llvm::Type::getInt32Ty(VMContext));
+  Types.push_back(Int32Ty);
 
   bool HasCopyAndDispose = BlockRequiresCopying(Ty);
   if (HasCopyAndDispose) {
@@ -388,26 +388,135 @@
   return Info.first;
 }
 
+namespace {
+  struct CallArrayDtor : EHScopeStack::Cleanup {
+    CallArrayDtor(const CXXDestructorDecl *Dtor, 
+                  const ConstantArrayType *Type,
+                  llvm::Value *Loc)
+      : Dtor(Dtor), Type(Type), Loc(Loc) {}
+
+    const CXXDestructorDecl *Dtor;
+    const ConstantArrayType *Type;
+    llvm::Value *Loc;
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      QualType BaseElementTy = CGF.getContext().getBaseElementType(Type);
+      const llvm::Type *BasePtr = CGF.ConvertType(BaseElementTy);
+      BasePtr = llvm::PointerType::getUnqual(BasePtr);
+      llvm::Value *BaseAddrPtr = CGF.Builder.CreateBitCast(Loc, BasePtr);
+      CGF.EmitCXXAggrDestructorCall(Dtor, Type, BaseAddrPtr);
+    }
+  };
+
+  struct CallVarDtor : EHScopeStack::Cleanup {
+    CallVarDtor(const CXXDestructorDecl *Dtor,
+                llvm::Value *NRVOFlag,
+                llvm::Value *Loc)
+      : Dtor(Dtor), NRVOFlag(NRVOFlag), Loc(Loc) {}
+
+    const CXXDestructorDecl *Dtor;
+    llvm::Value *NRVOFlag;
+    llvm::Value *Loc;
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      // Along the exceptions path we always execute the dtor.
+      bool NRVO = !IsForEH && NRVOFlag;
+
+      llvm::BasicBlock *SkipDtorBB = 0;
+      if (NRVO) {
+        // If we exited via NRVO, we skip the destructor call.
+        llvm::BasicBlock *RunDtorBB = CGF.createBasicBlock("nrvo.unused");
+        SkipDtorBB = CGF.createBasicBlock("nrvo.skipdtor");
+        llvm::Value *DidNRVO = CGF.Builder.CreateLoad(NRVOFlag, "nrvo.val");
+        CGF.Builder.CreateCondBr(DidNRVO, SkipDtorBB, RunDtorBB);
+        CGF.EmitBlock(RunDtorBB);
+      }
+          
+      CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
+                                /*ForVirtualBase=*/false, Loc);
+
+      if (NRVO) CGF.EmitBlock(SkipDtorBB);
+    }
+  };
+}
+
+namespace {
+  struct CallStackRestore : EHScopeStack::Cleanup {
+    llvm::Value *Stack;
+    CallStackRestore(llvm::Value *Stack) : Stack(Stack) {}
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      llvm::Value *V = CGF.Builder.CreateLoad(Stack, "tmp");
+      llvm::Value *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
+      CGF.Builder.CreateCall(F, V);
+    }
+  };
+
+  struct CallCleanupFunction : EHScopeStack::Cleanup {
+    llvm::Constant *CleanupFn;
+    const CGFunctionInfo &FnInfo;
+    llvm::Value *Addr;
+    const VarDecl &Var;
+    
+    CallCleanupFunction(llvm::Constant *CleanupFn, const CGFunctionInfo *Info,
+                        llvm::Value *Addr, const VarDecl *Var)
+      : CleanupFn(CleanupFn), FnInfo(*Info), Addr(Addr), Var(*Var) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      // 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 = FnInfo.arg_begin()->type;
+      llvm::Value *Arg =
+        CGF.Builder.CreateBitCast(Addr, CGF.ConvertType(ArgTy));
+
+      CallArgList Args;
+      Args.push_back(std::make_pair(RValue::get(Arg),
+                            CGF.getContext().getPointerType(Var.getType())));
+      CGF.EmitCall(FnInfo, CleanupFn, ReturnValueSlot(), Args);
+    }
+  };
+
+  struct CallBlockRelease : EHScopeStack::Cleanup {
+    llvm::Value *Addr;
+    CallBlockRelease(llvm::Value *Addr) : Addr(Addr) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      llvm::Value *V = CGF.Builder.CreateStructGEP(Addr, 1, "forwarding");
+      V = CGF.Builder.CreateLoad(V);
+      CGF.BuildBlockRelease(V);
+    }
+  };
+}
+
 /// 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) {
+void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D,
+                                            SpecialInitFn *SpecialInit) {
   QualType Ty = D.getType();
+  unsigned Alignment = getContext().getDeclAlign(&D).getQuantity();
   bool isByRef = D.hasAttr<BlocksAttr>();
   bool needsDispose = false;
   CharUnits Align = CharUnits::Zero();
   bool IsSimpleConstantInitializer = false;
 
+  bool NRVO = false;
+  llvm::Value *NRVOFlag = 0;
   llvm::Value *DeclPtr;
   if (Ty->isConstantSizeType()) {
     if (!Target.useGlobalsForAutomaticVariables()) {
-      
+      NRVO = getContext().getLangOptions().ElideConstructors && 
+             D.isNRVOVariable();
       // 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 &&
+      // a staticly determinable constant, try to optimize it (unless the NRVO
+      // is already optimizing this).
+      if (!NRVO && D.getInit() && !isByRef &&
           (Ty->isArrayType() || Ty->isRecordType()) &&
           Ty->isPODType() &&
-          D.getInit()->isConstantInitializer(getContext())) {
+          D.getInit()->isConstantInitializer(getContext(), false)) {
         // If this variable is marked 'const', emit the value as a global.
         if (CGM.getCodeGenOpts().MergeAllConstants &&
             Ty.isConstant(getContext())) {
@@ -418,23 +527,48 @@
         IsSimpleConstantInitializer = true;
       }
       
-      // A normal fixed sized variable becomes an alloca in the entry block.
+      // A normal fixed sized variable becomes an alloca in the entry block,
+      // unless it's an NRVO variable.
       const llvm::Type *LTy = ConvertTypeForMem(Ty);
-      if (isByRef)
-        LTy = BuildByRefType(&D);
-      llvm::AllocaInst *Alloc = CreateTempAlloca(LTy);
-      Alloc->setName(D.getNameAsString());
+      
+      if (NRVO) {
+        // The named return value optimization: allocate this variable in the
+        // return slot, so that we can elide the copy when returning this
+        // variable (C++0x [class.copy]p34).
+        DeclPtr = ReturnValue;
+        
+        if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
+          if (!cast<CXXRecordDecl>(RecordTy->getDecl())->hasTrivialDestructor()) {
+            // Create a flag that is used to indicate when the NRVO was applied
+            // to this variable. Set it to zero to indicate that NRVO was not 
+            // applied.
+            const llvm::Type *BoolTy = llvm::Type::getInt1Ty(VMContext);
+            llvm::Value *Zero = llvm::ConstantInt::get(BoolTy, 0);
+            NRVOFlag = CreateTempAlloca(BoolTy, "nrvo");            
+            Builder.CreateStore(Zero, NRVOFlag);
+            
+            // Record the NRVO flag for this variable.
+            NRVOFlags[&D] = NRVOFlag;
+          }
+        }
+      } else {
+        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;
+        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.";
+        D.getStorageClass() == SC_Register ? ".reg." : ".auto.";
       DeclPtr = CreateStaticBlockVarDecl(D, Class,
                                          llvm::GlobalValue
                                          ::InternalLinkage);
@@ -458,27 +592,17 @@
 
       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);
-      }
+      // Push a cleanup block and restore the stack there.
+      EHStack.pushCleanup<CallStackRestore>(NormalCleanup, Stack);
     }
 
     // Get the element type.
     const llvm::Type *LElemTy = ConvertTypeForMem(Ty);
     const llvm::Type *LElemPtrTy =
-      llvm::PointerType::get(LElemTy, D.getType().getAddressSpace());
+      llvm::PointerType::get(LElemTy, Ty.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");
@@ -543,18 +667,18 @@
     int isa = 0;
     if (flag&BLOCK_FIELD_IS_WEAK)
       isa = 1;
-    V = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), isa);
+    V = llvm::ConstantInt::get(Int32Ty, 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);
+    V = llvm::ConstantInt::get(Int32Ty, 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),
+    V = llvm::ConstantInt::get(Int32Ty,
                                CGM.GetTargetTypeStoreSize(V1).getQuantity());
     Builder.CreateStore(V, size_field);
 
@@ -572,24 +696,24 @@
     }
   }
 
-  if (Init) {
+  if (SpecialInit) {
+    SpecialInit(*this, D, DeclPtr);
+  } else if (Init) {
     llvm::Value *Loc = DeclPtr;
     if (isByRef)
       Loc = Builder.CreateStructGEP(DeclPtr, getByRefValueLLVMField(&D), 
                                     D.getNameAsString());
     
-    bool isVolatile =
-    getContext().getCanonicalType(D.getType()).isVolatileQualified();
+    bool isVolatile = getContext().getCanonicalType(Ty).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);
+      llvm::Constant *Init = CGM.EmitConstantExpr(D.getInit(), Ty,this);
       assert(Init != 0 && "Wasn't a simple constant init?");
       
       llvm::Value *AlignVal = 
-      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 
-                             Align.getQuantity());
+      llvm::ConstantInt::get(Int32Ty, Align.getQuantity());
       const llvm::Type *IntPtr =
       llvm::IntegerType::get(VMContext, LLVMPointerWidth);
       llvm::Value *SizeVal =
@@ -628,63 +752,42 @@
                             Loc, SrcPtr, SizeVal, AlignVal, NotVolatile);
       }
     } else if (Ty->isReferenceType()) {
-      RValue RV = EmitReferenceBindingToExpr(Init, /*IsInitializer=*/true);
-      EmitStoreOfScalar(RV.getScalarVal(), Loc, false, Ty);
+      RValue RV = EmitReferenceBindingToExpr(Init, &D);
+      EmitStoreOfScalar(RV.getScalarVal(), Loc, false, Alignment, Ty);
     } else if (!hasAggregateLLVMType(Init->getType())) {
       llvm::Value *V = EmitScalarExpr(Init);
-      EmitStoreOfScalar(V, Loc, isVolatile, D.getType());
+      EmitStoreOfScalar(V, Loc, isVolatile, Alignment, Ty);
     } 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 (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {      
       if (!ClassDecl->hasTrivialDestructor()) {
-        const CXXDestructorDecl *D = ClassDecl->getDestructor(getContext());
+        // Note: We suppress the destructor call when the corresponding NRVO
+        // flag has been set.
+        llvm::Value *Loc = DeclPtr;
+        if (isByRef)
+          Loc = Builder.CreateStructGEP(DeclPtr, getByRefValueLLVMField(&D), 
+                                        D.getNameAsString());
+        
+        const CXXDestructorDecl *D = ClassDecl->getDestructor();
         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);
-          }
+          EHStack.pushCleanup<CallArrayDtor>(NormalAndEHCleanup,
+                                             D, Array, Loc);
         } 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);
-          }
+          EHStack.pushCleanup<CallVarDtor>(NormalAndEHCleanup,
+                                           D, NRVOFlag, Loc);
         }
       }
   }
@@ -697,49 +800,14 @@
     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);
-    }
+    EHStack.pushCleanup<CallCleanupFunction>(NormalAndEHCleanup,
+                                             F, &Info, DeclPtr, &D);
   }
 
-  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);
-    }
-  }
+  // If this is a block variable, clean it up.
+  // FIXME: this should be an EH cleanup as well.  rdar://problem/8224178
+  if (needsDispose && CGM.getLangOptions().getGCMode() != LangOptions::GCOnly)
+    EHStack.pushCleanup<CallBlockRelease>(NormalCleanup, DeclPtr);
 }
 
 /// Emit an alloca (or GlobalValue depending on target)
@@ -761,7 +829,8 @@
     DeclPtr = CreateMemTemp(Ty, D.getName() + ".addr");
 
     // Store the initial value into the alloca.
-    EmitStoreOfScalar(Arg, DeclPtr, CTy.isVolatileQualified(), Ty);
+    unsigned Alignment = getContext().getDeclAlign(&D).getQuantity();
+    EmitStoreOfScalar(Arg, DeclPtr, CTy.isVolatileQualified(), Alignment, Ty);
   }
   Arg->setName(D.getName());
 
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index f6c805f..e0bd3a7 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -12,7 +12,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "CodeGenFunction.h"
-#include "clang/CodeGen/CodeGenOptions.h"
+#include "clang/Frontend/CodeGenOptions.h"
+#include "llvm/Intrinsics.h"
+
 using namespace clang;
 using namespace CodeGen;
 
@@ -22,55 +24,61 @@
   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();
 
+  unsigned Alignment = Context.getDeclAlign(&D).getQuantity();
   if (!CGF.hasAggregateLLVMType(T)) {
     llvm::Value *V = CGF.EmitScalarExpr(Init);
-    CGF.EmitStoreOfScalar(V, DeclPtr, isVolatile, T);
+    CGF.EmitStoreOfScalar(V, DeclPtr, isVolatile, Alignment, 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);
   }
 }
 
+static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
+                            llvm::Constant *DeclPtr) {
+  CodeGenModule &CGM = CGF.CGM;
+  ASTContext &Context = CGF.getContext();
+  
+  QualType T = D.getType();
+  
+  // Drill down past array types.
+  const ConstantArrayType *Array = Context.getAsConstantArrayType(T);
+  if (Array)
+    T = Context.getBaseElementType(Array);
+  
+  /// If that's not a record, we're done.
+  /// FIXME:  __attribute__((cleanup)) ?
+  const RecordType *RT = T->getAs<RecordType>();
+  if (!RT)
+    return;
+  
+  CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+  if (RD->hasTrivialDestructor())
+    return;
+  
+  CXXDestructorDecl *Dtor = RD->getDestructor();
+  
+  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) {
 
@@ -79,15 +87,13 @@
 
   if (!T->isReferenceType()) {
     EmitDeclInit(*this, D, DeclPtr);
+    EmitDeclDestroy(*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");
+
+  unsigned Alignment = getContext().getDeclAlign(&D).getQuantity();
+  RValue RV = EmitReferenceBindingToExpr(Init, &D);
+  EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T);
 }
 
 void
@@ -131,6 +137,25 @@
   Builder.CreateCall(AtExitFn, &Args[0], llvm::array_endof(Args));
 }
 
+static llvm::Function *
+CreateGlobalInitOrDestructFunction(CodeGenModule &CGM,
+                                   const llvm::FunctionType *FTy,
+                                   llvm::StringRef Name) {
+  llvm::Function *Fn =
+    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
+                           Name, &CGM.getModule());
+
+  // Set the section if needed.
+  if (const char *Section = 
+        CGM.getContext().Target.getStaticInitSectionSpecifier())
+    Fn->setSection(Section);
+
+  if (!CGM.getLangOptions().Exceptions)
+    Fn->setDoesNotThrow();
+
+  return Fn;
+}
+
 void
 CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D) {
   const llvm::FunctionType *FTy
@@ -139,17 +164,35 @@
 
   // Create a variable initialization function.
   llvm::Function *Fn =
-    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
-                           "__cxx_global_var_init", &TheModule);
+    CreateGlobalInitOrDestructFunction(*this, FTy, "__cxx_global_var_init");
 
   CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D);
 
-  CXXGlobalInits.push_back(Fn);
+  if (D->hasAttr<InitPriorityAttr>()) {
+    unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority();
+    OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size());
+    PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
+    DelayedCXXInitPosition.erase(D);
+  }
+  else {
+    llvm::DenseMap<const Decl *, unsigned>::iterator I =
+      DelayedCXXInitPosition.find(D);
+    if (I == DelayedCXXInitPosition.end()) {
+      CXXGlobalInits.push_back(Fn);
+    } else {
+      assert(CXXGlobalInits[I->second] == 0);
+      CXXGlobalInits[I->second] = Fn;
+      DelayedCXXInitPosition.erase(I);
+    }
+  }
 }
 
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
-  if (CXXGlobalInits.empty())
+  while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
+    CXXGlobalInits.pop_back();
+
+  if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty())
     return;
 
   const llvm::FunctionType *FTy
@@ -157,21 +200,29 @@
                               false);
 
   // Create our global initialization function.
-  llvm::Function *Fn =
-    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
-                           "_GLOBAL__I_a", &TheModule);
+  llvm::Function *Fn = 
+    CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a");
 
-  CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn,
-                                                   &CXXGlobalInits[0],
-                                                   CXXGlobalInits.size());
+  if (!PrioritizedCXXGlobalInits.empty()) {
+    llvm::SmallVector<llvm::Constant*, 8> LocalCXXGlobalInits;
+    llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(), 
+                         PrioritizedCXXGlobalInits.end()); 
+    for (unsigned i = 0; i < PrioritizedCXXGlobalInits.size(); i++) {
+      llvm::Function *Fn = PrioritizedCXXGlobalInits[i].second;
+      LocalCXXGlobalInits.push_back(Fn);
+    }
+    LocalCXXGlobalInits.append(CXXGlobalInits.begin(), CXXGlobalInits.end());
+    CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn,
+                                                    &LocalCXXGlobalInits[0],
+                                                    LocalCXXGlobalInits.size());
+  }
+  else
+    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;
@@ -182,8 +233,7 @@
 
   // Create our global destructor function.
   llvm::Function *Fn =
-    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
-                           "_GLOBAL__D_a", &TheModule);
+    CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__D_a");
 
   CodeGenFunction(*this).GenerateCXXGlobalDtorFunc(Fn, CXXGlobalDtors);
   AddGlobalDtor(Fn);
@@ -207,20 +257,21 @@
                 SourceLocation());
 
   for (unsigned i = 0; i != NumDecls; ++i)
-    Builder.CreateCall(Decls[i]);
+    if (Decls[i])
+      Builder.CreateCall(Decls[i]);
 
   FinishFunction();
 }
 
 void CodeGenFunction::GenerateCXXGlobalDtorFunc(llvm::Function *Fn,
-                const std::vector<std::pair<llvm::Constant*, llvm::Constant*> >
+                  const std::vector<std::pair<llvm::WeakVH, 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::Value *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.
@@ -276,17 +327,33 @@
   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort");
 }
 
+namespace {
+  struct CallGuardAbort : EHScopeStack::Cleanup {
+    llvm::GlobalVariable *Guard;
+    CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      // It shouldn't be possible for this to throw, but if it can,
+      // this should allow for the possibility of an invoke.
+      CGF.Builder.CreateCall(getGuardAbortFn(CGF), Guard)
+        ->setDoesNotThrow();
+    }
+  };
+}
+
 void
 CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D,
                                                llvm::GlobalVariable *GV) {
+  // Bail out early if this initializer isn't reachable.
+  if (!Builder.GetInsertBlock()) return;
+
   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 =
+  llvm::GlobalVariable *GuardVariable =
     new llvm::GlobalVariable(CGM.getModule(), Int64Ty,
                              false, GV->getLinkage(),
                              llvm::Constant::getNullValue(Int64Ty),
@@ -307,7 +374,8 @@
 
   EmitBlock(InitCheckBlock);
 
-  if (ThreadsafeStatics) {
+  // Variables used when coping with thread-safe statics and exceptions.
+  if (ThreadsafeStatics) {    
     // Call __cxa_guard_acquire.
     V = Builder.CreateCall(getGuardAcquireFn(*this), GuardVariable);
                
@@ -316,35 +384,71 @@
     Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"),
                          InitBlock, EndBlock);
   
-    EmitBlock(InitBlock);
-
-    if (Exceptions) {
-      EHCleanupBlock Cleanup(*this);
+    // Call __cxa_guard_abort along the exceptional edge.
+    if (Exceptions)
+      EHStack.pushCleanup<CallGuardAbort>(EHCleanup, GuardVariable);
     
-      // Call __cxa_guard_abort.
-      Builder.CreateCall(getGuardAbortFn(*this), GuardVariable);
-    }
+    EmitBlock(InitBlock);
   }
 
   if (D.getType()->isReferenceType()) {
+    unsigned Alignment = getContext().getDeclAlign(&D).getQuantity();
     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);
-
+    RValue RV = EmitReferenceBindingToExpr(D.getInit(), &D);
+    EmitStoreOfScalar(RV.getScalarVal(), GV, /*Volatile=*/false, Alignment, T);
   } else
     EmitDeclInit(*this, D, GV);
 
   if (ThreadsafeStatics) {
-    // Call __cxa_guard_release.
-    Builder.CreateCall(getGuardReleaseFn(*this), GuardVariable);
+    // Pop the guard-abort cleanup if we pushed one.
+    if (Exceptions)
+      PopCleanupBlock();
+
+    // Call __cxa_guard_release.  This cannot throw.
+    Builder.CreateCall(getGuardReleaseFn(*this), GuardVariable);    
   } else {
     llvm::Value *One = 
       llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 1);
     Builder.CreateStore(One, Builder.CreateBitCast(GuardVariable, PtrTy));
   }
 
+  // Register the call to the destructor.
+  if (!D.getType()->isReferenceType())
+    EmitDeclDestroy(*this, D, GV);
+  
   EmitBlock(EndBlock);
 }
+
+/// GenerateCXXAggrDestructorHelper - Generates a helper function which when
+/// invoked, calls the default destructor on array elements in reverse order of
+/// construction.
+llvm::Function * 
+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()));
+  
+  const CGFunctionInfo &FI = 
+    CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args, 
+                                   FunctionType::ExtInfo());
+  const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false);
+  llvm::Function *Fn = 
+    CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor");
+
+  StartFunction(GlobalDecl(), getContext().VoidTy, Fn, Args, SourceLocation());
+
+  QualType BaseElementTy = getContext().getBaseElementType(Array);
+  const llvm::Type *BasePtr = ConvertType(BaseElementTy)->getPointerTo();
+  llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr);
+  
+  EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
+  
+  FinishFunction();
+  
+  return Fn;
+}
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index 405df40..7fb616e 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -14,11 +14,163 @@
 #include "clang/AST/StmtCXX.h"
 
 #include "llvm/Intrinsics.h"
+#include "llvm/Support/CallSite.h"
 
+#include "CGObjCRuntime.h"
 #include "CodeGenFunction.h"
+#include "CGException.h"
+#include "TargetInfo.h"
+
 using namespace clang;
 using namespace CodeGen;
 
+/// Push an entry of the given size onto this protected-scope stack.
+char *EHScopeStack::allocate(size_t Size) {
+  if (!StartOfBuffer) {
+    unsigned Capacity = 1024;
+    while (Capacity < Size) Capacity *= 2;
+    StartOfBuffer = new char[Capacity];
+    StartOfData = EndOfBuffer = StartOfBuffer + Capacity;
+  } else if (static_cast<size_t>(StartOfData - StartOfBuffer) < Size) {
+    unsigned CurrentCapacity = EndOfBuffer - StartOfBuffer;
+    unsigned UsedCapacity = CurrentCapacity - (StartOfData - StartOfBuffer);
+
+    unsigned NewCapacity = CurrentCapacity;
+    do {
+      NewCapacity *= 2;
+    } while (NewCapacity < UsedCapacity + Size);
+
+    char *NewStartOfBuffer = new char[NewCapacity];
+    char *NewEndOfBuffer = NewStartOfBuffer + NewCapacity;
+    char *NewStartOfData = NewEndOfBuffer - UsedCapacity;
+    memcpy(NewStartOfData, StartOfData, UsedCapacity);
+    delete [] StartOfBuffer;
+    StartOfBuffer = NewStartOfBuffer;
+    EndOfBuffer = NewEndOfBuffer;
+    StartOfData = NewStartOfData;
+  }
+
+  assert(StartOfBuffer + Size <= StartOfData);
+  StartOfData -= Size;
+  return StartOfData;
+}
+
+EHScopeStack::stable_iterator
+EHScopeStack::getEnclosingEHCleanup(iterator it) const {
+  assert(it != end());
+  do {
+    if (isa<EHCleanupScope>(*it)) {
+      if (cast<EHCleanupScope>(*it).isEHCleanup())
+        return stabilize(it);
+      return cast<EHCleanupScope>(*it).getEnclosingEHCleanup();
+    }
+    ++it;
+  } while (it != end());
+  return stable_end();
+}
+
+
+void *EHScopeStack::pushCleanup(CleanupKind Kind, size_t Size) {
+  assert(((Size % sizeof(void*)) == 0) && "cleanup type is misaligned");
+  char *Buffer = allocate(EHCleanupScope::getSizeForCleanupSize(Size));
+  bool IsNormalCleanup = Kind & NormalCleanup;
+  bool IsEHCleanup = Kind & EHCleanup;
+  bool IsActive = !(Kind & InactiveCleanup);
+  EHCleanupScope *Scope =
+    new (Buffer) EHCleanupScope(IsNormalCleanup,
+                                IsEHCleanup,
+                                IsActive,
+                                Size,
+                                BranchFixups.size(),
+                                InnermostNormalCleanup,
+                                InnermostEHCleanup);
+  if (IsNormalCleanup)
+    InnermostNormalCleanup = stable_begin();
+  if (IsEHCleanup)
+    InnermostEHCleanup = stable_begin();
+
+  return Scope->getCleanupBuffer();
+}
+
+void EHScopeStack::popCleanup() {
+  assert(!empty() && "popping exception stack when not empty");
+
+  assert(isa<EHCleanupScope>(*begin()));
+  EHCleanupScope &Cleanup = cast<EHCleanupScope>(*begin());
+  InnermostNormalCleanup = Cleanup.getEnclosingNormalCleanup();
+  InnermostEHCleanup = Cleanup.getEnclosingEHCleanup();
+  StartOfData += Cleanup.getAllocatedSize();
+
+  if (empty()) NextEHDestIndex = FirstEHDestIndex;
+
+  // Destroy the cleanup.
+  Cleanup.~EHCleanupScope();
+
+  // Check whether we can shrink the branch-fixups stack.
+  if (!BranchFixups.empty()) {
+    // If we no longer have any normal cleanups, all the fixups are
+    // complete.
+    if (!hasNormalCleanups())
+      BranchFixups.clear();
+
+    // Otherwise we can still trim out unnecessary nulls.
+    else
+      popNullFixups();
+  }
+}
+
+EHFilterScope *EHScopeStack::pushFilter(unsigned NumFilters) {
+  char *Buffer = allocate(EHFilterScope::getSizeForNumFilters(NumFilters));
+  CatchDepth++;
+  return new (Buffer) EHFilterScope(NumFilters);
+}
+
+void EHScopeStack::popFilter() {
+  assert(!empty() && "popping exception stack when not empty");
+
+  EHFilterScope &Filter = cast<EHFilterScope>(*begin());
+  StartOfData += EHFilterScope::getSizeForNumFilters(Filter.getNumFilters());
+
+  if (empty()) NextEHDestIndex = FirstEHDestIndex;
+
+  assert(CatchDepth > 0 && "mismatched filter push/pop");
+  CatchDepth--;
+}
+
+EHCatchScope *EHScopeStack::pushCatch(unsigned NumHandlers) {
+  char *Buffer = allocate(EHCatchScope::getSizeForNumHandlers(NumHandlers));
+  CatchDepth++;
+  EHCatchScope *Scope = new (Buffer) EHCatchScope(NumHandlers);
+  for (unsigned I = 0; I != NumHandlers; ++I)
+    Scope->getHandlers()[I].Index = getNextEHDestIndex();
+  return Scope;
+}
+
+void EHScopeStack::pushTerminate() {
+  char *Buffer = allocate(EHTerminateScope::getSize());
+  CatchDepth++;
+  new (Buffer) EHTerminateScope(getNextEHDestIndex());
+}
+
+/// Remove any 'null' fixups on the stack.  However, we can't pop more
+/// fixups than the fixup depth on the innermost normal cleanup, or
+/// else fixups that we try to add to that cleanup will end up in the
+/// wrong place.  We *could* try to shrink fixup depths, but that's
+/// actually a lot of work for little benefit.
+void EHScopeStack::popNullFixups() {
+  // We expect this to only be called when there's still an innermost
+  // normal cleanup;  otherwise there really shouldn't be any fixups.
+  assert(hasNormalCleanups());
+
+  EHScopeStack::iterator it = find(InnermostNormalCleanup);
+  unsigned MinSize = cast<EHCleanupScope>(*it).getFixupDepth();
+  assert(BranchFixups.size() >= MinSize && "fixup stack out of order");
+
+  while (BranchFixups.size() > MinSize &&
+         BranchFixups.back().Destination == 0)
+    BranchFixups.pop_back();
+}
+
 static llvm::Constant *getAllocateExceptionFn(CodeGenFunction &CGF) {
   // void *__cxa_allocate_exception(size_t thrown_size);
   const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
@@ -66,8 +218,19 @@
   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow");
 }
 
+static llvm::Constant *getGetExceptionPtrFn(CodeGenFunction &CGF) {
+  // void *__cxa_get_exception_ptr(void*);
+  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_get_exception_ptr");
+}
+
 static llvm::Constant *getBeginCatchFn(CodeGenFunction &CGF) {
-  // void* __cxa_begin_catch();
+  // void *__cxa_begin_catch(void*);
 
   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
   std::vector<const llvm::Type*> Args(1, Int8PtrTy);
@@ -100,17 +263,17 @@
   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
 }
 
-static llvm::Constant *getUnwindResumeOrRethrowFn(CodeGenFunction &CGF) {
-  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+llvm::Constant *CodeGenFunction::getUnwindResumeOrRethrowFn() {
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
   std::vector<const llvm::Type*> Args(1, Int8PtrTy);
 
   const llvm::FunctionType *FTy =
-    llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), Args,
+    llvm::FunctionType::get(llvm::Type::getVoidTy(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");
+  if (CGM.getLangOptions().SjLjExceptions)
+    return CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume_or_Rethrow");
+  return CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume_or_Rethrow");
 }
 
 static llvm::Constant *getTerminateFn(CodeGenFunction &CGF) {
@@ -119,7 +282,132 @@
   const llvm::FunctionType *FTy =
     llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false);
 
-  return CGF.CGM.CreateRuntimeFunction(FTy, "_ZSt9terminatev");
+  return CGF.CGM.CreateRuntimeFunction(FTy, 
+      CGF.CGM.getLangOptions().CPlusPlus ? "_ZSt9terminatev" : "abort");
+}
+
+static llvm::Constant *getCatchallRethrowFn(CodeGenFunction &CGF,
+                                            const char *Name) {
+  const llvm::Type *Int8PtrTy =
+    llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  std::vector<const llvm::Type*> Args(1, Int8PtrTy);
+
+  const llvm::Type *VoidTy = llvm::Type::getVoidTy(CGF.getLLVMContext());
+  const llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, Args, false);
+
+  return CGF.CGM.CreateRuntimeFunction(FTy, Name);
+}
+
+const EHPersonality EHPersonality::GNU_C("__gcc_personality_v0");
+const EHPersonality EHPersonality::NeXT_ObjC("__objc_personality_v0");
+const EHPersonality EHPersonality::GNU_CPlusPlus("__gxx_personality_v0");
+const EHPersonality EHPersonality::GNU_CPlusPlus_SJLJ("__gxx_personality_sj0");
+const EHPersonality EHPersonality::GNU_ObjC("__gnu_objc_personality_v0",
+                                            "objc_exception_throw");
+
+static const EHPersonality &getCPersonality(const LangOptions &L) {
+  return EHPersonality::GNU_C;
+}
+
+static const EHPersonality &getObjCPersonality(const LangOptions &L) {
+  if (L.NeXTRuntime) {
+    if (L.ObjCNonFragileABI) return EHPersonality::NeXT_ObjC;
+    else return getCPersonality(L);
+  } else {
+    return EHPersonality::GNU_ObjC;
+  }
+}
+
+static const EHPersonality &getCXXPersonality(const LangOptions &L) {
+  if (L.SjLjExceptions)
+    return EHPersonality::GNU_CPlusPlus_SJLJ;
+  else
+    return EHPersonality::GNU_CPlusPlus;
+}
+
+/// Determines the personality function to use when both C++
+/// and Objective-C exceptions are being caught.
+static const EHPersonality &getObjCXXPersonality(const LangOptions &L) {
+  // The ObjC personality defers to the C++ personality for non-ObjC
+  // handlers.  Unlike the C++ case, we use the same personality
+  // function on targets using (backend-driven) SJLJ EH.
+  if (L.NeXTRuntime) {
+    if (L.ObjCNonFragileABI)
+      return EHPersonality::NeXT_ObjC;
+
+    // In the fragile ABI, just use C++ exception handling and hope
+    // they're not doing crazy exception mixing.
+    else
+      return getCXXPersonality(L);
+  }
+
+  // The GNU runtime's personality function inherently doesn't support
+  // mixed EH.  Use the C++ personality just to avoid returning null.
+  return getCXXPersonality(L);
+}
+
+const EHPersonality &EHPersonality::get(const LangOptions &L) {
+  if (L.CPlusPlus && L.ObjC1)
+    return getObjCXXPersonality(L);
+  else if (L.CPlusPlus)
+    return getCXXPersonality(L);
+  else if (L.ObjC1)
+    return getObjCPersonality(L);
+  else
+    return getCPersonality(L);
+}
+
+static llvm::Constant *getPersonalityFn(CodeGenFunction &CGF,
+                                        const EHPersonality &Personality) {
+  const char *Name = Personality.getPersonalityFnName();
+
+  llvm::Constant *Fn =
+    CGF.CGM.CreateRuntimeFunction(llvm::FunctionType::get(
+                                    llvm::Type::getInt32Ty(
+                                      CGF.CGM.getLLVMContext()),
+                                    true),
+                            Name);
+  return llvm::ConstantExpr::getBitCast(Fn, CGF.CGM.PtrToInt8Ty);
+}
+
+/// Returns the value to inject into a selector to indicate the
+/// presence of a catch-all.
+static llvm::Constant *getCatchAllValue(CodeGenFunction &CGF) {
+  // Possibly we should use @llvm.eh.catch.all.value here.
+  return llvm::ConstantPointerNull::get(CGF.CGM.PtrToInt8Ty);
+}
+
+/// Returns the value to inject into a selector to indicate the
+/// presence of a cleanup.
+static llvm::Constant *getCleanupValue(CodeGenFunction &CGF) {
+  return llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
+}
+
+namespace {
+  /// A cleanup to free the exception object if its initialization
+  /// throws.
+  struct FreeExceptionCleanup : EHScopeStack::Cleanup {
+    FreeExceptionCleanup(llvm::Value *ShouldFreeVar,
+                         llvm::Value *ExnLocVar)
+      : ShouldFreeVar(ShouldFreeVar), ExnLocVar(ExnLocVar) {}
+
+    llvm::Value *ShouldFreeVar;
+    llvm::Value *ExnLocVar;
+    
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      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)
+        ->setDoesNotThrow();
+      CGF.EmitBlock(DoneBB);
+    }
+  };
 }
 
 // Emits an exception expression into the given location.  This
@@ -144,21 +432,14 @@
   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();
+  // Make sure the exception object is cleaned up if there's an
+  // exception during initialization.
+  // FIXME: stmt expressions might require this to be a normal
+  // cleanup, too.
+  CGF.EHStack.pushCleanup<FreeExceptionCleanup>(EHCleanup,
+                                                ShouldFreeVar,
+                                                ExnLocVar);
+  EHScopeStack::stable_iterator Cleanup = CGF.EHStack.stable_begin();
 
   CGF.Builder.CreateStore(ExnLoc, ExnLocVar);
   CGF.Builder.CreateStore(llvm::ConstantInt::getTrue(CGF.getLLVMContext()),
@@ -181,74 +462,38 @@
   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);
+  // Technically, the exception object is like a temporary; it has to
+  // be cleaned up when its full-expression is complete.
+  // Unfortunately, the AST represents full-expressions by creating a
+  // CXXExprWithTemporaries, which it only does when there are actually
+  // temporaries.
+  //
+  // If any cleanups have been added since we pushed ours, they must
+  // be from temporaries;  this will get popped at the same time.
+  // Otherwise we need to pop ours off.  FIXME: this is very brittle.
+  if (Cleanup == CGF.EHStack.stable_begin())
+    CGF.PopCleanupBlock();
 }
 
-// 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");
+llvm::Value *CodeGenFunction::getExceptionSlot() {
+  if (!ExceptionSlot) {
+    const llvm::Type *i8p = llvm::Type::getInt8PtrTy(getLLVMContext());
+    ExceptionSlot = CreateTempAlloca(i8p, "exn.slot");
   }
+  return ExceptionSlot;
 }
 
 void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) {
   if (!E->getSubExpr()) {
     if (getInvokeDest()) {
-      llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
-      Builder.CreateInvoke(getReThrowFn(*this), Cont, getInvokeDest())
+      Builder.CreateInvoke(getReThrowFn(*this),
+                           getUnreachableBlock(),
+                           getInvokeDest())
         ->setDoesNotReturn();
-      EmitBlock(Cont);
-    } else
+    } else {
       Builder.CreateCall(getReThrowFn(*this))->setDoesNotReturn();
-    Builder.CreateUnreachable();
+      Builder.CreateUnreachable();
+    }
 
     // Clear the insertion point to indicate we are in unreachable code.
     Builder.ClearInsertionPoint();
@@ -262,16 +507,17 @@
   uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
 
   llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(*this);
-  llvm::Value *ExceptionPtr =
+  llvm::CallInst *ExceptionPtr =
     Builder.CreateCall(AllocExceptionFn,
                        llvm::ConstantInt::get(SizeTy, TypeSize),
                        "exception");
+  ExceptionPtr->setDoesNotThrow();
   
   EmitAnyExprToExn(*this, E->getSubExpr(), ExceptionPtr);
 
   // Now throw the exception.
   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
-  llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType);
+  llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType, true);
 
   // The address of the destructor.  If the exception type has a
   // trivial destructor (or isn't a record), we just pass null.
@@ -279,7 +525,7 @@
   if (const RecordType *RecordTy = ThrowType->getAs<RecordType>()) {
     CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
     if (!Record->hasTrivialDestructor()) {
-      CXXDestructorDecl *DtorD = Record->getDestructor(getContext());
+      CXXDestructorDecl *DtorD = Record->getDestructor();
       Dtor = CGM.GetAddrOfCXXDestructor(DtorD, Dtor_Complete);
       Dtor = llvm::ConstantExpr::getBitCast(Dtor, Int8PtrTy);
     }
@@ -287,18 +533,17 @@
   if (!Dtor) Dtor = llvm::Constant::getNullValue(Int8PtrTy);
 
   if (getInvokeDest()) {
-    llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
     llvm::InvokeInst *ThrowCall =
-      Builder.CreateInvoke3(getThrowFn(*this), Cont, getInvokeDest(),
+      Builder.CreateInvoke3(getThrowFn(*this),
+                            getUnreachableBlock(), getInvokeDest(),
                             ExceptionPtr, TypeInfo, Dtor);
     ThrowCall->setDoesNotReturn();
-    EmitBlock(Cont);
   } else {
     llvm::CallInst *ThrowCall =
       Builder.CreateCall3(getThrowFn(*this), ExceptionPtr, TypeInfo, Dtor);
     ThrowCall->setDoesNotReturn();
+    Builder.CreateUnreachable();
   }
-  Builder.CreateUnreachable();
 
   // Clear the insertion point to indicate we are in unreachable code.
   Builder.ClearInsertionPoint();
@@ -324,85 +569,15 @@
   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;
+  unsigned NumExceptions = Proto->getNumExceptions();
+  EHFilterScope *Filter = EHStack.pushFilter(NumExceptions);
 
-  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);
+  for (unsigned I = 0; I != NumExceptions; ++I) {
+    QualType Ty = Proto->getExceptionType(I);
+    QualType ExceptType = Ty.getNonReferenceType().getUnqualifiedType();
+    llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType, true);
+    Filter->setFilter(I, 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) {
@@ -419,328 +594,981 @@
   if (!Proto->hasExceptionSpec())
     return;
 
-  setInvokeDest(0);
+  EHStack.popFilter();
 }
 
 void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
-  CXXTryStmtInfo Info = EnterCXXTryStmt(S);
+  EnterCXXTryStmt(S);
   EmitStmt(S.getTryBlock());
-  ExitCXXTryStmt(S, Info);
+  ExitCXXTryStmt(S);
 }
 
-CodeGenFunction::CXXTryStmtInfo
-CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S) {
-  CXXTryStmtInfo Info;
-  Info.SavedLandingPad = getInvokeDest();
-  Info.HandlerBlock = createBasicBlock("try.handler");
-  Info.FinallyBlock = createBasicBlock("finally");
+void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
+  unsigned NumHandlers = S.getNumHandlers();
+  EHCatchScope *CatchScope = EHStack.pushCatch(NumHandlers);
 
-  PushCleanupBlock(Info.FinallyBlock);
-  setInvokeDest(Info.HandlerBlock);
+  for (unsigned I = 0; I != NumHandlers; ++I) {
+    const CXXCatchStmt *C = S.getHandler(I);
+
+    llvm::BasicBlock *Handler = createBasicBlock("catch");
+    if (C->getExceptionDecl()) {
+      // FIXME: Dropping the reference type on the type into makes it
+      // impossible to correctly implement catch-by-reference
+      // semantics for pointers.  Unfortunately, this is what all
+      // existing compilers do, and it's not clear that the standard
+      // personality routine is capable of doing this right.  See C++ DR 388:
+      //   http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#388
+      QualType CaughtType = C->getCaughtType();
+      CaughtType = CaughtType.getNonReferenceType().getUnqualifiedType();
+
+      llvm::Value *TypeInfo = 0;
+      if (CaughtType->isObjCObjectPointerType())
+        TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType);
+      else
+        TypeInfo = CGM.GetAddrOfRTTIDescriptor(CaughtType, true);
+      CatchScope->setHandler(I, TypeInfo, Handler);
+    } else {
+      // No exception decl indicates '...', a catch-all.
+      CatchScope->setCatchAllHandler(I, Handler);
+    }
+  }
+}
+
+/// Check whether this is a non-EH scope, i.e. a scope which doesn't
+/// affect exception handling.  Currently, the only non-EH scopes are
+/// normal-only cleanup scopes.
+static bool isNonEHScope(const EHScope &S) {
+  switch (S.getKind()) {
+  case EHScope::Cleanup:
+    return !cast<EHCleanupScope>(S).isEHCleanup();
+  case EHScope::Filter:
+  case EHScope::Catch:
+  case EHScope::Terminate:
+    return false;
+  }
+
+  // Suppress warning.
+  return false;
+}
+
+llvm::BasicBlock *CodeGenFunction::getInvokeDestImpl() {
+  assert(EHStack.requiresLandingPad());
+  assert(!EHStack.empty());
+
+  if (!Exceptions)
+    return 0;
+
+  // Check the innermost scope for a cached landing pad.  If this is
+  // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad.
+  llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad();
+  if (LP) return LP;
+
+  // Build the landing pad for this scope.
+  LP = EmitLandingPad();
+  assert(LP);
+
+  // Cache the landing pad on the innermost scope.  If this is a
+  // non-EH scope, cache the landing pad on the enclosing scope, too.
+  for (EHScopeStack::iterator ir = EHStack.begin(); true; ++ir) {
+    ir->setCachedLandingPad(LP);
+    if (!isNonEHScope(*ir)) break;
+  }
+
+  return LP;
+}
+
+llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
+  assert(EHStack.requiresLandingPad());
+
+  // This function contains a hack to work around a design flaw in
+  // LLVM's EH IR which breaks semantics after inlining.  This same
+  // hack is implemented in llvm-gcc.
+  //
+  // The LLVM EH abstraction is basically a thin veneer over the
+  // traditional GCC zero-cost design: for each range of instructions
+  // in the function, there is (at most) one "landing pad" with an
+  // associated chain of EH actions.  A language-specific personality
+  // function interprets this chain of actions and (1) decides whether
+  // or not to resume execution at the landing pad and (2) if so,
+  // provides an integer indicating why it's stopping.  In LLVM IR,
+  // the association of a landing pad with a range of instructions is
+  // achieved via an invoke instruction, the chain of actions becomes
+  // the arguments to the @llvm.eh.selector call, and the selector
+  // call returns the integer indicator.  Other than the required
+  // presence of two intrinsic function calls in the landing pad,
+  // the IR exactly describes the layout of the output code.
+  //
+  // A principal advantage of this design is that it is completely
+  // language-agnostic; in theory, the LLVM optimizers can treat
+  // landing pads neutrally, and targets need only know how to lower
+  // the intrinsics to have a functioning exceptions system (assuming
+  // that platform exceptions follow something approximately like the
+  // GCC design).  Unfortunately, landing pads cannot be combined in a
+  // language-agnostic way: given selectors A and B, there is no way
+  // to make a single landing pad which faithfully represents the
+  // semantics of propagating an exception first through A, then
+  // through B, without knowing how the personality will interpret the
+  // (lowered form of the) selectors.  This means that inlining has no
+  // choice but to crudely chain invokes (i.e., to ignore invokes in
+  // the inlined function, but to turn all unwindable calls into
+  // invokes), which is only semantically valid if every unwind stops
+  // at every landing pad.
+  //
+  // Therefore, the invoke-inline hack is to guarantee that every
+  // landing pad has a catch-all.
+  const bool UseInvokeInlineHack = true;
+
+  for (EHScopeStack::iterator ir = EHStack.begin(); ; ) {
+    assert(ir != EHStack.end() &&
+           "stack requiring landing pad is nothing but non-EH scopes?");
+
+    // If this is a terminate scope, just use the singleton terminate
+    // landing pad.
+    if (isa<EHTerminateScope>(*ir))
+      return getTerminateLandingPad();
+
+    // If this isn't an EH scope, iterate; otherwise break out.
+    if (!isNonEHScope(*ir)) break;
+    ++ir;
+
+    // We haven't checked this scope for a cached landing pad yet.
+    if (llvm::BasicBlock *LP = ir->getCachedLandingPad())
+      return LP;
+  }
+
+  // Save the current IR generation state.
+  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
+
+  const EHPersonality &Personality =
+    EHPersonality::get(CGF.CGM.getLangOptions());
+
+  // Create and configure the landing pad.
+  llvm::BasicBlock *LP = createBasicBlock("lpad");
+  EmitBlock(LP);
+
+  // Save the exception pointer.  It's safe to use a single exception
+  // pointer per function because EH cleanups can never have nested
+  // try/catches.
+  llvm::CallInst *Exn =
+    Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_exception), "exn");
+  Exn->setDoesNotThrow();
+  Builder.CreateStore(Exn, getExceptionSlot());
+  
+  // Build the selector arguments.
+  llvm::SmallVector<llvm::Value*, 8> EHSelector;
+  EHSelector.push_back(Exn);
+  EHSelector.push_back(getPersonalityFn(*this, Personality));
+
+  // Accumulate all the handlers in scope.
+  llvm::DenseMap<llvm::Value*, UnwindDest> EHHandlers;
+  UnwindDest CatchAll;
+  bool HasEHCleanup = false;
+  bool HasEHFilter = false;
+  llvm::SmallVector<llvm::Value*, 8> EHFilters;
+  for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.end();
+         I != E; ++I) {
+
+    switch (I->getKind()) {
+    case EHScope::Cleanup:
+      if (!HasEHCleanup)
+        HasEHCleanup = cast<EHCleanupScope>(*I).isEHCleanup();
+      // We otherwise don't care about cleanups.
+      continue;
+
+    case EHScope::Filter: {
+      assert(I.next() == EHStack.end() && "EH filter is not end of EH stack");
+      assert(!CatchAll.isValid() && "EH filter reached after catch-all");
+
+      // Filter scopes get added to the selector in wierd ways.
+      EHFilterScope &Filter = cast<EHFilterScope>(*I);
+      HasEHFilter = true;
+
+      // Add all the filter values which we aren't already explicitly
+      // catching.
+      for (unsigned I = 0, E = Filter.getNumFilters(); I != E; ++I) {
+        llvm::Value *FV = Filter.getFilter(I);
+        if (!EHHandlers.count(FV))
+          EHFilters.push_back(FV);
+      }
+      goto done;
+    }
+
+    case EHScope::Terminate:
+      // Terminate scopes are basically catch-alls.
+      assert(!CatchAll.isValid());
+      CatchAll = UnwindDest(getTerminateHandler(),
+                            EHStack.getEnclosingEHCleanup(I),
+                            cast<EHTerminateScope>(*I).getDestIndex());
+      goto done;
+
+    case EHScope::Catch:
+      break;
+    }
+
+    EHCatchScope &Catch = cast<EHCatchScope>(*I);
+    for (unsigned HI = 0, HE = Catch.getNumHandlers(); HI != HE; ++HI) {
+      EHCatchScope::Handler Handler = Catch.getHandler(HI);
+
+      // Catch-all.  We should only have one of these per catch.
+      if (!Handler.Type) {
+        assert(!CatchAll.isValid());
+        CatchAll = UnwindDest(Handler.Block,
+                              EHStack.getEnclosingEHCleanup(I),
+                              Handler.Index);
+        continue;
+      }
+
+      // Check whether we already have a handler for this type.
+      UnwindDest &Dest = EHHandlers[Handler.Type];
+      if (Dest.isValid()) continue;
+
+      EHSelector.push_back(Handler.Type);
+      Dest = UnwindDest(Handler.Block,
+                        EHStack.getEnclosingEHCleanup(I),
+                        Handler.Index);
+    }
+
+    // Stop if we found a catch-all.
+    if (CatchAll.isValid()) break;
+  }
+
+ done:
+  unsigned LastToEmitInLoop = EHSelector.size();
+
+  // If we have a catch-all, add null to the selector.
+  if (CatchAll.isValid()) {
+    EHSelector.push_back(getCatchAllValue(CGF));
+
+  // If we have an EH filter, we need to add those handlers in the
+  // right place in the selector, which is to say, at the end.
+  } else if (HasEHFilter) {
+    // Create a filter expression: an integer constant saying how many
+    // filters there are (+1 to avoid ambiguity with 0 for cleanup),
+    // followed by the filter types.  The personality routine only
+    // lands here if the filter doesn't match.
+    EHSelector.push_back(llvm::ConstantInt::get(Builder.getInt32Ty(),
+                                                EHFilters.size() + 1));
+    EHSelector.append(EHFilters.begin(), EHFilters.end());
+
+    // Also check whether we need a cleanup.
+    if (UseInvokeInlineHack || HasEHCleanup)
+      EHSelector.push_back(UseInvokeInlineHack
+                           ? getCatchAllValue(CGF)
+                           : getCleanupValue(CGF));
+
+  // Otherwise, signal that we at least have cleanups.
+  } else if (UseInvokeInlineHack || HasEHCleanup) {
+    EHSelector.push_back(UseInvokeInlineHack
+                         ? getCatchAllValue(CGF)
+                         : getCleanupValue(CGF));
+  } else {
+    assert(LastToEmitInLoop > 2);
+    LastToEmitInLoop--;
+  }
+
+  assert(EHSelector.size() >= 3 && "selector call has only two arguments!");
+
+  // Tell the backend how to generate the landing pad.
+  llvm::CallInst *Selection =
+    Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_selector),
+                       EHSelector.begin(), EHSelector.end(), "eh.selector");
+  Selection->setDoesNotThrow();
+  
+  // Select the right handler.
+  llvm::Value *llvm_eh_typeid_for =
+    CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
+
+  // The results of llvm_eh_typeid_for aren't reliable --- at least
+  // not locally --- so we basically have to do this as an 'if' chain.
+  // We walk through the first N-1 catch clauses, testing and chaining,
+  // and then fall into the final clause (which is either a cleanup, a
+  // filter (possibly with a cleanup), a catch-all, or another catch).
+  for (unsigned I = 2; I != LastToEmitInLoop; ++I) {
+    llvm::Value *Type = EHSelector[I];
+    UnwindDest Dest = EHHandlers[Type];
+    assert(Dest.isValid() && "no handler entry for value in selector?");
+
+    // Figure out where to branch on a match.  As a debug code-size
+    // optimization, if the scope depth matches the innermost cleanup,
+    // we branch directly to the catch handler.
+    llvm::BasicBlock *Match = Dest.getBlock();
+    bool MatchNeedsCleanup =
+      Dest.getScopeDepth() != EHStack.getInnermostEHCleanup();
+    if (MatchNeedsCleanup)
+      Match = createBasicBlock("eh.match");
+
+    llvm::BasicBlock *Next = createBasicBlock("eh.next");
+
+    // Check whether the exception matches.
+    llvm::CallInst *Id
+      = Builder.CreateCall(llvm_eh_typeid_for,
+                           Builder.CreateBitCast(Type, CGM.PtrToInt8Ty));
+    Id->setDoesNotThrow();
+    Builder.CreateCondBr(Builder.CreateICmpEQ(Selection, Id),
+                         Match, Next);
+    
+    // Emit match code if necessary.
+    if (MatchNeedsCleanup) {
+      EmitBlock(Match);
+      EmitBranchThroughEHCleanup(Dest);
+    }
+
+    // Continue to the next match.
+    EmitBlock(Next);
+  }
+
+  // Emit the final case in the selector.
+  // This might be a catch-all....
+  if (CatchAll.isValid()) {
+    assert(isa<llvm::ConstantPointerNull>(EHSelector.back()));
+    EmitBranchThroughEHCleanup(CatchAll);
+
+  // ...or an EH filter...
+  } else if (HasEHFilter) {
+    llvm::Value *SavedSelection = Selection;
+
+    // First, unwind out to the outermost scope if necessary.
+    if (EHStack.hasEHCleanups()) {
+      // The end here might not dominate the beginning, so we might need to
+      // save the selector if we need it.
+      llvm::AllocaInst *SelectorVar = 0;
+      if (HasEHCleanup) {
+        SelectorVar = CreateTempAlloca(Builder.getInt32Ty(), "selector.var");
+        Builder.CreateStore(Selection, SelectorVar);
+      }
+
+      llvm::BasicBlock *CleanupContBB = createBasicBlock("ehspec.cleanup.cont");
+      EmitBranchThroughEHCleanup(UnwindDest(CleanupContBB, EHStack.stable_end(),
+                                            EHStack.getNextEHDestIndex()));
+      EmitBlock(CleanupContBB);
+
+      if (HasEHCleanup)
+        SavedSelection = Builder.CreateLoad(SelectorVar, "ehspec.saved-selector");
+    }
+
+    // If there was a cleanup, we'll need to actually check whether we
+    // landed here because the filter triggered.
+    if (UseInvokeInlineHack || HasEHCleanup) {
+      llvm::BasicBlock *RethrowBB = createBasicBlock("cleanup");
+      llvm::BasicBlock *UnexpectedBB = createBasicBlock("ehspec.unexpected");
+
+      llvm::Constant *Zero = llvm::ConstantInt::get(Builder.getInt32Ty(), 0);
+      llvm::Value *FailsFilter =
+        Builder.CreateICmpSLT(SavedSelection, Zero, "ehspec.fails");
+      Builder.CreateCondBr(FailsFilter, UnexpectedBB, RethrowBB);
+
+      // The rethrow block is where we land if this was a cleanup.
+      // TODO: can this be _Unwind_Resume if the InvokeInlineHack is off?
+      EmitBlock(RethrowBB);
+      Builder.CreateCall(getUnwindResumeOrRethrowFn(),
+                         Builder.CreateLoad(getExceptionSlot()))
+        ->setDoesNotReturn();
+      Builder.CreateUnreachable();
+
+      EmitBlock(UnexpectedBB);
+    }
+
+    // Call __cxa_call_unexpected.  This doesn't need to be an invoke
+    // because __cxa_call_unexpected magically filters exceptions
+    // according to the last landing pad the exception was thrown
+    // into.  Seriously.
+    Builder.CreateCall(getUnexpectedFn(*this),
+                       Builder.CreateLoad(getExceptionSlot()))
+      ->setDoesNotReturn();
+    Builder.CreateUnreachable();
+
+  // ...or a normal catch handler...
+  } else if (!UseInvokeInlineHack && !HasEHCleanup) {
+    llvm::Value *Type = EHSelector.back();
+    EmitBranchThroughEHCleanup(EHHandlers[Type]);
+
+  // ...or a cleanup.
+  } else {
+    EmitBranchThroughEHCleanup(getRethrowDest());
+  }
+
+  // Restore the old IR generation state.
+  Builder.restoreIP(SavedIP);
+
+  return LP;
+}
+
+namespace {
+  /// A cleanup to call __cxa_end_catch.  In many cases, the caught
+  /// exception type lets us state definitively that the thrown exception
+  /// type does not have a destructor.  In particular:
+  ///   - Catch-alls tell us nothing, so we have to conservatively
+  ///     assume that the thrown exception might have a destructor.
+  ///   - Catches by reference behave according to their base types.
+  ///   - Catches of non-record types will only trigger for exceptions
+  ///     of non-record types, which never have destructors.
+  ///   - Catches of record types can trigger for arbitrary subclasses
+  ///     of the caught type, so we have to assume the actual thrown
+  ///     exception type might have a throwing destructor, even if the
+  ///     caught type's destructor is trivial or nothrow.
+  struct CallEndCatch : EHScopeStack::Cleanup {
+    CallEndCatch(bool MightThrow) : MightThrow(MightThrow) {}
+    bool MightThrow;
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      if (!MightThrow) {
+        CGF.Builder.CreateCall(getEndCatchFn(CGF))->setDoesNotThrow();
+        return;
+      }
+
+      CGF.EmitCallOrInvoke(getEndCatchFn(CGF), 0, 0);
+    }
+  };
+}
+
+/// Emits a call to __cxa_begin_catch and enters a cleanup to call
+/// __cxa_end_catch.
+///
+/// \param EndMightThrow - true if __cxa_end_catch might throw
+static llvm::Value *CallBeginCatch(CodeGenFunction &CGF,
+                                   llvm::Value *Exn,
+                                   bool EndMightThrow) {
+  llvm::CallInst *Call = CGF.Builder.CreateCall(getBeginCatchFn(CGF), Exn);
+  Call->setDoesNotThrow();
+
+  CGF.EHStack.pushCleanup<CallEndCatch>(NormalAndEHCleanup, EndMightThrow);
+
+  return Call;
+}
+
+/// A "special initializer" callback for initializing a catch
+/// parameter during catch initialization.
+static void InitCatchParam(CodeGenFunction &CGF,
+                           const VarDecl &CatchParam,
+                           llvm::Value *ParamAddr) {
+  // Load the exception from where the landing pad saved it.
+  llvm::Value *Exn = CGF.Builder.CreateLoad(CGF.getExceptionSlot(), "exn");
+
+  CanQualType CatchType =
+    CGF.CGM.getContext().getCanonicalType(CatchParam.getType());
+  const llvm::Type *LLVMCatchTy = CGF.ConvertTypeForMem(CatchType);
+
+  // If we're catching by reference, we can just cast the object
+  // pointer to the appropriate pointer.
+  if (isa<ReferenceType>(CatchType)) {
+    QualType CaughtType = cast<ReferenceType>(CatchType)->getPointeeType();
+    bool EndCatchMightThrow = CaughtType->isRecordType();
+
+    // __cxa_begin_catch returns the adjusted object pointer.
+    llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, EndCatchMightThrow);
+
+    // We have no way to tell the personality function that we're
+    // catching by reference, so if we're catching a pointer,
+    // __cxa_begin_catch will actually return that pointer by value.
+    if (const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
+      QualType PointeeType = PT->getPointeeType();
+
+      // When catching by reference, generally we should just ignore
+      // this by-value pointer and use the exception object instead.
+      if (!PointeeType->isRecordType()) {
+
+        // Exn points to the struct _Unwind_Exception header, which
+        // we have to skip past in order to reach the exception data.
+        unsigned HeaderSize =
+          CGF.CGM.getTargetCodeGenInfo().getSizeOfUnwindException();
+        AdjustedExn = CGF.Builder.CreateConstGEP1_32(Exn, HeaderSize);
+
+      // However, if we're catching a pointer-to-record type that won't
+      // work, because the personality function might have adjusted
+      // the pointer.  There's actually no way for us to fully satisfy
+      // the language/ABI contract here:  we can't use Exn because it
+      // might have the wrong adjustment, but we can't use the by-value
+      // pointer because it's off by a level of abstraction.
+      //
+      // The current solution is to dump the adjusted pointer into an
+      // alloca, which breaks language semantics (because changing the
+      // pointer doesn't change the exception) but at least works.
+      // The better solution would be to filter out non-exact matches
+      // and rethrow them, but this is tricky because the rethrow
+      // really needs to be catchable by other sites at this landing
+      // pad.  The best solution is to fix the personality function.
+      } else {
+        // Pull the pointer for the reference type off.
+        const llvm::Type *PtrTy =
+          cast<llvm::PointerType>(LLVMCatchTy)->getElementType();
+
+        // Create the temporary and write the adjusted pointer into it.
+        llvm::Value *ExnPtrTmp = CGF.CreateTempAlloca(PtrTy, "exn.byref.tmp");
+        llvm::Value *Casted = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);
+        CGF.Builder.CreateStore(Casted, ExnPtrTmp);
+
+        // Bind the reference to the temporary.
+        AdjustedExn = ExnPtrTmp;
+      }
+    }
+
+    llvm::Value *ExnCast =
+      CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.byref");
+    CGF.Builder.CreateStore(ExnCast, ParamAddr);
+    return;
+  }
+
+  // Non-aggregates (plus complexes).
+  bool IsComplex = false;
+  if (!CGF.hasAggregateLLVMType(CatchType) ||
+      (IsComplex = CatchType->isAnyComplexType())) {
+    llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, false);
+    
+    // If the catch type is a pointer type, __cxa_begin_catch returns
+    // the pointer by value.
+    if (CatchType->hasPointerRepresentation()) {
+      llvm::Value *CastExn =
+        CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.casted");
+      CGF.Builder.CreateStore(CastExn, ParamAddr);
+      return;
+    }
+
+    // Otherwise, it returns a pointer into the exception object.
+
+    const llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok
+    llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);
+
+    if (IsComplex) {
+      CGF.StoreComplexToAddr(CGF.LoadComplexFromAddr(Cast, /*volatile*/ false),
+                             ParamAddr, /*volatile*/ false);
+    } else {
+      unsigned Alignment =
+        CGF.getContext().getDeclAlign(&CatchParam).getQuantity();
+      llvm::Value *ExnLoad = CGF.Builder.CreateLoad(Cast, "exn.scalar");
+      CGF.EmitStoreOfScalar(ExnLoad, ParamAddr, /*volatile*/ false, Alignment,
+                            CatchType);
+    }
+    return;
+  }
+
+  // FIXME: this *really* needs to be done via a proper, Sema-emitted
+  // initializer expression.
+
+  CXXRecordDecl *RD = CatchType.getTypePtr()->getAsCXXRecordDecl();
+  assert(RD && "aggregate catch type was not a record!");
+
+  const llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok
+
+  if (RD->hasTrivialCopyConstructor()) {
+    llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, true);
+    llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);
+    CGF.EmitAggregateCopy(ParamAddr, Cast, CatchType);
+    return;
+  }
+
+  // We have to call __cxa_get_exception_ptr to get the adjusted
+  // pointer before copying.
+  llvm::CallInst *AdjustedExn =
+    CGF.Builder.CreateCall(getGetExceptionPtrFn(CGF), Exn);
+  AdjustedExn->setDoesNotThrow();
+  llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);
+
+  CXXConstructorDecl *CD = RD->getCopyConstructor(CGF.getContext(), 0);
+  assert(CD && "record has no copy constructor!");
+  llvm::Value *CopyCtor = CGF.CGM.GetAddrOfCXXConstructor(CD, Ctor_Complete);
+
+  CallArgList CallArgs;
+  CallArgs.push_back(std::make_pair(RValue::get(ParamAddr),
+                                    CD->getThisType(CGF.getContext())));
+  CallArgs.push_back(std::make_pair(RValue::get(Cast),
+                                    CD->getParamDecl(0)->getType()));
+
+  const FunctionProtoType *FPT
+    = CD->getType()->getAs<FunctionProtoType>();
+
+  // Call the copy ctor in a terminate scope.
+  CGF.EHStack.pushTerminate();
+  CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(CallArgs, FPT),
+               CopyCtor, ReturnValueSlot(), CallArgs, CD);
+  CGF.EHStack.popTerminate();
+
+  // Finally we can call __cxa_begin_catch.
+  CallBeginCatch(CGF, Exn, true);
+}
+
+/// Begins a catch statement by initializing the catch variable and
+/// calling __cxa_begin_catch.
+static void BeginCatch(CodeGenFunction &CGF,
+                       const CXXCatchStmt *S) {
+  // We have to be very careful with the ordering of cleanups here:
+  //   C++ [except.throw]p4:
+  //     The destruction [of the exception temporary] occurs
+  //     immediately after the destruction of the object declared in
+  //     the exception-declaration in the handler.
+  //
+  // So the precise ordering is:
+  //   1.  Construct catch variable.
+  //   2.  __cxa_begin_catch
+  //   3.  Enter __cxa_end_catch cleanup
+  //   4.  Enter dtor cleanup
+  //
+  // We do this by initializing the exception variable with a
+  // "special initializer", InitCatchParam.  Delegation sequence:
+  //   - ExitCXXTryStmt opens a RunCleanupsScope
+  //     - EmitLocalBlockVarDecl creates the variable and debug info
+  //       - InitCatchParam initializes the variable from the exception
+  //         - CallBeginCatch calls __cxa_begin_catch
+  //         - CallBeginCatch enters the __cxa_end_catch cleanup
+  //     - EmitLocalBlockVarDecl enters the variable destructor cleanup
+  //   - EmitCXXTryStmt emits the code for the catch body
+  //   - EmitCXXTryStmt close the RunCleanupsScope
+
+  VarDecl *CatchParam = S->getExceptionDecl();
+  if (!CatchParam) {
+    llvm::Value *Exn = CGF.Builder.CreateLoad(CGF.getExceptionSlot(), "exn");
+    CallBeginCatch(CGF, Exn, true);
+    return;
+  }
+
+  // Emit the local.
+  CGF.EmitLocalBlockVarDecl(*CatchParam, &InitCatchParam);
+}
+
+namespace {
+  struct CallRethrow : EHScopeStack::Cleanup {
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      CGF.EmitCallOrInvoke(getReThrowFn(CGF), 0, 0);
+    }
+  };
+}
+
+void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
+  unsigned NumHandlers = S.getNumHandlers();
+  EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
+  assert(CatchScope.getNumHandlers() == NumHandlers);
+
+  // Copy the handler blocks off before we pop the EH stack.  Emitting
+  // the handlers might scribble on this memory.
+  llvm::SmallVector<EHCatchScope::Handler, 8> Handlers(NumHandlers);
+  memcpy(Handlers.data(), CatchScope.begin(),
+         NumHandlers * sizeof(EHCatchScope::Handler));
+  EHStack.popCatch();
+
+  // The fall-through block.
+  llvm::BasicBlock *ContBB = createBasicBlock("try.cont");
+
+  // We just emitted the body of the try; jump to the continue block.
+  if (HaveInsertPoint())
+    Builder.CreateBr(ContBB);
+
+  // Determine if we need an implicit rethrow for all these catch handlers.
+  bool ImplicitRethrow = false;
+  if (IsFnTryBlock)
+    ImplicitRethrow = isa<CXXDestructorDecl>(CurCodeDecl) ||
+                      isa<CXXConstructorDecl>(CurCodeDecl);
+
+  for (unsigned I = 0; I != NumHandlers; ++I) {
+    llvm::BasicBlock *CatchBlock = Handlers[I].Block;
+    EmitBlock(CatchBlock);
+
+    // Catch the exception if this isn't a catch-all.
+    const CXXCatchStmt *C = S.getHandler(I);
+
+    // Enter a cleanup scope, including the catch variable and the
+    // end-catch.
+    RunCleanupsScope CatchScope(*this);
+
+    // Initialize the catch variable and set up the cleanups.
+    BeginCatch(*this, C);
+
+    // If there's an implicit rethrow, push a normal "cleanup" to call
+    // _cxa_rethrow.  This needs to happen before __cxa_end_catch is
+    // called, and so it is pushed after BeginCatch.
+    if (ImplicitRethrow)
+      EHStack.pushCleanup<CallRethrow>(NormalCleanup);
+
+    // Perform the body of the catch.
+    EmitStmt(C->getHandlerBlock());
+
+    // Fall out through the catch cleanups.
+    CatchScope.ForceCleanup();
+
+    // Branch out of the try.
+    if (HaveInsertPoint())
+      Builder.CreateBr(ContBB);
+  }
+
+  EmitBlock(ContBB);
+}
+
+namespace {
+  struct CallEndCatchForFinally : EHScopeStack::Cleanup {
+    llvm::Value *ForEHVar;
+    llvm::Value *EndCatchFn;
+    CallEndCatchForFinally(llvm::Value *ForEHVar, llvm::Value *EndCatchFn)
+      : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");
+      llvm::BasicBlock *CleanupContBB =
+        CGF.createBasicBlock("finally.cleanup.cont");
+
+      llvm::Value *ShouldEndCatch =
+        CGF.Builder.CreateLoad(ForEHVar, "finally.endcatch");
+      CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
+      CGF.EmitBlock(EndCatchBB);
+      CGF.EmitCallOrInvoke(EndCatchFn, 0, 0); // catch-all, so might throw
+      CGF.EmitBlock(CleanupContBB);
+    }
+  };
+
+  struct PerformFinally : EHScopeStack::Cleanup {
+    const Stmt *Body;
+    llvm::Value *ForEHVar;
+    llvm::Value *EndCatchFn;
+    llvm::Value *RethrowFn;
+    llvm::Value *SavedExnVar;
+
+    PerformFinally(const Stmt *Body, llvm::Value *ForEHVar,
+                   llvm::Value *EndCatchFn,
+                   llvm::Value *RethrowFn, llvm::Value *SavedExnVar)
+      : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
+        RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      // Enter a cleanup to call the end-catch function if one was provided.
+      if (EndCatchFn)
+        CGF.EHStack.pushCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,
+                                                        ForEHVar, EndCatchFn);
+
+      // Save the current cleanup destination in case there are
+      // cleanups in the finally block.
+      llvm::Value *SavedCleanupDest =
+        CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot(),
+                               "cleanup.dest.saved");
+
+      // Emit the finally block.
+      CGF.EmitStmt(Body);
+
+      // If the end of the finally is reachable, check whether this was
+      // for EH.  If so, rethrow.
+      if (CGF.HaveInsertPoint()) {
+        llvm::BasicBlock *RethrowBB = CGF.createBasicBlock("finally.rethrow");
+        llvm::BasicBlock *ContBB = CGF.createBasicBlock("finally.cont");
+
+        llvm::Value *ShouldRethrow =
+          CGF.Builder.CreateLoad(ForEHVar, "finally.shouldthrow");
+        CGF.Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
+
+        CGF.EmitBlock(RethrowBB);
+        if (SavedExnVar) {
+          llvm::Value *Args[] = { CGF.Builder.CreateLoad(SavedExnVar) };
+          CGF.EmitCallOrInvoke(RethrowFn, Args, Args+1);
+        } else {
+          CGF.EmitCallOrInvoke(RethrowFn, 0, 0);
+        }
+        CGF.Builder.CreateUnreachable();
+
+        CGF.EmitBlock(ContBB);
+
+        // Restore the cleanup destination.
+        CGF.Builder.CreateStore(SavedCleanupDest,
+                                CGF.getNormalCleanupDestSlot());
+      }
+
+      // Leave the end-catch cleanup.  As an optimization, pretend that
+      // the fallthrough path was inaccessible; we've dynamically proven
+      // that we're not in the EH case along that path.
+      if (EndCatchFn) {
+        CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
+        CGF.PopCleanupBlock();
+        CGF.Builder.restoreIP(SavedIP);
+      }
+    
+      // Now make sure we actually have an insertion point or the
+      // cleanup gods will hate us.
+      CGF.EnsureInsertPoint();
+    }
+  };
+}
+
+/// Enters a finally block for an implementation using zero-cost
+/// exceptions.  This is mostly general, but hard-codes some
+/// language/ABI-specific behavior in the catch-all sections.
+CodeGenFunction::FinallyInfo
+CodeGenFunction::EnterFinallyBlock(const Stmt *Body,
+                                   llvm::Constant *BeginCatchFn,
+                                   llvm::Constant *EndCatchFn,
+                                   llvm::Constant *RethrowFn) {
+  assert((BeginCatchFn != 0) == (EndCatchFn != 0) &&
+         "begin/end catch functions not paired");
+  assert(RethrowFn && "rethrow function is required");
+
+  // The rethrow function has one of the following two types:
+  //   void (*)()
+  //   void (*)(void*)
+  // In the latter case we need to pass it the exception object.
+  // But we can't use the exception slot because the @finally might
+  // have a landing pad (which would overwrite the exception slot).
+  const llvm::FunctionType *RethrowFnTy =
+    cast<llvm::FunctionType>(
+      cast<llvm::PointerType>(RethrowFn->getType())
+      ->getElementType());
+  llvm::Value *SavedExnVar = 0;
+  if (RethrowFnTy->getNumParams())
+    SavedExnVar = CreateTempAlloca(Builder.getInt8PtrTy(), "finally.exn");
+
+  // A finally block is a statement which must be executed on any edge
+  // out of a given scope.  Unlike a cleanup, the finally block may
+  // contain arbitrary control flow leading out of itself.  In
+  // addition, finally blocks should always be executed, even if there
+  // are no catch handlers higher on the stack.  Therefore, we
+  // surround the protected scope with a combination of a normal
+  // cleanup (to catch attempts to break out of the block via normal
+  // control flow) and an EH catch-all (semantically "outside" any try
+  // statement to which the finally block might have been attached).
+  // The finally block itself is generated in the context of a cleanup
+  // which conditionally leaves the catch-all.
+
+  FinallyInfo Info;
+
+  // Jump destination for performing the finally block on an exception
+  // edge.  We'll never actually reach this block, so unreachable is
+  // fine.
+  JumpDest RethrowDest = getJumpDestInCurrentScope(getUnreachableBlock());
+
+  // Whether the finally block is being executed for EH purposes.
+  llvm::AllocaInst *ForEHVar = CreateTempAlloca(CGF.Builder.getInt1Ty(),
+                                                "finally.for-eh");
+  InitTempAlloca(ForEHVar, llvm::ConstantInt::getFalse(getLLVMContext()));
+
+  // Enter a normal cleanup which will perform the @finally block.
+  EHStack.pushCleanup<PerformFinally>(NormalCleanup, Body,
+                                      ForEHVar, EndCatchFn,
+                                      RethrowFn, SavedExnVar);
+
+  // Enter a catch-all scope.
+  llvm::BasicBlock *CatchAllBB = createBasicBlock("finally.catchall");
+  CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
+  Builder.SetInsertPoint(CatchAllBB);
+
+  // If there's a begin-catch function, call it.
+  if (BeginCatchFn) {
+    Builder.CreateCall(BeginCatchFn, Builder.CreateLoad(getExceptionSlot()))
+      ->setDoesNotThrow();
+  }
+
+  // If we need to remember the exception pointer to rethrow later, do so.
+  if (SavedExnVar) {
+    llvm::Value *SavedExn = Builder.CreateLoad(getExceptionSlot());
+    Builder.CreateStore(SavedExn, SavedExnVar);
+  }
+
+  // Tell the finally block that we're in EH.
+  Builder.CreateStore(llvm::ConstantInt::getTrue(getLLVMContext()), ForEHVar);
+
+  // Thread a jump through the finally cleanup.
+  EmitBranchThroughCleanup(RethrowDest);
+
+  Builder.restoreIP(SavedIP);
+
+  EHCatchScope *CatchScope = EHStack.pushCatch(1);
+  CatchScope->setCatchAllHandler(0, CatchAllBB);
 
   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);
+void CodeGenFunction::ExitFinallyBlock(FinallyInfo &Info) {
+  // Leave the finally catch-all.
+  EHCatchScope &Catch = cast<EHCatchScope>(*EHStack.begin());
+  llvm::BasicBlock *CatchAllBB = Catch.getHandler(0).Block;
+  EHStack.popCatch();
 
-  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");
+  // And leave the normal cleanup.
+  PopCleanupBlock();
 
-  // Jump to end if there is no exception
-  EmitBranchThroughCleanup(FinallyEnd);
+  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
+  EmitBlock(CatchAllBB, true);
 
-  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);
+  Builder.restoreIP(SavedIP);
 }
 
-CodeGenFunction::EHCleanupBlock::~EHCleanupBlock() {
-  CGF.setInvokeDest(PreviousInvokeDest);
+llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {
+  if (TerminateLandingPad)
+    return TerminateLandingPad;
 
-  llvm::BasicBlock *EndOfCleanup = CGF.Builder.GetInsertBlock();
+  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
 
-  // 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);
+  // This will get inserted at the end of the function.
+  TerminateLandingPad = createBasicBlock("terminate.lpad");
+  Builder.SetInsertPoint(TerminateLandingPad);
 
-  // %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");
+  // Tell the backend that this is a landing pad.
+  llvm::CallInst *Exn =
+    Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_exception), "exn");
+  Exn->setDoesNotThrow();
 
-  llvm::Constant *Null = llvm::ConstantPointerNull::get(CGF.PtrToInt8Ty);
+  const EHPersonality &Personality = EHPersonality::get(CGM.getLangOptions());
+  
+  // Tell the backend what the exception table should be:
+  // nothing but a catch-all.
+  llvm::Value *Args[3] = { Exn, getPersonalityFn(*this, Personality),
+                           getCatchAllValue(*this) };
+  Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_selector),
+                     Args, Args+3, "eh.selector")
+    ->setDoesNotThrow();
 
-  // %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);
+  llvm::CallInst *TerminateCall = Builder.CreateCall(getTerminateFn(*this));
+  TerminateCall->setDoesNotReturn();
+  TerminateCall->setDoesNotThrow();
   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);
+  // Restore the saved insertion state.
+  Builder.restoreIP(SavedIP);
+
+  return TerminateLandingPad;
 }
 
 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();
+  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
 
-  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
+  // Set up the terminate handler.  This block is inserted at the very
+  // end of the function by FinishFunction.
   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));
+  Builder.SetInsertPoint(TerminateHandler);
+  llvm::CallInst *TerminateCall = Builder.CreateCall(getTerminateFn(*this));
   TerminateCall->setDoesNotReturn();
   TerminateCall->setDoesNotThrow();
   Builder.CreateUnreachable();
 
   // Restore the saved insertion state.
-  Builder.SetInsertPoint(SavedInsertBlock, SavedInsertPoint);
+  Builder.restoreIP(SavedIP);
 
   return TerminateHandler;
 }
+
+CodeGenFunction::UnwindDest CodeGenFunction::getRethrowDest() {
+  if (RethrowBlock.isValid()) return RethrowBlock;
+
+  CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
+
+  // We emit a jump to a notional label at the outermost unwind state.
+  llvm::BasicBlock *Unwind = createBasicBlock("eh.resume");
+  Builder.SetInsertPoint(Unwind);
+
+  const EHPersonality &Personality = EHPersonality::get(CGM.getLangOptions());
+
+  // This can always be a call because we necessarily didn't find
+  // anything on the EH stack which needs our help.
+  llvm::Constant *RethrowFn;
+  if (const char *RethrowName = Personality.getCatchallRethrowFnName())
+    RethrowFn = getCatchallRethrowFn(*this, RethrowName);
+  else
+    RethrowFn = getUnwindResumeOrRethrowFn();
+
+  Builder.CreateCall(RethrowFn, Builder.CreateLoad(getExceptionSlot()))
+    ->setDoesNotReturn();
+  Builder.CreateUnreachable();
+
+  Builder.restoreIP(SavedIP);
+
+  RethrowBlock = UnwindDest(Unwind, EHStack.stable_end(), 0);
+  return RethrowBlock;
+}
+
+EHScopeStack::Cleanup::~Cleanup() {
+  llvm_unreachable("Cleanup is indestructable");
+}
diff --git a/lib/CodeGen/CGException.h b/lib/CodeGen/CGException.h
new file mode 100644
index 0000000..f129474
--- /dev/null
+++ b/lib/CodeGen/CGException.h
@@ -0,0 +1,593 @@
+//===-- CGException.h - Classes for exceptions IR generation ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes support the generation of LLVM IR for exceptions in
+// C++ and Objective C.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGEXCEPTION_H
+#define CLANG_CODEGEN_CGEXCEPTION_H
+
+/// EHScopeStack is defined in CodeGenFunction.h, but its
+/// implementation is in this file and in CGException.cpp.
+#include "CodeGenFunction.h"
+
+namespace llvm {
+  class Value;
+  class BasicBlock;
+}
+
+namespace clang {
+namespace CodeGen {
+
+/// The exceptions personality for a function.  When 
+class EHPersonality {
+  const char *PersonalityFn;
+
+  // If this is non-null, this personality requires a non-standard
+  // function for rethrowing an exception after a catchall cleanup.
+  // This function must have prototype void(void*).
+  const char *CatchallRethrowFn;
+
+  EHPersonality(const char *PersonalityFn,
+                const char *CatchallRethrowFn = 0)
+    : PersonalityFn(PersonalityFn),
+      CatchallRethrowFn(CatchallRethrowFn) {}
+
+public:
+  static const EHPersonality &get(const LangOptions &Lang);
+  static const EHPersonality GNU_C;
+  static const EHPersonality GNU_ObjC;
+  static const EHPersonality NeXT_ObjC;
+  static const EHPersonality GNU_CPlusPlus;
+  static const EHPersonality GNU_CPlusPlus_SJLJ;
+
+  const char *getPersonalityFnName() const { return PersonalityFn; }
+  const char *getCatchallRethrowFnName() const { return CatchallRethrowFn; }
+};
+
+/// A protected scope for zero-cost EH handling.
+class EHScope {
+  llvm::BasicBlock *CachedLandingPad;
+
+  unsigned K : 2;
+
+protected:
+  enum { BitsRemaining = 30 };
+
+public:
+  enum Kind { Cleanup, Catch, Terminate, Filter };
+
+  EHScope(Kind K) : CachedLandingPad(0), K(K) {}
+
+  Kind getKind() const { return static_cast<Kind>(K); }
+
+  llvm::BasicBlock *getCachedLandingPad() const {
+    return CachedLandingPad;
+  }
+
+  void setCachedLandingPad(llvm::BasicBlock *Block) {
+    CachedLandingPad = Block;
+  }
+};
+
+/// A scope which attempts to handle some, possibly all, types of
+/// exceptions.
+///
+/// Objective C @finally blocks are represented using a cleanup scope
+/// after the catch scope.
+class EHCatchScope : public EHScope {
+  unsigned NumHandlers : BitsRemaining;
+
+  // In effect, we have a flexible array member
+  //   Handler Handlers[0];
+  // But that's only standard in C99, not C++, so we have to do
+  // annoying pointer arithmetic instead.
+
+public:
+  struct Handler {
+    /// A type info value, or null (C++ null, not an LLVM null pointer)
+    /// for a catch-all.
+    llvm::Value *Type;
+
+    /// The catch handler for this type.
+    llvm::BasicBlock *Block;
+
+    /// The unwind destination index for this handler.
+    unsigned Index;
+  };
+
+private:
+  friend class EHScopeStack;
+
+  Handler *getHandlers() {
+    return reinterpret_cast<Handler*>(this+1);
+  }
+
+  const Handler *getHandlers() const {
+    return reinterpret_cast<const Handler*>(this+1);
+  }
+
+public:
+  static size_t getSizeForNumHandlers(unsigned N) {
+    return sizeof(EHCatchScope) + N * sizeof(Handler);
+  }
+
+  EHCatchScope(unsigned NumHandlers)
+    : EHScope(Catch), NumHandlers(NumHandlers) {
+  }
+
+  unsigned getNumHandlers() const {
+    return NumHandlers;
+  }
+
+  void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block) {
+    setHandler(I, /*catchall*/ 0, Block);
+  }
+
+  void setHandler(unsigned I, llvm::Value *Type, llvm::BasicBlock *Block) {
+    assert(I < getNumHandlers());
+    getHandlers()[I].Type = Type;
+    getHandlers()[I].Block = Block;
+  }
+
+  const Handler &getHandler(unsigned I) const {
+    assert(I < getNumHandlers());
+    return getHandlers()[I];
+  }
+
+  typedef const Handler *iterator;
+  iterator begin() const { return getHandlers(); }
+  iterator end() const { return getHandlers() + getNumHandlers(); }
+
+  static bool classof(const EHScope *Scope) {
+    return Scope->getKind() == Catch;
+  }
+};
+
+/// A cleanup scope which generates the cleanup blocks lazily.
+class EHCleanupScope : public EHScope {
+  /// Whether this cleanup needs to be run along normal edges.
+  bool IsNormalCleanup : 1;
+
+  /// Whether this cleanup needs to be run along exception edges.
+  bool IsEHCleanup : 1;
+
+  /// Whether this cleanup was activated before all normal uses.
+  bool ActivatedBeforeNormalUse : 1;
+
+  /// Whether this cleanup was activated before all EH uses.
+  bool ActivatedBeforeEHUse : 1;
+
+  /// The amount of extra storage needed by the Cleanup.
+  /// Always a multiple of the scope-stack alignment.
+  unsigned CleanupSize : 12;
+
+  /// The number of fixups required by enclosing scopes (not including
+  /// this one).  If this is the top cleanup scope, all the fixups
+  /// from this index onwards belong to this scope.
+  unsigned FixupDepth : BitsRemaining - 16;
+
+  /// The nearest normal cleanup scope enclosing this one.
+  EHScopeStack::stable_iterator EnclosingNormal;
+
+  /// The nearest EH cleanup scope enclosing this one.
+  EHScopeStack::stable_iterator EnclosingEH;
+
+  /// The dual entry/exit block along the normal edge.  This is lazily
+  /// created if needed before the cleanup is popped.
+  llvm::BasicBlock *NormalBlock;
+
+  /// The dual entry/exit block along the EH edge.  This is lazily
+  /// created if needed before the cleanup is popped.
+  llvm::BasicBlock *EHBlock;
+
+  /// An optional i1 variable indicating whether this cleanup has been
+  /// activated yet.  This has one of three states:
+  ///   - it is null if the cleanup is inactive
+  ///   - it is activeSentinel() if the cleanup is active and was not
+  ///     required before activation
+  ///   - it points to a valid variable
+  llvm::AllocaInst *ActiveVar;
+
+  /// Extra information required for cleanups that have resolved
+  /// branches through them.  This has to be allocated on the side
+  /// because everything on the cleanup stack has be trivially
+  /// movable.
+  struct ExtInfo {
+    /// The destinations of normal branch-afters and branch-throughs.
+    llvm::SmallPtrSet<llvm::BasicBlock*, 4> Branches;
+
+    /// Normal branch-afters.
+    llvm::SmallVector<std::pair<llvm::BasicBlock*,llvm::ConstantInt*>, 4>
+      BranchAfters;
+
+    /// The destinations of EH branch-afters and branch-throughs.
+    /// TODO: optimize for the extremely common case of a single
+    /// branch-through.
+    llvm::SmallPtrSet<llvm::BasicBlock*, 4> EHBranches;
+
+    /// EH branch-afters.
+    llvm::SmallVector<std::pair<llvm::BasicBlock*,llvm::ConstantInt*>, 4>
+    EHBranchAfters;
+  };
+  mutable struct ExtInfo *ExtInfo;
+
+  struct ExtInfo &getExtInfo() {
+    if (!ExtInfo) ExtInfo = new struct ExtInfo();
+    return *ExtInfo;
+  }
+
+  const struct ExtInfo &getExtInfo() const {
+    if (!ExtInfo) ExtInfo = new struct ExtInfo();
+    return *ExtInfo;
+  }
+
+public:
+  /// Gets the size required for a lazy cleanup scope with the given
+  /// cleanup-data requirements.
+  static size_t getSizeForCleanupSize(size_t Size) {
+    return sizeof(EHCleanupScope) + Size;
+  }
+
+  size_t getAllocatedSize() const {
+    return sizeof(EHCleanupScope) + CleanupSize;
+  }
+
+  EHCleanupScope(bool IsNormal, bool IsEH, bool IsActive,
+                 unsigned CleanupSize, unsigned FixupDepth,
+                 EHScopeStack::stable_iterator EnclosingNormal,
+                 EHScopeStack::stable_iterator EnclosingEH)
+    : EHScope(EHScope::Cleanup),
+      IsNormalCleanup(IsNormal), IsEHCleanup(IsEH),
+      ActivatedBeforeNormalUse(IsActive),
+      ActivatedBeforeEHUse(IsActive),
+      CleanupSize(CleanupSize), FixupDepth(FixupDepth),
+      EnclosingNormal(EnclosingNormal), EnclosingEH(EnclosingEH),
+      NormalBlock(0), EHBlock(0),
+      ActiveVar(IsActive ? activeSentinel() : 0),
+      ExtInfo(0)
+  {
+    assert(this->CleanupSize == CleanupSize && "cleanup size overflow");
+  }
+
+  ~EHCleanupScope() {
+    delete ExtInfo;
+  }
+
+  bool isNormalCleanup() const { return IsNormalCleanup; }
+  llvm::BasicBlock *getNormalBlock() const { return NormalBlock; }
+  void setNormalBlock(llvm::BasicBlock *BB) { NormalBlock = BB; }
+
+  bool isEHCleanup() const { return IsEHCleanup; }
+  llvm::BasicBlock *getEHBlock() const { return EHBlock; }
+  void setEHBlock(llvm::BasicBlock *BB) { EHBlock = BB; }
+
+  static llvm::AllocaInst *activeSentinel() {
+    return reinterpret_cast<llvm::AllocaInst*>(1);
+  }
+
+  bool isActive() const { return ActiveVar != 0; }
+  llvm::AllocaInst *getActiveVar() const { return ActiveVar; }
+  void setActiveVar(llvm::AllocaInst *Var) { ActiveVar = Var; }
+
+  bool wasActivatedBeforeNormalUse() const { return ActivatedBeforeNormalUse; }
+  void setActivatedBeforeNormalUse(bool B) { ActivatedBeforeNormalUse = B; }
+
+  bool wasActivatedBeforeEHUse() const { return ActivatedBeforeEHUse; }
+  void setActivatedBeforeEHUse(bool B) { ActivatedBeforeEHUse = B; }
+
+  unsigned getFixupDepth() const { return FixupDepth; }
+  EHScopeStack::stable_iterator getEnclosingNormalCleanup() const {
+    return EnclosingNormal;
+  }
+  EHScopeStack::stable_iterator getEnclosingEHCleanup() const {
+    return EnclosingEH;
+  }
+
+  size_t getCleanupSize() const { return CleanupSize; }
+  void *getCleanupBuffer() { return this + 1; }
+
+  EHScopeStack::Cleanup *getCleanup() {
+    return reinterpret_cast<EHScopeStack::Cleanup*>(getCleanupBuffer());
+  }
+
+  /// True if this cleanup scope has any branch-afters or branch-throughs.
+  bool hasBranches() const { return ExtInfo && !ExtInfo->Branches.empty(); }
+
+  /// Add a branch-after to this cleanup scope.  A branch-after is a
+  /// branch from a point protected by this (normal) cleanup to a
+  /// point in the normal cleanup scope immediately containing it.
+  /// For example,
+  ///   for (;;) { A a; break; }
+  /// contains a branch-after.
+  ///
+  /// Branch-afters each have their own destination out of the
+  /// cleanup, guaranteed distinct from anything else threaded through
+  /// it.  Therefore branch-afters usually force a switch after the
+  /// cleanup.
+  void addBranchAfter(llvm::ConstantInt *Index,
+                      llvm::BasicBlock *Block) {
+    struct ExtInfo &ExtInfo = getExtInfo();
+    if (ExtInfo.Branches.insert(Block))
+      ExtInfo.BranchAfters.push_back(std::make_pair(Block, Index));
+  }
+
+  /// Return the number of unique branch-afters on this scope.
+  unsigned getNumBranchAfters() const {
+    return ExtInfo ? ExtInfo->BranchAfters.size() : 0;
+  }
+
+  llvm::BasicBlock *getBranchAfterBlock(unsigned I) const {
+    assert(I < getNumBranchAfters());
+    return ExtInfo->BranchAfters[I].first;
+  }
+
+  llvm::ConstantInt *getBranchAfterIndex(unsigned I) const {
+    assert(I < getNumBranchAfters());
+    return ExtInfo->BranchAfters[I].second;
+  }
+
+  /// Add a branch-through to this cleanup scope.  A branch-through is
+  /// a branch from a scope protected by this (normal) cleanup to an
+  /// enclosing scope other than the immediately-enclosing normal
+  /// cleanup scope.
+  ///
+  /// In the following example, the branch through B's scope is a
+  /// branch-through, while the branch through A's scope is a
+  /// branch-after:
+  ///   for (;;) { A a; B b; break; }
+  ///
+  /// All branch-throughs have a common destination out of the
+  /// cleanup, one possibly shared with the fall-through.  Therefore
+  /// branch-throughs usually don't force a switch after the cleanup.
+  ///
+  /// \return true if the branch-through was new to this scope
+  bool addBranchThrough(llvm::BasicBlock *Block) {
+    return getExtInfo().Branches.insert(Block);
+  }
+
+  /// Determines if this cleanup scope has any branch throughs.
+  bool hasBranchThroughs() const {
+    if (!ExtInfo) return false;
+    return (ExtInfo->BranchAfters.size() != ExtInfo->Branches.size());
+  }
+
+  // Same stuff, only for EH branches instead of normal branches.
+  // It's quite possible that we could find a better representation
+  // for this.
+
+  bool hasEHBranches() const { return ExtInfo && !ExtInfo->EHBranches.empty(); }
+  void addEHBranchAfter(llvm::ConstantInt *Index,
+                        llvm::BasicBlock *Block) {
+    struct ExtInfo &ExtInfo = getExtInfo();
+    if (ExtInfo.EHBranches.insert(Block))
+      ExtInfo.EHBranchAfters.push_back(std::make_pair(Block, Index));
+  }
+
+  unsigned getNumEHBranchAfters() const {
+    return ExtInfo ? ExtInfo->EHBranchAfters.size() : 0;
+  }
+
+  llvm::BasicBlock *getEHBranchAfterBlock(unsigned I) const {
+    assert(I < getNumEHBranchAfters());
+    return ExtInfo->EHBranchAfters[I].first;
+  }
+
+  llvm::ConstantInt *getEHBranchAfterIndex(unsigned I) const {
+    assert(I < getNumEHBranchAfters());
+    return ExtInfo->EHBranchAfters[I].second;
+  }
+
+  bool addEHBranchThrough(llvm::BasicBlock *Block) {
+    return getExtInfo().EHBranches.insert(Block);
+  }
+
+  bool hasEHBranchThroughs() const {
+    if (!ExtInfo) return false;
+    return (ExtInfo->EHBranchAfters.size() != ExtInfo->EHBranches.size());
+  }
+
+  static bool classof(const EHScope *Scope) {
+    return (Scope->getKind() == Cleanup);
+  }
+};
+
+/// An exceptions scope which filters exceptions thrown through it.
+/// Only exceptions matching the filter types will be permitted to be
+/// thrown.
+///
+/// This is used to implement C++ exception specifications.
+class EHFilterScope : public EHScope {
+  unsigned NumFilters : BitsRemaining;
+
+  // Essentially ends in a flexible array member:
+  // llvm::Value *FilterTypes[0];
+
+  llvm::Value **getFilters() {
+    return reinterpret_cast<llvm::Value**>(this+1);
+  }
+
+  llvm::Value * const *getFilters() const {
+    return reinterpret_cast<llvm::Value* const *>(this+1);
+  }
+
+public:
+  EHFilterScope(unsigned NumFilters) :
+    EHScope(Filter), NumFilters(NumFilters) {}
+
+  static size_t getSizeForNumFilters(unsigned NumFilters) {
+    return sizeof(EHFilterScope) + NumFilters * sizeof(llvm::Value*);
+  }
+
+  unsigned getNumFilters() const { return NumFilters; }
+
+  void setFilter(unsigned I, llvm::Value *FilterValue) {
+    assert(I < getNumFilters());
+    getFilters()[I] = FilterValue;
+  }
+
+  llvm::Value *getFilter(unsigned I) const {
+    assert(I < getNumFilters());
+    return getFilters()[I];
+  }
+
+  static bool classof(const EHScope *Scope) {
+    return Scope->getKind() == Filter;
+  }
+};
+
+/// An exceptions scope which calls std::terminate if any exception
+/// reaches it.
+class EHTerminateScope : public EHScope {
+  unsigned DestIndex : BitsRemaining;
+public:
+  EHTerminateScope(unsigned Index) : EHScope(Terminate), DestIndex(Index) {}
+  static size_t getSize() { return sizeof(EHTerminateScope); }
+
+  unsigned getDestIndex() const { return DestIndex; }
+
+  static bool classof(const EHScope *Scope) {
+    return Scope->getKind() == Terminate;
+  }
+};
+
+/// A non-stable pointer into the scope stack.
+class EHScopeStack::iterator {
+  char *Ptr;
+
+  friend class EHScopeStack;
+  explicit iterator(char *Ptr) : Ptr(Ptr) {}
+
+public:
+  iterator() : Ptr(0) {}
+
+  EHScope *get() const { 
+    return reinterpret_cast<EHScope*>(Ptr);
+  }
+
+  EHScope *operator->() const { return get(); }
+  EHScope &operator*() const { return *get(); }
+
+  iterator &operator++() {
+    switch (get()->getKind()) {
+    case EHScope::Catch:
+      Ptr += EHCatchScope::getSizeForNumHandlers(
+          static_cast<const EHCatchScope*>(get())->getNumHandlers());
+      break;
+
+    case EHScope::Filter:
+      Ptr += EHFilterScope::getSizeForNumFilters(
+          static_cast<const EHFilterScope*>(get())->getNumFilters());
+      break;
+
+    case EHScope::Cleanup:
+      Ptr += static_cast<const EHCleanupScope*>(get())
+        ->getAllocatedSize();
+      break;
+
+    case EHScope::Terminate:
+      Ptr += EHTerminateScope::getSize();
+      break;
+    }
+
+    return *this;
+  }
+
+  iterator next() {
+    iterator copy = *this;
+    ++copy;
+    return copy;
+  }
+
+  iterator operator++(int) {
+    iterator copy = *this;
+    operator++();
+    return copy;
+  }
+
+  bool encloses(iterator other) const { return Ptr >= other.Ptr; }
+  bool strictlyEncloses(iterator other) const { return Ptr > other.Ptr; }
+
+  bool operator==(iterator other) const { return Ptr == other.Ptr; }
+  bool operator!=(iterator other) const { return Ptr != other.Ptr; }
+};
+
+inline EHScopeStack::iterator EHScopeStack::begin() const {
+  return iterator(StartOfData);
+}
+
+inline EHScopeStack::iterator EHScopeStack::end() const {
+  return iterator(EndOfBuffer);
+}
+
+inline void EHScopeStack::popCatch() {
+  assert(!empty() && "popping exception stack when not empty");
+
+  assert(isa<EHCatchScope>(*begin()));
+  StartOfData += EHCatchScope::getSizeForNumHandlers(
+                          cast<EHCatchScope>(*begin()).getNumHandlers());
+
+  if (empty()) NextEHDestIndex = FirstEHDestIndex;
+
+  assert(CatchDepth > 0 && "mismatched catch/terminate push/pop");
+  CatchDepth--;
+}
+
+inline void EHScopeStack::popTerminate() {
+  assert(!empty() && "popping exception stack when not empty");
+
+  assert(isa<EHTerminateScope>(*begin()));
+  StartOfData += EHTerminateScope::getSize();
+
+  if (empty()) NextEHDestIndex = FirstEHDestIndex;
+
+  assert(CatchDepth > 0 && "mismatched catch/terminate push/pop");
+  CatchDepth--;
+}
+
+inline EHScopeStack::iterator EHScopeStack::find(stable_iterator sp) const {
+  assert(sp.isValid() && "finding invalid savepoint");
+  assert(sp.Size <= stable_begin().Size && "finding savepoint after pop");
+  return iterator(EndOfBuffer - sp.Size);
+}
+
+inline EHScopeStack::stable_iterator
+EHScopeStack::stabilize(iterator ir) const {
+  assert(StartOfData <= ir.Ptr && ir.Ptr <= EndOfBuffer);
+  return stable_iterator(EndOfBuffer - ir.Ptr);
+}
+
+inline EHScopeStack::stable_iterator
+EHScopeStack::getInnermostActiveNormalCleanup() const {
+  for (EHScopeStack::stable_iterator
+         I = getInnermostNormalCleanup(), E = stable_end(); I != E; ) {
+    EHCleanupScope &S = cast<EHCleanupScope>(*find(I));
+    if (S.isActive()) return I;
+    I = S.getEnclosingNormalCleanup();
+  }
+  return stable_end();
+}
+
+inline EHScopeStack::stable_iterator
+EHScopeStack::getInnermostActiveEHCleanup() const {
+  for (EHScopeStack::stable_iterator
+         I = getInnermostEHCleanup(), E = stable_end(); I != E; ) {
+    EHCleanupScope &S = cast<EHCleanupScope>(*find(I));
+    if (S.isActive()) return I;
+    I = S.getEnclosingEHCleanup();
+  }
+  return stable_end();
+}
+
+}
+}
+
+#endif
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 5c9374d..f6cf592 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -19,7 +19,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "llvm/Intrinsics.h"
-#include "clang/CodeGen/CodeGenOptions.h"
+#include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/Target/TargetData.h"
 using namespace clang;
 using namespace CodeGen;
@@ -44,8 +44,8 @@
   Block->getInstList().insertAfter(&*AllocaInsertPt, Store);
 }
 
-llvm::Value *CodeGenFunction::CreateIRTemp(QualType Ty,
-                                           const llvm::Twine &Name) {
+llvm::AllocaInst *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);
@@ -53,8 +53,8 @@
   return Alloc;
 }
 
-llvm::Value *CodeGenFunction::CreateMemTemp(QualType Ty,
-                                            const llvm::Twine &Name) {
+llvm::AllocaInst *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);
@@ -65,22 +65,12 @@
 /// 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 (const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>()) {
+    llvm::Value *MemPtr = EmitScalarExpr(E);
+    return CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, MemPtr, MPT);
   }
+
+  QualType BoolTy = getContext().BoolTy;
   if (!E->getType()->isAnyComplexType())
     return EmitScalarConversion(EmitScalarExpr(E), E->getType(), BoolTy);
 
@@ -130,122 +120,239 @@
     EmitAggExpr(E, Location, IsLocationVolatile, /*Ignore*/ false, IsInit);
   else {
     RValue RV = RValue::get(EmitScalarExpr(E, /*Ignore*/ false));
-    LValue LV = LValue::MakeAddr(Location, MakeQualifiers(E->getType()));
+    LValue LV = MakeAddrLValue(Location, 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;
+/// \brief An adjustment to be made to the temporary created when emitting a
+/// reference binding, which accesses a particular subobject of that temporary.
+struct SubobjectAdjustment {
+  enum { DerivedToBaseAdjustment, FieldAdjustment } Kind;
+  
+  union {
+    struct {
+      const CastExpr *BasePath;
+      const CXXRecordDecl *DerivedClass;
+    } DerivedToBase;
     
-    // Keep track of the current cleanup stack depth.
-    OldNumLiveTemporaries = LiveTemporaries.size();
-    
-    E = TE->getSubExpr();
+    FieldDecl *Field;
+  };
+  
+  SubobjectAdjustment(const CastExpr *BasePath, 
+                      const CXXRecordDecl *DerivedClass)
+    : Kind(DerivedToBaseAdjustment) 
+  {
+    DerivedToBase.BasePath = BasePath;
+    DerivedToBase.DerivedClass = DerivedClass;
   }
   
-  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();
-      }
+  SubobjectAdjustment(FieldDecl *Field)
+    : Kind(FieldAdjustment)
+  { 
+    this->Field = Field;
+  }
+};
+
+static llvm::Value *
+CreateReferenceTemporary(CodeGenFunction& CGF, QualType Type,
+                         const NamedDecl *InitializedDecl) {
+  if (const VarDecl *VD = dyn_cast_or_null<VarDecl>(InitializedDecl)) {
+    if (VD->hasGlobalStorage()) {
+      llvm::SmallString<256> Name;
+      CGF.CGM.getMangleContext().mangleReferenceTemporary(VD, Name);
       
-      return RValue::get(LV.getAddress());
+      const llvm::Type *RefTempTy = CGF.ConvertTypeForMem(Type);
+  
+      // Create the reference temporary.
+      llvm::GlobalValue *RefTemp =
+        new llvm::GlobalVariable(CGF.CGM.getModule(), 
+                                 RefTempTy, /*isConstant=*/false,
+                                 llvm::GlobalValue::InternalLinkage,
+                                 llvm::Constant::getNullValue(RefTempTy),
+                                 Name.str());
+      return RefTemp;
     }
+  }
+
+  return CGF.CreateMemTemp(Type, "ref.tmp");
+}
+
+static llvm::Value *
+EmitExprForReferenceBinding(CodeGenFunction& CGF, const Expr* E,
+                            llvm::Value *&ReferenceTemporary,
+                            const CXXDestructorDecl *&ReferenceTemporaryDtor,
+                            const NamedDecl *InitializedDecl) {
+  if (const CXXDefaultArgExpr *DAE = dyn_cast<CXXDefaultArgExpr>(E))
+    E = DAE->getExpr();
+  
+  if (const CXXExprWithTemporaries *TE = dyn_cast<CXXExprWithTemporaries>(E)) {
+    CodeGenFunction::RunCleanupsScope Scope(CGF);
+
+    return EmitExprForReferenceBinding(CGF, TE->getSubExpr(), 
+                                       ReferenceTemporary, 
+                                       ReferenceTemporaryDtor,
+                                       InitializedDecl);
+  }
+
+  RValue RV;
+  if (E->isLvalue(CGF.getContext()) == Expr::LV_Valid) {
+    // Emit the expression as an lvalue.
+    LValue LV = CGF.EmitLValue(E);
+
+    if (LV.isSimple())
+      return LV.getAddress();
     
-    Val = EmitLoadOfLValue(LV, E->getType());
-    
-    if (ShouldDestroyTemporaries) {
-      // Pop temporaries.
-      while (LiveTemporaries.size() > OldNumLiveTemporaries)
-        PopCXXTemporary();
-    }      
+    // We have to load the lvalue.
+    RV = CGF.EmitLoadOfLValue(LV, E->getType());
   } 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();
+    QualType ResultTy = E->getType();
 
-        BasePath = &CE->getBasePath();
-        DerivedClassDecl = 
-          cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
-      }
-    }
-      
-    Val = EmitAnyExprToTemp(E, /*IsAggLocVolatile=*/false,
-                            IsInitializer);
+    llvm::SmallVector<SubobjectAdjustment, 2> Adjustments;
+    while (true) {
+      if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
+        E = PE->getSubExpr();
+        continue;
+      } 
 
-    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());
+      if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
+        if ((CE->getCastKind() == CK_DerivedToBase ||
+             CE->getCastKind() == CK_UncheckedDerivedToBase) &&
+            E->getType()->isRecordType()) {
+          E = CE->getSubExpr();
+          CXXRecordDecl *Derived 
+            = cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
+          Adjustments.push_back(SubobjectAdjustment(CE, Derived));
+          continue;
+        }
 
-            {
-              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());
-            }
+        if (CE->getCastKind() == CK_NoOp) {
+          E = CE->getSubExpr();
+          continue;
+        }
+      } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
+        if (ME->getBase()->isLvalue(CGF.getContext()) != Expr::LV_Valid &&
+            ME->getBase()->getType()->isRecordType()) {
+          if (FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
+            E = ME->getBase();
+            Adjustments.push_back(SubobjectAdjustment(Field));
+            continue;
           }
         }
       }
+
+      // Nothing changed.
+      break;
     }
     
-    // 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);
+    // Create a reference temporary if necessary.
+    if (CGF.hasAggregateLLVMType(E->getType()) &&
+        !E->getType()->isAnyComplexType())
+      ReferenceTemporary = CreateReferenceTemporary(CGF, E->getType(), 
+                                                    InitializedDecl);
+      
+    RV = CGF.EmitAnyExpr(E, ReferenceTemporary, /*IsAggLocVolatile=*/false,
+                         /*IgnoreResult=*/false, InitializedDecl);
+
+    if (InitializedDecl) {
+      // Get the destructor for the reference temporary.
+      if (const RecordType *RT = E->getType()->getAs<RecordType>()) {
+        CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+        if (!ClassDecl->hasTrivialDestructor())
+          ReferenceTemporaryDtor = ClassDecl->getDestructor();
+      }
+    }
+
+    // Check if need to perform derived-to-base casts and/or field accesses, to
+    // get from the temporary object we created (and, potentially, for which we
+    // extended the lifetime) to the subobject we're binding the reference to.
+    if (!Adjustments.empty()) {
+      llvm::Value *Object = RV.getAggregateAddr();
+      for (unsigned I = Adjustments.size(); I != 0; --I) {
+        SubobjectAdjustment &Adjustment = Adjustments[I-1];
+        switch (Adjustment.Kind) {
+        case SubobjectAdjustment::DerivedToBaseAdjustment:
+          Object = 
+              CGF.GetAddressOfBaseClass(Object, 
+                                        Adjustment.DerivedToBase.DerivedClass, 
+                              Adjustment.DerivedToBase.BasePath->path_begin(),
+                              Adjustment.DerivedToBase.BasePath->path_end(),
+                                        /*NullCheckValue=*/false);
+          break;
+            
+        case SubobjectAdjustment::FieldAdjustment: {
+          LValue LV = 
+            CGF.EmitLValueForField(Object, Adjustment.Field, 0);
+          if (LV.isSimple()) {
+            Object = LV.getAddress();
+            break;
+          }
+          
+          // For non-simple lvalues, we actually have to create a copy of
+          // the object we're binding to.
+          QualType T = Adjustment.Field->getType().getNonReferenceType()
+                                                  .getUnqualifiedType();
+          Object = CreateReferenceTemporary(CGF, T, InitializedDecl);
+          LValue TempLV = CGF.MakeAddrLValue(Object,
+                                             Adjustment.Field->getType());
+          CGF.EmitStoreThroughLValue(CGF.EmitLoadOfLValue(LV, T), TempLV, T);
+          break;
+        }
+
+        }
+      }
+      
+      const llvm::Type *ResultPtrTy = CGF.ConvertType(ResultTy)->getPointerTo();
+      return CGF.Builder.CreateBitCast(Object, ResultPtrTy, "temp");
     }
   }
 
-  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);
+  if (RV.isAggregate())
+    return RV.getAggregateAddr();
+
+  // Create a temporary variable that we can bind the reference to.
+  ReferenceTemporary = CreateReferenceTemporary(CGF, E->getType(), 
+                                                InitializedDecl);
+
+
+  unsigned Alignment =
+    CGF.getContext().getTypeAlignInChars(E->getType()).getQuantity();
+  if (RV.isScalar())
+    CGF.EmitStoreOfScalar(RV.getScalarVal(), ReferenceTemporary,
+                          /*Volatile=*/false, Alignment, E->getType());
+  else
+    CGF.StoreComplexToAddr(RV.getComplexVal(), ReferenceTemporary,
+                           /*Volatile=*/false);
+  return ReferenceTemporary;
+}
+
+RValue
+CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E,
+                                            const NamedDecl *InitializedDecl) {
+  llvm::Value *ReferenceTemporary = 0;
+  const CXXDestructorDecl *ReferenceTemporaryDtor = 0;
+  llvm::Value *Value = EmitExprForReferenceBinding(*this, E, ReferenceTemporary,
+                                                   ReferenceTemporaryDtor,
+                                                   InitializedDecl);
+
+  if (!ReferenceTemporaryDtor)
+    return RValue::get(Value);
+  
+  // Make sure to call the destructor for the reference temporary.
+  if (const VarDecl *VD = dyn_cast_or_null<VarDecl>(InitializedDecl)) {
+    if (VD->hasGlobalStorage()) {
+      llvm::Constant *DtorFn = 
+        CGM.GetAddrOfCXXDestructor(ReferenceTemporaryDtor, Dtor_Complete);
+      CGF.EmitCXXGlobalDtorRegistration(DtorFn, 
+                                      cast<llvm::Constant>(ReferenceTemporary));
+      
+      return RValue::get(Value);
+    }
   }
 
-  return Val;
+  PushDestructorCleanup(ReferenceTemporaryDtor, ReferenceTemporary);
+
+  return RValue::get(Value);
 }
 
 
@@ -263,119 +370,28 @@
   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);
+  const llvm::Type *IntPtrT = IntPtrTy;
+  llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, &IntPtrT, 1);
+  const llvm::IntegerType *Int1Ty = llvm::Type::getInt1Ty(VMContext);
 
   // 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);
+  llvm::Value *NegativeOne = llvm::ConstantInt::get(IntPtrTy, -1ULL);
   Builder.CreateCondBr(Builder.CreateICmpEQ(C, NegativeOne), Cont, Check);
     
   EmitBlock(Check);
   Builder.CreateCondBr(Builder.CreateICmpUGE(C,
-                                        llvm::ConstantInt::get(Size_tTy, Size)),
+                                        llvm::ConstantInt::get(IntPtrTy, 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) {
@@ -425,9 +441,12 @@
     return RValue::getComplex(std::make_pair(U, U));
   }
   
+  // If this is a use of an undefined aggregate type, the aggregate must have an
+  // identifiable address.  Just because the contents of the value are undefined
+  // doesn't mean that the address can't be taken and compared.
   if (hasAggregateLLVMType(Ty)) {
-    const llvm::Type *LTy = llvm::PointerType::getUnqual(ConvertType(Ty));
-    return RValue::getAggregate(llvm::UndefValue::get(LTy));
+    llvm::Value *DestPtr = CreateMemTemp(Ty, "undef.agg.tmp");
+    return RValue::getAggregate(DestPtr);
   }
   
   return RValue::get(llvm::UndefValue::get(ConvertType(Ty)));
@@ -443,8 +462,7 @@
                                               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()));
+  return MakeAddrLValue(llvm::UndefValue::get(Ty), E->getType());
 }
 
 LValue CodeGenFunction::EmitCheckedLValue(const Expr *E) {
@@ -473,6 +491,8 @@
   switch (E->getStmtClass()) {
   default: return EmitUnsupportedLValue(E, "l-value expression");
 
+  case Expr::ObjCSelectorExprClass:
+  return EmitObjCSelectorLValue(cast<ObjCSelectorExpr>(E));
   case Expr::ObjCIsaExprClass:
     return EmitObjCIsaExpr(cast<ObjCIsaExpr>(E));
   case Expr::BinaryOperatorClass:
@@ -505,8 +525,8 @@
     return EmitCXXBindTemporaryLValue(cast<CXXBindTemporaryExpr>(E));
   case Expr::CXXExprWithTemporariesClass:
     return EmitCXXExprWithTemporariesLValue(cast<CXXExprWithTemporaries>(E));
-  case Expr::CXXZeroInitValueExprClass:
-    return EmitNullInitializationLValue(cast<CXXZeroInitValueExpr>(E));
+  case Expr::CXXScalarValueInitExprClass:
+    return EmitNullInitializationLValue(cast<CXXScalarValueInitExpr>(E));
   case Expr::CXXDefaultArgExprClass:
     return EmitLValue(cast<CXXDefaultArgExpr>(E)->getExpr());
   case Expr::CXXTypeidExprClass:
@@ -551,10 +571,12 @@
 }
 
 llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
-                                               QualType Ty) {
+                                              unsigned Alignment, QualType Ty) {
   llvm::LoadInst *Load = Builder.CreateLoad(Addr, "tmp");
   if (Volatile)
     Load->setVolatile(true);
+  if (Alignment)
+    Load->setAlignment(Alignment);
 
   // Bool can have different representation in memory than in registers.
   llvm::Value *V = Load;
@@ -566,14 +588,18 @@
 }
 
 void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
-                                        bool Volatile, QualType Ty) {
+                                        bool Volatile, unsigned Alignment,
+                                        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);
+
+  llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile);
+  if (Alignment)
+    Store->setAlignment(Alignment);
 }
 
 /// EmitLoadOfLValue - Given an expression that represents a value lvalue, this
@@ -589,18 +615,15 @@
 
   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));
+    // Functions are l-values that don't require loading.
+    if (ExprType->isFunctionType())
+      return RValue::get(Ptr);
 
-    assert(ExprType->isFunctionType() && "Unknown scalar value");
-    return RValue::get(Ptr);
+    // Everything needs a load.
+    return RValue::get(EmitLoadOfScalar(Ptr, LV.isVolatileQualified(),
+                                        LV.getAlignment(), ExprType));
+
   }
 
   if (LV.isVectorElt()) {
@@ -721,8 +744,7 @@
   const VectorType *ExprVT = ExprType->getAs<VectorType>();
   if (!ExprVT) {
     unsigned InIdx = getAccessedFieldNo(0, Elts);
-    llvm::Value *Elt = llvm::ConstantInt::get(
-                                      llvm::Type::getInt32Ty(VMContext), InIdx);
+    llvm::Value *Elt = llvm::ConstantInt::get(Int32Ty, InIdx);
     return RValue::get(Builder.CreateExtractElement(Vec, Elt, "tmp"));
   }
 
@@ -732,8 +754,7 @@
   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));
+    Mask.push_back(llvm::ConstantInt::get(Int32Ty, InIdx));
   }
 
   llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
@@ -799,8 +820,10 @@
       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 if (Dst.isGlobalObjCRef()) {
+      CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst,
+                                                Dst.isThreadLocalRef());
+    }
     else
       CGM.getObjCRuntime().EmitObjCStrongCastAssign(*this, src, LvalueDst);
     return;
@@ -808,7 +831,7 @@
 
   assert(Src.isScalar() && "Can't emit an agg store with this method");
   EmitStoreOfScalar(Src.getScalarVal(), Dst.getAddress(),
-                    Dst.isVolatileQualified(), Ty);
+                    Dst.isVolatileQualified(), Dst.getAlignment(), Ty);
 }
 
 void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
@@ -949,8 +972,7 @@
       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);
+        Mask[InIdx] = llvm::ConstantInt::get(Int32Ty, i);
       }
 
       llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
@@ -963,7 +985,6 @@
       // 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));
@@ -994,7 +1015,6 @@
   } 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");
   }
@@ -1011,20 +1031,22 @@
     return;
   
   if (isa<ObjCIvarRefExpr>(E)) {
-    LV.SetObjCIvar(LV, true);
+    LV.setObjCIvar(true);
     ObjCIvarRefExpr *Exp = cast<ObjCIvarRefExpr>(const_cast<Expr*>(E));
     LV.setBaseIvarExp(Exp->getBase());
-    LV.SetObjCArray(LV, E->getType()->isArrayType());
+    LV.setObjCArray(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);
+          VD->isFileVarDecl()) {
+        LV.setGlobalObjCRef(true);
+        LV.setThreadLocalRef(VD->isThreadSpecified());
+      }
     }
-    LV.SetObjCArray(LV, E->getType()->isArrayType());
+    LV.setObjCArray(E->getType()->isArrayType());
     return;
   }
   
@@ -1042,7 +1064,7 @@
       if (ExpTy->isPointerType())
         ExpTy = ExpTy->getAs<PointerType>()->getPointeeType();
       if (ExpTy->isRecordType())
-        LV.SetObjCIvar(LV, false); 
+        LV.setObjCIvar(false); 
     }
     return;
   }
@@ -1061,11 +1083,11 @@
     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); 
+      LV.setObjCIvar(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);
+      LV.setGlobalObjCRef(false);
     return;
   }
   
@@ -1073,7 +1095,7 @@
     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());
+    LV.setObjCArray(E->getType()->isArrayType());
     return;
   }
 }
@@ -1086,7 +1108,8 @@
   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()));
+  unsigned Alignment = CGF.getContext().getDeclAlign(VD).getQuantity();
+  LValue LV = CGF.MakeAddrLValue(V, E->getType(), Alignment);
   setObjCGCLValueClass(CGF.getContext(), E, LV);
   return LV;
 }
@@ -1106,20 +1129,18 @@
       V = CGF.Builder.CreateBitCast(V, CGF.ConvertType(NoProtoType), "tmp");
     }
   }
-  return LValue::MakeAddr(V, CGF.MakeQualifiers(E->getType()));
+  unsigned Alignment = CGF.getContext().getDeclAlign(FD).getQuantity();
+  return CGF.MakeAddrLValue(V, E->getType(), Alignment);
 }
 
 LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
   const NamedDecl *ND = E->getDecl();
+  unsigned Alignment = CGF.getContext().getDeclAlign(ND).getQuantity();
 
   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;
+    return MakeAddrLValue(Aliasee, E->getType(), Alignment);
   }
 
   if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
@@ -1136,11 +1157,6 @@
       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);
@@ -1149,21 +1165,31 @@
     }
     if (VD->getType()->isReferenceType())
       V = Builder.CreateLoad(V, "tmp");
-    LValue LV = LValue::MakeAddr(V, Quals);
-    LValue::SetObjCNonGC(LV, NonGCable);
+
+    LValue LV = MakeAddrLValue(V, E->getType(), Alignment);
+    if (NonGCable) {
+      LV.getQuals().removeObjCGCAttr();
+      LV.setNonGC(true);
+    }
     setObjCGCLValueClass(getContext(), E, LV);
     return LV;
   }
   
+  // If we're emitting an instance method as an independent lvalue,
+  // we're actually emitting a member pointer.
+  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ND))
+    if (MD->isInstance()) {
+      llvm::Value *V = CGM.getCXXABI().EmitMemberPointer(MD);
+      return MakeAddrLValue(V, MD->getType(), Alignment);
+    }
   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()));
+  // If we're emitting a field as an independent lvalue, we're
+  // actually emitting a member pointer.
+  if (const FieldDecl *FD = dyn_cast<FieldDecl>(ND)) {
+    llvm::Value *V = CGM.getCXXABI().EmitMemberPointer(FD);
+    return MakeAddrLValue(V, FD->getType(), Alignment);
   }
   
   assert(false && "Unhandled DeclRefExpr");
@@ -1174,25 +1200,26 @@
 }
 
 LValue CodeGenFunction::EmitBlockDeclRefLValue(const BlockDeclRefExpr *E) {
-  return LValue::MakeAddr(GetAddrOfBlockDecl(E), MakeQualifiers(E->getType()));
+  unsigned Alignment =
+    CGF.getContext().getDeclAlign(E->getDecl()).getQuantity();
+  return MakeAddrLValue(GetAddrOfBlockDecl(E), E->getType(), Alignment);
 }
 
 LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
   // __extension__ doesn't affect lvalue-ness.
-  if (E->getOpcode() == UnaryOperator::Extension)
+  if (E->getOpcode() == UO_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: {
+  case UO_Deref: {
     QualType T = E->getSubExpr()->getType()->getPointeeType();
     assert(!T.isNull() && "CodeGenFunction::EmitUnaryOpLValue: Illegal type");
 
-    Qualifiers Quals = MakeQualifiers(T);
-    Quals.setAddressSpace(ExprTy.getAddressSpace());
+    LValue LV = MakeAddrLValue(EmitScalarExpr(E->getSubExpr()), T);
+    LV.getQuals().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
@@ -1200,21 +1227,21 @@
     if (getContext().getLangOptions().ObjC1 &&
         getContext().getLangOptions().getGCMode() != LangOptions::NonGC &&
         LV.isObjCWeak())
-      LValue::SetObjCNonGC(LV, !E->isOBJCGCCandidate(getContext()));
+      LV.setNonGC(!E->isOBJCGCCandidate(getContext()));
     return LV;
   }
-  case UnaryOperator::Real:
-  case UnaryOperator::Imag: {
+  case UO_Real:
+  case UO_Imag: {
     LValue LV = EmitLValue(E->getSubExpr());
-    unsigned Idx = E->getOpcode() == UnaryOperator::Imag;
-    return LValue::MakeAddr(Builder.CreateStructGEP(LV.getAddress(),
+    unsigned Idx = E->getOpcode() == UO_Imag;
+    return MakeAddrLValue(Builder.CreateStructGEP(LV.getAddress(),
                                                     Idx, "idx"),
-                            MakeQualifiers(ExprTy));
+                          ExprTy);
   }
-  case UnaryOperator::PreInc:
-  case UnaryOperator::PreDec: {
+  case UO_PreInc:
+  case UO_PreDec: {
     LValue LV = EmitLValue(E->getSubExpr());
-    bool isInc = E->getOpcode() == UnaryOperator::PreInc;
+    bool isInc = E->getOpcode() == UO_PreInc;
     
     if (E->getType()->isAnyComplexType())
       EmitComplexPrePostIncDec(E, LV, isInc, true/*isPre*/);
@@ -1226,53 +1253,56 @@
 }
 
 LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
-  return LValue::MakeAddr(CGM.GetAddrOfConstantStringFromLiteral(E),
-                          Qualifiers());
+  return MakeAddrLValue(CGM.GetAddrOfConstantStringFromLiteral(E),
+                        E->getType());
 }
 
 LValue CodeGenFunction::EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E) {
-  return LValue::MakeAddr(CGM.GetAddrOfConstantStringFromObjCEncode(E),
-                          Qualifiers());
+  return MakeAddrLValue(CGM.GetAddrOfConstantStringFromObjCEncode(E),
+                        E->getType());
 }
 
 
-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());
+  case PredefinedExpr::PrettyFunction: {
+    unsigned Type = E->getIdentType();
+    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;
+
+    const Decl *CurDecl = CurCodeDecl;
+    if (CurDecl == 0)
+      CurDecl = getContext().getTranslationUnitDecl();
+
+    std::string FunctionName =
+      PredefinedExpr::ComputeName((PredefinedExpr::IdentType)Type, CurDecl);
+
+    llvm::Constant *C =
+      CGM.GetAddrOfConstantCString(FunctionName, GlobalVarName.c_str());
+    return MakeAddrLValue(C, E->getType());
+  }
   }
 }
 
@@ -1281,10 +1311,9 @@
 
   // 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
+  // did in fact fail.  If we are optimizing, we collapse all calls to trap down
   // to just one per function to save on codesize.
-  if (GCO.OptimizationLevel
-      && TrapBB)
+  if (GCO.OptimizationLevel && TrapBB)
     return TrapBB;
 
   llvm::BasicBlock *Cont = 0;
@@ -1306,6 +1335,22 @@
   return TrapBB;
 }
 
+/// isSimpleArrayDecayOperand - If the specified expr is a simple decay from an
+/// array to pointer, return the array subexpression.
+static const Expr *isSimpleArrayDecayOperand(const Expr *E) {
+  // If this isn't just an array->pointer decay, bail out.
+  const CastExpr *CE = dyn_cast<CastExpr>(E);
+  if (CE == 0 || CE->getCastKind() != CK_ArrayToPointerDecay)
+    return 0;
+  
+  // If this is a decay from variable width array, bail out.
+  const Expr *SubExpr = CE->getSubExpr();
+  if (SubExpr->getType()->isVariableArrayType())
+    return 0;
+  
+  return SubExpr;
+}
+
 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());
@@ -1318,27 +1363,21 @@
     // 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");
+    Idx = Builder.CreateIntCast(Idx, CGF.Int32Ty, 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),
+  if (!Idx->getType()->isIntegerTy(LLVMPointerWidth))
+    Idx = Builder.CreateIntCast(Idx, IntPtrTy,
                                 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 ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E->getBase())){
       if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) {
-        if (ICE->getCastKind() == CastExpr::CK_ArrayToPointerDecay) {
+        if (ICE->getCastKind() == CK_ArrayToPointerDecay) {
           if (const ConstantArrayType *CAT
               = getContext().getAsConstantArrayType(DRE->getType())) {
             llvm::APInt Size = CAT->getSize();
@@ -1368,9 +1407,13 @@
     Idx = Builder.CreateUDiv(Idx,
                              llvm::ConstantInt::get(Idx->getType(),
                                  BaseTypeSize.getQuantity()));
+    
+    // The base must be a pointer, which is not an aggregate.  Emit it.
+    llvm::Value *Base = EmitScalarExpr(E->getBase());
+    
     Address = Builder.CreateInBoundsGEP(Base, Idx, "arrayidx");
-  } else if (const ObjCInterfaceType *OIT =
-             dyn_cast<ObjCInterfaceType>(E->getType())) {
+  } else if (const ObjCObjectType *OIT = E->getType()->getAs<ObjCObjectType>()){
+    // Indexing over an interface, as in "NSString *P; P[4];"
     llvm::Value *InterfaceSize =
       llvm::ConstantInt::get(Idx->getType(),
           getContext().getTypeSizeInChars(OIT).getQuantity());
@@ -1378,10 +1421,27 @@
     Idx = Builder.CreateMul(Idx, InterfaceSize);
 
     const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext);
+    
+    // The base must be a pointer, which is not an aggregate.  Emit it.
+    llvm::Value *Base = EmitScalarExpr(E->getBase());
     Address = Builder.CreateGEP(Builder.CreateBitCast(Base, i8PTy),
                                 Idx, "arrayidx");
     Address = Builder.CreateBitCast(Address, Base->getType());
+  } else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) {
+    // If this is A[i] where A is an array, the frontend will have decayed the
+    // base to be a ArrayToPointerDecay implicit cast.  While correct, it is
+    // inefficient at -O0 to emit a "gep A, 0, 0" when codegen'ing it, then a
+    // "gep x, i" here.  Emit one "gep A, 0, i".
+    assert(Array->getType()->isArrayType() &&
+           "Array to pointer decay must have array source type!");
+    llvm::Value *ArrayPtr = EmitLValue(Array).getAddress();
+    llvm::Value *Zero = llvm::ConstantInt::get(Int32Ty, 0);
+    llvm::Value *Args[] = { Zero, Idx };
+    
+    Address = Builder.CreateInBoundsGEP(ArrayPtr, Args, Args+2, "arrayidx");
   } else {
+    // The base must be a pointer, which is not an aggregate.  Emit it.
+    llvm::Value *Base = EmitScalarExpr(E->getBase());
     Address = Builder.CreateInBoundsGEP(Base, Idx, "arrayidx");
   }
 
@@ -1389,13 +1449,12 @@
   assert(!T.isNull() &&
          "CodeGenFunction::EmitArraySubscriptExpr(): Illegal base type");
 
-  Qualifiers Quals = MakeQualifiers(T);
-  Quals.setAddressSpace(E->getBase()->getType().getAddressSpace());
+  LValue LV = MakeAddrLValue(Address, T);
+  LV.getQuals().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()));
+    LV.setNonGC(!E->isOBJCGCCandidate(getContext()));
     setObjCGCLValueClass(getContext(), E, LV);
   }
   return LV;
@@ -1406,17 +1465,15 @@
                                        llvm::SmallVector<unsigned, 4> &Elts) {
   llvm::SmallVector<llvm::Constant*, 4> CElts;
 
+  const llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext);
   for (unsigned i = 0, e = Elts.size(); i != e; ++i)
-    CElts.push_back(llvm::ConstantInt::get(
-                                   llvm::Type::getInt32Ty(VMContext), Elts[i]));
+    CElts.push_back(llvm::ConstantInt::get(Int32Ty, 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;
 
@@ -1426,9 +1483,8 @@
     // 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);
+    Base = MakeAddrLValue(Ptr, PT->getPointeeType());
+    Base.getQuals().removeObjCGCAttr();
   } 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.
@@ -1443,7 +1499,7 @@
     // 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());
+    Base = MakeAddrLValue(VecMem, E->getBase()->getType());
   }
   
   // Encode the element access list into a vector of unsigned indices.
@@ -1503,7 +1559,7 @@
   if (FieldDecl *Field = dyn_cast<FieldDecl>(ND)) {
     LValue LV = EmitLValueForField(BaseValue, Field, 
                                    BaseQuals.getCVRQualifiers());
-    LValue::SetObjCNonGC(LV, isNonGC);
+    LV.setNonGC(isNonGC);
     setObjCGCLValueClass(getContext(), E, LV);
     return LV;
   }
@@ -1528,6 +1584,35 @@
                              Field->getType().getCVRQualifiers()|CVRQualifiers);
 }
 
+/// EmitLValueForAnonRecordField - Given that the field is a member of
+/// an anonymous struct or union buried inside a record, and given
+/// that the base value is a pointer to the enclosing record, derive
+/// an lvalue for the ultimate field.
+LValue CodeGenFunction::EmitLValueForAnonRecordField(llvm::Value *BaseValue,
+                                                     const FieldDecl *Field,
+                                                     unsigned CVRQualifiers) {
+  llvm::SmallVector<const FieldDecl *, 8> Path;
+  Path.push_back(Field);
+
+  while (Field->getParent()->isAnonymousStructOrUnion()) {
+    const ValueDecl *VD = Field->getParent()->getAnonymousStructOrUnionObject();
+    if (!isa<FieldDecl>(VD)) break;
+    Field = cast<FieldDecl>(VD);
+    Path.push_back(Field);
+  }
+
+  llvm::SmallVectorImpl<const FieldDecl*>::reverse_iterator
+    I = Path.rbegin(), E = Path.rend();
+  while (true) {
+    LValue LV = EmitLValueForField(BaseValue, *I, CVRQualifiers);
+    if (++I == E) return LV;
+
+    assert(LV.isSimple());
+    BaseValue = LV.getAddress();
+    CVRQualifiers |= LV.getVRQualifiers();
+  }
+}
+
 LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,
                                            const FieldDecl* Field,
                                            unsigned CVRQualifiers) {
@@ -1553,13 +1638,15 @@
   if (Field->getType()->isReferenceType())
     V = Builder.CreateLoad(V, "tmp");
 
-  Qualifiers Quals = MakeQualifiers(Field->getType());
-  Quals.addCVRQualifiers(CVRQualifiers);
+  unsigned Alignment = getContext().getDeclAlign(Field).getQuantity();
+  LValue LV = MakeAddrLValue(V, Field->getType(), Alignment);
+  LV.getQuals().addCVRQualifiers(CVRQualifiers);
+
   // __weak attribute on a field is ignored.
-  if (Quals.getObjCGCAttr() == Qualifiers::Weak)
-    Quals.removeObjCGCAttr();
+  if (LV.getQuals().getObjCGCAttr() == Qualifiers::Weak)
+    LV.getQuals().removeObjCGCAttr();
   
-  return LValue::MakeAddr(V, Quals);
+  return LV;
 }
 
 LValue 
@@ -1578,13 +1665,14 @@
 
   assert(!FieldType.getObjCGCAttr() && "fields cannot have GC attrs");
 
-  return LValue::MakeAddr(V, MakeQualifiers(FieldType));
+  unsigned Alignment = getContext().getDeclAlign(Field).getQuantity();
+  return MakeAddrLValue(V, FieldType, Alignment);
 }
 
 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()));
+  LValue Result = MakeAddrLValue(DeclPtr, E->getType());
 
   EmitAnyExprToMem(InitExpr, DeclPtr, /*Volatile*/ false);
 
@@ -1637,7 +1725,7 @@
     EmitBlock(ContBlock);
     
     Temp = Builder.CreateLoad(Temp, "lv");
-    return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
+    return MakeAddrLValue(Temp, E->getType());
   }
   
   // ?: here should be an aggregate.
@@ -1657,42 +1745,89 @@
 /// cast from scalar to union.
 LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
   switch (E->getCastKind()) {
-  default:
+  case CK_ToVoid:
     return EmitUnsupportedLValue(E, "unexpected cast lvalue");
+   
+  case CK_NoOp:
+    if (E->getSubExpr()->Classify(getContext()).getKind() 
+                                          != Expr::Classification::CL_PRValue) {
+      LValue LV = EmitLValue(E->getSubExpr());
+      if (LV.isPropertyRef()) {
+        QualType QT = E->getSubExpr()->getType();
+        RValue RV = EmitLoadOfPropertyRefLValue(LV, QT);
+        assert(!RV.isScalar() && "EmitCastLValue-scalar cast of property ref");
+        llvm::Value *V = RV.getAggregateAddr();
+        return MakeAddrLValue(V, QT);
+      }
+      return LV;
+    }
+    // Fall through to synthesize a temporary.
+      
+  case CK_Unknown:
+  case CK_BitCast:
+  case CK_ArrayToPointerDecay:
+  case CK_FunctionToPointerDecay:
+  case CK_NullToMemberPointer:
+  case CK_IntegralToPointer:
+  case CK_PointerToIntegral:
+  case CK_VectorSplat:
+  case CK_IntegralCast:
+  case CK_IntegralToFloating:
+  case CK_FloatingToIntegral:
+  case CK_FloatingCast:
+  case CK_DerivedToBaseMemberPointer:
+  case CK_BaseToDerivedMemberPointer:
+  case CK_MemberPointerToBoolean:
+  case CK_AnyPointerToBlockPointerCast: {
+    // These casts only produce lvalues when we're binding a reference to a 
+    // temporary realized from a (converted) pure rvalue. Emit the expression
+    // as a value, copy it into a temporary, and return an lvalue referring to
+    // that temporary.
+    llvm::Value *V = CreateMemTemp(E->getType(), "ref.temp");
+    EmitAnyExprToMem(E, V, false, false);
+    return MakeAddrLValue(V, E->getType());
+  }
 
-  case CastExpr::CK_Dynamic: {
+  case 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()));
+    return MakeAddrLValue(EmitDynamicCast(V, DCE), E->getType());
   }
 
-  case CastExpr::CK_NoOp:
-  case CastExpr::CK_ConstructorConversion:
-  case CastExpr::CK_UserDefinedConversion:
-  case CastExpr::CK_AnyPointerToObjCPointerCast:
+  case CK_ConstructorConversion:
+  case CK_UserDefinedConversion:
+  case CK_AnyPointerToObjCPointerCast:
     return EmitLValue(E->getSubExpr());
   
-  case CastExpr::CK_UncheckedDerivedToBase:
-  case CastExpr::CK_DerivedToBase: {
+  case CK_UncheckedDerivedToBase:
+  case CK_DerivedToBase: {
     const RecordType *DerivedClassTy = 
       E->getSubExpr()->getType()->getAs<RecordType>();
     CXXRecordDecl *DerivedClassDecl = 
       cast<CXXRecordDecl>(DerivedClassTy->getDecl());
     
     LValue LV = EmitLValue(E->getSubExpr());
+    llvm::Value *This;
+    if (LV.isPropertyRef()) {
+      RValue RV = EmitLoadOfPropertyRefLValue(LV, E->getSubExpr()->getType());
+      assert (!RV.isScalar() && "EmitCastLValue");
+      This = RV.getAggregateAddr();
+    }
+    else
+      This = LV.getAddress();
     
     // Perform the derived-to-base conversion
     llvm::Value *Base = 
-      GetAddressOfBaseClass(LV.getAddress(), DerivedClassDecl, 
-                            E->getBasePath(), /*NullCheckValue=*/false);
+      GetAddressOfBaseClass(This, DerivedClassDecl, 
+                            E->path_begin(), E->path_end(),
+                            /*NullCheckValue=*/false);
     
-    return LValue::MakeAddr(Base, MakeQualifiers(E->getType()));
+    return MakeAddrLValue(Base, E->getType());
   }
-  case CastExpr::CK_ToUnion:
+  case CK_ToUnion:
     return EmitAggExprToLValue(E);
-  case CastExpr::CK_BaseToDerived: {
+  case CK_BaseToDerived: {
     const RecordType *DerivedClassTy = E->getType()->getAs<RecordType>();
     CXXRecordDecl *DerivedClassDecl = 
       cast<CXXRecordDecl>(DerivedClassTy->getDecl());
@@ -1702,27 +1837,37 @@
     // Perform the base-to-derived conversion
     llvm::Value *Derived = 
       GetAddressOfDerivedClass(LV.getAddress(), DerivedClassDecl, 
-                               E->getBasePath(),/*NullCheckValue=*/false);
+                               E->path_begin(), E->path_end(),
+                               /*NullCheckValue=*/false);
     
-    return LValue::MakeAddr(Derived, MakeQualifiers(E->getType()));
+    return MakeAddrLValue(Derived, E->getType());
   }
-  case CastExpr::CK_BitCast: {
+  case CK_LValueBitCast: {
     // 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()));
+    return MakeAddrLValue(V, E->getType());
+  }
+  case CK_ObjCObjectLValueCast: {
+    LValue LV = EmitLValue(E->getSubExpr());
+    QualType ToType = getContext().getLValueReferenceType(E->getType());
+    llvm::Value *V = Builder.CreateBitCast(LV.getAddress(), 
+                                           ConvertType(ToType));
+    return MakeAddrLValue(V, E->getType());
   }
   }
+  
+  llvm_unreachable("Unhandled lvalue cast kind?");
 }
 
 LValue CodeGenFunction::EmitNullInitializationLValue(
-                                              const CXXZeroInitValueExpr *E) {
+                                              const CXXScalarValueInitExpr *E) {
   QualType Ty = E->getType();
-  LValue LV = LValue::MakeAddr(CreateMemTemp(Ty), MakeQualifiers(Ty));
-  EmitMemSetToZero(LV.getAddress(), Ty);
+  LValue LV = MakeAddrLValue(CreateMemTemp(Ty), Ty);
+  EmitNullInitialization(LV.getAddress(), Ty);
   return LV;
 }
 
@@ -1771,28 +1916,26 @@
 
 LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
   // Comma expressions just emit their LHS then their RHS as an l-value.
-  if (E->getOpcode() == BinaryOperator::Comma) {
+  if (E->getOpcode() == BO_Comma) {
     EmitAnyExpr(E->getLHS());
     EnsureInsertPoint();
     return EmitLValue(E->getRHS());
   }
 
-  if (E->getOpcode() == BinaryOperator::PtrMemD ||
-      E->getOpcode() == BinaryOperator::PtrMemI)
+  if (E->getOpcode() == BO_PtrMemD ||
+      E->getOpcode() == BO_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)
+  if (E->getOpcode() != BO_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());
+    // Store the value through the l-value.
+    EmitStoreThroughLValue(EmitAnyExpr(E->getRHS()), LV, E->getType());
     return LV;
   }
   
@@ -1803,13 +1946,13 @@
   RValue RV = EmitCallExpr(E);
 
   if (!RV.isScalar())
-    return LValue::MakeAddr(RV.getAggregateAddr(),MakeQualifiers(E->getType()));
+    return MakeAddrLValue(RV.getAggregateAddr(), 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()));
+  return MakeAddrLValue(RV.getScalarVal(), E->getType());
 }
 
 LValue CodeGenFunction::EmitVAArgExprLValue(const VAArgExpr *E) {
@@ -1820,27 +1963,38 @@
 LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) {
   llvm::Value *Temp = CreateMemTemp(E->getType(), "tmp");
   EmitCXXConstructExpr(Temp, E);
-  return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
+  return MakeAddrLValue(Temp, E->getType());
 }
 
 LValue
 CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) {
-  llvm::Value *Temp = EmitCXXTypeidExpr(E);
-  return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
+  return MakeAddrLValue(EmitCXXTypeidExpr(E), E->getType());
 }
 
 LValue
 CodeGenFunction::EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E) {
   LValue LV = EmitLValue(E->getSubExpr());
-  PushCXXTemporary(E->getTemporary(), LV.getAddress());
+  EmitCXXTemporary(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()));
+  
+  if (!RV.isScalar())
+    return MakeAddrLValue(RV.getAggregateAddr(), E->getType());
+  
+  assert(E->getMethodDecl()->getResultType()->isReferenceType() &&
+         "Can't have a scalar return unless the return type is a "
+         "reference type!");
+  
+  return MakeAddrLValue(RV.getScalarVal(), E->getType());
+}
+
+LValue CodeGenFunction::EmitObjCSelectorLValue(const ObjCSelectorExpr *E) {
+  llvm::Value *V = 
+    CGM.getObjCRuntime().GetSelector(Builder, E->getSelector(), true);
+  return MakeAddrLValue(V, E->getType());
 }
 
 llvm::Value *CodeGenFunction::EmitIvarOffset(const ObjCInterfaceDecl *Interface,
@@ -1902,7 +2056,7 @@
 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()));
+  return MakeAddrLValue(RV.getAggregateAddr(), E->getType());
 }
 
 RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
@@ -1931,7 +2085,7 @@
 LValue CodeGenFunction::
 EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) {
   llvm::Value *BaseV;
-  if (E->getOpcode() == BinaryOperator::PtrMemI)
+  if (E->getOpcode() == BO_PtrMemI)
     BaseV = EmitScalarExpr(E->getLHS());
   else
     BaseV = EmitLValue(E->getLHS()).getAddress();
@@ -1945,6 +2099,6 @@
   
   const llvm::Type *PType = ConvertType(getContext().getPointerType(Ty));
   AddV = Builder.CreateBitCast(AddV, PType);
-  return LValue::MakeAddr(AddV, MakeQualifiers(Ty));
+  return MakeAddrLValue(AddV, Ty);
 }
 
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index 84841bf..2d8e2b2 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -37,6 +37,16 @@
   bool IgnoreResult;
   bool IsInitializer;
   bool RequiresGCollection;
+
+  ReturnValueSlot getReturnValueSlot() const {
+    // If the destination slot requires garbage collection, we can't
+    // use the real return value slot, because we have to use the GC
+    // API.
+    if (RequiresGCollection) return ReturnValueSlot();
+
+    return ReturnValueSlot(DestPtr, VolatileDest);
+  }
+
 public:
   AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool v,
                  bool ignore, bool isinit, bool requiresGCollection)
@@ -58,6 +68,10 @@
   void EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore = false);
   void EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore = false);
 
+  void EmitGCMove(const Expr *E, RValue Src);
+
+  bool TypeRequiresGCollection(QualType T);
+
   //===--------------------------------------------------------------------===//
   //                            Visitor Methods
   //===--------------------------------------------------------------------===//
@@ -94,7 +108,6 @@
   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) {
@@ -113,7 +126,7 @@
   void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
   void VisitCXXConstructExpr(const CXXConstructExpr *E);
   void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
-  void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
+  void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
   void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }
 
   void VisitVAArgExpr(VAArgExpr *E);
@@ -137,23 +150,74 @@
   EmitFinalDestCopy(E, LV);
 }
 
+/// \brief True if the given aggregate type requires special GC API calls.
+bool AggExprEmitter::TypeRequiresGCollection(QualType T) {
+  // Only record types have members that might require garbage collection.
+  const RecordType *RecordTy = T->getAs<RecordType>();
+  if (!RecordTy) return false;
+
+  // Don't mess with non-trivial C++ types.
+  RecordDecl *Record = RecordTy->getDecl();
+  if (isa<CXXRecordDecl>(Record) &&
+      (!cast<CXXRecordDecl>(Record)->hasTrivialCopyConstructor() ||
+       !cast<CXXRecordDecl>(Record)->hasTrivialDestructor()))
+    return false;
+
+  // Check whether the type has an object member.
+  return Record->hasObjectMember();
+}
+
+/// \brief Perform the final move to DestPtr if RequiresGCollection is set.
+///
+/// The idea is that you do something like this:
+///   RValue Result = EmitSomething(..., getReturnValueSlot());
+///   EmitGCMove(E, Result);
+/// If GC doesn't interfere, this will cause the result to be emitted
+/// directly into the return value slot.  If GC does interfere, a final
+/// move will be performed.
+void AggExprEmitter::EmitGCMove(const Expr *E, RValue Src) {
+  if (RequiresGCollection) {
+    std::pair<uint64_t, unsigned> TypeInfo = 
+      CGF.getContext().getTypeInfo(E->getType());
+    unsigned long size = TypeInfo.first/8;
+    const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
+    llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size);
+    CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, DestPtr,
+                                                    Src.getAggregateAddr(),
+                                                    SizeVal);
+  }
+}
+
 /// 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 is null, then we're evaluating an aggregate expression
+  // in a context (like an expression statement) that doesn't care
+  // about the result.  C says that an lvalue-to-rvalue conversion is
+  // performed in these cases; C++ says that it is not.  In either
+  // case, we don't actually need to do anything unless the value is
+  // volatile.
   if (DestPtr == 0) {
-    if (!Src.isVolatileQualified() || (IgnoreResult && Ignore))
+    if (!Src.isVolatileQualified() ||
+        CGF.CGM.getLangOptions().CPlusPlus ||
+        (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) {
+    std::pair<uint64_t, unsigned> TypeInfo = 
+    CGF.getContext().getTypeInfo(E->getType());
+    unsigned long size = TypeInfo.first/8;
+    const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
+    llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size);
     CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF,
                                               DestPtr, Src.getAggregateAddr(),
-                                              E->getType());
+                                              SizeVal);
     return;
   }
   // If the result of the assignment is used, copy the LHS there also.
@@ -178,7 +242,7 @@
 //===----------------------------------------------------------------------===//
 
 void AggExprEmitter::VisitCastExpr(CastExpr *E) {
-  if (!DestPtr) {
+  if (!DestPtr && E->getCastKind() != CK_Dynamic) {
     Visit(E->getSubExpr());
     return;
   }
@@ -186,94 +250,54 @@
   switch (E->getCastKind()) {
   default: assert(0 && "Unhandled cast kind!");
 
-  case CastExpr::CK_ToUnion: {
+  case CK_Dynamic: {
+    assert(isa<CXXDynamicCastExpr>(E) && "CK_Dynamic without a dynamic_cast?");
+    LValue LV = CGF.EmitCheckedLValue(E->getSubExpr());
+    // FIXME: Do we also need to handle property references here?
+    if (LV.isSimple())
+      CGF.EmitDynamicCast(LV.getAddress(), cast<CXXDynamicCastExpr>(E));
+    else
+      CGF.CGM.ErrorUnsupported(E, "non-simple lvalue dynamic_cast");
+    
+    if (DestPtr)
+      CGF.CGM.ErrorUnsupported(E, "lvalue dynamic_cast with a destination");      
+    break;
+  }
+      
+  case CK_ToUnion: {
     // GCC union extension
-    QualType PtrTy =
-    CGF.getContext().getPointerType(E->getSubExpr()->getType());
+    QualType Ty = E->getSubExpr()->getType();
+    QualType PtrTy = CGF.getContext().getPointerType(Ty);
     llvm::Value *CastPtr = Builder.CreateBitCast(DestPtr,
                                                  CGF.ConvertType(PtrTy));
-    EmitInitializationToLValue(E->getSubExpr(),
-                               LValue::MakeAddr(CastPtr, Qualifiers()), 
-                               E->getSubExpr()->getType());
+    EmitInitializationToLValue(E->getSubExpr(), CGF.MakeAddrLValue(CastPtr, Ty),
+                               Ty);
+    break;
+  }
+
+  case CK_DerivedToBase:
+  case CK_BaseToDerived:
+  case CK_UncheckedDerivedToBase: {
+    assert(0 && "cannot perform hierarchy conversion in EmitAggExpr: "
+                "should have been unpacked before we got here");
     break;
   }
 
   // FIXME: Remove the CK_Unknown check here.
-  case CastExpr::CK_Unknown:
-  case CastExpr::CK_NoOp:
-  case CastExpr::CK_UserDefinedConversion:
-  case CastExpr::CK_ConstructorConversion:
+  case CK_Unknown:
+  case CK_NoOp:
+  case CK_UserDefinedConversion:
+  case 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);
-
+  case CK_LValueBitCast:
+    llvm_unreachable("there are no lvalue bit-casts on aggregates");
     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) {
@@ -282,31 +306,24 @@
     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);
+  RValue RV = CGF.EmitCallExpr(E, getReturnValueSlot());
+  EmitGCMove(E, RV);
 }
 
 void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
-  RValue RV = CGF.EmitObjCMessageExpr(E);
-  EmitFinalDestCopy(E, RV);
+  RValue RV = CGF.EmitObjCMessageExpr(E, getReturnValueSlot());
+  EmitGCMove(E, RV);
 }
 
 void AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
-  RValue RV = CGF.EmitObjCPropertyGet(E);
-  EmitFinalDestCopy(E, RV);
+  RValue RV = CGF.EmitObjCPropertyGet(E, getReturnValueSlot());
+  EmitGCMove(E, RV);
 }
 
 void AggExprEmitter::VisitObjCImplicitSetterGetterRefExpr(
                                    ObjCImplicitSetterGetterRefExpr *E) {
-  RValue RV = CGF.EmitObjCPropertyGet(E);
-  EmitFinalDestCopy(E, RV);
+  RValue RV = CGF.EmitObjCPropertyGet(E, getReturnValueSlot());
+  EmitGCMove(E, RV);
 }
 
 void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
@@ -315,55 +332,12 @@
                   /*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)
+  if (E->getOpcode() == BO_PtrMemD || E->getOpcode() == BO_PtrMemI)
     VisitPointerToDataMemberBinaryOperator(E);
   else
     CGF.ErrorUnsupported(E, "aggregate binary expression");
@@ -401,11 +375,9 @@
                             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();
-    }
+    if (CGF.getContext().getLangOptions().getGCMode())
+      RequiresGCollection = TypeRequiresGCollection(E->getLHS()->getType());
+
     // Codegen the RHS so that it stores directly into the LHS.
     CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), LHS.isVolatileQualified(),
                     false, false, RequiresGCollection);
@@ -458,7 +430,7 @@
     return;
   }
 
-  EmitFinalDestCopy(VE, LValue::MakeAddr(ArgPtr, Qualifiers()));
+  EmitFinalDestCopy(VE, CGF.MakeAddrLValue(ArgPtr, VE->getType()));
 }
 
 void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
@@ -475,23 +447,15 @@
 
   // Don't make this a live temporary if we're emitting an initializer expr.
   if (!IsInitializer)
-    CGF.PushCXXTemporary(E->getTemporary(), Val);
+    CGF.EmitCXXTemporary(E->getTemporary(), Val);
 }
 
 void
 AggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) {
   llvm::Value *Val = DestPtr;
 
-  if (!Val) {
-    // Create a temporary variable.
+  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);
 }
@@ -502,15 +466,15 @@
   CGF.EmitCXXExprWithTemporaries(E, Val, VolatileDest, IsInitializer);
 }
 
-void AggExprEmitter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+void AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *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());
+  EmitNullInitializationToLValue(CGF.MakeAddrLValue(Val, E->getType()),
+                                 E->getType());
 }
 
 void AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
@@ -520,8 +484,8 @@
     // Create a temporary variable.
     Val = CGF.CreateMemTemp(E->getType(), "tmp");
   }
-  LValue LV = LValue::MakeAddr(Val, Qualifiers());
-  EmitNullInitializationToLValue(LV, E->getType());
+  EmitNullInitializationToLValue(CGF.MakeAddrLValue(Val, E->getType()),
+                                 E->getType());
 }
 
 void 
@@ -531,7 +495,7 @@
   if (isa<ImplicitValueInitExpr>(E)) {
     EmitNullInitializationToLValue(LV, T);
   } else if (T->isReferenceType()) {
-    RValue RV = CGF.EmitReferenceBindingToExpr(E, /*IsInitializer=*/false);
+    RValue RV = CGF.EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0);
     CGF.EmitStoreThroughLValue(RV, LV, T);
   } else if (T->isAnyComplexType()) {
     CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
@@ -548,14 +512,10 @@
     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);
+    CGF.EmitNullInitialization(LV.getAddress(), T);
   }
 }
 
@@ -570,7 +530,7 @@
     llvm::GlobalVariable* GV =
     new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true,
                              llvm::GlobalValue::InternalLinkage, C, "");
-    EmitFinalDestCopy(E, LValue::MakeAddr(GV, Qualifiers()));
+    EmitFinalDestCopy(E, CGF.MakeAddrLValue(GV, E->getType()));
     return;
   }
 #endif
@@ -601,17 +561,15 @@
     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");
+      LValue LV = CGF.MakeAddrLValue(NextVal, ElementType);
       if (i < NumInitElements)
-        EmitInitializationToLValue(E->getInit(i),
-                                   LValue::MakeAddr(NextVal, Quals), 
-                                   ElementType);
+        EmitInitializationToLValue(E->getInit(i), LV, ElementType);
+
       else
-        EmitNullInitializationToLValue(LValue::MakeAddr(NextVal, Quals),
-                                       ElementType);
+        EmitNullInitializationToLValue(LV, ElementType);
     }
     return;
   }
@@ -662,7 +620,7 @@
   // 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()),
+                               CGF.MakeAddrLValue(DestPtr, E->getType()),
                                E->getType());
     return;
   }
@@ -683,7 +641,7 @@
     // FIXME: volatility
     LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, *Field, 0);
     // We never generate write-barries for initialized fields.
-    LValue::SetObjCNonGC(FieldLoc, true);
+    FieldLoc.setNonGC(true);
     if (CurInitVal < NumInitElements) {
       // Store the initializer into the field.
       EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc,
@@ -721,16 +679,10 @@
 
 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);
+  LValue LV = MakeAddrLValue(Temp, E->getType());
+  EmitAggExpr(E, Temp, LV.isVolatileQualified());
+  return LV;
 }
 
 void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
@@ -738,6 +690,19 @@
                                         bool isVolatile) {
   assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
 
+  if (getContext().getLangOptions().CPlusPlus) {
+    if (const RecordType *RT = Ty->getAs<RecordType>()) {
+      CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
+      assert((Record->hasTrivialCopyConstructor() || 
+              Record->hasTrivialCopyAssignment()) &&
+             "Trying to aggregate-copy a type without a trivial copy "
+             "constructor or assignment operator");
+      // Ignore empty classes in C++.
+      if (Record->isEmpty())
+        return;
+    }
+  }
+  
   // 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
@@ -748,18 +713,11 @@
   // 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:
@@ -773,25 +731,46 @@
   //
   // 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::Type *DBP =
+    llvm::Type::getInt8PtrTy(VMContext, DPT->getAddressSpace());
+  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");
+  const llvm::Type *SBP =
+    llvm::Type::getInt8PtrTy(VMContext, SPT->getAddressSpace());
+  SrcPtr = Builder.CreateBitCast(SrcPtr, SBP, "tmp");
 
+  if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
+    RecordDecl *Record = RecordTy->getDecl();
+    if (Record->hasObjectMember()) {
+      unsigned long size = TypeInfo.first/8;
+      const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
+      llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size);
+      CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, 
+                                                    SizeVal);
+      return;
+    }
+  } else if (getContext().getAsArrayType(Ty)) {
+    QualType BaseType = getContext().getBaseElementType(Ty);
+    if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) {
+      if (RecordTy->getDecl()->hasObjectMember()) {
+        unsigned long size = TypeInfo.first/8;
+        const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
+        llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size);
+        CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, 
+                                                      SizeVal);
+        return;
+      }
+    }
+  }
+  
   Builder.CreateCall5(CGM.getMemCpyFn(DestPtr->getType(), SrcPtr->getType(),
-                                      IntPtr),
+                                      IntPtrTy),
                       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));
+                      llvm::ConstantInt::get(IntPtrTy, TypeInfo.first/8),
+                      Builder.getInt32(TypeInfo.second/8),
+                      Builder.getInt1(isVolatile));
 }
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index 934d2db..97ee76c 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -12,6 +12,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "CodeGenFunction.h"
+#include "CGObjCRuntime.h"
+#include "llvm/Intrinsics.h"
 using namespace clang;
 using namespace CodeGen;
 
@@ -151,89 +153,27 @@
   
   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);
+  llvm::Value *MemFnPtr = EmitScalarExpr(MemFnExpr);
 
   // Emit the 'this' pointer.
   llvm::Value *This;
   
-  if (BO->getOpcode() == BinaryOperator::PtrMemI)
+  if (BO->getOpcode() == BO_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");
+  // Ask the ABI to load the callee.  Note that This is modified.
+  llvm::Value *Callee =
+    CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(CGF, This, MemFnPtr, MPT);
   
-  // 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 = 
@@ -255,13 +195,23 @@
                                                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();
+      LValue LV = EmitLValue(E->getArg(0));
+      llvm::Value *This;
+      if (LV.isPropertyRef()) {
+        llvm::Value *AggLoc  = CreateMemTemp(E->getArg(1)->getType());
+        EmitAggExpr(E->getArg(1), AggLoc, false /*VolatileDest*/);
+        EmitObjCPropertySet(LV.getPropertyRefExpr(),
+                            RValue::getAggregate(AggLoc, false /*VolatileDest*/));
+        return RValue::getAggregate(0, false);
+      }
+      else
+        This = LV.getAddress();
+      
       llvm::Value *Src = EmitLValue(E->getArg(1)).getAddress();
       QualType Ty = E->getType();
       EmitAggregateCopy(This, Src, Ty);
@@ -273,8 +223,15 @@
   const llvm::Type *Ty =
     CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
                                    FPT->isVariadic());
-
-  llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
+  LValue LV = EmitLValue(E->getArg(0));
+  llvm::Value *This;
+  if (LV.isPropertyRef()) {
+    RValue RV = EmitLoadOfPropertyRefLValue(LV, E->getArg(0)->getType());
+    assert (!RV.isScalar() && "EmitCXXOperatorMemberCallExpr");
+    This = RV.getAggregateAddr();
+  }
+  else
+    This = LV.getAddress();
 
   llvm::Value *Callee;
   if (MD->isVirtual() && !canDevirtualizeMemberFunctionCalls(E->getArg(0)))
@@ -291,45 +248,55 @@
                                       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);
+  
+  // If we require zero initialization before (or instead of) calling the
+  // constructor, as can be the case with a non-user-provided default
+  // constructor, emit the zero initialization now.
+  if (E->requiresZeroInitialization())
+    EmitNullInitialization(Dest, E->getType());
+
+  
+  // If this is a call to a trivial default constructor, do nothing.
+  if (CD->isTrivial() && CD->isDefaultConstructor())
     return;
+  
+  // Code gen optimization to eliminate copy constructor and return
+  // its first argument instead, if in fact that argument is a temporary 
+  // object.
+  if (getContext().getLangOptions().ElideConstructors && E->isElidable()) {
+    if (const Expr *Arg = E->getArg(0)->getTemporaryObject()) {
+      EmitAggExpr(Arg, Dest, false);
+      return;
+    }
   }
+  
+  const ConstantArrayType *Array 
+    = getContext().getAsConstantArrayType(E->getType());
   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);
+      Builder.CreateBitCast(Dest, BasePtr);
     
     EmitCXXAggrConstructorCall(CD, Array, BaseAddrPtr, 
                                E->arg_begin(), E->arg_end());
   }
-  else
+  else {
+    CXXCtorType Type = 
+      (E->getConstructionKind() == CXXConstructExpr::CK_Complete) 
+      ? Ctor_Complete : Ctor_Base;
+    bool ForVirtualBase = 
+      E->getConstructionKind() == CXXConstructExpr::CK_VirtualBase;
+    
     // Call the constructor.
-    EmitCXXConstructorCall(CD, 
-                           E->isBaseInitialization()? Ctor_Base : Ctor_Complete, 
-                           Dest,
+    EmitCXXConstructorCall(CD, Type, ForVirtualBase, Dest,
                            E->arg_begin(), E->arg_end());
+  }
 }
 
 static CharUnits CalculateCookiePadding(ASTContext &Ctx, QualType ElementType) {
+  ElementType = Ctx.getBaseElementType(ElementType);
   const RecordType *RT = ElementType->getAs<RecordType>();
   if (!RT)
     return CharUnits::Zero();
@@ -374,6 +341,24 @@
                   Ctx.getTypeAlignInChars(ElementType));
 }
 
+/// Check whether the given operator new[] is the global placement
+/// operator new[].
+static bool IsPlacementOperatorNewArray(ASTContext &Ctx,
+                                        const FunctionDecl *Fn) {
+  // Must be in global scope.  Note that allocation functions can't be
+  // declared in namespaces.
+  if (!Fn->getDeclContext()->getLookupContext()->isFileContext())
+    return false;
+
+  // Signature must be void *operator new[](size_t, void*).
+  // The size_t is common to all operator new[]s.
+  if (Fn->getNumParams() != 2)
+    return false;
+
+  CanQualType ParamType = Ctx.getCanonicalType(Fn->getParamDecl(1)->getType());
+  return (ParamType == Ctx.VoidPtrTy);
+}
+
 static CharUnits CalculateCookiePadding(ASTContext &Ctx, const CXXNewExpr *E) {
   if (!E->isArray())
     return CharUnits::Zero();
@@ -381,114 +366,120 @@
   // 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();
-    }
-  }
-      
+  if (IsPlacementOperatorNewArray(Ctx, OperatorNew))
+    return CharUnits::Zero();
+
   return CalculateCookiePadding(Ctx, E->getAllocatedType());
 }
 
 static llvm::Value *EmitCXXNewAllocSize(ASTContext &Context,
-                                        CodeGenFunction &CGF, 
+                                        CodeGenFunction &CGF,
                                         const CXXNewExpr *E,
-                                        llvm::Value *& NumElements) {
-  QualType Type = E->getAllocatedType();
-  CharUnits TypeSize = CGF.getContext().getTypeSizeInChars(Type);
+                                        llvm::Value *&NumElements,
+                                        llvm::Value *&SizeWithoutCookie) {
+  QualType ElemType = E->getAllocatedType();
+  
+  if (!E->isArray()) {
+    CharUnits TypeSize = CGF.getContext().getTypeSizeInChars(ElemType);
+    const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
+    SizeWithoutCookie = llvm::ConstantInt::get(SizeTy, TypeSize.getQuantity());
+    return SizeWithoutCookie;
+  }
+
+  // Emit the array size expression.
+  // We multiply the size of all dimensions for NumElements.
+  // e.g for 'int[2][3]', ElemType is 'int' and NumElements is 6.
+  NumElements = CGF.EmitScalarExpr(E->getArraySize());
+  while (const ConstantArrayType *CAT
+             = CGF.getContext().getAsConstantArrayType(ElemType)) {
+    ElemType = CAT->getElementType();
+    llvm::Value *ArraySize
+        = llvm::ConstantInt::get(CGF.CGM.getLLVMContext(), CAT->getSize());
+    NumElements = CGF.Builder.CreateMul(NumElements, ArraySize);
+  }
+
+  CharUnits TypeSize = CGF.getContext().getTypeSizeInChars(ElemType);
   const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
+  llvm::Value *Size = llvm::ConstantInt::get(SizeTy, TypeSize.getQuantity());
   
-  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;
+  // If someone is doing 'new int[42]' there is no need to do a dynamic check.
+  // Don't bloat the -O0 code.
+  if (llvm::ConstantInt *NumElementsC =
+        dyn_cast<llvm::ConstantInt>(NumElements)) {
+    // Determine if there is an overflow here by doing an extended multiply.
+    llvm::APInt NEC = NumElementsC->getValue();
+    NEC.zext(NEC.getBitWidth()*2);
     
-    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();
+    llvm::APInt SC = cast<llvm::ConstantInt>(Size)->getValue();
+    SC.zext(SC.getBitWidth()*2);
+    SC *= NEC;
+    
+    if (SC.countLeadingZeros() >= NumElementsC->getValue().getBitWidth()) {
+      SC.trunc(NumElementsC->getValue().getBitWidth());
+      Size = llvm::ConstantInt::get(Size->getContext(), SC);
+    } else {
+      // On overflow, produce a -1 so operator new throws.
+      Size = llvm::Constant::getAllOnesValue(Size->getType());
     }
     
-    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();
-  }
+  } else {
+    // Multiply with the type size.  This multiply can overflow, e.g. in:
+    //   new double[n]
+    // where n is 2^30 on a 32-bit machine or 2^62 on a 64-bit machine.  Because
+    // of this, we need to detect the overflow and ensure that an exception is
+    // called by forcing the size to -1 on overflow.
+    llvm::Value *UMulF =
+      CGF.CGM.getIntrinsic(llvm::Intrinsic::umul_with_overflow, &SizeTy, 1);
+    llvm::Value *MulRes = CGF.Builder.CreateCall2(UMulF, NumElements, Size);
+    // Branch on the overflow bit to the overflow block, which is lazily
+    // created.
+    llvm::Value *DidOverflow = CGF.Builder.CreateExtractValue(MulRes, 1);
+    // Get the normal result of the multiplication.
+    llvm::Value *V = CGF.Builder.CreateExtractValue(MulRes, 0);
+    
+    llvm::BasicBlock *NormalBB = CGF.createBasicBlock("no_overflow");
+    llvm::BasicBlock *OverflowBB = CGF.createBasicBlock("overflow");
+    
+    CGF.Builder.CreateCondBr(DidOverflow, OverflowBB, NormalBB);
 
-  // And add the cookie padding if necessary.
+    llvm::BasicBlock *PrevBB = CGF.Builder.GetInsertBlock();
+    
+    // We just need the overflow block to build a PHI node.
+    CGF.EmitBlock(OverflowBB);
+    CGF.EmitBlock(NormalBB);
+    
+    llvm::PHINode *PN = CGF.Builder.CreatePHI(V->getType());
+    
+    PN->addIncoming(V, PrevBB);
+    PN->addIncoming(llvm::Constant::getAllOnesValue(V->getType()), OverflowBB);
+    Size = PN;
+  }
+  SizeWithoutCookie = Size;
+  
+  // Add the cookie padding if necessary.
+  CharUnits CookiePadding = CalculateCookiePadding(CGF.getContext(), E);
   if (!CookiePadding.isZero())
-    V = CGF.Builder.CreateAdd(V, 
+    Size = CGF.Builder.CreateAdd(Size, 
         llvm::ConstantInt::get(SizeTy, CookiePadding.getQuantity()));
   
-  return V;
+  return Size;
 }
 
-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;
-  }
+static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const CXXNewExpr *E,
+                                    llvm::Value *NewPtr) {
   
-  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);
-    
+  QualType AllocType = E->getAllocatedType();
+
+  unsigned Alignment =
+    CGF.getContext().getTypeAlignInChars(AllocType).getQuantity();
   if (!CGF.hasAggregateLLVMType(AllocType)) 
     CGF.EmitStoreOfScalar(CGF.EmitScalarExpr(Init), NewPtr,
-                          AllocType.isVolatileQualified(), AllocType);
+                          AllocType.isVolatileQualified(), Alignment,
+                          AllocType);
   else if (AllocType->isAnyComplexType())
     CGF.EmitComplexExprIntoAddr(Init, NewPtr, 
                                 AllocType.isVolatileQualified());
@@ -496,6 +487,140 @@
     CGF.EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
 }
 
+void
+CodeGenFunction::EmitNewArrayInitializer(const CXXNewExpr *E, 
+                                         llvm::Value *NewPtr,
+                                         llvm::Value *NumElements) {
+  // We have a POD type.
+  if (E->getNumConstructorArgs() == 0)
+    return;
+  
+  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(NewPtr, Counter, 
+                                                   "arrayidx");
+  StoreAnyExprIntoOneUnit(*this, E, Address);
+  
+  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);
+}
+
+static void EmitZeroMemSet(CodeGenFunction &CGF, QualType T,
+                           llvm::Value *NewPtr, llvm::Value *Size) {
+  llvm::LLVMContext &VMContext = CGF.CGM.getLLVMContext();
+  const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
+  if (NewPtr->getType() != BP)
+    NewPtr = CGF.Builder.CreateBitCast(NewPtr, BP, "tmp");
+  
+  CGF.Builder.CreateCall5(CGF.CGM.getMemSetFn(BP, CGF.IntPtrTy), NewPtr,
+                llvm::Constant::getNullValue(llvm::Type::getInt8Ty(VMContext)),
+                          Size,
+                    llvm::ConstantInt::get(CGF.Int32Ty, 
+                                           CGF.getContext().getTypeAlign(T)/8),
+                          llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext),
+                                                 0));
+}
+                       
+static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,
+                               llvm::Value *NewPtr,
+                               llvm::Value *NumElements,
+                               llvm::Value *AllocSizeWithoutCookie) {
+  if (E->isArray()) {
+    if (CXXConstructorDecl *Ctor = E->getConstructor()) {
+      bool RequiresZeroInitialization = false;
+      if (Ctor->getParent()->hasTrivialConstructor()) {
+        // If new expression did not specify value-initialization, then there
+        // is no initialization.
+        if (!E->hasInitializer() || Ctor->getParent()->isEmpty())
+          return;
+      
+        if (CGF.CGM.getTypes().isZeroInitializable(E->getAllocatedType())) {
+          // Optimization: since zero initialization will just set the memory
+          // to all zeroes, generate a single memset to do it in one shot.
+          EmitZeroMemSet(CGF, E->getAllocatedType(), NewPtr, 
+                         AllocSizeWithoutCookie);
+          return;
+        }
+
+        RequiresZeroInitialization = true;
+      }
+      
+      CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr, 
+                                     E->constructor_arg_begin(), 
+                                     E->constructor_arg_end(),
+                                     RequiresZeroInitialization);
+      return;
+    } else if (E->getNumConstructorArgs() == 1 &&
+               isa<ImplicitValueInitExpr>(E->getConstructorArg(0))) {
+      // Optimization: since zero initialization will just set the memory
+      // to all zeroes, generate a single memset to do it in one shot.
+      EmitZeroMemSet(CGF, E->getAllocatedType(), NewPtr, 
+                     AllocSizeWithoutCookie);
+      return;      
+    } else {
+      CGF.EmitNewArrayInitializer(E, NewPtr, NumElements);
+      return;
+    }
+  }
+
+  if (CXXConstructorDecl *Ctor = E->getConstructor()) {
+    // Per C++ [expr.new]p15, if we have an initializer, then we're performing
+    // direct initialization. C++ [dcl.init]p5 requires that we 
+    // zero-initialize storage if there are no user-declared constructors.
+    if (E->hasInitializer() && 
+        !Ctor->getParent()->hasUserDeclaredConstructor() &&
+        !Ctor->getParent()->isEmpty())
+      CGF.EmitNullInitialization(NewPtr, E->getAllocatedType());
+      
+    CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false, 
+                               NewPtr, E->constructor_arg_begin(),
+                               E->constructor_arg_end());
+
+    return;
+  }
+  // We have a POD type.
+  if (E->getNumConstructorArgs() == 0)
+    return;
+  
+  StoreAnyExprIntoOneUnit(CGF, E, NewPtr);
+}
+
 llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
   QualType AllocType = E->getAllocatedType();
   FunctionDecl *NewFD = E->getOperatorNew();
@@ -507,8 +632,10 @@
   QualType SizeTy = getContext().getSizeType();
 
   llvm::Value *NumElements = 0;
+  llvm::Value *AllocSizeWithoutCookie = 0;
   llvm::Value *AllocSize = EmitCXXNewAllocSize(getContext(),
-                                               *this, E, NumElements);
+                                               *this, E, NumElements,
+                                               AllocSizeWithoutCookie);
   
   NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
 
@@ -600,12 +727,12 @@
     NewPtr = 
       Builder.CreateBitCast(NewPtr, 
                           ConvertType(getContext().getPointerType(AllocType)));
-    EmitNewInitializer(*this, E, NewPtr, NumElements);
+    EmitNewInitializer(*this, E, NewPtr, NumElements, AllocSizeWithoutCookie);
     NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
   }
   else {
     NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
-    EmitNewInitializer(*this, E, NewPtr, NumElements);
+    EmitNewInitializer(*this, E, NewPtr, NumElements, AllocSizeWithoutCookie);
   }
   
   if (NullCheckResult) {
@@ -712,7 +839,7 @@
   // to void*.
   const Expr *Arg = E->getArgument();
   while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
-    if (ICE->getCastKind() != CastExpr::CK_UserDefinedConversion &&
+    if (ICE->getCastKind() != CK_UserDefinedConversion &&
         ICE->getType()->isVoidPointerType())
       Arg = ICE->getSubExpr();
     else
@@ -740,7 +867,7 @@
   if (const RecordType *RT = DeleteTy->getAs<RecordType>()) {
     if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
       if (!RD->hasTrivialDestructor()) {
-        const CXXDestructorDecl *Dtor = RD->getDestructor(getContext());
+        const CXXDestructorDecl *Dtor = RD->getDestructor();
         if (E->isArrayForm()) {
           llvm::Value *AllocatedObjectPtr;
           llvm::Value *NumElements;
@@ -760,7 +887,8 @@
           // The dtor took care of deleting the object.
           ShouldCallDelete = false;
         } else 
-          EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr);
+          EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false,
+                                Ptr);
       }
     }
   }
@@ -797,7 +925,7 @@
       // FIXME: PointerType->hasAttr<NonNullAttr>()
       bool CanBeZero = false;
       if (UnaryOperator *UO = dyn_cast<UnaryOperator>(subE->IgnoreParens()))
-        if (UO->getOpcode() == UnaryOperator::Deref)
+        if (UO->getOpcode() == UO_Deref)
           CanBeZero = true;
       if (CanBeZero) {
         llvm::BasicBlock *NonZeroBlock = createBasicBlock();
@@ -843,6 +971,8 @@
       ToVoid = true;
   } else {
     LTy = LTy->getPointerTo();
+    
+    // FIXME: What if exceptions are disabled?
     ThrowOnBad = true;
   }
 
@@ -909,15 +1039,21 @@
 
     if (ThrowOnBad) {
       BadCastBlock = createBasicBlock();
-
       Builder.CreateCondBr(Builder.CreateIsNotNull(V), ContBlock, BadCastBlock);
       EmitBlock(BadCastBlock);
-      /// Call __cxa_bad_cast
+      /// Invoke __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();
+      if (llvm::BasicBlock *InvokeDest = getInvokeDest()) {
+        llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
+        Builder.CreateInvoke(F, Cont, InvokeDest)->setDoesNotReturn();
+        EmitBlock(Cont);
+      } else {
+        // FIXME: Does this ever make sense?
+        Builder.CreateCall(F)->setDoesNotReturn();
+      }
       Builder.CreateUnreachable();
     }
   }
diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp
index 0a0c914..79e9dd4 100644
--- a/lib/CodeGen/CGExprComplex.cpp
+++ b/lib/CodeGen/CGExprComplex.cpp
@@ -131,14 +131,14 @@
 
   // FIXME: CompoundLiteralExpr
 
-  ComplexPairTy EmitCast(Expr *Op, QualType DestTy);
+  ComplexPairTy EmitCast(CastExpr::CastKind CK, 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());
+    return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType());
   }
   ComplexPairTy VisitCastExpr(CastExpr *E) {
-    return EmitCast(E->getSubExpr(), E->getType());
+    return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType());
   }
   ComplexPairTy VisitCallExpr(const CallExpr *E);
   ComplexPairTy VisitStmtExpr(const StmtExpr *E);
@@ -181,7 +181,7 @@
   ComplexPairTy VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
     return CGF.EmitCXXExprWithTemporaries(E).getComplexVal();
   }
-  ComplexPairTy VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+  ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
     assert(E->getType()->isAnyComplexType() && "Expected complex type!");
     QualType Elem = E->getType()->getAs<ComplexType>()->getElementType();
     llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
@@ -339,11 +339,22 @@
   return Val;
 }
 
-ComplexPairTy ComplexExprEmitter::EmitCast(Expr *Op, QualType DestTy) {
+ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, 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);
 
+  // FIXME: We should be looking at all of the cast kinds here, not
+  // cherry-picking the ones we have test cases for.
+  if (CK == CK_LValueBitCast) {
+    llvm::Value *V = CGF.EmitLValue(Op).getAddress();
+    V = Builder.CreateBitCast(V, 
+                      CGF.ConvertType(CGF.getContext().getPointerType(DestTy)));
+    // FIXME: Are the qualifiers correct here?
+    return EmitLoadOfComplex(V, DestTy.isVolatileQualified());
+  }
+  
   // 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
@@ -521,22 +532,22 @@
   // 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);
+  OpInfo.RHS = EmitCast(CK_Unknown, E->getRHS(), OpInfo.Ty);
   
-  LValue LHSLV = CGF.EmitLValue(E->getLHS());
+  LValue LHS = 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();
+  if (LHS.isPropertyRef())
+    LHSComplexPair =
+      CGF.EmitObjCPropertyGet(LHS.getPropertyRefExpr()).getComplexVal();
+  else if (LHS.isKVCRef())
+    LHSComplexPair =
+      CGF.EmitObjCPropertyGet(LHS.getKVCRefExpr()).getComplexVal();
   else
-    LHSComplexPair = EmitLoadOfComplex(LHSLV.getAddress(), 
-                                       LHSLV.isVolatileQualified());
+    LHSComplexPair = EmitLoadOfComplex(LHS.getAddress(),
+                                       LHS.isVolatileQualified());
   
-  OpInfo.LHS=EmitComplexToComplexCast(LHSComplexPair, LHSTy, OpInfo.Ty);
+  OpInfo.LHS = EmitComplexToComplexCast(LHSComplexPair, LHSTy, OpInfo.Ty);
 
   // Expand the binary operator.
   ComplexPairTy Result = (this->*Func)(OpInfo);
@@ -545,23 +556,26 @@
   Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
 
   // Store the result value into the LHS lvalue.
-  if (LHSLV.isPropertyRef())
-    CGF.EmitObjCPropertySet(LHSLV.getPropertyRefExpr(), 
+  if (LHS.isPropertyRef())
+    CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(),
                             RValue::getComplex(Result));
-  else if (LHSLV.isKVCRef())
-    CGF.EmitObjCPropertySet(LHSLV.getKVCRefExpr(), RValue::getComplex(Result));
+  else if (LHS.isKVCRef())
+    CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), RValue::getComplex(Result));
   else
-    EmitStoreOfComplex(Result, LHSLV.getAddress(), LHSLV.isVolatileQualified());
-  // And now return the LHS
+    EmitStoreOfComplex(Result, LHS.getAddress(), LHS.isVolatileQualified());
+
+  // Restore the Ignore* flags.
   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());
+ 
+  // Objective-C property assignment never reloads the value following a store.
+  if (LHS.isPropertyRef() || LHS.isKVCRef())
+    return Result;
+
+  // Otherwise, reload the value.
+  return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified());
 }
 
 ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
@@ -569,8 +583,8 @@
   TestAndClearIgnoreImag();
   bool ignreal = TestAndClearIgnoreRealAssign();
   bool ignimag = TestAndClearIgnoreImagAssign();
-  assert(CGF.getContext().getCanonicalType(E->getLHS()->getType()) ==
-         CGF.getContext().getCanonicalType(E->getRHS()->getType()) &&
+  assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), 
+                                                 E->getRHS()->getType()) &&
          "Invalid assignment");
   // Emit the RHS.
   ComplexPairTy Val = Visit(E->getRHS());
@@ -578,31 +592,26 @@
   // 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).
+  // Store the result value into the LHS lvalue.
   if (LHS.isPropertyRef())
     CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(), RValue::getComplex(Val));
-  else
+  else if (LHS.isKVCRef())
     CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), RValue::getComplex(Val));
+  else
+    EmitStoreOfComplex(Val, LHS.getAddress(), LHS.isVolatileQualified());
 
-  // There is no reload after a store through a method, but we need to restore
-  // the Ignore* flags.
+  // Restore the Ignore* flags.
   IgnoreReal = ignreal;
   IgnoreImag = ignimag;
   IgnoreRealAssign = ignreal;
   IgnoreImagAssign = ignimag;
-  return Val;
+
+  // Objective-C property assignment never reloads the value following a store.
+  if (LHS.isPropertyRef() || LHS.isKVCRef())
+    return Val;
+
+  // Otherwise, reload the value.
+  return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified());
 }
 
 ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index ab0805e..a3a1fea 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -52,8 +52,8 @@
   bool AppendField(const FieldDecl *Field, uint64_t FieldOffset,
                    llvm::Constant *InitExpr);
 
-  bool AppendBitField(const FieldDecl *Field, uint64_t FieldOffset,
-                      llvm::Constant *InitExpr);
+  void AppendBitField(const FieldDecl *Field, uint64_t FieldOffset,
+                      llvm::ConstantInt *InitExpr);
 
   void AppendPadding(uint64_t NumBytes);
 
@@ -81,10 +81,6 @@
   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.
@@ -123,14 +119,9 @@
   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;
-
+void ConstStructBuilder::AppendBitField(const FieldDecl *Field,
+                                        uint64_t FieldOffset,
+                                        llvm::ConstantInt *CI) {
   if (FieldOffset > NextFieldOffsetInBytes * 8) {
     // We need to add padding.
     uint64_t NumBytes =
@@ -195,16 +186,43 @@
       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()))
+    // 'or' in the bits that go into the previous byte.
+    llvm::Value *LastElt = Elements.back();
+    if (llvm::ConstantInt *Val = dyn_cast<llvm::ConstantInt>(LastElt))
       Tmp |= Val->getValue();
-    else
-      assert(isa<llvm::UndefValue>(Elements.back()));
+    else {
+      assert(isa<llvm::UndefValue>(LastElt));
+      // If there is an undef field that we're adding to, it can either be a
+      // scalar undef (in which case, we just replace it with our field) or it
+      // is an array.  If it is an array, we have to pull one byte off the
+      // array so that the other undef bytes stay around.
+      if (!isa<llvm::IntegerType>(LastElt->getType())) {
+        // The undef padding will be a multibyte array, create a new smaller
+        // padding and then an hole for our i8 to get plopped into.
+        assert(isa<llvm::ArrayType>(LastElt->getType()) &&
+               "Expected array padding of undefs");
+        const llvm::ArrayType *AT = cast<llvm::ArrayType>(LastElt->getType());
+        assert(AT->getElementType()->isIntegerTy(8) &&
+               AT->getNumElements() != 0 &&
+               "Expected non-empty array padding of undefs");
+        
+        // Remove the padding array.
+        NextFieldOffsetInBytes -= AT->getNumElements();
+        Elements.pop_back();
+        
+        // Add the padding back in two chunks.
+        AppendPadding(AT->getNumElements()-1);
+        AppendPadding(1);
+        assert(isa<llvm::UndefValue>(Elements.back()) &&
+               Elements.back()->getType()->isIntegerTy(8) &&
+               "Padding addition didn't work right");
+      }
+    }
 
     Elements.back() = llvm::ConstantInt::get(CGM.getLLVMContext(), Tmp);
 
     if (FitsCompletelyInPreviousByte)
-      return true;
+      return;
   }
 
   while (FieldValue.getBitWidth() > 8) {
@@ -248,7 +266,6 @@
   Elements.push_back(llvm::ConstantInt::get(CGM.getLLVMContext(),
                                             FieldValue));
   NextFieldOffsetInBytes++;
-  return true;
 }
 
 void ConstStructBuilder::AppendPadding(uint64_t NumBytes) {
@@ -339,6 +356,9 @@
                                      Field->getType(), CGF);
     else
       EltInit = CGM.EmitNullConstant(Field->getType());
+
+    if (!EltInit)
+      return false;
     
     if (!Field->isBitField()) {
       // Handle non-bitfield members.
@@ -346,8 +366,8 @@
         return false;
     } else {
       // Otherwise we have a bitfield.
-      if (!AppendBitField(*Field, Layout.getFieldOffset(FieldNo), EltInit))
-        return false;
+      AppendBitField(*Field, Layout.getFieldOffset(FieldNo),
+                     cast<llvm::ConstantInt>(EltInit));
     }
   }
 
@@ -434,54 +454,15 @@
     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();
+          E->getType()->getAs<MemberPointerType>()) {
       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));
+      if (MPT->isMemberFunctionPointer())
+        return CGM.getCXXABI().EmitMemberPointer(cast<CXXMethodDecl>(ND));
+      else 
+        return CGM.getCXXABI().EmitMemberPointer(cast<FieldDecl>(ND));
     }
 
     return 0;
@@ -510,7 +491,7 @@
     
   llvm::Constant *VisitCastExpr(CastExpr* E) {
     switch (E->getCastKind()) {
-    case CastExpr::CK_ToUnion: {
+    case CK_ToUnion: {
       // GCC cast to union extension
       assert(E->getType()->isUnionType() &&
              "Destination type is not union type!");
@@ -545,44 +526,21 @@
         llvm::StructType::get(C->getType()->getContext(), Types, false);
       return llvm::ConstantStruct::get(STy, Elts);
     }
-    case CastExpr::CK_NullToMemberPointer:
-      return CGM.EmitNullConstant(E->getType());
+    case CK_NullToMemberPointer: {
+      const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
+      return CGM.getCXXABI().EmitNullMemberPointer(MPT);
+    }
       
-    case CastExpr::CK_BaseToDerivedMemberPointer: {
+    case CK_BaseToDerivedMemberPointer: {
       Expr *SubExpr = E->getSubExpr();
+      llvm::Constant *C = 
+        CGM.EmitConstantExpr(SubExpr, SubExpr->getType(), CGF);
+      if (!C) return 0;
 
-      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;
-      }          
+      return CGM.getCXXABI().EmitMemberPointerConversion(C, E);
     }
 
-    case CastExpr::CK_BitCast: 
+    case CK_BitCast: 
       // This must be a member function pointer cast.
       return Visit(E->getSubExpr());
 
@@ -788,7 +746,7 @@
     case Expr::DeclRefExprClass: {
       ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
       if (Decl->hasAttr<WeakRefAttr>())
-	return CGM.GetWeakRefReference(Decl);
+        return CGM.GetWeakRefReference(Decl);
       if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
         return CGM.GetAddrOfFunction(FD);
       if (const VarDecl* VD = dyn_cast<VarDecl>(Decl)) {
@@ -817,7 +775,7 @@
     case Expr::PredefinedExprClass: {
       unsigned Type = cast<PredefinedExpr>(E)->getIdentType();
       if (CGF) {
-        LValue Res = CGF->EmitPredefinedFunctionName(Type);
+        LValue Res = CGF->EmitPredefinedLValue(cast<PredefinedExpr>(E));
         return cast<llvm::Constant>(Res.getAddress());
       } else if (Type == PredefinedExpr::PrettyFunction) {
         return CGM.GetAddrOfConstantCString("top level", ".tmp");
@@ -925,7 +883,7 @@
       llvm::Constant *C = llvm::ConstantInt::get(VMContext,
                                                  Result.Val.getInt());
 
-      if (C->getType() == llvm::Type::getInt1Ty(VMContext)) {
+      if (C->getType()->isIntegerTy(1)) {
         const llvm::Type *BoolTy = getTypes().ConvertTypeForMem(E->getType());
         C = llvm::ConstantExpr::getZExt(C, BoolTy);
       }
@@ -972,39 +930,92 @@
   }
 
   llvm::Constant* C = ConstExprEmitter(*this, CGF).Visit(const_cast<Expr*>(E));
-  if (C && C->getType() == llvm::Type::getInt1Ty(VMContext)) {
+  if (C && C->getType()->isIntegerTy(1)) {
     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>()) {
+static void
+FillInNullDataMemberPointers(CodeGenModule &CGM, QualType T,
+                             std::vector<llvm::Constant *> &Elements,
+                             uint64_t StartOffset) {
+  assert(StartOffset % 8 == 0 && "StartOffset not byte aligned!");
+
+  if (CGM.getTypes().isZeroInitializable(T))
+    return;
+
+  if (const ConstantArrayType *CAT = 
+        CGM.getContext().getAsConstantArrayType(T)) {
+    QualType ElementTy = CAT->getElementType();
+    uint64_t ElementSize = CGM.getContext().getTypeSize(ElementTy);
+    
+    for (uint64_t I = 0, E = CAT->getSize().getZExtValue(); I != E; ++I) {
+      FillInNullDataMemberPointers(CGM, ElementTy, Elements,
+                                   StartOffset + I * ElementSize);
+    }
+  } else if (const RecordType *RT = T->getAs<RecordType>()) {
     const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+    const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+
+    // Go through all bases and fill in any null pointer to data members.
+    for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+         E = RD->bases_end(); I != E; ++I) {
+      if (I->isVirtual()) {
+        // FIXME: We should initialize null pointer to data members in virtual
+        // bases here.
+        continue;
+      }
+      
+      const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+      
+      // Ignore empty bases.
+      if (BaseDecl->isEmpty())
+        continue;
+      
+      // Ignore bases that don't have any pointer to data members.
+      if (CGM.getTypes().isZeroInitializable(BaseDecl))
+        continue;
+
+      uint64_t BaseOffset = Layout.getBaseClassOffset(BaseDecl);
+      FillInNullDataMemberPointers(CGM, I->getType(),
+                                   Elements, StartOffset + BaseOffset);
+    }
     
-    // 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();
+    // Visit all fields.
+    unsigned FieldNo = 0;
+    for (RecordDecl::field_iterator I = RD->field_begin(),
+         E = RD->field_end(); I != E; ++I, ++FieldNo) {
+      QualType FieldType = I->getType();
+      
+      if (CGM.getTypes().isZeroInitializable(FieldType))
+        continue;
+
+      uint64_t FieldOffset = StartOffset + Layout.getFieldOffset(FieldNo);
+      FillInNullDataMemberPointers(CGM, FieldType, Elements, FieldOffset);
+    }
+  } else {
+    assert(T->isMemberPointerType() && "Should only see member pointers here!");
+    assert(!T->getAs<MemberPointerType>()->getPointeeType()->isFunctionType() &&
+           "Should only see pointers to data members here!");
   
-  return false;
+    uint64_t StartIndex = StartOffset / 8;
+    uint64_t EndIndex = StartIndex + CGM.getContext().getTypeSize(T) / 8;
+
+    llvm::Constant *NegativeOne =
+      llvm::ConstantInt::get(llvm::Type::getInt8Ty(CGM.getLLVMContext()),
+                             -1ULL, /*isSigned=*/true);
+
+    // Fill in the null data member pointer.
+    for (uint64_t I = StartIndex; I != EndIndex; ++I)
+      Elements[I] = NegativeOne;
+  }
 }
 
 llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {
-  if (!containsPointerToDataMember(getTypes(), T))
+  if (getTypes().isZeroInitializable(T))
     return llvm::Constant::getNullValue(getTypes().ConvertTypeForMem(T));
     
   if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(T)) {
@@ -1024,21 +1035,69 @@
 
   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);
 
+    const CGRecordLayout &Layout = getTypes().getCGRecordLayout(RD);
+    
+    // Go through all bases and fill in any null pointer to data members.
+    for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+         E = RD->bases_end(); I != E; ++I) {
+      if (I->isVirtual()) {
+        // FIXME: We should initialize null pointer to data members in virtual
+        // bases here.
+        continue;
+      }
+
+      const CXXRecordDecl *BaseDecl = 
+        cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+      // Ignore empty bases.
+      if (BaseDecl->isEmpty())
+        continue;
+
+      // Ignore bases that don't have any pointer to data members.
+      if (getTypes().isZeroInitializable(BaseDecl))
+        continue;
+
+      // Currently, all bases are arrays of i8. Figure out how many elements
+      // this base array has.
+      unsigned BaseFieldNo = Layout.getNonVirtualBaseLLVMFieldNo(BaseDecl);
+      const llvm::ArrayType *BaseArrayTy =
+        cast<llvm::ArrayType>(STy->getElementType(BaseFieldNo));
+      
+      unsigned NumBaseElements = BaseArrayTy->getNumElements();
+      std::vector<llvm::Constant *> BaseElements(NumBaseElements);
+      
+      // Now fill in null data member pointers.
+      FillInNullDataMemberPointers(*this, I->getType(), BaseElements, 0);
+      
+      // Now go through all other elements and zero them out.
+      if (NumBaseElements) {
+        llvm::Constant *Zero =
+          llvm::ConstantInt::get(llvm::Type::getInt8Ty(getLLVMContext()), 0);
+        
+        for (unsigned I = 0; I != NumBaseElements; ++I) {
+          if (!BaseElements[I])
+            BaseElements[I] = Zero;
+        }
+      }
+      
+      Elements[BaseFieldNo] = llvm::ConstantArray::get(BaseArrayTy, 
+                                                       BaseElements);
+    }
+      
     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);
+      // Ignore bit fields.
+      if (FD->isBitField())
+        continue;
+
+      unsigned FieldNo = Layout.getLLVMFieldNo(FD);
       Elements[FieldNo] = EmitNullConstant(FD->getType());
     }
     
@@ -1051,6 +1110,7 @@
     return llvm::ConstantStruct::get(STy, Elements);
   }
 
+  assert(T->isMemberPointerType() && "Should only see member pointers here!");
   assert(!T->getAs<MemberPointerType>()->getPointeeType()->isFunctionType() &&
          "Should only see pointers to data members here!");
   
@@ -1059,29 +1119,3 @@
   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
index 842590b..dd88135 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -40,7 +40,8 @@
   Value *LHS;
   Value *RHS;
   QualType Ty;  // Computation Type.
-  const BinaryOperator *E;
+  BinaryOperator::Opcode Opcode; // Opcode of BinOp to perform
+  const Expr *E;      // Entire expr, for error unsupported.  May not be binop.
 };
 
 namespace {
@@ -96,6 +97,9 @@
   Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
                                        QualType SrcTy, QualType DstTy);
 
+  /// EmitNullValue - Emit a value that corresponds to null for the given type.
+  Value *EmitNullValue(QualType Ty);
+
   //===--------------------------------------------------------------------===//
   //                            Visitor Methods
   //===--------------------------------------------------------------------===//
@@ -122,17 +126,18 @@
   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 *VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
+    return EmitNullValue(E->getType());
   }
   Value *VisitGNUNullExpr(const GNUNullExpr *E) {
-    return llvm::Constant::getNullValue(ConvertType(E->getType()));
+    return EmitNullValue(E->getType());
   }
   Value *VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
     return llvm::ConstantInt::get(ConvertType(E->getType()),
                                   CGF.getContext().typesAreCompatible(
                                     E->getArgType1(), E->getArgType2()));
   }
+  Value *VisitOffsetOfExpr(OffsetOfExpr *E);
   Value *VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
   Value *VisitAddrLabelExpr(const AddrLabelExpr *E) {
     llvm::Value *V = CGF.GetAddrOfLabel(E->getLabel());
@@ -144,7 +149,10 @@
     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());
+      llvm::ConstantInt *CI 
+        = llvm::ConstantInt::get(VMContext, Result.Val.getInt());
+      CGF.EmitDeclRefExprDbgValue(E, CI);
+      return CI;
     }
     return EmitLoadOfLValue(E);
   }
@@ -185,7 +193,7 @@
   Value *VisitInitListExpr(InitListExpr *E);
 
   Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
-    return llvm::Constant::getNullValue(ConvertType(E->getType()));
+    return CGF.CGM.EmitNullConstant(E->getType());
   }
   Value *VisitCastExpr(CastExpr *E) {
     // Make sure to evaluate VLA bounds now so that we have them for later.
@@ -208,23 +216,31 @@
   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);
+    LValue LV = EmitLValue(E->getSubExpr());
+    return EmitScalarPrePostIncDec(E, LV, false, false);
   }
   Value *VisitUnaryPostInc(const UnaryOperator *E) {
-    return VisitPrePostIncDec(E, true, false);
+    LValue LV = EmitLValue(E->getSubExpr());
+    return EmitScalarPrePostIncDec(E, LV, true, false);
   }
   Value *VisitUnaryPreDec(const UnaryOperator *E) {
-    return VisitPrePostIncDec(E, false, true);
+    LValue LV = EmitLValue(E->getSubExpr());
+    return EmitScalarPrePostIncDec(E, LV, false, true);
   }
   Value *VisitUnaryPreInc(const UnaryOperator *E) {
-    return VisitPrePostIncDec(E, true, true);
+    LValue LV = EmitLValue(E->getSubExpr());
+    return EmitScalarPrePostIncDec(E, LV, true, true);
   }
+
+  llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
+                                       bool isInc, bool isPre);
+
+    
   Value *VisitUnaryAddrOf(const UnaryOperator *E) {
+    // If the sub-expression is an instance member reference,
+    // EmitDeclRefLValue will magically emit it with the appropriate
+    // value as the "address".
     return EmitLValue(E->getSubExpr()).getAddress();
   }
   Value *VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
@@ -241,8 +257,7 @@
   Value *VisitUnaryExtension(const UnaryOperator *E) {
     return Visit(E->getSubExpr());
   }
-  Value *VisitUnaryOffsetOf(const UnaryOperator *E);
-
+    
   // C++
   Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
     return Visit(DAE->getExpr());
@@ -277,7 +292,7 @@
   }
 
   Value *VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
-    return llvm::Constant::getNullValue(ConvertType(E->getType()));
+    return EmitNullValue(E->getType());
   }
 
   Value *VisitCXXThrowExpr(const CXXThrowExpr *E) {
@@ -287,9 +302,17 @@
 
   // Binary Operators.
   Value *EmitMul(const BinOpInfo &Ops) {
-    if (CGF.getContext().getLangOptions().OverflowChecking
-        && Ops.Ty->isSignedIntegerType())
-      return EmitOverflowCheckedBinOp(Ops);
+    if (Ops.Ty->hasSignedIntegerRepresentation()) {
+      switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
+      case LangOptions::SOB_Undefined:
+        return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
+      case LangOptions::SOB_Defined:
+        return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
+      case LangOptions::SOB_Trapping:
+        return EmitOverflowCheckedBinOp(Ops);
+      }
+    }
+    
     if (Ops.LHS->getType()->isFPOrFPVectorTy())
       return Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul");
     return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
@@ -316,7 +339,7 @@
   BinOpInfo EmitBinOps(const BinaryOperator *E);
   LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
                             Value *(ScalarExprEmitter::*F)(const BinOpInfo &),
-                                  Value *&BitFieldResult);
+                                  Value *&Result);
 
   Value *EmitCompoundAssign(const CompoundAssignOperator *E,
                             Value *(ScalarExprEmitter::*F)(const BinOpInfo &));
@@ -391,11 +414,8 @@
     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");
-  }
+  if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
+    return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, Src, MPT);
 
   assert((SrcType->isIntegerType() || isa<llvm::PointerType>(Src->getType())) &&
          "Unknown scalar type to convert");
@@ -431,8 +451,6 @@
 
   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);
@@ -454,8 +472,7 @@
     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);
+    const llvm::Type *MiddleTy = CGF.IntPtrTy;
     bool InputSigned = SrcType->isSignedIntegerType();
     llvm::Value* IntResult =
         Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
@@ -477,16 +494,14 @@
 
     // 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);
+    llvm::Value *Idx = llvm::ConstantInt::get(CGF.Int32Ty, 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));
+      Args.push_back(llvm::ConstantInt::get(CGF.Int32Ty, 0));
 
     llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], NumElements);
     llvm::Value *Yay = Builder.CreateShuffleVector(UnV, UnV, Mask, "splat");
@@ -548,6 +563,12 @@
   return EmitScalarConversion(Src.first, SrcTy, DstTy);
 }
 
+Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
+  if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
+    return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT);
+
+  return llvm::Constant::getNullValue(ConvertType(Ty));
+}
 
 //===----------------------------------------------------------------------===//
 //                            Visitor Methods
@@ -561,12 +582,104 @@
 }
 
 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))));
+  // Vector Mask Case
+  if (E->getNumSubExprs() == 2 || 
+      (E->getNumSubExprs() == 3 && E->getExpr(2)->getType()->isVectorType())) {
+    Value *LHS = CGF.EmitScalarExpr(E->getExpr(0));
+    Value *RHS = CGF.EmitScalarExpr(E->getExpr(1));
+    Value *Mask;
+    
+    const llvm::VectorType *LTy = cast<llvm::VectorType>(LHS->getType());
+    unsigned LHSElts = LTy->getNumElements();
+
+    if (E->getNumSubExprs() == 3) {
+      Mask = CGF.EmitScalarExpr(E->getExpr(2));
+      
+      // Shuffle LHS & RHS into one input vector.
+      llvm::SmallVector<llvm::Constant*, 32> concat;
+      for (unsigned i = 0; i != LHSElts; ++i) {
+        concat.push_back(llvm::ConstantInt::get(CGF.Int32Ty, 2*i));
+        concat.push_back(llvm::ConstantInt::get(CGF.Int32Ty, 2*i+1));
+      }
+      
+      Value* CV = llvm::ConstantVector::get(concat.begin(), concat.size());
+      LHS = Builder.CreateShuffleVector(LHS, RHS, CV, "concat");
+      LHSElts *= 2;
+    } else {
+      Mask = RHS;
+    }
+    
+    const llvm::VectorType *MTy = cast<llvm::VectorType>(Mask->getType());
+    llvm::Constant* EltMask;
+    
+    // Treat vec3 like vec4.
+    if ((LHSElts == 6) && (E->getNumSubExprs() == 3))
+      EltMask = llvm::ConstantInt::get(MTy->getElementType(),
+                                       (1 << llvm::Log2_32(LHSElts+2))-1);
+    else if ((LHSElts == 3) && (E->getNumSubExprs() == 2))
+      EltMask = llvm::ConstantInt::get(MTy->getElementType(),
+                                       (1 << llvm::Log2_32(LHSElts+1))-1);
+    else
+      EltMask = llvm::ConstantInt::get(MTy->getElementType(),
+                                       (1 << llvm::Log2_32(LHSElts))-1);
+             
+    // Mask off the high bits of each shuffle index.
+    llvm::SmallVector<llvm::Constant *, 32> MaskV;
+    for (unsigned i = 0, e = MTy->getNumElements(); i != e; ++i)
+      MaskV.push_back(EltMask);
+    
+    Value* MaskBits = llvm::ConstantVector::get(MaskV.begin(), MaskV.size());
+    Mask = Builder.CreateAnd(Mask, MaskBits, "mask");
+    
+    // newv = undef
+    // mask = mask & maskbits
+    // for each elt
+    //   n = extract mask i
+    //   x = extract val n
+    //   newv = insert newv, x, i
+    const llvm::VectorType *RTy = llvm::VectorType::get(LTy->getElementType(),
+                                                        MTy->getNumElements());
+    Value* NewV = llvm::UndefValue::get(RTy);
+    for (unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
+      Value *Indx = llvm::ConstantInt::get(CGF.Int32Ty, i);
+      Indx = Builder.CreateExtractElement(Mask, Indx, "shuf_idx");
+      Indx = Builder.CreateZExt(Indx, CGF.Int32Ty, "idx_zext");
+      
+      // Handle vec3 special since the index will be off by one for the RHS.
+      if ((LHSElts == 6) && (E->getNumSubExprs() == 3)) {
+        Value *cmpIndx, *newIndx;
+        cmpIndx = Builder.CreateICmpUGT(Indx,
+                                        llvm::ConstantInt::get(CGF.Int32Ty, 3),
+                                        "cmp_shuf_idx");
+        newIndx = Builder.CreateSub(Indx, llvm::ConstantInt::get(CGF.Int32Ty,1),
+                                    "shuf_idx_adj");
+        Indx = Builder.CreateSelect(cmpIndx, newIndx, Indx, "sel_shuf_idx");
+      }
+      Value *VExt = Builder.CreateExtractElement(LHS, Indx, "shuf_elt");
+      NewV = Builder.CreateInsertElement(NewV, VExt, Indx, "shuf_ins");
+    }
+    return NewV;
   }
+  
   Value* V1 = CGF.EmitScalarExpr(E->getExpr(0));
   Value* V2 = CGF.EmitScalarExpr(E->getExpr(1));
+  
+  // Handle vec3 special since the index will be off by one for the RHS.
+  llvm::SmallVector<llvm::Constant*, 32> indices;
+  for (unsigned i = 2; i < E->getNumSubExprs(); i++) {
+    llvm::Constant *C = cast<llvm::Constant>(CGF.EmitScalarExpr(E->getExpr(i)));
+    const llvm::VectorType *VTy = cast<llvm::VectorType>(V1->getType());
+    if (VTy->getNumElements() == 3) {
+      if (llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(C)) {
+        uint64_t cVal = CI->getZExtValue();
+        if (cVal > 3) {
+          C = llvm::ConstantInt::get(C->getType(), cVal-1);
+        }
+      }
+    }
+    indices.push_back(C);
+  }
+
   Value* SV = llvm::ConstantVector::get(indices.begin(), indices.size());
   return Builder.CreateShuffleVector(V1, V2, SV, "shuffle");
 }
@@ -597,10 +710,7 @@
   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");
+  Idx = Builder.CreateIntCast(Idx, CGF.Int32Ty, IdxSigned, "vecidxcast");
   return Builder.CreateExtractElement(Base, Idx, "vecext");
 }
 
@@ -629,7 +739,6 @@
     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
@@ -660,7 +769,7 @@
             // insert into undef -> shuffle (src, undef)
             Args.push_back(C);
             for (unsigned j = 1; j != ResElts; ++j)
-              Args.push_back(llvm::UndefValue::get(I32Ty));
+              Args.push_back(llvm::UndefValue::get(CGF.Int32Ty));
 
             LHS = EI->getVectorOperand();
             RHS = V;
@@ -669,11 +778,11 @@
             // 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, 
+              Args.push_back(getMaskElt(SVV, j, 0, CGF.Int32Ty));
+            Args.push_back(llvm::ConstantInt::get(CGF.Int32Ty, 
                                                   ResElts + C->getZExtValue()));
             for (unsigned j = CurIdx + 1; j != ResElts; ++j)
-              Args.push_back(llvm::UndefValue::get(I32Ty));
+              Args.push_back(llvm::UndefValue::get(CGF.Int32Ty));
             
             LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
             RHS = EI->getVectorOperand();
@@ -687,7 +796,7 @@
           }
         }
       }
-      Value *Idx = llvm::ConstantInt::get(I32Ty, CurIdx);
+      Value *Idx = llvm::ConstantInt::get(CGF.Int32Ty, CurIdx);
       V = Builder.CreateInsertElement(V, Init, Idx, "vecinit");
       VIsUndefShuffle = false;
       ++CurIdx;
@@ -711,15 +820,15 @@
           // this shuffle directly into it.
           if (VIsUndefShuffle) {
             Args.push_back(getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0,
-                                      I32Ty));
+                                      CGF.Int32Ty));
           } else {
-            Args.push_back(llvm::ConstantInt::get(I32Ty, j));
+            Args.push_back(llvm::ConstantInt::get(CGF.Int32Ty, j));
           }
         }
         for (unsigned j = 0, je = InitElts; j != je; ++j)
-          Args.push_back(getMaskElt(SVI, j, Offset, I32Ty));
+          Args.push_back(getMaskElt(SVI, j, Offset, CGF.Int32Ty));
         for (unsigned j = CurIdx + InitElts; j != ResElts; ++j)
-          Args.push_back(llvm::UndefValue::get(I32Ty));
+          Args.push_back(llvm::UndefValue::get(CGF.Int32Ty));
 
         if (VIsUndefShuffle)
           V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
@@ -732,20 +841,20 @@
     // to the vector initializer into V.
     if (Args.empty()) {
       for (unsigned j = 0; j != InitElts; ++j)
-        Args.push_back(llvm::ConstantInt::get(I32Ty, j));
+        Args.push_back(llvm::ConstantInt::get(CGF.Int32Ty, j));
       for (unsigned j = InitElts; j != ResElts; ++j)
-        Args.push_back(llvm::UndefValue::get(I32Ty));
+        Args.push_back(llvm::UndefValue::get(CGF.Int32Ty));
       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));
+        Args.push_back(llvm::ConstantInt::get(CGF.Int32Ty, j));
       for (unsigned j = 0; j != InitElts; ++j)
-        Args.push_back(llvm::ConstantInt::get(I32Ty, j+Offset));
+        Args.push_back(llvm::ConstantInt::get(CGF.Int32Ty, j+Offset));
       for (unsigned j = CurIdx + InitElts; j != ResElts; ++j)
-        Args.push_back(llvm::UndefValue::get(I32Ty));
+        Args.push_back(llvm::UndefValue::get(CGF.Int32Ty));
     }
 
     // If V is undef, make sure it ends up on the RHS of the shuffle to aid
@@ -764,7 +873,7 @@
   
   // Emit remaining default initializers
   for (/* Do not initialize i*/; CurIdx < ResElts; ++CurIdx) {
-    Value *Idx = llvm::ConstantInt::get(I32Ty, CurIdx);
+    Value *Idx = llvm::ConstantInt::get(CGF.Int32Ty, CurIdx);
     llvm::Value *Init = llvm::Constant::getNullValue(EltTy);
     V = Builder.CreateInsertElement(V, Init, Idx, "vecinit");
   }
@@ -774,7 +883,7 @@
 static bool ShouldNullCheckClassCastValue(const CastExpr *CE) {
   const Expr *E = CE->getSubExpr();
 
-  if (CE->getCastKind() == CastExpr::CK_UncheckedDerivedToBase)
+  if (CE->getCastKind() == CK_UncheckedDerivedToBase)
     return false;
   
   if (isa<CXXThisExpr>(E)) {
@@ -783,8 +892,8 @@
   }
   
   if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
-    // And that lvalue casts are never null.
-    if (ICE->isLvalueCast())
+    // And that glvalue casts are never null.
+    if (ICE->getValueKind() != VK_RValue)
       return false;
   }
 
@@ -797,7 +906,7 @@
 Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
   Expr *E = CE->getSubExpr();
   QualType DestTy = CE->getType();
-  CastExpr::CastKind Kind = CE->getCastKind();
+  CastKind Kind = CE->getCastKind();
   
   if (!DestTy->isVoidType())
     TestAndClearIgnoreResultAssign();
@@ -806,50 +915,58 @@
   // 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:
+  case 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: {
+  case CK_LValueBitCast: 
+  case CK_ObjCObjectLValueCast: {
+    Value *V = EmitLValue(E).getAddress();
+    V = Builder.CreateBitCast(V, 
+                          ConvertType(CGF.getContext().getPointerType(DestTy)));
+    return EmitLoadOfLValue(CGF.MakeAddrLValue(V, DestTy), DestTy);
+  }
+      
+  case CK_AnyPointerToObjCPointerCast:
+  case CK_AnyPointerToBlockPointerCast:
+  case CK_BitCast: {
     Value *Src = Visit(const_cast<Expr*>(E));
     return Builder.CreateBitCast(Src, ConvertType(DestTy));
   }
-  case CastExpr::CK_NoOp:
-  case CastExpr::CK_UserDefinedConversion:
+  case CK_NoOp:
+  case CK_UserDefinedConversion:
     return Visit(const_cast<Expr*>(E));
 
-  case CastExpr::CK_BaseToDerived: {
+  case CK_BaseToDerived: {
     const CXXRecordDecl *DerivedClassDecl = 
       DestTy->getCXXRecordDeclForPointerType();
     
     return CGF.GetAddressOfDerivedClass(Visit(E), DerivedClassDecl, 
-                                        CE->getBasePath(), 
+                                        CE->path_begin(), CE->path_end(),
                                         ShouldNullCheckClassCastValue(CE));
   }
-  case CastExpr::CK_UncheckedDerivedToBase:
-  case CastExpr::CK_DerivedToBase: {
+  case CK_UncheckedDerivedToBase:
+  case 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(),
+                                     CE->path_begin(), CE->path_end(),
                                      ShouldNullCheckClassCastValue(CE));
   }
-  case CastExpr::CK_Dynamic: {
+  case CK_Dynamic: {
     Value *V = Visit(const_cast<Expr*>(E));
     const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(CE);
     return CGF.EmitDynamicCast(V, DCE);
   }
-  case CastExpr::CK_ToUnion:
+  case CK_ToUnion:
     assert(0 && "Should be unreachable!");
     break;
 
-  case CastExpr::CK_ArrayToPointerDecay: {
+  case CK_ArrayToPointerDecay: {
     assert(E->getType()->isArrayType() &&
            "Array to pointer decay must have array source type!");
 
@@ -867,93 +984,97 @@
 
     return V;
   }
-  case CastExpr::CK_FunctionToPointerDecay:
+  case CK_FunctionToPointerDecay:
     return EmitLValue(E).getAddress();
 
-  case CastExpr::CK_NullToMemberPointer:
-    return CGF.CGM.EmitNullConstant(DestTy);
+  case CK_NullToMemberPointer: {
+    // If the subexpression's type is the C++0x nullptr_t, emit the
+    // subexpression, which may have side effects.
+    if (E->getType()->isNullPtrType())
+      (void) Visit(E);
 
-  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;
+    const MemberPointerType *MPT = CE->getType()->getAs<MemberPointerType>();
+    return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT);
   }
 
-  case CastExpr::CK_ConstructorConversion:
+  case CK_BaseToDerivedMemberPointer:
+  case CK_DerivedToBaseMemberPointer: {
+    Value *Src = Visit(E);
+    
+    // Note that the AST doesn't distinguish between checked and
+    // unchecked member pointer conversions, so we always have to
+    // implement checked conversions here.  This is inefficient when
+    // actual control flow may be required in order to perform the
+    // check, which it is for data member pointers (but not member
+    // function pointers on Itanium and ARM).
+    return CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, Src);
+  }
+  
+
+  case CK_ConstructorConversion:
     assert(0 && "Should be unreachable!");
     break;
 
-  case CastExpr::CK_IntegralToPointer: {
+  case 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);
+    const llvm::Type *MiddleTy = CGF.IntPtrTy;
     bool InputSigned = E->getType()->isSignedIntegerType();
     llvm::Value* IntResult =
       Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
-    
+
     return Builder.CreateIntToPtr(IntResult, ConvertType(DestTy));
   }
-  case CastExpr::CK_PointerToIntegral: {
+  case CK_PointerToIntegral: {
     Value *Src = Visit(const_cast<Expr*>(E));
+
+    // Handle conversion to bool correctly.
+    if (DestTy->isBooleanType())
+      return EmitScalarConversion(Visit(E), E->getType(), DestTy);
+
     return Builder.CreatePtrToInt(Src, ConvertType(DestTy));
   }
-  case CastExpr::CK_ToVoid: {
-    CGF.EmitAnyExpr(E, 0, false, true);
+  case CK_ToVoid: {
+    if (E->Classify(CGF.getContext()).isGLValue())
+      CGF.EmitLValue(E);
+    else
+      CGF.EmitAnyExpr(E, 0, false, true);
     return 0;
   }
-  case CastExpr::CK_VectorSplat: {
+  case 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);
+    llvm::Value *Idx = llvm::ConstantInt::get(CGF.Int32Ty, 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));
+      Args.push_back(llvm::ConstantInt::get(CGF.Int32Ty, 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:
+  case CK_IntegralCast:
+  case CK_IntegralToFloating:
+  case CK_FloatingToIntegral:
+  case CK_FloatingCast:
     return EmitScalarConversion(Visit(E), E->getType(), DestTy);
 
-  case CastExpr::CK_MemberPointerToBoolean:
-    return CGF.EvaluateExprAsBool(E);
+  case CK_MemberPointerToBoolean: {
+    llvm::Value *MemPtr = Visit(E);
+    const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
+    return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, MemPtr, MPT);
   }
-
+  }
+  
   // Handle cases where the source is an non-complex type.
 
   if (!CGF.hasAggregateLLVMType(E->getType())) {
@@ -1003,12 +1124,127 @@
 //                             Unary Operators
 //===----------------------------------------------------------------------===//
 
+llvm::Value *ScalarExprEmitter::
+EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
+                        bool isInc, bool isPre) {
+  
+  QualType ValTy = E->getSubExpr()->getType();
+  llvm::Value *InVal = EmitLoadOfLValue(LV, ValTy);
+  
+  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
+    CGF.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(CGF.Int32Ty, AmountVal);
+    if (!isa<llvm::FunctionType>(PT->getElementType())) {
+      QualType PTEE = ValTy->getPointeeType();
+      if (const ObjCObjectType *OIT = PTEE->getAs<ObjCObjectType>()) {
+        // Handle interface types, which are not represented with a concrete
+        // type.
+        int size = CGF.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 = CGF.MakeAddrLValue(lhs, 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()->isIntegerTy(1) && 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);
+    
+    if (!ValTy->isSignedIntegerType())
+      // Unsigned integer inc is always two's complement.
+      NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
+    else {
+      switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
+      case LangOptions::SOB_Undefined:
+        NextVal = Builder.CreateNSWAdd(InVal, NextVal, isInc ? "inc" : "dec");
+        break;
+      case LangOptions::SOB_Defined:
+        NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
+        break;
+      case LangOptions::SOB_Trapping:
+        BinOpInfo BinOp;
+        BinOp.LHS = InVal;
+        BinOp.RHS = NextVal;
+        BinOp.Ty = E->getType();
+        BinOp.Opcode = BO_Add;
+        BinOp.E = E;
+        NextVal = EmitOverflowCheckedBinOp(BinOp);
+        break;
+      }
+    }
+  } 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(CGF.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())
+    CGF.EmitStoreThroughBitfieldLValue(RValue::get(NextVal), LV, ValTy, &NextVal);
+  else
+    CGF.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;
+}
+
+
+
 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");
+  // Emit unary minus with EmitSub so we handle overflow cases etc.
+  BinOpInfo BinOp;
+  BinOp.RHS = Visit(E->getSubExpr());
+  
+  if (BinOp.RHS->getType()->isFPOrFPVectorTy())
+    BinOp.LHS = llvm::ConstantFP::getZeroValueForNegation(BinOp.RHS->getType());
+  else 
+    BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
+  BinOp.Ty = E->getType();
+  BinOp.Opcode = BO_Sub;
+  BinOp.E = E;
+  return EmitSub(BinOp);
 }
 
 Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
@@ -1030,6 +1266,96 @@
   return Builder.CreateZExt(BoolVal, ConvertType(E->getType()), "lnot.ext");
 }
 
+Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
+  // Try folding the offsetof to a constant.
+  Expr::EvalResult EvalResult;
+  if (E->Evaluate(EvalResult, CGF.getContext()))
+    return llvm::ConstantInt::get(VMContext, EvalResult.Val.getInt());
+
+  // Loop over the components of the offsetof to compute the value.
+  unsigned n = E->getNumComponents();
+  const llvm::Type* ResultType = ConvertType(E->getType());
+  llvm::Value* Result = llvm::Constant::getNullValue(ResultType);
+  QualType CurrentType = E->getTypeSourceInfo()->getType();
+  for (unsigned i = 0; i != n; ++i) {
+    OffsetOfExpr::OffsetOfNode ON = E->getComponent(i);
+    llvm::Value *Offset = 0;
+    switch (ON.getKind()) {
+    case OffsetOfExpr::OffsetOfNode::Array: {
+      // Compute the index
+      Expr *IdxExpr = E->getIndexExpr(ON.getArrayExprIndex());
+      llvm::Value* Idx = CGF.EmitScalarExpr(IdxExpr);
+      bool IdxSigned = IdxExpr->getType()->isSignedIntegerType();
+      Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned, "conv");
+
+      // Save the element type
+      CurrentType =
+          CGF.getContext().getAsArrayType(CurrentType)->getElementType();
+
+      // Compute the element size
+      llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
+          CGF.getContext().getTypeSizeInChars(CurrentType).getQuantity());
+
+      // Multiply out to compute the result
+      Offset = Builder.CreateMul(Idx, ElemSize);
+      break;
+    }
+
+    case OffsetOfExpr::OffsetOfNode::Field: {
+      FieldDecl *MemberDecl = ON.getField();
+      RecordDecl *RD = CurrentType->getAs<RecordType>()->getDecl();
+      const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
+
+      // Compute the index of the field in its parent.
+      unsigned i = 0;
+      // FIXME: It would be nice if we didn't have to loop here!
+      for (RecordDecl::field_iterator Field = RD->field_begin(),
+                                      FieldEnd = RD->field_end();
+           Field != FieldEnd; (void)++Field, ++i) {
+        if (*Field == MemberDecl)
+          break;
+      }
+      assert(i < RL.getFieldCount() && "offsetof field in wrong type");
+
+      // Compute the offset to the field
+      int64_t OffsetInt = RL.getFieldOffset(i) /
+                          CGF.getContext().getCharWidth();
+      Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
+
+      // Save the element type.
+      CurrentType = MemberDecl->getType();
+      break;
+    }
+
+    case OffsetOfExpr::OffsetOfNode::Identifier:
+      llvm_unreachable("dependent __builtin_offsetof");
+
+    case OffsetOfExpr::OffsetOfNode::Base: {
+      if (ON.getBase()->isVirtual()) {
+        CGF.ErrorUnsupported(E, "virtual base in offsetof");
+        continue;
+      }
+
+      RecordDecl *RD = CurrentType->getAs<RecordType>()->getDecl();
+      const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
+
+      // Save the element type.
+      CurrentType = ON.getBase()->getType();
+      
+      // Compute the offset to the base.
+      const RecordType *BaseRT = CurrentType->getAs<RecordType>();
+      CXXRecordDecl *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
+      int64_t OffsetInt = RL.getBaseClassOffset(BaseRD) /
+                          CGF.getContext().getCharWidth();
+      Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
+      break;
+    }
+    }
+    Result = Builder.CreateAdd(Result, Offset);
+  }
+  return Result;
+}
+
 /// VisitSizeOfAlignOfExpr - Return the size or alignment of the type of
 /// argument of the sizeof expression as an integer.
 Value *
@@ -1078,12 +1404,6 @@
   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
 //===----------------------------------------------------------------------===//
@@ -1094,6 +1414,7 @@
   Result.LHS = Visit(E->getLHS());
   Result.RHS = Visit(E->getRHS());
   Result.Ty  = E->getType();
+  Result.Opcode = E->getOpcode();
   Result.E = E;
   return Result;
 }
@@ -1101,9 +1422,8 @@
 LValue ScalarExprEmitter::EmitCompoundAssignLValue(
                                               const CompoundAssignOperator *E,
                         Value *(ScalarExprEmitter::*Func)(const BinOpInfo &),
-                                                   Value *&BitFieldResult) {
+                                                   Value *&Result) {
   QualType LHSTy = E->getLHS()->getType();
-  BitFieldResult = 0;
   BinOpInfo OpInfo;
   
   if (E->getComputationResultType()->isAnyComplexType()) {
@@ -1112,7 +1432,7 @@
     // 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()));
+    Result = llvm::UndefValue::get(CGF.ConvertType(E->getType()));
     return LValue();
   }
   
@@ -1120,6 +1440,7 @@
   // first, plus this should improve codegen a little.
   OpInfo.RHS = Visit(E->getRHS());
   OpInfo.Ty = E->getComputationResultType();
+  OpInfo.Opcode = E->getOpcode();
   OpInfo.E = E;
   // Load/convert the LHS.
   LValue LHSLV = EmitCheckedLValue(E->getLHS());
@@ -1128,7 +1449,7 @@
                                     E->getComputationLHSType());
   
   // Expand the binary operator.
-  Value *Result = (this->*Func)(OpInfo);
+  Result = (this->*Func)(OpInfo);
   
   // Convert the result back to the LHS type.
   Result = EmitScalarConversion(Result, E->getComputationResultType(), LHSTy);
@@ -1137,37 +1458,42 @@
   // 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
+  if (LHSLV.isBitField())
+    CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, LHSTy,
+                                       &Result);
+  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;
-  
+  Value *RHS;
+  LValue LHS = EmitCompoundAssignLValue(E, Func, RHS);
+
+  // If the result is clearly ignored, return now.
   if (Ignore)
     return 0;
-  return EmitLoadOfLValue(LHSLV, E->getType());
+
+  // Objective-C property assignment never reloads the value following a store.
+  if (LHS.isPropertyRef() || LHS.isKVCRef())
+    return RHS;
+
+  // If the lvalue is non-volatile, return the computed value of the assignment.
+  if (!LHS.isVolatileQualified())
+    return RHS;
+
+  // Otherwise, reload the value.
+  return EmitLoadOfLValue(LHS, 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())
+  else if (Ops.Ty->hasUnsignedIntegerRepresentation())
     return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div");
   else
     return Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div");
@@ -1185,19 +1511,19 @@
   unsigned IID;
   unsigned OpID = 0;
 
-  switch (Ops.E->getOpcode()) {
-  case BinaryOperator::Add:
-  case BinaryOperator::AddAssign:
+  switch (Ops.Opcode) {
+  case BO_Add:
+  case BO_AddAssign:
     OpID = 1;
     IID = llvm::Intrinsic::sadd_with_overflow;
     break;
-  case BinaryOperator::Sub:
-  case BinaryOperator::SubAssign:
+  case BO_Sub:
+  case BO_SubAssign:
     OpID = 2;
     IID = llvm::Intrinsic::ssub_with_overflow;
     break;
-  case BinaryOperator::Mul:
-  case BinaryOperator::MulAssign:
+  case BO_Mul:
+  case BO_MulAssign:
     OpID = 3;
     IID = llvm::Intrinsic::smul_with_overflow;
     break;
@@ -1217,100 +1543,75 @@
   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);
+  llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn);
+  llvm::BasicBlock *continueBB = CGF.createBasicBlock("nooverflow", CGF.CurFn);
 
   Builder.CreateCondBr(overflow, overflowBB, continueBB);
 
-  // Handle overflow
-
+  // Handle overflow with llvm.trap.
+  // TODO: it would be better to generate one of these blocks per function.
   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
+  llvm::Function *Trap = CGF.CGM.getIntrinsic(llvm::Intrinsic::trap);
+  Builder.CreateCall(Trap);
+  Builder.CreateUnreachable();
+  
+  // Continue on.
   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;
+  return result;
 }
 
 Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) {
   if (!Ops.Ty->isAnyPointerType()) {
-    if (CGF.getContext().getLangOptions().OverflowChecking &&
-        Ops.Ty->isSignedIntegerType())
-      return EmitOverflowCheckedBinOp(Ops);
-
+    if (Ops.Ty->hasSignedIntegerRepresentation()) {
+      switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
+      case LangOptions::SOB_Undefined:
+        return Builder.CreateNSWAdd(Ops.LHS, Ops.RHS, "add");
+      case LangOptions::SOB_Defined:
+        return Builder.CreateAdd(Ops.LHS, Ops.RHS, "add");
+      case LangOptions::SOB_Trapping:
+        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");
   }
 
+  // Must have binary (not unary) expr here.  Unary pointer decrement doesn't
+  // use this path.
+  const BinaryOperator *BinOp = cast<BinaryOperator>(Ops.E);
+  
   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");
+    CGF.ErrorUnsupported(BinOp, "VLA pointer addition");
   }
+  
   Value *Ptr, *Idx;
   Expr *IdxExp;
-  const PointerType *PT = Ops.E->getLHS()->getType()->getAs<PointerType>();
+  const PointerType *PT = BinOp->getLHS()->getType()->getAs<PointerType>();
   const ObjCObjectPointerType *OPT =
-    Ops.E->getLHS()->getType()->getAs<ObjCObjectPointerType>();
+    BinOp->getLHS()->getType()->getAs<ObjCObjectPointerType>();
   if (PT || OPT) {
     Ptr = Ops.LHS;
     Idx = Ops.RHS;
-    IdxExp = Ops.E->getRHS();
+    IdxExp = BinOp->getRHS();
   } else {  // int + pointer
-    PT = Ops.E->getRHS()->getType()->getAs<PointerType>();
-    OPT = Ops.E->getRHS()->getType()->getAs<ObjCObjectPointerType>();
+    PT = BinOp->getRHS()->getType()->getAs<PointerType>();
+    OPT = BinOp->getRHS()->getType()->getAs<ObjCObjectPointerType>();
     assert((PT || OPT) && "Invalid add expr");
     Ptr = Ops.RHS;
     Idx = Ops.LHS;
-    IdxExp = Ops.E->getLHS();
+    IdxExp = BinOp->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);
+    const llvm::Type *IdxType = CGF.IntPtrTy;
     if (IdxExp->getType()->isSignedIntegerType())
       Idx = Builder.CreateSExt(Idx, IdxType, "idx.ext");
     else
@@ -1318,7 +1619,7 @@
   }
   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)) {
+  if (const ObjCObjectType *OIT = ElementType->getAs<ObjCObjectType>()) {
     llvm::Value *InterfaceSize =
       llvm::ConstantInt::get(Idx->getType(),
           CGF.getContext().getTypeSizeInChars(OIT).getQuantity());
@@ -1344,30 +1645,37 @@
 
 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.Ty->hasSignedIntegerRepresentation()) {
+      switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
+      case LangOptions::SOB_Undefined:
+        return Builder.CreateNSWSub(Ops.LHS, Ops.RHS, "sub");
+      case LangOptions::SOB_Defined:
+        return Builder.CreateSub(Ops.LHS, Ops.RHS, "sub");
+      case LangOptions::SOB_Trapping:
+        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()) {
+  // Must have binary (not unary) expr here.  Unary pointer increment doesn't
+  // use this path.
+  const BinaryOperator *BinOp = cast<BinaryOperator>(Ops.E);
+  
+  if (BinOp->getLHS()->getType()->isPointerType() &&
+      BinOp->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");
+    CGF.ErrorUnsupported(BinOp, "VLA pointer subtraction");
   }
 
-  const QualType LHSType = Ops.E->getLHS()->getType();
+  const QualType LHSType = BinOp->getLHS()->getType();
   const QualType LHSElementType = LHSType->getPointeeType();
   if (!isa<llvm::PointerType>(Ops.RHS->getType())) {
     // pointer - int
@@ -1376,9 +1684,8 @@
     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())
+      const llvm::Type *IdxType = CGF.IntPtrTy;
+      if (BinOp->getRHS()->getType()->isSignedIntegerType())
         Idx = Builder.CreateSExt(Idx, IdxType, "idx.ext");
       else
         Idx = Builder.CreateZExt(Idx, IdxType, "idx.ext");
@@ -1386,8 +1693,7 @@
     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)) {
+    if (const ObjCObjectType *OIT = LHSElementType->getAs<ObjCObjectType>()) {
       llvm::Value *InterfaceSize =
         llvm::ConstantInt::get(Idx->getType(),
                                CGF.getContext().
@@ -1480,7 +1786,7 @@
     CGF.EmitBlock(Cont);
   }
 
-  if (Ops.Ty->isUnsignedIntegerType())
+  if (Ops.Ty->hasUnsignedIntegerRepresentation())
     return Builder.CreateLShr(Ops.LHS, RHS, "shr");
   return Builder.CreateAShr(Ops.LHS, RHS, "shr");
 }
@@ -1490,33 +1796,13 @@
   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");
-    }
+  if (const MemberPointerType *MPT = LHSTy->getAs<MemberPointerType>()) {
+    assert(E->getOpcode() == BO_EQ ||
+           E->getOpcode() == BO_NE);
+    Value *LHS = CGF.EmitScalarExpr(E->getLHS());
+    Value *RHS = CGF.EmitScalarExpr(E->getRHS());
+    Result = CGF.CGM.getCXXABI().EmitMemberPointerComparison(
+                   CGF, LHS, RHS, MPT, E->getOpcode() == BO_NE);
   } else if (!LHSTy->isAnyComplexType()) {
     Value *LHS = Visit(E->getLHS());
     Value *RHS = Visit(E->getRHS());
@@ -1524,7 +1810,7 @@
     if (LHS->getType()->isFPOrFPVectorTy()) {
       Result = Builder.CreateFCmp((llvm::CmpInst::Predicate)FCmpOpc,
                                   LHS, RHS, "cmp");
-    } else if (LHSTy->isSignedIntegerType()) {
+    } else if (LHSTy->hasSignedIntegerRepresentation()) {
       Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)SICmpOpc,
                                   LHS, RHS, "cmp");
     } else {
@@ -1560,10 +1846,10 @@
                                    LHS.second, RHS.second, "cmp.i");
     }
 
-    if (E->getOpcode() == BinaryOperator::EQ) {
+    if (E->getOpcode() == BO_EQ) {
       Result = Builder.CreateAnd(ResultR, ResultI, "and.ri");
     } else {
-      assert(E->getOpcode() == BinaryOperator::NE &&
+      assert(E->getOpcode() == BO_NE &&
              "Complex comparison other than == or != ?");
       Result = Builder.CreateOr(ResultR, ResultI, "or.ri");
     }
@@ -1584,17 +1870,25 @@
   // 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
+  if (LHS.isBitField())
+    CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, E->getType(),
+                                       &RHS);
+  else
     CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS, E->getType());
+
+  // If the result is clearly ignored, return now.
   if (Ignore)
     return 0;
+
+  // Objective-C property assignment never reloads the value following a store.
+  if (LHS.isPropertyRef() || LHS.isKVCRef())
+    return RHS;
+
+  // If the lvalue is non-volatile, return the computed value of the assignment.
+  if (!LHS.isVolatileQualified())
+    return RHS;
+
+  // Otherwise, reload the value.
   return EmitLoadOfLValue(LHS, E->getType());
 }
 
@@ -1769,7 +2063,12 @@
     return Builder.CreateSelect(CondV, LHS, RHS, "cond");
   }
 
-
+  if (!E->getLHS() && CGF.getContext().getLangOptions().CPlusPlus) {
+    // Does not support GNU missing condition extension in C++ yet (see #7726)
+    CGF.ErrorUnsupported(E, "conditional operator with missing LHS");
+    return llvm::UndefValue::get(ConvertType(E->getType()));
+  }
+  
   llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
@@ -1894,6 +2193,13 @@
                                                                 DstTy);
 }
 
+
+llvm::Value *CodeGenFunction::
+EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
+                        bool isInc, bool isPre) {
+  return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
+}
+
 LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {
   llvm::Value *V;
   // object->isa or (*object).isa
@@ -1906,33 +2212,31 @@
     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();
+    V = ScalarExprEmitter(*this).EmitLoadOfLValue(
+      MakeAddrLValue(V, E->getType()), 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;
+  return MakeAddrLValue(V, E->getType());
 }
 
 
 LValue CodeGenFunction::EmitCompoundAssignOperatorLValue(
                                             const CompoundAssignOperator *E) {
   ScalarExprEmitter Scalar(*this);
-  Value *BitFieldResult = 0;
+  Value *Result = 0;
   switch (E->getOpcode()) {
 #define COMPOUND_OP(Op)                                                       \
-    case BinaryOperator::Op##Assign:                                          \
+    case BO_##Op##Assign:                                                     \
       return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
-                                             BitFieldResult)
+                                             Result)
   COMPOUND_OP(Mul);
   COMPOUND_OP(Div);
   COMPOUND_OP(Rem);
@@ -1945,28 +2249,28 @@
   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:
+  case BO_PtrMemD:
+  case BO_PtrMemI:
+  case BO_Mul:
+  case BO_Div:
+  case BO_Rem:
+  case BO_Add:
+  case BO_Sub:
+  case BO_Shl:
+  case BO_Shr:
+  case BO_LT:
+  case BO_GT:
+  case BO_LE:
+  case BO_GE:
+  case BO_EQ:
+  case BO_NE:
+  case BO_And:
+  case BO_Xor:
+  case BO_Or:
+  case BO_LAnd:
+  case BO_LOr:
+  case BO_Assign:
+  case BO_Comma:
     assert(false && "Not valid compound assignment operators");
     break;
   }
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 1ff30f2..6a6d63d 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -47,7 +47,8 @@
 }
 
 
-RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
+RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,
+                                            ReturnValueSlot Return) {
   // 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.
@@ -55,6 +56,7 @@
   CGObjCRuntime &Runtime = CGM.getObjCRuntime();
   bool isSuperMessage = false;
   bool isClassMessage = false;
+  ObjCInterfaceDecl *OID = 0;
   // Find the receiver
   llvm::Value *Receiver = 0;
   switch (E->getReceiverKind()) {
@@ -63,10 +65,12 @@
     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());
+    const ObjCObjectType *ObjTy
+      = E->getClassReceiver()->getAs<ObjCObjectType>();
+    assert(ObjTy && "Invalid Objective-C class message send");
+    OID = ObjTy->getInterface();
+    assert(OID && "Invalid Objective-C class message send");
+    Receiver = Runtime.GetClass(Builder, OID);
     isClassMessage = true;
     break;
   }
@@ -86,11 +90,14 @@
   CallArgList Args;
   EmitCallArgs(Args, E->getMethodDecl(), E->arg_begin(), E->arg_end());
 
+  QualType ResultType =
+    E->getMethodDecl() ? E->getMethodDecl()->getResultType() : E->getType();
+
   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(),
+    return Runtime.GenerateMessageSendSuper(*this, Return, ResultType,
                                             E->getSelector(),
                                             OMD->getClassInterface(),
                                             isCategoryImpl,
@@ -100,8 +107,9 @@
                                             E->getMethodDecl());
   }
 
-  return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(),
-                                     Receiver, isClassMessage, Args,
+  return Runtime.GenerateMessageSend(*this, Return, ResultType,
+                                     E->getSelector(),
+                                     Receiver, Args, OID,
                                      E->getMethodDecl());
 }
 
@@ -155,9 +163,6 @@
     !(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
@@ -206,8 +211,9 @@
                                            Types.ConvertType(PD->getType())));
     EmitReturnOfRValue(RV, PD->getType());
   } else {
-    LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0);
     if (Ivar->getType()->isAnyComplexType()) {
+      LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 
+                                    Ivar, 0);
       ComplexPairTy Pair = LoadComplexFromAddr(LV.getAddress(),
                                                LV.isVolatileQualified());
       StoreComplexToAddr(Pair, ReturnValue, LV.isVolatileQualified());
@@ -217,6 +223,8 @@
       if ((IsAtomic || (IsStrong = IvarTypeWithAggrGCObjects(Ivar->getType())))
           && CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect
           && CGM.getObjCRuntime().GetCopyStructFunction()) {
+        LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 
+                                      Ivar, 0);
         llvm::Value *GetCopyStructFn =
           CGM.getObjCRuntime().GetCopyStructFunction();
         CodeGenTypes &Types = CGM.getTypes();
@@ -249,9 +257,23 @@
                                        FunctionType::ExtInfo()),
                  GetCopyStructFn, ReturnValueSlot(), Args);
       }
-      else
-        EmitAggregateCopy(ReturnValue, LV.getAddress(), Ivar->getType());
+      else {
+        if (PID->getGetterCXXConstructor()) {
+          ReturnStmt *Stmt = 
+            new (getContext()) ReturnStmt(SourceLocation(), 
+                                          PID->getGetterCXXConstructor(),
+                                          0);
+          EmitReturnStmt(*Stmt);
+        }
+        else {
+          LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 
+                                        Ivar, 0);
+          EmitAggregateCopy(ReturnValue, LV.getAddress(), Ivar->getType());
+        }
+      }
     } else {
+      LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 
+                                    Ivar, 0);
       CodeGenTypes &Types = CGM.getTypes();
       RValue RV = EmitLoadOfLValue(LV, Ivar->getType());
       RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
@@ -272,9 +294,6 @@
   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;
@@ -366,6 +385,10 @@
     EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
                                    FunctionType::ExtInfo()),
              GetCopyStructFn, ReturnValueSlot(), Args);
+  } else if (PID->getSetterCXXAssignment()) {
+    EmitAnyExpr(PID->getSetterCXXAssignment(), (llvm::Value *)0, false, true,
+                false);
+                
   } else {
     // FIXME: Find a clean way to avoid AST node creation.
     SourceLocation Loc = PD->getLocation();
@@ -380,13 +403,14 @@
     // 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,
+      ImplicitCastExpr ArgCasted(ImplicitCastExpr::OnStack,
+                                 Ivar->getType(), CK_BitCast, &Arg,
+                                 VK_RValue);
+      BinaryOperator Assign(&IvarRef, &ArgCasted, BO_Assign,
                             Ivar->getType(), Loc);
       EmitStmt(&Assign);
     } else {
-      BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign,
+      BinaryOperator Assign(&IvarRef, &Arg, BO_Assign,
                             Ivar->getType(), Loc);
       EmitStmt(&Assign);
     }
@@ -395,6 +419,69 @@
   FinishFunction();
 }
 
+void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
+                                                 ObjCMethodDecl *MD,
+                                                 bool ctor) {
+  llvm::SmallVector<CXXBaseOrMemberInitializer *, 8> IvarInitializers;
+  MD->createImplicitParams(CGM.getContext(), IMP->getClassInterface());
+  StartObjCMethod(MD, IMP->getClassInterface());
+  for (ObjCImplementationDecl::init_const_iterator B = IMP->init_begin(),
+       E = IMP->init_end(); B != E; ++B) {
+    CXXBaseOrMemberInitializer *Member = (*B);
+    IvarInitializers.push_back(Member);
+  }
+  if (ctor) {
+    for (unsigned I = 0, E = IvarInitializers.size(); I != E; ++I) {
+      CXXBaseOrMemberInitializer *IvarInit = IvarInitializers[I];
+      FieldDecl *Field = IvarInit->getMember();
+      QualType FieldType = Field->getType();
+      ObjCIvarDecl  *Ivar = cast<ObjCIvarDecl>(Field);
+      LValue LV = EmitLValueForIvar(TypeOfSelfObject(), 
+                                    LoadObjCSelf(), Ivar, 0);
+      EmitAggExpr(IvarInit->getInit(), LV.getAddress(),
+                  LV.isVolatileQualified(), false, true);
+    }
+    // constructor returns 'self'.
+    CodeGenTypes &Types = CGM.getTypes();
+    QualType IdTy(CGM.getContext().getObjCIdType());
+    llvm::Value *SelfAsId =
+      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
+    EmitReturnOfRValue(RValue::get(SelfAsId), IdTy);
+  } else {
+    // dtor
+    for (size_t i = IvarInitializers.size(); i > 0; --i) {
+      FieldDecl *Field = IvarInitializers[i - 1]->getMember();
+      QualType FieldType = Field->getType();
+      const ConstantArrayType *Array = 
+        getContext().getAsConstantArrayType(FieldType);
+      if (Array)
+        FieldType = getContext().getBaseElementType(FieldType);
+      
+      ObjCIvarDecl  *Ivar = cast<ObjCIvarDecl>(Field);
+      LValue LV = EmitLValueForIvar(TypeOfSelfObject(), 
+                                    LoadObjCSelf(), Ivar, 0);
+      const RecordType *RT = FieldType->getAs<RecordType>();
+      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+      CXXDestructorDecl *Dtor = FieldClassDecl->getDestructor();
+      if (!Dtor->isTrivial()) {
+        if (Array) {
+          const llvm::Type *BasePtr = ConvertType(FieldType);
+          BasePtr = llvm::PointerType::getUnqual(BasePtr);
+          llvm::Value *BaseAddrPtr =
+            Builder.CreateBitCast(LV.getAddress(), BasePtr);
+          EmitCXXAggrDestructorCall(Dtor,
+                                    Array, BaseAddrPtr);
+        } else {
+          EmitCXXDestructorCall(Dtor,
+                                Dtor_Complete, /*ForVirtualBase=*/false,
+                                LV.getAddress());
+        }
+      }
+    }
+  }
+  FinishFunction();
+}
+
 bool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
   CGFunctionInfo::const_arg_iterator it = FI.arg_begin();
   it++; it++;
@@ -413,8 +500,6 @@
 
 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");
 }
 
@@ -427,12 +512,14 @@
 }
 
 RValue CodeGenFunction::EmitObjCSuperPropertyGet(const Expr *Exp,
-                                                 const Selector &S) {
+                                                 const Selector &S,
+                                                 ReturnValueSlot Return) {
   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,
+                                                       Return,
                                                        Exp->getType(),
                                                        S,
                                                        OMD->getClassInterface(),
@@ -443,17 +530,18 @@
 
 }
 
-RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
+RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp,
+                                            ReturnValueSlot Return) {
   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 EmitObjCSuperPropertyGet(E, S, Return);
     return CGM.getObjCRuntime().
-             GenerateMessageSend(*this, Exp->getType(), S,
+             GenerateMessageSend(*this, Return, Exp->getType(), S,
                                  EmitScalarExpr(E->getBase()),
-                                 false, CallArgList());
+                                 CallArgList());
   } else {
     const ObjCImplicitSetterGetterRefExpr *KE =
       cast<ObjCImplicitSetterGetterRefExpr>(Exp);
@@ -463,13 +551,13 @@
       const ObjCInterfaceDecl *OID = KE->getInterfaceDecl();
       Receiver = CGM.getObjCRuntime().GetClass(Builder, OID);
     } else if (isa<ObjCSuperExpr>(KE->getBase()))
-      return EmitObjCSuperPropertyGet(KE, S);
+      return EmitObjCSuperPropertyGet(KE, S, Return);
     else
       Receiver = EmitScalarExpr(KE->getBase());
     return CGM.getObjCRuntime().
-             GenerateMessageSend(*this, Exp->getType(), S,
+             GenerateMessageSend(*this, Return, Exp->getType(), S,
                                  Receiver,
-                                 KE->getInterfaceDecl() != 0, CallArgList());
+                                 CallArgList(), KE->getInterfaceDecl());
   }
 }
 
@@ -483,7 +571,8 @@
   bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
   Args.push_back(std::make_pair(Src, Exp->getType()));
   CGM.getObjCRuntime().GenerateMessageSendSuper(*this,
-                                                Exp->getType(),
+                                                ReturnValueSlot(),
+                                                getContext().VoidTy,
                                                 S,
                                                 OMD->getClassInterface(),
                                                 isCategoryImpl,
@@ -504,12 +593,14 @@
     }
     CallArgList Args;
     Args.push_back(std::make_pair(Src, E->getType()));
-    CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
+    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
+                                             getContext().VoidTy, S,
                                              EmitScalarExpr(E->getBase()),
-                                             false, Args);
+                                             Args);
   } else if (const ObjCImplicitSetterGetterRefExpr *E =
                dyn_cast<ObjCImplicitSetterGetterRefExpr>(Exp)) {
-    Selector S = E->getSetterMethod()->getSelector();
+    const ObjCMethodDecl *SetterMD = E->getSetterMethod();
+    Selector S = SetterMD->getSelector();
     CallArgList Args;
     llvm::Value *Receiver;
     if (E->getInterfaceDecl()) {
@@ -520,10 +611,12 @@
       return;
     } else
       Receiver = EmitScalarExpr(E->getBase());
-    Args.push_back(std::make_pair(Src, E->getType()));
-    CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
+    ObjCMethodDecl::param_iterator P = SetterMD->param_begin(); 
+    Args.push_back(std::make_pair(Src, (*P)->getType()));
+    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
+                                             getContext().VoidTy, S,
                                              Receiver,
-                                             E->getInterfaceDecl() != 0, Args);
+                                             Args, E->getInterfaceDecl());
   } else
     assert (0 && "bad expression node in EmitObjCPropertySet");
 }
@@ -553,7 +646,7 @@
   // Fast enumeration state.
   QualType StateTy = getContext().getObjCFastEnumerationStateType();
   llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr");
-  EmitMemSetToZero(StatePtr, StateTy);
+  EmitNullInitialization(StatePtr, StateTy);
 
   // Number of elements in the items array.
   static const unsigned NumItems = 16;
@@ -588,10 +681,10 @@
                                 getContext().UnsignedLongTy));
 
   RValue CountRV =
-    CGM.getObjCRuntime().GenerateMessageSend(*this,
+    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
                                              getContext().UnsignedLongTy,
                                              FastEnumSel,
-                                             Collection, false, Args);
+                                             Collection, Args);
 
   llvm::Value *LimitPtr = CreateMemTemp(getContext().UnsignedLongTy,
                                         "limit.ptr");
@@ -691,8 +784,8 @@
                               llvm::ConstantInt::get(UnsignedLongLTy, 1));
   Builder.CreateStore(Counter, CounterPtr);
 
-  llvm::BasicBlock *LoopEnd = createBasicBlock("loopend");
-  llvm::BasicBlock *AfterBody = createBasicBlock("afterbody");
+  JumpDest LoopEnd = getJumpDestInCurrentScope("loopend");
+  JumpDest AfterBody = getJumpDestInCurrentScope("afterbody");
 
   BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
 
@@ -700,7 +793,7 @@
 
   BreakContinueStack.pop_back();
 
-  EmitBlock(AfterBody);
+  EmitBlock(AfterBody.getBlock());
 
   llvm::BasicBlock *FetchMore = createBasicBlock("fetchmore");
 
@@ -713,10 +806,10 @@
   EmitBlock(FetchMore);
 
   CountRV =
-    CGM.getObjCRuntime().GenerateMessageSend(*this,
+    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
                                              getContext().UnsignedLongTy,
                                              FastEnumSel,
-                                             Collection, false, Args);
+                                             Collection, Args);
   Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
   Limit = Builder.CreateLoad(LimitPtr);
 
@@ -736,11 +829,11 @@
                         LV.getAddress());
   }
 
-  EmitBlock(LoopEnd);
+  EmitBlock(LoopEnd.getBlock());
 }
 
 void CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) {
-  CGM.getObjCRuntime().EmitTryOrSynchronizedStmt(*this, S);
+  CGM.getObjCRuntime().EmitTryStmt(*this, S);
 }
 
 void CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) {
@@ -749,7 +842,9 @@
 
 void CodeGenFunction::EmitObjCAtSynchronizedStmt(
                                               const ObjCAtSynchronizedStmt &S) {
-  CGM.getObjCRuntime().EmitTryOrSynchronizedStmt(*this, S);
+  CGM.getObjCRuntime().EmitSynchronizedStmt(*this, S);
 }
 
 CGObjCRuntime::~CGObjCRuntime() {}
+
+
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index e8ade2a..d7960be 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -17,6 +17,7 @@
 #include "CGObjCRuntime.h"
 #include "CodeGenModule.h"
 #include "CodeGenFunction.h"
+#include "CGException.h"
 
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
@@ -26,6 +27,7 @@
 
 #include "llvm/Intrinsics.h"
 #include "llvm/Module.h"
+#include "llvm/LLVMContext.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/Compiler.h"
@@ -81,6 +83,8 @@
   llvm::Constant *Zeros[2];
   llvm::Constant *NULLPtr;
   llvm::LLVMContext &VMContext;
+  /// Metadata kind used to tie method lookups to message sends.
+  unsigned msgSendMDKind;
 private:
   llvm::Constant *GenerateIvarList(
       const llvm::SmallVectorImpl<llvm::Constant *>  &IvarNames,
@@ -112,7 +116,8 @@
       llvm::Constant *Methods,
       llvm::Constant *Protocols,
       llvm::Constant *IvarOffsets,
-      llvm::Constant *Properties);
+      llvm::Constant *Properties,
+      bool isMeta=false);
   llvm::Constant *GenerateProtocolMethodList(
       const llvm::SmallVectorImpl<llvm::Constant *>  &MethodNames,
       const llvm::SmallVectorImpl<llvm::Constant *>  &MethodTypes);
@@ -138,14 +143,16 @@
   virtual llvm::Constant *GenerateConstantString(const StringLiteral *);
   virtual CodeGen::RValue
   GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                      ReturnValueSlot Return,
                       QualType ResultType,
                       Selector Sel,
                       llvm::Value *Receiver,
-                      bool IsClassMessage,
                       const CallArgList &CallArgs,
+                      const ObjCInterfaceDecl *Class,
                       const ObjCMethodDecl *Method);
   virtual CodeGen::RValue
   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                           ReturnValueSlot Return,
                            QualType ResultType,
                            Selector Sel,
                            const ObjCInterfaceDecl *Class,
@@ -156,9 +163,11 @@
                            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, Selector Sel,
+                                   bool lval = false);
   virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
       *Method);
+  virtual llvm::Constant *GetEHType(QualType T);
 
   virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
                                          const ObjCContainerDecl *CD);
@@ -173,8 +182,10 @@
   virtual llvm::Function *GetCopyStructFunction();
   virtual llvm::Constant *EnumerationMutationFunction();
 
-  virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
-                                         const Stmt &S);
+  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
+                           const ObjCAtTryStmt &S);
+  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                    const ObjCAtSynchronizedStmt &S);
   virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
                              const ObjCAtThrowStmt &S);
   virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
@@ -182,7 +193,8 @@
   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
                                   llvm::Value *src, llvm::Value *dst);
   virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
-                                    llvm::Value *src, llvm::Value *dest);
+                                    llvm::Value *src, llvm::Value *dest,
+                                    bool threadlocal=false);
   virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
                                     llvm::Value *src, llvm::Value *dest,
                                     llvm::Value *ivarOffset);
@@ -191,7 +203,7 @@
   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
                                         llvm::Value *DestPtr,
                                         llvm::Value *SrcPtr,
-                                        QualType Ty);
+                                        llvm::Value *Size);
   virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
                                       QualType ObjectTy,
                                       llvm::Value *BaseValue,
@@ -200,6 +212,10 @@
   virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
                                       const ObjCInterfaceDecl *Interface,
                                       const ObjCIvarDecl *Ivar);
+  virtual llvm::Constant *GCBlockLayout(CodeGen::CodeGenFunction &CGF,
+              const llvm::SmallVectorImpl<const BlockDeclRefExpr *> &) {
+    return NULLPtr;
+  }
 };
 } // end anonymous namespace
 
@@ -222,10 +238,6 @@
     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)
 {
@@ -235,10 +247,28 @@
   return std::string(isClassMethod ? "_c_" : "_i_") + ClassName + "_" +
     CategoryName + "_" + MethodNameColonStripped;
 }
+static std::string MangleSelectorTypes(const std::string &TypeString) {
+  std::string Mangled = TypeString;
+  // Simple mangling to avoid breaking when we mix JIT / static code.
+  // Not part of the ABI, subject to change without notice.
+  std::replace(Mangled.begin(), Mangled.end(), '@', '_');
+  std::replace(Mangled.begin(), Mangled.end(), ':', 'J');
+  std::replace(Mangled.begin(), Mangled.end(), '*', 'e');
+  std::replace(Mangled.begin(), Mangled.end(), '#', 'E');
+  std::replace(Mangled.begin(), Mangled.end(), ':', 'j');
+  std::replace(Mangled.begin(), Mangled.end(), '(', 'g');
+  std::replace(Mangled.begin(), Mangled.end(), ')', 'G');
+  std::replace(Mangled.begin(), Mangled.end(), '[', 'h');
+  std::replace(Mangled.begin(), Mangled.end(), ']', 'H');
+  return Mangled;
+}
 
 CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm)
   : CGM(cgm), TheModule(CGM.getModule()), ClassPtrAlias(0),
     MetaClassPtrAlias(0), VMContext(cgm.getLLVMContext()) {
+
+  msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend");
+
   IntTy = cast<llvm::IntegerType>(
       CGM.getTypes().ConvertType(CGM.getContext().IntTy));
   LongTy = cast<llvm::IntegerType>(
@@ -340,14 +370,16 @@
   return Builder.CreateCall(ClassLookupFn, ClassName);
 }
 
-llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) {
+llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel,
+                                    bool lval) {
   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);
-
+  if (lval)
+    return US;
   return Builder.CreateLoad(US);
 }
 
@@ -376,6 +408,11 @@
   return Builder.CreateLoad(Sel);
 }
 
+llvm::Constant *CGObjCGNU::GetEHType(QualType T) {
+  llvm_unreachable("asking for catch type for ObjC type in GNU runtime");
+  return 0;
+}
+
 llvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str,
                                               const std::string &Name) {
   llvm::Constant *ConstStr = CGM.GetAddrOfConstantCString(Str, Name.c_str());
@@ -412,7 +449,7 @@
 /// Generate an NSConstantString object.
 llvm::Constant *CGObjCGNU::GenerateConstantString(const StringLiteral *SL) {
 
-  std::string Str(SL->getStrData(), SL->getByteLength());
+  std::string Str = SL->getString().str();
 
   // Look for an existing one
   llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
@@ -437,6 +474,7 @@
 ///should be called.
 CodeGen::RValue
 CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                                    ReturnValueSlot Return,
                                     QualType ResultType,
                                     Selector Sel,
                                     const ObjCInterfaceDecl *Class,
@@ -453,12 +491,15 @@
       return RValue::get(0);
     }
   }
-  llvm::Value *cmd = GetSelector(CGF.Builder, Sel);
+
+  CGBuilderTy &Builder = CGF.Builder;
+  llvm::Value *cmd = GetSelector(Builder, Sel);
+
 
   CallArgList ActualArgs;
 
   ActualArgs.push_back(
-      std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)),
+      std::make_pair(RValue::get(Builder.CreateBitCast(Receiver, IdTy)),
       ASTIdTy));
   ActualArgs.push_back(std::make_pair(RValue::get(cmd),
                                       CGF.getContext().getObjCSelType()));
@@ -482,7 +523,7 @@
       classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
             IdTy, Params, true), "objc_get_class");
     }
-    ReceiverClass = CGF.Builder.CreateCall(classLookupFunction,
+    ReceiverClass = Builder.CreateCall(classLookupFunction,
         MakeConstantString(Class->getNameAsString()));
   } else {
     // Set up global aliases for the metaclass or class pointer if they do not
@@ -507,47 +548,77 @@
     }
   }
   // Cast the pointer to a simplified version of the class structure
-  ReceiverClass = CGF.Builder.CreateBitCast(ReceiverClass,
+  ReceiverClass = Builder.CreateBitCast(ReceiverClass,
       llvm::PointerType::getUnqual(
         llvm::StructType::get(VMContext, IdTy, IdTy, NULL)));
   // Get the superclass pointer
-  ReceiverClass = CGF.Builder.CreateStructGEP(ReceiverClass, 1);
+  ReceiverClass = Builder.CreateStructGEP(ReceiverClass, 1);
   // Load the superclass pointer
-  ReceiverClass = CGF.Builder.CreateLoad(ReceiverClass);
+  ReceiverClass = 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);
+  llvm::Value *ObjCSuper = Builder.CreateAlloca(ObjCSuperTy);
 
-  CGF.Builder.CreateStore(Receiver, CGF.Builder.CreateStructGEP(ObjCSuper, 0));
-  CGF.Builder.CreateStore(ReceiverClass,
-      CGF.Builder.CreateStructGEP(ObjCSuper, 1));
+  Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
+  Builder.CreateStore(ReceiverClass, 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::Value *lookupArgs[] = {ObjCSuper, cmd};
+  llvm::Value *imp;
+
+  if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
+    // 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_slot_lookup_super");
+
+    llvm::CallInst *slot = Builder.CreateCall(lookupFunction, lookupArgs,
+        lookupArgs+2);
+    slot->setOnlyReadsMemory();
+
+    imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4));
+  } else {
   llvm::Constant *lookupFunction =
     CGM.CreateRuntimeFunction(llvm::FunctionType::get(
           llvm::PointerType::getUnqual(impType), Params, true),
         "objc_msg_lookup_super");
+    imp = Builder.CreateCall(lookupFunction, lookupArgs, lookupArgs+2);
+  }
 
-  llvm::Value *lookupArgs[] = {ObjCSuper, cmd};
-  llvm::Value *imp = CGF.Builder.CreateCall(lookupFunction, lookupArgs,
-      lookupArgs+2);
+  llvm::Value *impMD[] = {
+      llvm::MDString::get(VMContext, Sel.getAsString()),
+      llvm::MDString::get(VMContext, Class->getSuperClass()->getNameAsString()),
+      llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsClassMessage)
+   };
+  llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD, 3);
 
-  return CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs);
+  llvm::Instruction *call;
+  RValue msgRet = CGF.EmitCall(FnInfo, imp, Return, ActualArgs,
+      0, &call);
+  call->setMetadata(msgSendMDKind, node);
+  return msgRet;
 }
 
 /// Generate code for a message send expression.
 CodeGen::RValue
 CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                               ReturnValueSlot Return,
                                QualType ResultType,
                                Selector Sel,
                                llvm::Value *Receiver,
-                               bool IsClassMessage,
                                const CallArgList &CallArgs,
+                               const ObjCInterfaceDecl *Class,
                                const ObjCMethodDecl *Method) {
+  // Strip out message sends to retain / release in GC mode
   if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
     if (Sel == RetainSel || Sel == AutoreleaseSel) {
       return RValue::get(Receiver);
@@ -556,7 +627,39 @@
       return RValue::get(0);
     }
   }
+
   CGBuilderTy &Builder = CGF.Builder;
+
+  // If the return type is something that goes in an integer register, the
+  // runtime will handle 0 returns.  For other cases, we fill in the 0 value
+  // ourselves.
+  //
+  // The language spec says the result of this kind of message send is
+  // undefined, but lots of people seem to have forgotten to read that
+  // paragraph and insist on sending messages to nil that have structure
+  // returns.  With GCC, this generates a random return value (whatever happens
+  // to be on the stack / in those registers at the time) on most platforms,
+  // and generates a SegV on SPARC.  With LLVM it corrupts the stack.  
+  bool isPointerSizedReturn = false;
+  if (ResultType->isAnyPointerType() || 
+      ResultType->isIntegralOrEnumerationType() || ResultType->isVoidType())
+    isPointerSizedReturn = true;
+
+  llvm::BasicBlock *startBB = 0;
+  llvm::BasicBlock *messageBB = 0;
+  llvm::BasicBlock *continueBB = 0;
+
+  if (!isPointerSizedReturn) {
+    startBB = Builder.GetInsertBlock();
+    messageBB = CGF.createBasicBlock("msgSend");
+    continueBB = CGF.createBasicBlock("continue");
+
+    llvm::Value *isNil = Builder.CreateICmpEQ(Receiver, 
+            llvm::Constant::getNullValue(Receiver->getType()));
+    Builder.CreateCondBr(isNil, continueBB, messageBB);
+    CGF.EmitBlock(messageBB);
+  }
+
   IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
   llvm::Value *cmd;
   if (Method)
@@ -578,6 +681,14 @@
   const llvm::FunctionType *impType =
     Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
 
+  llvm::Value *impMD[] = {
+        llvm::MDString::get(VMContext, Sel.getAsString()),
+        llvm::MDString::get(VMContext, Class ? Class->getNameAsString() :""),
+        llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), Class!=0)
+   };
+  llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD, 3);
+
+
   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.
@@ -591,7 +702,7 @@
     Params.push_back(SelectorTy);
     llvm::Value *self;
 
-    if (isa<ObjCMethodDecl>(CGF.CurFuncDecl)) {
+    if (isa<ObjCMethodDecl>(CGF.CurCodeDecl)) {
       self = CGF.LoadObjCSelf();
     } else {
       self = llvm::ConstantPointerNull::get(IdTy);
@@ -612,13 +723,17 @@
       LookupFn->setDoesNotCapture(1);
     }
 
-    llvm::Value *slot =
+    llvm::CallInst *slot =
         Builder.CreateCall3(lookupFunction, ReceiverPtr, cmd, self);
+    slot->setOnlyReadsMemory();
+    slot->setMetadata(msgSendMDKind, node);
+
     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);
+    ActualArgs[0] = std::make_pair(RValue::get(
+        Builder.CreateLoad(ReceiverPtr, true)), ASTIdTy);
   } else {
     std::vector<const llvm::Type*> Params;
     Params.push_back(Receiver->getType());
@@ -629,9 +744,49 @@
       "objc_msg_lookup");
 
     imp = Builder.CreateCall2(lookupFunction, Receiver, cmd);
+    cast<llvm::CallInst>(imp)->setMetadata(msgSendMDKind, node);
   }
+  llvm::Instruction *call;
+  RValue msgRet = CGF.EmitCall(FnInfo, imp, Return, ActualArgs,
+      0, &call);
+  call->setMetadata(msgSendMDKind, node);
 
-  return CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs);
+
+  if (!isPointerSizedReturn) {
+    messageBB = CGF.Builder.GetInsertBlock();
+    CGF.Builder.CreateBr(continueBB);
+    CGF.EmitBlock(continueBB);
+    if (msgRet.isScalar()) {
+      llvm::Value *v = msgRet.getScalarVal();
+      llvm::PHINode *phi = Builder.CreatePHI(v->getType());
+      phi->addIncoming(v, messageBB);
+      phi->addIncoming(llvm::Constant::getNullValue(v->getType()), startBB);
+      msgRet = RValue::get(phi);
+    } else if (msgRet.isAggregate()) {
+      llvm::Value *v = msgRet.getAggregateAddr();
+      llvm::PHINode *phi = Builder.CreatePHI(v->getType());
+      const llvm::PointerType *RetTy = cast<llvm::PointerType>(v->getType());
+      llvm::AllocaInst *NullVal = 
+          CGF.CreateTempAlloca(RetTy->getElementType(), "null");
+      CGF.InitTempAlloca(NullVal,
+          llvm::Constant::getNullValue(RetTy->getElementType()));
+      phi->addIncoming(v, messageBB);
+      phi->addIncoming(NullVal, startBB);
+      msgRet = RValue::getAggregate(phi);
+    } else /* isComplex() */ {
+      std::pair<llvm::Value*,llvm::Value*> v = msgRet.getComplexVal();
+      llvm::PHINode *phi = Builder.CreatePHI(v.first->getType());
+      phi->addIncoming(v.first, messageBB);
+      phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
+          startBB);
+      llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType());
+      phi2->addIncoming(v.second, messageBB);
+      phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
+          startBB);
+      msgRet = RValue::getComplex(phi, phi2);
+    }
+  }
+  return msgRet;
 }
 
 /// Generates a MethodList.  Used in construction of a objc_class and
@@ -750,7 +905,8 @@
     llvm::Constant *Methods,
     llvm::Constant *Protocols,
     llvm::Constant *IvarOffsets,
-    llvm::Constant *Properties) {
+    llvm::Constant *Properties,
+    bool isMeta) {
   // 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.
@@ -800,8 +956,8 @@
   // 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);
+  return MakeGlobal(ClassTy, Elements, (isMeta ? "_OBJC_METACLASS_":
+      "_OBJC_CLASS_") + std::string(Name), llvm::GlobalValue::ExternalLinkage);
 }
 
 llvm::Constant *CGObjCGNU::GenerateProtocolMethodList(
@@ -1417,7 +1573,7 @@
   //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);
+        empty, empty, empty), ClassMethodList, NULLPtr, NULLPtr, NULLPtr, true);
 
   // Generate the class structure
   llvm::Constant *ClassStruct =
@@ -1548,34 +1704,36 @@
     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");
+      true, llvm::GlobalValue::LinkOnceODRLinkage,
+      llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2),
+      MangleSelectorTypes(".objc_sel_ptr"+iter->first.first+"."+
+         iter->first.second));
     // 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);
+    (*iter).second->replaceAllUsesWith(SelPtr);
+    (*iter).second->eraseFromParent();
   }
   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");
+    llvm::Constant *SelPtr = new llvm::GlobalVariable(TheModule, SelStructPtrTy,
+      true, llvm::GlobalValue::LinkOnceODRLinkage,
+      llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2),
+      MangleSelectorTypes(std::string(".objc_sel_ptr")+iter->getKey().str()));
     // 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);
+    (*iter).second->replaceAllUsesWith(SelPtr);
+    (*iter).second->eraseFromParent();
   }
   // Number of classes defined.
   Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
@@ -1707,245 +1865,173 @@
   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");
+namespace {
+  struct CallSyncExit : EHScopeStack::Cleanup {
+    llvm::Value *SyncExitFn;
+    llvm::Value *SyncArg;
+    CallSyncExit(llvm::Value *SyncExitFn, llvm::Value *SyncArg)
+      : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
 
-  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");
+    void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
+      CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
+    }
+  };
+}
 
-  // @synchronized()
-  if (!isTry) {
+void CGObjCGNU::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                     const ObjCAtSynchronizedStmt &S) {
+  std::vector<const llvm::Type*> Args(1, IdTy);
+  llvm::FunctionType *FTy =
+    llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
+
+  // Evaluate the lock operand.  This should dominate the cleanup.
+  llvm::Value *SyncArg =
+    CGF.EmitScalarExpr(S.getSynchExpr());
+
+  // Acquire the lock.
+  llvm::Value *SyncEnter = CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
+  SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy);
+  CGF.Builder.CreateCall(SyncEnter, SyncArg);
+
+  // Register an all-paths cleanup to release the lock.
+  llvm::Value *SyncExit = CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
+  CGF.EHStack.pushCleanup<CallSyncExit>(NormalAndEHCleanup, SyncExit, SyncArg);
+
+  // Emit the body of the statement.
+  CGF.EmitStmt(S.getSynchBody());
+
+  // Pop the lock-release cleanup.
+  CGF.PopCleanupBlock();
+}
+
+namespace {
+  struct CatchHandler {
+    const VarDecl *Variable;
+    const Stmt *Body;
+    llvm::BasicBlock *Block;
+    llvm::Value *TypeInfo;
+  };
+}
+
+void CGObjCGNU::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
+                            const ObjCAtTryStmt &S) {
+  // Unlike the Apple non-fragile runtimes, which also uses
+  // unwind-based zero cost exceptions, the GNU Objective C runtime's
+  // EH support isn't a veneer over C++ EH.  Instead, exception
+  // objects are created by __objc_exception_throw and destroyed by
+  // the personality function; this avoids the need for bracketing
+  // catch handlers with calls to __blah_begin_catch/__blah_end_catch
+  // (or even _Unwind_DeleteException), but probably doesn't
+  // interoperate very well with foreign exceptions.
+
+  // Jump destination for falling out of catch bodies.
+  CodeGenFunction::JumpDest Cont;
+  if (S.getNumCatchStmts())
+    Cont = CGF.getJumpDestInCurrentScope("eh.cont");
+
+  // We handle @finally statements by pushing them as a cleanup
+  // before entering the catch.
+  CodeGenFunction::FinallyInfo FinallyInfo;
+  if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt()) {
     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);
+    llvm::Constant *Rethrow =
+      CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
+
+    FinallyInfo = CGF.EnterFinallyBlock(Finally->getFinallyBody(), 0, 0,
+                                        Rethrow);
   }
 
+  llvm::SmallVector<CatchHandler, 8> Handlers;
 
-  // Push an EH context entry, used for handling rethrows and jumps
-  // through finally.
-  CGF.PushCleanupBlock(FinallyBlock);
+  // Enter the catch, if there is one.
+  if (S.getNumCatchStmts()) {
+    for (unsigned I = 0, N = S.getNumCatchStmts(); I != N; ++I) {
+      const ObjCAtCatchStmt *CatchStmt = S.getCatchStmt(I);
+      const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl();
 
-  // Emit the statements in the @try {} block
-  CGF.setInvokeDest(TryHandler);
+      Handlers.push_back(CatchHandler());
+      CatchHandler &Handler = Handlers.back();
+      Handler.Variable = CatchDecl;
+      Handler.Body = CatchStmt->getCatchBody();
+      Handler.Block = CGF.createBasicBlock("catch");
 
-  CGF.EmitBlock(TryBlock);
-  CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
-                     : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
+      // @catch() and @catch(id) both catch any ObjC exception.
+      // Treat them as catch-alls.
+      // FIXME: this is what this code was doing before, but should 'id'
+      // really be catching foreign exceptions?
+      if (!CatchDecl
+          || CatchDecl->getType()->isObjCIdType()
+          || CatchDecl->getType()->isObjCQualifiedIdType()) {
 
-  // Jump to @finally if there is no exception
-  CGF.EmitBranchThroughCleanup(FinallyEnd);
+        Handler.TypeInfo = 0; // catch-all
 
-  // 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));
+        // Don't consider any other catches.
+        break;
       }
 
-      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);
+      // All other types should be Objective-C interface pointer types.
+      const ObjCObjectPointerType *OPT =
+        CatchDecl->getType()->getAs<ObjCObjectPointerType>();
+      assert(OPT && "Invalid @catch type.");
+      const ObjCInterfaceDecl *IDecl =
+        OPT->getObjectType()->getInterface();
+      assert(IDecl && "Invalid @catch type.");
+      Handler.TypeInfo = MakeConstantString(IDecl->getNameAsString());
     }
+
+    EHCatchScope *Catch = CGF.EHStack.pushCatch(Handlers.size());
+    for (unsigned I = 0, E = Handlers.size(); I != E; ++I)
+      Catch->setHandler(I, Handlers[I].TypeInfo, Handlers[I].Block);
   }
-  // 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));
+  
+  // Emit the try body.
+  CGF.EmitStmt(S.getTryBody());
+
+  // Leave the try.
+  if (S.getNumCatchStmts())
+    CGF.EHStack.popCatch();
+
+  // Remember where we were.
+  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
+
+  // Emit the handlers.
+  for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
+    CatchHandler &Handler = Handlers[I];
+    CGF.EmitBlock(Handler.Block);
+
+    llvm::Value *Exn = CGF.Builder.CreateLoad(CGF.getExceptionSlot());
+
+    // Bind the catch parameter if it exists.
+    if (const VarDecl *CatchParam = Handler.Variable) {
+      const llvm::Type *CatchType = CGF.ConvertType(CatchParam->getType());
+      Exn = CGF.Builder.CreateBitCast(Exn, CatchType);
+
+      CGF.EmitLocalBlockVarDecl(*CatchParam);
+      CGF.Builder.CreateStore(Exn, CGF.GetAddrOfLocalVar(CatchParam));
+    }
+
+    CGF.ObjCEHValueStack.push_back(Exn);
+    CGF.EmitStmt(Handler.Body);
+    CGF.ObjCEHValueStack.pop_back();
+
+    CGF.EmitBranchThroughCleanup(Cont);
+  }  
+
+  // Go back to the try-statement fallthrough.
+  CGF.Builder.restoreIP(SavedIP);
+
+  // Pop out of the finally.
+  if (S.getFinallyStmt())
+    CGF.ExitFinallyBlock(FinallyInfo);
+
+  if (Cont.isValid()) {
+    if (Cont.getBlock()->use_empty())
+      delete Cont.getBlock();
+    else
+      CGF.EmitBlock(Cont.getBlock());
   }
-  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,
@@ -2006,11 +2092,16 @@
 }
 
 void CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
-                                     llvm::Value *src, llvm::Value *dst) {
+                                     llvm::Value *src, llvm::Value *dst,
+                                     bool threadlocal) {
   CGBuilderTy B = CGF.Builder;
   src = EnforceType(B, src, IdTy);
   dst = EnforceType(B, dst, PtrToIdTy);
-  B.CreateCall2(GlobalAssignFn, src, dst);
+  if (!threadlocal)
+    B.CreateCall2(GlobalAssignFn, src, dst);
+  else
+    // FIXME. Add threadloca assign API
+    assert(false && "EmitObjCGlobalAssign - Threal Local API NYI");
 }
 
 void CGObjCGNU::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
@@ -2033,17 +2124,12 @@
 void CGObjCGNU::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
                                          llvm::Value *DestPtr,
                                          llvm::Value *SrcPtr,
-                                         QualType Ty) {
+                                         llvm::Value *Size) {
   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);
+  B.CreateCall3(MemMoveFn, DestPtr, SrcPtr, Size);
 }
 
 llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
@@ -2091,7 +2177,8 @@
                                        llvm::Value *BaseValue,
                                        const ObjCIvarDecl *Ivar,
                                        unsigned CVRQualifiers) {
-  const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl();
+  const ObjCInterfaceDecl *ID =
+    ObjectTy->getAs<ObjCObjectType>()->getInterface();
   return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
                                   EmitIvarOffset(CGF, ID, Ivar));
 }
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 3905bd4..f4ff951 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -16,21 +16,24 @@
 #include "CGRecordLayout.h"
 #include "CodeGenModule.h"
 #include "CodeGenFunction.h"
+#include "CGException.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 "clang/Frontend/CodeGenOptions.h"
 
-#include "llvm/Intrinsics.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/IntrinsicInst.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/CallSite.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetData.h"
 #include <cstdio>
@@ -104,11 +107,11 @@
   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);
+  if (!Ivar->isBitField()) {
+    LValue LV = CGF.MakeAddrLValue(V, IvarTy);
+    LV.getQuals().addCVRQualifiers(CVRQualifiers);
+    return LV;
+  }
 
   // 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
@@ -141,7 +144,8 @@
 
   // 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());
+  return LValue::MakeBitfield(V, *Info,
+                              IvarTy.getCVRQualifiers() | CVRQualifiers);
 }
 
 ///
@@ -400,6 +404,16 @@
     return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
   }
 
+  /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
+  llvm::Constant *getGcAssignThreadLocalFn() {
+    // id objc_assign_threadlocal(id src, id * dest)
+    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_threadlocal");
+  }
+  
   /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
   llvm::Constant *getGcAssignIvarFn() {
     // id objc_assign_ivar(id, id *, ptrdiff_t)
@@ -423,7 +437,7 @@
 
   /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
   llvm::Constant *getGcAssignStrongCastFn() {
-    // id objc_assign_global(id, id *)
+    // id objc_assign_strongCast(id, id *)
     std::vector<const llvm::Type*> Args(1, ObjectPtrTy);
     Args.push_back(ObjectPtrTy->getPointerTo());
     llvm::FunctionType *FTy =
@@ -440,6 +454,15 @@
     return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
   }
 
+  /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
+  llvm::Constant *getExceptionRethrowFn() {
+    // void objc_exception_rethrow(void)
+    std::vector<const llvm::Type*> Args;
+    llvm::FunctionType *FTy =
+      llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, true);
+    return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
+  }
+  
   /// SyncEnterFn - LLVM object_sync_enter function.
   llvm::Constant *getSyncEnterFn() {
     // void objc_sync_enter (id)
@@ -708,25 +731,6 @@
                                      "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*, ...)
@@ -749,28 +753,6 @@
                                       "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),
@@ -843,6 +825,9 @@
   /// MethodVarNames - uniqued method variable names.
   llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
 
+  /// DefinedCategoryNames - list of category names in form Class_Category.
+  llvm::SetVector<std::string> DefinedCategoryNames;
+
   /// MethodVarTypes - uniqued method type signatures. We have to use
   /// a StringMap here because have no other unique reference.
   llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
@@ -891,7 +876,6 @@
   /// 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 *.
@@ -912,11 +896,15 @@
   /// name. The return value has type char *.
   llvm::Constant *GetClassName(IdentifierInfo *Ident);
 
+  llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
+
   /// BuildIvarLayout - Builds ivar layout bitmap for the class
   /// implementation for the __strong or __weak case.
   ///
   llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
                                   bool ForStrongLayout);
+  
+  llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap);
 
   void BuildAggrIvarRecordLayout(const RecordType *RT,
                                  unsigned int BytePos, bool ForStrongLayout,
@@ -973,6 +961,7 @@
                                           bool AddToUsed);
 
   CodeGen::RValue EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
+                                        ReturnValueSlot Return,
                                         QualType ResultType,
                                         llvm::Value *Sel,
                                         llvm::Value *Arg0,
@@ -1007,6 +996,9 @@
   /// 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;
+  virtual llvm::Constant *GCBlockLayout(CodeGen::CodeGenFunction &CGF,
+                      const llvm::SmallVectorImpl<const BlockDeclRefExpr *> &);
+  
 };
 
 class CGObjCMac : public CGObjCCommonMac {
@@ -1038,14 +1030,6 @@
   /// 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
@@ -1118,7 +1102,8 @@
 
   /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
   /// for the given selector.
-  llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel);
+  llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel, 
+                            bool lval=false);
 
 public:
   CGObjCMac(CodeGen::CodeGenModule &cgm);
@@ -1126,15 +1111,17 @@
   virtual llvm::Function *ModuleInitFunction();
 
   virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                                              ReturnValueSlot Return,
                                               QualType ResultType,
                                               Selector Sel,
                                               llvm::Value *Receiver,
-                                              bool IsClassMessage,
                                               const CallArgList &CallArgs,
+                                              const ObjCInterfaceDecl *Class,
                                               const ObjCMethodDecl *Method);
 
   virtual CodeGen::RValue
   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                           ReturnValueSlot Return,
                            QualType ResultType,
                            Selector Sel,
                            const ObjCInterfaceDecl *Class,
@@ -1147,13 +1134,16 @@
   virtual llvm::Value *GetClass(CGBuilderTy &Builder,
                                 const ObjCInterfaceDecl *ID);
 
-  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel);
+  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel, 
+                                   bool lval = false);
 
   /// The NeXT/Apple runtimes do not support typed selectors; just emit an
   /// untyped one.
   virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
                                    const ObjCMethodDecl *Method);
 
+  virtual llvm::Constant *GetEHType(QualType T);
+
   virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
 
   virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
@@ -1166,8 +1156,11 @@
   virtual llvm::Constant *GetCopyStructFunction();
   virtual llvm::Constant *EnumerationMutationFunction();
 
-  virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
-                                         const Stmt &S);
+  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
+                           const ObjCAtTryStmt &S);
+  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                    const ObjCAtSynchronizedStmt &S);
+  void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
   virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
                              const ObjCAtThrowStmt &S);
   virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
@@ -1175,7 +1168,8 @@
   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
                                   llvm::Value *src, llvm::Value *dst);
   virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
-                                    llvm::Value *src, llvm::Value *dest);
+                                    llvm::Value *src, llvm::Value *dest,
+                                    bool threadlocal = false);
   virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
                                   llvm::Value *src, llvm::Value *dest,
                                   llvm::Value *ivarOffset);
@@ -1183,7 +1177,7 @@
                                         llvm::Value *src, llvm::Value *dest);
   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
                                         llvm::Value *dest, llvm::Value *src,
-                                        QualType Ty);
+                                        llvm::Value *size);
 
   virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
                                       QualType ObjectTy,
@@ -1279,6 +1273,7 @@
                                    ObjCProtocolDecl::protocol_iterator end);
 
   CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
+                                  ReturnValueSlot Return,
                                   QualType ResultType,
                                   Selector Sel,
                                   llvm::Value *Receiver,
@@ -1314,11 +1309,12 @@
 
   /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
   /// for the given selector.
-  llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel);
+  llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel, 
+                            bool lval=false);
 
   /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
   /// interface. The return value has type EHTypePtrTy.
-  llvm::Value *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
+  llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
                                   bool ForDefinition);
 
   const char *getMetaclassSymbolPrefix() const {
@@ -1354,15 +1350,17 @@
   virtual llvm::Function *ModuleInitFunction();
 
   virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                                              ReturnValueSlot Return,
                                               QualType ResultType,
                                               Selector Sel,
                                               llvm::Value *Receiver,
-                                              bool IsClassMessage,
                                               const CallArgList &CallArgs,
+                                              const ObjCInterfaceDecl *Class,
                                               const ObjCMethodDecl *Method);
 
   virtual CodeGen::RValue
   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                           ReturnValueSlot Return,
                            QualType ResultType,
                            Selector Sel,
                            const ObjCInterfaceDecl *Class,
@@ -1375,8 +1373,9 @@
   virtual llvm::Value *GetClass(CGBuilderTy &Builder,
                                 const ObjCInterfaceDecl *ID);
 
-  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel)
-    { return EmitSelector(Builder, Sel); }
+  virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
+                                   bool lvalue = false)
+    { return EmitSelector(Builder, Sel, lvalue); }
 
   /// The NeXT/Apple runtimes do not support typed selectors; just emit an
   /// untyped one.
@@ -1390,6 +1389,8 @@
   virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
                                            const ObjCProtocolDecl *PD);
 
+  virtual llvm::Constant *GetEHType(QualType T);
+
   virtual llvm::Constant *GetPropertyGetFunction() {
     return ObjCTypes.getGetPropertyFn();
   }
@@ -1405,8 +1406,10 @@
     return ObjCTypes.getEnumerationMutationFn();
   }
 
-  virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
-                                         const Stmt &S);
+  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
+                           const ObjCAtTryStmt &S);
+  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                    const ObjCAtSynchronizedStmt &S);
   virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
                              const ObjCAtThrowStmt &S);
   virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
@@ -1414,7 +1417,8 @@
   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
                                   llvm::Value *src, llvm::Value *dst);
   virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
-                                    llvm::Value *src, llvm::Value *dest);
+                                    llvm::Value *src, llvm::Value *dest,
+                                    bool threadlocal = false);
   virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
                                   llvm::Value *src, llvm::Value *dest,
                                   llvm::Value *ivarOffset);
@@ -1422,7 +1426,7 @@
                                         llvm::Value *src, llvm::Value *dest);
   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
                                         llvm::Value *dest, llvm::Value *src,
-                                        QualType Ty);
+                                        llvm::Value *size);
   virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
                                       QualType ObjectTy,
                                       llvm::Value *BaseValue,
@@ -1476,14 +1480,20 @@
 }
 
 /// 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, Selector Sel, 
+                                    bool lval) {
+  return EmitSelector(Builder, Sel, lval);
 }
 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
                                     *Method) {
   return EmitSelector(Builder, Method->getSelector());
 }
 
+llvm::Constant *CGObjCMac::GetEHType(QualType T) {
+  llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
+  return 0;
+}
+
 /// Generate a constant CFString object.
 /*
   struct __builtin_CFString {
@@ -1515,6 +1525,7 @@
 /// which class's method should be called.
 CodeGen::RValue
 CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                                    ReturnValueSlot Return,
                                     QualType ResultType,
                                     Selector Sel,
                                     const ObjCInterfaceDecl *Class,
@@ -1566,7 +1577,7 @@
   Target = CGF.Builder.CreateBitCast(Target, ClassTy);
   CGF.Builder.CreateStore(Target,
                           CGF.Builder.CreateStructGEP(ObjCSuper, 1));
-  return EmitLegacyMessageSend(CGF, ResultType,
+  return EmitLegacyMessageSend(CGF, Return, ResultType,
                                EmitSelector(CGF.Builder, Sel),
                                ObjCSuper, ObjCTypes.SuperPtrCTy,
                                true, CallArgs, Method, ObjCTypes);
@@ -1574,13 +1585,14 @@
 
 /// Generate code for a message send expression.
 CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                                               ReturnValueSlot Return,
                                                QualType ResultType,
                                                Selector Sel,
                                                llvm::Value *Receiver,
-                                               bool IsClassMessage,
                                                const CallArgList &CallArgs,
+                                               const ObjCInterfaceDecl *Class,
                                                const ObjCMethodDecl *Method) {
-  return EmitLegacyMessageSend(CGF, ResultType,
+  return EmitLegacyMessageSend(CGF, Return, ResultType,
                                EmitSelector(CGF.Builder, Sel),
                                Receiver, CGF.getContext().getObjCIdType(),
                                false, CallArgs, Method, ObjCTypes);
@@ -1588,6 +1600,7 @@
 
 CodeGen::RValue
 CGObjCCommonMac::EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
+                                       ReturnValueSlot Return,
                                        QualType ResultType,
                                        llvm::Value *Sel,
                                        llvm::Value *Arg0,
@@ -1610,31 +1623,108 @@
   const llvm::FunctionType *FTy =
     Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
 
+  if (Method)
+    assert(CGM.getContext().getCanonicalType(Method->getResultType()) ==
+           CGM.getContext().getCanonicalType(ResultType) &&
+           "Result type mismatch!");
+
   llvm::Constant *Fn = NULL;
-  if (CGM.ReturnTypeUsesSret(FnInfo)) {
+  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 if (CGM.ReturnTypeUsesFPRet(ResultType)) {
+    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
+      : 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);
+  Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy));
+  return CGF.EmitCall(FnInfo, Fn, Return, ActualArgs);
+}
+
+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;
+}
+
+llvm::Constant *CGObjCCommonMac::GCBlockLayout(CodeGen::CodeGenFunction &CGF,
+              const llvm::SmallVectorImpl<const BlockDeclRefExpr *> &DeclRefs) {
+  llvm::Constant *NullPtr = 
+    llvm::Constant::getNullValue(llvm::Type::getInt8PtrTy(VMContext));
+  if ((CGM.getLangOptions().getGCMode() == LangOptions::NonGC) ||
+      DeclRefs.empty())
+    return NullPtr;
+  bool hasUnion = false;
+  SkipIvars.clear();
+  IvarsInfo.clear();
+  unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0);
+  unsigned ByteSizeInBits = CGM.getContext().Target.getCharWidth();
+  
+  for (size_t i = 0; i < DeclRefs.size(); ++i) {
+    const BlockDeclRefExpr *BDRE = DeclRefs[i];
+    const ValueDecl *VD = BDRE->getDecl();
+    CharUnits Offset = CGF.BlockDecls[VD];
+    uint64_t FieldOffset = Offset.getQuantity();
+    QualType Ty = VD->getType();
+    assert(!Ty->isArrayType() && 
+           "Array block variable should have been caught");
+    if ((Ty->isRecordType() || Ty->isUnionType()) && !BDRE->isByRef()) {
+      BuildAggrIvarRecordLayout(Ty->getAs<RecordType>(),
+                                FieldOffset,
+                                true,
+                                hasUnion);
+      continue;
+    }
+      
+    Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), Ty);
+    unsigned FieldSize = CGM.getContext().getTypeSize(Ty);
+    // __block variables are passed by their descriptior address. So, size
+    // must reflect this.
+    if (BDRE->isByRef())
+      FieldSize = WordSizeInBits;
+    if (GCAttr == Qualifiers::Strong || BDRE->isByRef())
+      IvarsInfo.push_back(GC_IVAR(FieldOffset,
+                                  FieldSize / WordSizeInBits));
+    else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)
+      SkipIvars.push_back(GC_IVAR(FieldOffset,
+                                  FieldSize / ByteSizeInBits));
+  }
+  
+  if (IvarsInfo.empty())
+    return NullPtr;
+  // Sort on byte position in case we encounterred a union nested in
+  // block variable type's aggregate type.
+  if (hasUnion && !IvarsInfo.empty())
+    std::sort(IvarsInfo.begin(), IvarsInfo.end());
+  if (hasUnion && !SkipIvars.empty())
+    std::sort(SkipIvars.begin(), SkipIvars.end());
+  
+  std::string BitMap;
+  llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
+  if (CGM.getLangOptions().ObjCGCBitmapPrint) {
+    printf("\n block variable layout for block: ");
+    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");
+  }
+  
+  return C;
 }
 
 llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
@@ -1899,10 +1989,18 @@
     Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
                                                    Prop));
   }
-  if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
+  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);
+      PushProtocolProperties(PropertySet, Properties, Container, (*P), 
+                             ObjCTypes);
+  }
+  else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
+    for (ObjCCategoryDecl::protocol_iterator P = CD->protocol_begin(),
+         E = CD->protocol_end(); P != E; ++P)
+      PushProtocolProperties(PropertySet, Properties, Container, (*P), 
+                             ObjCTypes);
+  }
 
   // Return null for empty list.
   if (Properties.empty())
@@ -2039,6 +2137,7 @@
                       "__OBJC,__category,regular,no_dead_strip",
                       4, true);
   DefinedCategories.push_back(GV);
+  DefinedCategoryNames.insert(ExtName.str());
 }
 
 // FIXME: Get from somewhere?
@@ -2083,6 +2182,8 @@
                      Interface->protocol_begin(),
                      Interface->protocol_end());
   unsigned Flags = eClassFlags_Factory;
+  if (ID->getNumIvarInitializers())
+    Flags |= eClassFlags_HasCXXStructors;
   unsigned Size =
     CGM.getContext().getASTObjCImplementationLayout(ID).getSize() / 8;
 
@@ -2389,8 +2490,7 @@
 /// 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];
+  llvm::Function *Fn = GetMethodDefinition(MD);
   if (!Fn)
     return 0;
 
@@ -2482,11 +2582,260 @@
   return ObjCTypes.getEnumerationMutationFn();
 }
 
+void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
+  return EmitTryOrSynchronizedStmt(CGF, S);
+}
+
+void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
+                                     const ObjCAtSynchronizedStmt &S) {
+  return EmitTryOrSynchronizedStmt(CGF, S);
+}
+
+namespace {
+  struct PerformFragileFinally : EHScopeStack::Cleanup {
+    const Stmt &S;
+    llvm::Value *SyncArgSlot;
+    llvm::Value *CallTryExitVar;
+    llvm::Value *ExceptionData;
+    ObjCTypesHelper &ObjCTypes;
+    PerformFragileFinally(const Stmt *S,
+                          llvm::Value *SyncArgSlot,
+                          llvm::Value *CallTryExitVar,
+                          llvm::Value *ExceptionData,
+                          ObjCTypesHelper *ObjCTypes)
+      : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
+        ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      // Check whether we need to call objc_exception_try_exit.
+      // In optimized code, this branch will always be folded.
+      llvm::BasicBlock *FinallyCallExit =
+        CGF.createBasicBlock("finally.call_exit");
+      llvm::BasicBlock *FinallyNoCallExit =
+        CGF.createBasicBlock("finally.no_call_exit");
+      CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
+                               FinallyCallExit, FinallyNoCallExit);
+
+      CGF.EmitBlock(FinallyCallExit);
+      CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData)
+        ->setDoesNotThrow();
+
+      CGF.EmitBlock(FinallyNoCallExit);
+
+      if (isa<ObjCAtTryStmt>(S)) {
+        if (const ObjCAtFinallyStmt* FinallyStmt =
+              cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
+          // Save the current cleanup destination in case there's
+          // control flow inside the finally statement.
+          llvm::Value *CurCleanupDest =
+            CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot());
+
+          CGF.EmitStmt(FinallyStmt->getFinallyBody());
+
+          if (CGF.HaveInsertPoint()) {
+            CGF.Builder.CreateStore(CurCleanupDest,
+                                    CGF.getNormalCleanupDestSlot());
+          } else {
+            // Currently, the end of the cleanup must always exist.
+            CGF.EnsureInsertPoint();
+          }
+        }
+      } else {
+        // Emit objc_sync_exit(expr); as finally's sole statement for
+        // @synchronized.
+        llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
+        CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg)
+          ->setDoesNotThrow();
+      }
+    }
+  };
+
+  class FragileHazards {
+    CodeGenFunction &CGF;
+    llvm::SmallVector<llvm::Value*, 20> Locals;
+    llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
+
+    llvm::InlineAsm *ReadHazard;
+    llvm::InlineAsm *WriteHazard;
+
+    llvm::FunctionType *GetAsmFnType();
+
+    void collectLocals();
+    void emitReadHazard(CGBuilderTy &Builder);
+
+  public:
+    FragileHazards(CodeGenFunction &CGF);
+
+    void emitWriteHazard();
+    void emitHazardsInNewBlocks();
+  };
+}
+
+/// Create the fragile-ABI read and write hazards based on the current
+/// state of the function, which is presumed to be immediately prior
+/// to a @try block.  These hazards are used to maintain correct
+/// semantics in the face of optimization and the fragile ABI's
+/// cavalier use of setjmp/longjmp.
+FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
+  collectLocals();
+
+  if (Locals.empty()) return;
+
+  // Collect all the blocks in the function.
+  for (llvm::Function::iterator
+         I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I)
+    BlocksBeforeTry.insert(&*I);
+
+  llvm::FunctionType *AsmFnTy = GetAsmFnType();
+
+  // Create a read hazard for the allocas.  This inhibits dead-store
+  // optimizations and forces the values to memory.  This hazard is
+  // inserted before any 'throwing' calls in the protected scope to
+  // reflect the possibility that the variables might be read from the
+  // catch block if the call throws.
+  {
+    std::string Constraint;
+    for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
+      if (I) Constraint += ',';
+      Constraint += "*m";
+    }
+
+    ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
+  }
+
+  // Create a write hazard for the allocas.  This inhibits folding
+  // loads across the hazard.  This hazard is inserted at the
+  // beginning of the catch path to reflect the possibility that the
+  // variables might have been written within the protected scope.
+  {
+    std::string Constraint;
+    for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
+      if (I) Constraint += ',';
+      Constraint += "=*m";
+    }
+
+    WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
+  }
+}
+
+/// Emit a write hazard at the current location.
+void FragileHazards::emitWriteHazard() {
+  if (Locals.empty()) return;
+
+  CGF.Builder.CreateCall(WriteHazard, Locals.begin(), Locals.end())
+    ->setDoesNotThrow();
+}
+
+void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
+  assert(!Locals.empty());
+  Builder.CreateCall(ReadHazard, Locals.begin(), Locals.end())
+    ->setDoesNotThrow();
+}
+
+/// Emit read hazards in all the protected blocks, i.e. all the blocks
+/// which have been inserted since the beginning of the try.
+void FragileHazards::emitHazardsInNewBlocks() {
+  if (Locals.empty()) return;
+
+  CGBuilderTy Builder(CGF.getLLVMContext());
+
+  // Iterate through all blocks, skipping those prior to the try.
+  for (llvm::Function::iterator
+         FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) {
+    llvm::BasicBlock &BB = *FI;
+    if (BlocksBeforeTry.count(&BB)) continue;
+
+    // Walk through all the calls in the block.
+    for (llvm::BasicBlock::iterator
+           BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
+      llvm::Instruction &I = *BI;
+
+      // Ignore instructions that aren't non-intrinsic calls.
+      // These are the only calls that can possibly call longjmp.
+      if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue;
+      if (isa<llvm::IntrinsicInst>(I))
+        continue;
+
+      // Ignore call sites marked nounwind.  This may be questionable,
+      // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
+      llvm::CallSite CS(&I);
+      if (CS.doesNotThrow()) continue;
+
+      // Insert a read hazard before the call.  This will ensure that
+      // any writes to the locals are performed before making the
+      // call.  If the call throws, then this is sufficient to
+      // guarantee correctness as long as it doesn't also write to any
+      // locals.
+      Builder.SetInsertPoint(&BB, BI);
+      emitReadHazard(Builder);
+    }
+  }
+}
+
+static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) {
+  if (V) S.insert(V);
+}
+
+void FragileHazards::collectLocals() {
+  // Compute a set of allocas to ignore.
+  llvm::DenseSet<llvm::Value*> AllocasToIgnore;
+  addIfPresent(AllocasToIgnore, CGF.ReturnValue);
+  addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);
+  addIfPresent(AllocasToIgnore, CGF.EHCleanupDest);
+
+  // Collect all the allocas currently in the function.  This is
+  // probably way too aggressive.
+  llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
+  for (llvm::BasicBlock::iterator
+         I = Entry.begin(), E = Entry.end(); I != E; ++I)
+    if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
+      Locals.push_back(&*I);
+}
+
+llvm::FunctionType *FragileHazards::GetAsmFnType() {
+  std::vector<const llvm::Type *> Tys(Locals.size());
+  for (unsigned I = 0, E = Locals.size(); I != E; ++I)
+    Tys[I] = Locals[I]->getType();
+  return llvm::FunctionType::get(CGF.Builder.getVoidTy(), Tys, false);
+}
+
 /*
 
   Objective-C setjmp-longjmp (sjlj) Exception Handling
   --
 
+  A catch buffer is a setjmp buffer plus:
+    - a pointer to the exception that was caught
+    - a pointer to the previous exception data buffer
+    - two pointers of reserved storage
+  Therefore catch buffers form a stack, with a pointer to the top
+  of the stack kept in thread-local storage.
+
+  objc_exception_try_enter pushes a catch buffer onto the EH stack.
+  objc_exception_try_exit pops the given catch buffer, which is
+    required to be the top of the EH stack.
+  objc_exception_throw pops the top of the EH stack, writes the
+    thrown exception into the appropriate field, and longjmps
+    to the setjmp buffer.  It crashes the process (with a printf
+    and an abort()) if there are no catch buffers on the stack.
+  objc_exception_extract just reads the exception pointer out of the
+    catch buffer.
+
+  There's no reason an implementation couldn't use a light-weight
+  setjmp here --- something like __builtin_setjmp, but API-compatible
+  with the heavyweight setjmp.  This will be more important if we ever
+  want to implement correct ObjC/C++ exception interactions for the
+  fragile ABI.
+
+  Note that for this use of setjmp/longjmp to be correct, we may need
+  to mark some local variables volatile: if a non-volatile local
+  variable is modified between the setjmp and the longjmp, it has
+  indeterminate value.  For the purposes of LLVM IR, it may be
+  sufficient to make loads and stores within the @try (to variables
+  declared outside the @try) volatile.  This is necessary for
+  optimized correctness, but is not currently being done; this is
+  being tracked as rdar://problem/8160285
+
   The basic framework for a @try-catch-finally is as follows:
   {
   objc_exception_data d;
@@ -2548,119 +2897,165 @@
   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.
+  '@throw;' is supported by pushing the currently-caught exception
+  onto ObjCEHStack while the @catch blocks are emitted.
 
-  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.
+  Branches through the @finally block are handled with an ordinary
+  normal cleanup.  We do not register an EH cleanup; fragile-ABI ObjC
+  exceptions are not compatible with C++ exceptions, and this is
+  hardly the only place where this will go wrong.
 
-  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); }
+  @synchronized(expr) { stmt; } is emitted as if it were:
+    id synch_value = expr;
+    objc_sync_enter(synch_value);
+    @try { stmt; } @finally { objc_sync_exit(synch_value); }
 */
 
 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");
+
+  // A destination for the fall-through edges of the catch handlers to
+  // jump to.
+  CodeGenFunction::JumpDest FinallyEnd =
+    CGF.getJumpDestInCurrentScope("finally.end");
+
+  // A destination for the rethrow edge of the catch handlers to jump
+  // to.
+  CodeGenFunction::JumpDest FinallyRethrow =
+    CGF.getJumpDestInCurrentScope("finally.rethrow");
 
   // 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;
+  // @synchronized.  We can't avoid a temp here because we need the
+  // value to be preserved.  If the backend ever does liveness
+  // correctly after setjmp, this will be unnecessary.
+  llvm::Value *SyncArgSlot = 0;
   if (!isTry) {
-    SyncArg =
+    llvm::Value *SyncArg =
       CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
     SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
-    CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg);
+    CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg)
+      ->setDoesNotThrow();
+
+    SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg");
+    CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
   }
 
-  // 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.
+  // Allocate memory for the setjmp buffer.  This needs to be kept
+  // live throughout the try and catch blocks.
   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),
+
+  // Create the fragile hazards.  Note that this will not capture any
+  // of the allocas required for exception processing, but will
+  // capture the current basic block (which extends all the way to the
+  // setjmp call) as "before the @try".
+  FragileHazards Hazards(CGF);
+
+  // Create a flag indicating whether the cleanup needs to call
+  // objc_exception_try_exit.  This is true except when
+  //   - no catches match and we're branching through the cleanup
+  //     just to rethrow the exception, or
+  //   - a catch matched and we're falling out of the catch handler.
+  // The setjmp-safety rule here is that we should always store to this
+  // variable in a place that dominates the branch through the cleanup
+  // without passing through any setjmps.
+  llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(),
                                                      "_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");
+  // Push a normal cleanup to leave the try scope.
+  CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalCleanup, &S,
+                                                 SyncArgSlot,
+                                                 CallTryExitVar,
+                                                 ExceptionData,
+                                                 &ObjCTypes);
 
+  // Enter a try block:
+  //  - Call objc_exception_try_enter to push ExceptionData on top of
+  //    the EH stack.
+  CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
+      ->setDoesNotThrow();
+
+  //  - Call setjmp on the exception data buffer.
+  llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
+  llvm::Value *GEPIndexes[] = { Zero, Zero, Zero };
+  llvm::Value *SetJmpBuffer =
+    CGF.Builder.CreateGEP(ExceptionData, GEPIndexes, GEPIndexes+3, "setjmp_buffer");
+  llvm::CallInst *SetJmpResult =
+    CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
+  SetJmpResult->setDoesNotThrow();
+
+  // If setjmp returned 0, enter the protected block; otherwise,
+  // branch to the handler.
   llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
   llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
-  CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(SetJmpResult, "threw"),
-                           TryHandler, TryBlock);
+  llvm::Value *DidCatch =
+    CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
+  CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
 
-  // Emit the @try block.
+  // Emit the protected block.
   CGF.EmitBlock(TryBlock);
+  CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
   CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
-               : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
-  CGF.EmitBranchThroughCleanup(FinallyEnd);
+                     : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
 
-  // Emit the "exception in @try" block.
+  CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
+
+  // Emit the exception handler 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);
+  // Don't optimize loads of the in-scope locals across this point.
+  Hazards.emitWriteHazard();
+
+  // For a @synchronized (or a @try with no catches), just branch
+  // through the cleanup to the rethrow block.
+  if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
+    // Tell the cleanup not to re-pop the exit.
+    CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
     CGF.EmitBranchThroughCleanup(FinallyRethrow);
-  } else if (cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
+
+  // Otherwise, we have to match against the caught exceptions.
+  } else {
+    // Retrieve the exception object.  We may emit multiple blocks but
+    // nothing can cross this so the value is already in SSA form.
+    llvm::CallInst *Caught =
+      CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
+                             ExceptionData, "caught");
+    Caught->setDoesNotThrow();
+
+    // Push the exception to rethrow onto the EH value stack for the
+    // benefit of any @throws in the handlers.
+    CGF.ObjCEHValueStack.push_back(Caught);
+
     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");
+    bool HasFinally = (AtTryStmt->getFinallyStmt() != 0);
 
-    llvm::BasicBlock *CatchBlock = CGF.createBasicBlock("catch");
-    llvm::BasicBlock *CatchHandler = CGF.createBasicBlock("catch.handler");
-    CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
+    llvm::BasicBlock *CatchBlock = 0;
+    llvm::BasicBlock *CatchHandler = 0;
+    if (HasFinally) {
+      // Enter a new exception try block (in case a @catch block
+      // throws an exception).
+      CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
+        ->setDoesNotThrow();
 
-    CGF.EmitBlock(CatchBlock);
+      llvm::CallInst *SetJmpResult =
+        CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer,
+                               "setjmp.result");
+      SetJmpResult->setDoesNotThrow();
+
+      llvm::Value *Threw =
+        CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
+
+      CatchBlock = CGF.createBasicBlock("catch");
+      CatchHandler = CGF.createBasicBlock("catch_for_catch");
+      CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
+
+      CGF.EmitBlock(CatchBlock);
+    }
+
+    CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);
 
     // Handle catch list. As a special case we check if everything is
     // matched and avoid generating code for falling off the end if
@@ -2668,7 +3063,6 @@
     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;
@@ -2679,47 +3073,67 @@
       } else {
         OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
 
-        // catch(id e) always matches.
+        // catch(id e) always matches under this ABI, since only
+        // ObjC exceptions end up here in the first place.
         // 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 this is a catch-all, we don't need to test anything.
       if (AllMatched) {
+        CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
+
         if (CatchParam) {
           CGF.EmitLocalBlockVarDecl(*CatchParam);
           assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
+
+          // These types work out because ConvertType(id) == i8*.
           CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
         }
 
         CGF.EmitStmt(CatchStmt->getCatchBody());
+
+        // The scope of the catch variable ends right here.
+        CatchVarCleanups.ForceCleanup();
+
         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!");
+      const ObjCObjectType *ObjTy = OPT->getObjectType();
+
+      // FIXME: @catch (Class c) ?
+      ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
+      assert(IDecl && "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 *Class = EmitClassRef(CGF.Builder, IDecl);
 
-      llvm::Value *Match =
+      llvm::CallInst *Match =
         CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(),
                                 Class, Caught, "match");
+      Match->setDoesNotThrow();
 
-      llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("matched");
+      llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
+      llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
 
       CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
                                MatchedBlock, NextCatchBlock);
 
       // Emit the @catch block.
       CGF.EmitBlock(MatchedBlock);
+
+      // Collect any cleanups for the catch variable.  The scope lasts until
+      // the end of the catch body.
+      CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
+
       CGF.EmitLocalBlockVarDecl(*CatchParam);
       assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
 
+      // Initialize the catch variable.
       llvm::Value *Tmp =
         CGF.Builder.CreateBitCast(Caught,
                                   CGF.ConvertType(CatchParam->getType()),
@@ -2727,73 +3141,66 @@
       CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
 
       CGF.EmitStmt(CatchStmt->getCatchBody());
+
+      // We're done with the catch variable.
+      CatchVarCleanups.ForceCleanup();
+
       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.ObjCEHValueStack.pop_back();
+
+    // If nothing wanted anything to do with the caught exception,
+    // kill the extract call.
+    if (Caught->use_empty())
+      Caught->eraseFromParent();
+
+    if (!AllMatched)
+      CGF.EmitBranchThroughCleanup(FinallyRethrow);
+
+    if (HasFinally) {
+      // Emit the exception handler for the @catch blocks.
+      CGF.EmitBlock(CatchHandler);
+
+      // In theory we might now need a write hazard, but actually it's
+      // unnecessary because there's no local-accessing code between
+      // the try's write hazard and here.
+      //Hazards.emitWriteHazard();
+
+      // Don't pop the catch handler; the throw already did.
+      CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
       CGF.EmitBranchThroughCleanup(FinallyRethrow);
     }
+  }
 
-    // Emit the exception handler for the @catch blocks.
-    CGF.EmitBlock(CatchHandler);
-    CGF.Builder.CreateStore(
+  // Insert read hazards as required in the new blocks.
+  Hazards.emitHazardsInNewBlocks();
+
+  // Pop the cleanup.
+  CGF.Builder.restoreIP(TryFallthroughIP);
+  if (CGF.HaveInsertPoint())
+    CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
+  CGF.PopCleanupBlock();
+  CGF.EmitBlock(FinallyEnd.getBlock(), true);
+
+  // Emit the rethrow block.
+  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
+  CGF.EmitBlock(FinallyRethrow.getBlock(), true);
+  if (CGF.HaveInsertPoint()) {
+    // Just look in the buffer for the exception to throw.
+    llvm::CallInst *Caught =
       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);
+                             ExceptionData);
+    Caught->setDoesNotThrow();
+
+    CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), Caught)
+      ->setDoesNotThrow();
+    CGF.Builder.CreateUnreachable();
   }
 
-  // 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);
+  CGF.Builder.restoreIP(SavedIP);
 }
 
 void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
@@ -2810,7 +3217,8 @@
     ExceptionAsObject = CGF.ObjCEHValueStack.back();
   }
 
-  CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject);
+  CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
+    ->setDoesNotReturn();
   CGF.Builder.CreateUnreachable();
 
   // Clear the insertion point to indicate we are in unreachable code.
@@ -2856,7 +3264,8 @@
 /// objc_assign_global (id src, id *dst)
 ///
 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
-                                     llvm::Value *src, llvm::Value *dst) {
+                                     llvm::Value *src, llvm::Value *dst,
+                                     bool threadlocal) {
   const llvm::Type * SrcTy = src->getType();
   if (!isa<llvm::PointerType>(SrcTy)) {
     unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
@@ -2867,8 +3276,12 @@
   }
   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
-  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
-                          src, dst, "globalassign");
+  if (!threadlocal)
+    CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
+                            src, dst, "globalassign");
+  else
+    CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
+                            src, dst, "threadlocalassign");
   return;
 }
 
@@ -2917,15 +3330,11 @@
 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;
+                                         llvm::Value *size) {
   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);
+                          DestPtr, SrcPtr, size);
   return;
 }
 
@@ -2936,7 +3345,8 @@
                                        llvm::Value *BaseValue,
                                        const ObjCIvarDecl *Ivar,
                                        unsigned CVRQualifiers) {
-  const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl();
+  const ObjCInterfaceDecl *ID =
+    ObjectTy->getAs<ObjCObjectType>()->getInterface();
   return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
                                   EmitIvarOffset(CGF, ID, Ivar));
 }
@@ -2984,12 +3394,14 @@
   // We never allow @synthesize of a superclass property.
   flags |= eImageInfo_CorrectedSynthesize;
 
+  const llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext);
+  
   // 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::ConstantInt::get(Int32Ty, version),
+    llvm::ConstantInt::get(Int32Ty, flags)
   };
-  llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext), 2);
+  llvm::ArrayType *AT = llvm::ArrayType::get(Int32Ty, 2);
 
   const char *Section;
   if (ObjCABI == 1)
@@ -3089,7 +3501,8 @@
   return Builder.CreateLoad(Entry, "tmp");
 }
 
-llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel) {
+llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel,
+                                     bool lvalue) {
   llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
 
   if (!Entry) {
@@ -3102,6 +3515,8 @@
                         4, true);
   }
 
+  if (lvalue)
+    return Entry;
   return Builder.CreateLoad(Entry, "tmp");
 }
 
@@ -3118,6 +3533,22 @@
   return getConstantGEP(VMContext, Entry, 0, 0);
 }
 
+llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
+  llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
+      I = MethodDefinitions.find(MD);
+  if (I != MethodDefinitions.end())
+    return I->second;
+
+  if (MD->hasBody() && MD->getPCHLevel() > 0) {
+    // MD isn't emitted yet because it comes from PCH.
+    CGM.EmitTopLevelDecl(const_cast<ObjCMethodDecl*>(MD));
+    assert(MethodDefinitions[MD] && "EmitTopLevelDecl didn't emit the method!");
+    return MethodDefinitions[MD];
+  }
+
+  return NULL;
+}
+
 /// GetIvarLayoutName - Returns a unique constant for the given
 /// ivar layout bitmap.
 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
@@ -3125,22 +3556,6 @@
   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,
@@ -3304,63 +3719,19 @@
                                 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;
-
+/// BuildIvarLayoutBitmap - This routine is the horsework for doing all
+/// the computations and returning the layout bitmap (for ivar or blocks) in
+/// the given argument BitMap string container. Routine reads
+/// two containers, IvarsInfo and SkipIvars which are assumed to be
+/// filled already by the caller.
+llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string& BitMap) {
   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);
+  CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy);
   if (IvarsInfo[0].ivar_bytepos == 0) {
     WordsToSkip = 0;
     WordsToScan = IvarsInfo[0].ivar_size;
@@ -3370,7 +3741,7 @@
   }
   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;
+    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;
@@ -3384,7 +3755,7 @@
       SkScan.skip = WordsToSkip;
       SkScan.scan = WordsToScan;
       SkipScanIvars.push_back(SkScan);
-
+      
       // Skip the hole.
       SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
       SkScan.scan = 0;
@@ -3399,15 +3770,15 @@
     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;
+    SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
     LastIndex = IvarsInfo.size()-1;
     int LastByteScanned =
-      IvarsInfo[LastIndex].ivar_bytepos +
-      IvarsInfo[LastIndex].ivar_size * WordSize;
+    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;
@@ -3430,20 +3801,19 @@
       --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;
@@ -3468,11 +3838,71 @@
   // null terminate string.
   unsigned char zero = 0;
   BitMap += zero;
+  
+  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);
+}
 
-  if (CGM.getLangOptions().ObjCGCBitmapPrint) {
+/// 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;
+
+  const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+  if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
+    return llvm::Constant::getNullValue(PtrTy);
+
+  llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
+  const ObjCInterfaceDecl *OI = OMD->getClassInterface();
+  CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
+
+  llvm::SmallVector<FieldDecl*, 32> RecFields;
+  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());
+  
+  std::string BitMap;
+  llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
+  
+   if (CGM.getLangOptions().ObjCGCBitmapPrint) {
     printf("\n%s ivar layout for class '%s': ",
            ForStrongLayout ? "strong" : "weak",
-           OMD->getClassInterface()->getNameAsCString());
+           OMD->getClassInterface()->getName().data());
     const unsigned char *s = (unsigned char*)BitMap.c_str();
     for (unsigned i = 0; i < BitMap.size(); i++)
       if (!(s[i] & 0xf0))
@@ -3481,12 +3911,7 @@
         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);
+  return C;
 }
 
 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
@@ -3507,11 +3932,6 @@
   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);
@@ -3619,8 +4039,14 @@
       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)
+         e = LazySymbols.end(); I != e; ++I) {
       OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n";
+    }
+
+    for (size_t i = 0; i < DefinedCategoryNames.size(); ++i) {
+      OS << "\t.objc_category_name_" << DefinedCategoryNames[i] << "=0\n"
+         << "\t.globl .objc_category_name_" << DefinedCategoryNames[i] << "\n";
+    }
     
     CGM.getModule().setModuleInlineAsm(OS.str());
   }
@@ -3667,7 +4093,8 @@
   //   id self;
   //   Class cls;
   // }
-  RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
+  RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
+                                      Ctx.getTranslationUnitDecl(),
                                       SourceLocation(),
                                       &Ctx.Idents.get("_objc_super"));
   RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
@@ -3935,8 +4362,9 @@
     llvm::Type::getInt8PtrTy(VMContext), 4);
 
   ExceptionDataTy =
-    llvm::StructType::get(VMContext, llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext),
-                                                          SetJmpBufferSize),
+    llvm::StructType::get(VMContext,
+                        llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext),
+                                             SetJmpBufferSize),
                           StackPtrTy, NULL);
   CGM.getModule().addTypeName("struct._objc_exception_data",
                               ExceptionDataTy);
@@ -4128,7 +4556,8 @@
   // };
 
   // First the clang type for struct _message_ref_t
-  RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
+  RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
+                                      Ctx.getTranslationUnitDecl(),
                                       SourceLocation(),
                                       &Ctx.Idents.get("_message_ref_t"));
   RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
@@ -4497,6 +4926,8 @@
     CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden;
   if (classIsHidden)
     flags |= OBJC2_CLS_HIDDEN;
+  if (ID->getNumIvarInitializers())
+    flags |= eClassFlags_ABI2_HasCXXStructors;
   if (!ID->getClassInterface()->getSuperClass()) {
     // class is root
     flags |= CLS_ROOT;
@@ -4531,6 +4962,8 @@
   flags = CLS;
   if (classIsHidden)
     flags |= OBJC2_CLS_HIDDEN;
+  if (ID->getNumIvarInitializers())
+    flags |= eClassFlags_ABI2_HasCXXStructors;
 
   if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
     flags |= CLS_EXCEPTION;
@@ -4586,7 +5019,7 @@
                                    ObjCTypes.ExternalProtocolPtrTy);
 
   std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
-  ProtocolName += PD->getNameAsCString();
+  ProtocolName += PD->getName();
 
   llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
   if (PTGV)
@@ -4700,8 +5133,7 @@
 /// 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];
+  llvm::Function *Fn = GetMethodDefinition(MD);
   if (!Fn)
     return 0;
 
@@ -5087,12 +5519,12 @@
 /// @encode
 ///
 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
-  CodeGen::CodeGenFunction &CGF,
-  QualType ObjectTy,
-  llvm::Value *BaseValue,
-  const ObjCIvarDecl *Ivar,
-  unsigned CVRQualifiers) {
-  const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl();
+                                               CodeGen::CodeGenFunction &CGF,
+                                               QualType ObjectTy,
+                                               llvm::Value *BaseValue,
+                                               const ObjCIvarDecl *Ivar,
+                                               unsigned CVRQualifiers) {
+  ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
   return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
                                   EmitIvarOffset(CGF, ID, Ivar));
 }
@@ -5106,6 +5538,7 @@
 
 CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend(
   CodeGen::CodeGenFunction &CGF,
+  ReturnValueSlot Return,
   QualType ResultType,
   Selector Sel,
   llvm::Value *Receiver,
@@ -5127,46 +5560,25 @@
                               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";
+  if (CGM.ReturnTypeUsesSRet(FnInfo)) {
+    if (IsSuper) {
+      Fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
+      Name += "objc_msgSendSuper2_stret_fixup";
+    } else {
+      Fn = ObjCTypes.getMessageSendStretFixupFn();
+      Name += "objc_msgSend_stret_fixup";
+    }
+  } else if (!IsSuper && CGM.ReturnTypeUsesFPRet(ResultType)) {
+    Fn = ObjCTypes.getMessageSendFpretFixupFn();
+    Name += "objc_msgSend_fpret_fixup";
+  } else {
+    if (IsSuper) {
+      Fn = ObjCTypes.getMessageSendSuper2FixupFn();
+      Name += "objc_msgSendSuper2_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 += '_';
@@ -5205,23 +5617,25 @@
   const llvm::FunctionType *FTy = Types.GetFunctionType(FnInfo1, true);
   Callee = CGF.Builder.CreateBitCast(Callee,
                                      llvm::PointerType::getUnqual(FTy));
-  return CGF.EmitCall(FnInfo1, Callee, ReturnValueSlot(), ActualArgs);
+  return CGF.EmitCall(FnInfo1, Callee, Return, ActualArgs);
 }
 
 /// Generate code for a message send expression in the nonfragile abi.
 CodeGen::RValue
 CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                                            ReturnValueSlot Return,
                                             QualType ResultType,
                                             Selector Sel,
                                             llvm::Value *Receiver,
-                                            bool IsClassMessage,
                                             const CallArgList &CallArgs,
+                                            const ObjCInterfaceDecl *Class,
                                             const ObjCMethodDecl *Method) {
   return LegacyDispatchedSelector(Sel)
-    ? EmitLegacyMessageSend(CGF, ResultType, EmitSelector(CGF.Builder, Sel),
+    ? EmitLegacyMessageSend(CGF, Return, ResultType,
+                            EmitSelector(CGF.Builder, Sel),
                             Receiver, CGF.getContext().getObjCIdType(),
                             false, CallArgs, Method, ObjCTypes)
-    : EmitMessageSend(CGF, ResultType, Sel,
+    : EmitMessageSend(CGF, Return, ResultType, Sel,
                       Receiver, CGF.getContext().getObjCIdType(),
                       false, CallArgs);
 }
@@ -5328,6 +5742,7 @@
 /// which class's method should be called.
 CodeGen::RValue
 CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                                                 ReturnValueSlot Return,
                                                  QualType ResultType,
                                                  Selector Sel,
                                                  const ObjCInterfaceDecl *Class,
@@ -5370,16 +5785,17 @@
                           CGF.Builder.CreateStructGEP(ObjCSuper, 1));
 
   return (LegacyDispatchedSelector(Sel))
-    ? EmitLegacyMessageSend(CGF, ResultType,EmitSelector(CGF.Builder, Sel),
+    ? EmitLegacyMessageSend(CGF, Return, ResultType,
+                            EmitSelector(CGF.Builder, Sel),
                             ObjCSuper, ObjCTypes.SuperPtrCTy,
                             true, CallArgs, Method, ObjCTypes)
-    : EmitMessageSend(CGF, ResultType, Sel,
+    : EmitMessageSend(CGF, Return, ResultType, Sel,
                       ObjCSuper, ObjCTypes.SuperPtrCTy,
                       true, CallArgs);
 }
 
 llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
-                                                  Selector Sel) {
+                                                  Selector Sel, bool lval) {
   llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
 
   if (!Entry) {
@@ -5394,6 +5810,8 @@
     CGM.AddUsedGlobal(Entry);
   }
 
+  if (lval)
+    return Entry;
   return Builder.CreateLoad(Entry, "tmp");
 }
 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
@@ -5443,15 +5861,11 @@
   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;
+  llvm::Value *Size) {
   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);
+                          DestPtr, SrcPtr, Size);
   return;
 }
 
@@ -5494,7 +5908,8 @@
 /// objc_assign_global (id src, id *dst)
 ///
 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
-                                                  llvm::Value *src, llvm::Value *dst) {
+                                          llvm::Value *src, llvm::Value *dst,
+                                          bool threadlocal) {
   const llvm::Type * SrcTy = src->getType();
   if (!isa<llvm::PointerType>(SrcTy)) {
     unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy);
@@ -5505,306 +5920,236 @@
   }
   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
-  CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
-                          src, dst, "globalassign");
+  if (!threadlocal)
+    CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
+                            src, dst, "globalassign");
+  else
+    CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
+                            src, dst, "threadlocalassign");
   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");
+namespace {
+  struct CallSyncExit : EHScopeStack::Cleanup {
+    llvm::Value *SyncExitFn;
+    llvm::Value *SyncArg;
+    CallSyncExit(llvm::Value *SyncExitFn, llvm::Value *SyncArg)
+      : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
 
-  // 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);
+    void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
+      CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
+    }
+  };
+}
+
+void
+CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                             const ObjCAtSynchronizedStmt &S) {
+  // Evaluate the lock operand.  This should dominate the cleanup.
+  llvm::Value *SyncArg = CGF.EmitScalarExpr(S.getSynchExpr());
+
+  // Acquire the lock.
+  SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
+  CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg)
+    ->setDoesNotThrow();
+
+  // Register an all-paths cleanup to release the lock.
+  CGF.EHStack.pushCleanup<CallSyncExit>(NormalAndEHCleanup,
+                                        ObjCTypes.getSyncExitFn(),
+                                        SyncArg);
+
+  // Emit the body of the statement.
+  CGF.EmitStmt(S.getSynchBody());
+
+  // Pop the lock-release cleanup.
+  CGF.PopCleanupBlock();
+}
+
+namespace {
+  struct CatchHandler {
+    const VarDecl *Variable;
+    const Stmt *Body;
+    llvm::BasicBlock *Block;
+    llvm::Value *TypeInfo;
+  };
+
+  struct CallObjCEndCatch : EHScopeStack::Cleanup {
+    CallObjCEndCatch(bool MightThrow, llvm::Value *Fn) :
+      MightThrow(MightThrow), Fn(Fn) {}
+    bool MightThrow;
+    llvm::Value *Fn;
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      if (!MightThrow) {
+        CGF.Builder.CreateCall(Fn)->setDoesNotThrow();
+        return;
+      }
+
+      CGF.EmitCallOrInvoke(Fn, 0, 0);
+    }
+  };
+}
+
+llvm::Constant *
+CGObjCNonFragileABIMac::GetEHType(QualType T) {
+  // There's a particular fixed type info for 'id'.
+  if (T->isObjCIdType() ||
+      T->isObjCQualifiedIdType()) {
+    llvm::Constant *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");
+    return IDEHType;
   }
 
-  // Push an EH context entry, used for handling rethrows and jumps
-  // through finally.
-  CGF.PushCleanupBlock(FinallyBlock);
+  // All other types should be Objective-C interface pointer types.
+  const ObjCObjectPointerType *PT =
+    T->getAs<ObjCObjectPointerType>();
+  assert(PT && "Invalid @catch type.");
+  const ObjCInterfaceType *IT = PT->getInterfaceType();
+  assert(IT && "Invalid @catch type.");
+  return GetInterfaceEHType(IT->getDecl(), false);
+}                                                  
 
-  CGF.setInvokeDest(TryHandler);
+void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
+                                         const ObjCAtTryStmt &S) {
+  // Jump destination for falling out of catch bodies.
+  CodeGenFunction::JumpDest Cont;
+  if (S.getNumCatchStmts())
+    Cont = CGF.getJumpDestInCurrentScope("eh.cont");
 
-  CGF.EmitBlock(TryBlock);
-  CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
-               : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
-  CGF.EmitBranchThroughCleanup(FinallyEnd);
+  CodeGenFunction::FinallyInfo FinallyInfo;
+  if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt())
+    FinallyInfo = CGF.EnterFinallyBlock(Finally->getFinallyBody(),
+                                        ObjCTypes.getObjCBeginCatchFn(),
+                                        ObjCTypes.getObjCEndCatchFn(),
+                                        ObjCTypes.getExceptionRethrowFn());
 
-  // Emit the exception handler.
+  llvm::SmallVector<CatchHandler, 8> Handlers;
 
-  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);
+  // Enter the catch, if there is one.
+  if (S.getNumCatchStmts()) {
+    for (unsigned I = 0, N = S.getNumCatchStmts(); I != N; ++I) {
+      const ObjCAtCatchStmt *CatchStmt = S.getCatchStmt(I);
       const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl();
-      Handlers.push_back(std::make_pair(CatchDecl, CatchStmt->getCatchBody()));
 
-      // catch(...) always matches.
+      Handlers.push_back(CatchHandler());
+      CatchHandler &Handler = Handlers.back();
+      Handler.Variable = CatchDecl;
+      Handler.Body = CatchStmt->getCatchBody();
+      Handler.Block = CGF.createBasicBlock("catch");
+
+      // @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;
+        Handler.TypeInfo = 0; // catch-all
+        // Don't consider any other catches.
         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);
+      Handler.TypeInfo = GetEHType(CatchDecl->getType());
     }
 
-    if (CatchBody) {
-      llvm::BasicBlock *MatchEnd = CGF.createBasicBlock("match.end");
+    EHCatchScope *Catch = CGF.EHStack.pushCatch(Handlers.size());
+    for (unsigned I = 0, E = Handlers.size(); I != E; ++I)
+      Catch->setHandler(I, Handlers[I].TypeInfo, Handlers[I].Block);
+  }
+  
+  // Emit the try body.
+  CGF.EmitStmt(S.getTryBody());
 
-      // Cleanups must call objc_end_catch.
-      CGF.PushCleanupBlock(MatchEnd);
+  // Leave the try.
+  if (S.getNumCatchStmts())
+    CGF.EHStack.popCatch();
 
-      llvm::Value *ExcObject =
-        CGF.Builder.CreateCall(ObjCTypes.getObjCBeginCatchFn(), Exc);
+  // Remember where we were.
+  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
 
-      // 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));
-      }
+  // Emit the handlers.
+  for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
+    CatchHandler &Handler = Handlers[I];
 
-      // 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.EmitBlock(Handler.Block);
+    llvm::Value *RawExn = CGF.Builder.CreateLoad(CGF.getExceptionSlot());
 
-      CGF.EmitBranchThroughCleanup(FinallyEnd);
+    // Enter the catch.
+    llvm::CallInst *Exn =
+      CGF.Builder.CreateCall(ObjCTypes.getObjCBeginCatchFn(), RawExn,
+                             "exn.adjusted");
+    Exn->setDoesNotThrow();
 
-      // 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);
-      }
+    // Add a cleanup to leave the catch.
+    bool EndCatchMightThrow = (Handler.Variable == 0);
+    CGF.EHStack.pushCleanup<CallObjCEndCatch>(NormalAndEHCleanup,
+                                              EndCatchMightThrow,
+                                              ObjCTypes.getObjCEndCatchFn());
 
-      CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock();
+    // Bind the catch parameter if it exists.
+    if (const VarDecl *CatchParam = Handler.Variable) {
+      const llvm::Type *CatchType = CGF.ConvertType(CatchParam->getType());
+      llvm::Value *CastExn = CGF.Builder.CreateBitCast(Exn, CatchType);
 
-      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);
+      CGF.EmitLocalBlockVarDecl(*CatchParam);
+      CGF.Builder.CreateStore(CastExn, CGF.GetAddrOfLocalVar(CatchParam));
     }
-  }
 
-  // Pop the cleanup entry, the @finally is outside this cleanup
-  // scope.
-  CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock();
-  CGF.setInvokeDest(PrevLandingPad);
+    CGF.ObjCEHValueStack.push_back(Exn);
+    CGF.EmitStmt(Handler.Body);
+    CGF.ObjCEHValueStack.pop_back();
 
-  CGF.EmitBlock(FinallyBlock);
+    // Leave the earlier cleanup.
+    CGF.PopCleanupBlock();
 
-  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);
-  }
+    CGF.EmitBranchThroughCleanup(Cont);
+  }  
 
-  if (Info.SwitchBlock)
-    CGF.EmitBlock(Info.SwitchBlock);
-  if (Info.EndBlock)
-    CGF.EmitBlock(Info.EndBlock);
+  // Go back to the try-statement fallthrough.
+  CGF.Builder.restoreIP(SavedIP);
 
-  // Branch around the rethrow code.
-  CGF.EmitBranch(FinallyEnd);
+  // Pop out of the normal cleanup on the finally.
+  if (S.getFinallyStmt())
+    CGF.ExitFinallyBlock(FinallyInfo);
 
-  // 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);
+  if (Cont.isValid())
+    CGF.EmitBlock(Cont.getBlock());
 }
 
 /// EmitThrowStmt - Generate code for a throw statement.
 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
                                            const ObjCAtThrowStmt &S) {
   llvm::Value *Exception;
+  llvm::Constant *FunctionThrowOrRethrow;
   if (const Expr *ThrowExpr = S.getThrowExpr()) {
     Exception = CGF.EmitScalarExpr(ThrowExpr);
+    FunctionThrowOrRethrow = ObjCTypes.getExceptionThrowFn();
   } else {
     assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
            "Unexpected rethrow outside @catch block.");
     Exception = CGF.ObjCEHValueStack.back();
+    FunctionThrowOrRethrow = ObjCTypes.getExceptionRethrowFn();
   }
 
   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,
+    CGF.Builder.CreateInvoke(FunctionThrowOrRethrow,
+                             CGF.getUnreachableBlock(), InvokeDest,
                              &ExceptionAsObject, &ExceptionAsObject + 1);
-    CGF.EmitBlock(Cont);
-  } else
-    CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject);
-  CGF.Builder.CreateUnreachable();
+  } else {
+    CGF.Builder.CreateCall(FunctionThrowOrRethrow, ExceptionAsObject)
+      ->setDoesNotReturn();
+    CGF.Builder.CreateUnreachable();
+  }
 
   // Clear the insertion point to indicate we are in unreachable code.
   CGF.Builder.ClearInsertionPoint();
 }
 
-llvm::Value *
+llvm::Constant *
 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
                                            bool ForDefinition) {
   llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
@@ -5839,7 +6184,8 @@
                                         llvm::GlobalValue::ExternalLinkage,
                                         0, VTableName);
 
-  llvm::Value *VTableIdx = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 2);
+  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);
diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h
index 64e6808..584760f 100644
--- a/lib/CodeGen/CGObjCRuntime.h
+++ b/lib/CodeGen/CGObjCRuntime.h
@@ -52,6 +52,7 @@
   class Selector;
   class ObjCIvarDecl;
   class ObjCStringLiteral;
+  class BlockDeclRefExpr;
 
 namespace CodeGen {
   class CodeGenModule;
@@ -97,12 +98,18 @@
   /// return value should have the LLVM type for pointer-to
   /// ASTContext::getObjCSelType().
   virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
-                                   Selector Sel) = 0;
+                                   Selector Sel, bool lval=false) = 0;
 
   /// Get a typed selector.
   virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
                                    const ObjCMethodDecl *Method) = 0;
 
+  /// Get the type constant to catch for the given ObjC pointer type.
+  /// This is used externally to implement catching ObjC types in C++.
+  /// Runtimes which don't support this should add the appropriate
+  /// error to Sema.
+  virtual llvm::Constant *GetEHType(QualType T) = 0;
+
   /// Generate a constant string object.
   virtual llvm::Constant *GenerateConstantString(const StringLiteral *) = 0;
 
@@ -119,11 +126,12 @@
   /// a property setter or getter.
   virtual CodeGen::RValue
   GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                      ReturnValueSlot ReturnSlot,
                       QualType ResultType,
                       Selector Sel,
                       llvm::Value *Receiver,
-                      bool IsClassMessage,
                       const CallArgList &CallArgs,
+                      const ObjCInterfaceDecl *Class = 0,
                       const ObjCMethodDecl *Method = 0) = 0;
 
   /// Generate an Objective-C message send operation to the super
@@ -134,6 +142,7 @@
   /// a property setter or getter.
   virtual CodeGen::RValue
   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
+                           ReturnValueSlot ReturnSlot,
                            QualType ResultType,
                            Selector Sel,
                            const ObjCInterfaceDecl *Class,
@@ -179,8 +188,10 @@
   /// 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 EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                    const ObjCAtSynchronizedStmt &S) = 0;
+  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
+                           const ObjCAtTryStmt &S) = 0;
   virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
                              const ObjCAtThrowStmt &S) = 0;
   virtual llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
@@ -188,7 +199,8 @@
   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;
+                                    llvm::Value *src, llvm::Value *dest,
+                                    bool threadlocal=false) = 0;
   virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
                                   llvm::Value *src, llvm::Value *dest,
                                   llvm::Value *ivarOffset) = 0;
@@ -206,7 +218,10 @@
   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
                                         llvm::Value *DestPtr,
                                         llvm::Value *SrcPtr,
-                                        QualType Ty) = 0;
+                                        llvm::Value *Size) = 0;
+  virtual llvm::Constant *GCBlockLayout(CodeGen::CodeGenFunction &CGF,
+                  const llvm::SmallVectorImpl<const BlockDeclRefExpr *> &) = 0;
+                                        
 };
 
 /// Creates an instance of an Objective-C runtime class.
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp
index 5e3801d..2a90b37 100644
--- a/lib/CodeGen/CGRTTI.cpp
+++ b/lib/CodeGen/CGRTTI.cpp
@@ -11,9 +11,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/AST/Type.h"
-#include "clang/AST/RecordLayout.h"
 #include "CodeGenModule.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/Type.h"
+#include "clang/Frontend/CodeGenOptions.h"
+
 using namespace clang;
 using namespace CodeGen;
 
@@ -45,7 +47,11 @@
   
   /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used
   /// for pointer types.
-  void BuildPointerTypeInfo(const PointerType *Ty);
+  void BuildPointerTypeInfo(QualType PointeeTy);
+
+  /// BuildObjCObjectTypeInfo - Build the appropriate kind of
+  /// type_info for an object type.
+  void BuildObjCObjectTypeInfo(const ObjCObjectType *Ty);
   
   /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
   /// struct, used for member pointer types.
@@ -148,6 +154,9 @@
   };
   
   /// BuildTypeInfo - Build the RTTI type info struct for the given type.
+  ///
+  /// \param Force - true to force the creation of this RTTI value
+  /// \param ForEH - true if this is for exception handling
   llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);
 };
 }
@@ -241,10 +250,9 @@
   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) {
+/// IsStandardLibraryRTTIDescriptor - Returns whether the type
+/// information for the given type exists in the standard library.
+static bool IsStandardLibraryRTTIDescriptor(QualType Ty) {
   // Type info for builtin types is defined in the standard library.
   if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
     return TypeInfoIsInStandardLibrary(BuiltinTy);
@@ -254,6 +262,18 @@
   if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
     return TypeInfoIsInStandardLibrary(PointerTy);
 
+  return false;
+}
+
+/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
+/// the given type exists somewhere else, and that we should not emit the type
+/// information in this translation unit.  Assumes that it is not a
+/// standard-library type.
+static bool ShouldUseExternalRTTIDescriptor(ASTContext &Context,
+                                            QualType Ty) {
+  // If RTTI is disabled, don't consider key functions.
+  if (!Context.getLangOptions().RTTI) return false;
+
   if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
     const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
     if (!RD->hasDefinition())
@@ -264,7 +284,7 @@
 
     // Get the key function.
     const CXXMethodDecl *KeyFunction = RD->getASTContext().getKeyFunction(RD);
-    if (KeyFunction && !KeyFunction->getBody()) {
+    if (KeyFunction && !KeyFunction->hasBody()) {
       // 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;
@@ -376,21 +396,45 @@
 }
 
 void RTTIBuilder::BuildVTablePointer(const Type *Ty) {
-  const char *VTableName;
+  // abi::__class_type_info.
+  static const char * const ClassTypeInfo =
+    "_ZTVN10__cxxabiv117__class_type_infoE";
+  // abi::__si_class_type_info.
+  static const char * const SIClassTypeInfo =
+    "_ZTVN10__cxxabiv120__si_class_type_infoE";
+  // abi::__vmi_class_type_info.
+  static const char * const VMIClassTypeInfo =
+    "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
+
+  const char *VTableName = 0;
 
   switch (Ty->getTypeClass()) {
-  default: assert(0 && "Unhandled type!");
+#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");
+
+  case Type::LValueReference:
+  case Type::RValueReference:
+    assert(false && "References shouldn't get here");
 
   case Type::Builtin:
-  // GCC treats vector types as fundamental types.
+  // GCC treats vector and complex types as fundamental types.
   case Type::Vector:
   case Type::ExtVector:
+  case Type::Complex:
+  // FIXME: GCC treats block pointers as fundamental types?!
+  case Type::BlockPointer:
     // abi::__fundamental_type_info.
     VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
     break;
 
   case Type::ConstantArray:
   case Type::IncompleteArray:
+  case Type::VariableArray:
     // abi::__array_type_info.
     VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
     break;
@@ -405,25 +449,44 @@
     // 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";
+      VTableName = ClassTypeInfo;
     } else if (CanUseSingleInheritance(RD)) {
-      // abi::__si_class_type_info.
-      VTableName = "_ZTVN10__cxxabiv120__si_class_type_infoE";
+      VTableName = SIClassTypeInfo;
     } else {
-      // abi::__vmi_class_type_info.
-      VTableName = "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
+      VTableName = VMIClassTypeInfo;
     }
     
     break;
   }
 
+  case Type::ObjCObject:
+    // Ignore protocol qualifiers.
+    Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
+
+    // Handle id and Class.
+    if (isa<BuiltinType>(Ty)) {
+      VTableName = ClassTypeInfo;
+      break;
+    }
+
+    assert(isa<ObjCInterfaceType>(Ty));
+    // Fall through.
+
+  case Type::ObjCInterface:
+    if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
+      VTableName = SIClassTypeInfo;
+    } else {
+      VTableName = ClassTypeInfo;
+    }
+    break;
+
+  case Type::ObjCObjectPointer:
   case Type::Pointer:
     // abi::__pointer_type_info.
     VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
@@ -461,32 +524,52 @@
   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))
+  bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty);
+  if (!Force &&
+      (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM.getContext(), Ty)))
     return GetAddrOfExternalRTTIDescriptor(Ty);
 
-  llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(Ty);
+  // Emit the standard library with external linkage.
+  llvm::GlobalVariable::LinkageTypes Linkage;
+  if (IsStdLib)
+    Linkage = llvm::GlobalValue::ExternalLinkage;
+  else
+    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!");
+#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");
 
   // GCC treats vector types as fundamental types.
   case Type::Builtin:
   case Type::Vector:
   case Type::ExtVector:
+  case Type::Complex:
+  case Type::BlockPointer:
     // Itanium C++ ABI 2.9.5p4:
     // abi::__fundamental_type_info adds no data members to std::type_info.
     break;
-      
+
+  case Type::LValueReference:
+  case Type::RValueReference:
+    assert(false && "References shouldn't get here");
+
   case Type::ConstantArray:
   case Type::IncompleteArray:
+  case Type::VariableArray:
     // Itanium C++ ABI 2.9.5p5:
     // abi::__array_type_info adds no data members to std::type_info.
     break;
@@ -517,11 +600,20 @@
 
     break;
   }
+
+  case Type::ObjCObject:
+  case Type::ObjCInterface:
+    BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
+    break;
+
+  case Type::ObjCObjectPointer:
+    BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
+    break; 
       
   case Type::Pointer:
-    BuildPointerTypeInfo(cast<PointerType>(Ty));
+    BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
     break;
-  
+
   case Type::MemberPointer:
     BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
     break;
@@ -543,7 +635,18 @@
     OldGV->replaceAllUsesWith(NewPtr);
     OldGV->eraseFromParent();
   }
-    
+
+  // GCC only relies on the uniqueness of the type names, not the
+  // type_infos themselves, so we can emit these as hidden symbols.
+  // But don't do this if we're worried about strict visibility
+  // compatibility.
+  if (const RecordType *RT = dyn_cast<RecordType>(Ty))
+    CGM.setTypeVisibility(GV, cast<CXXRecordDecl>(RT->getDecl()),
+                          /*ForRTTI*/ true);
+  else if (CGM.getCodeGenOpts().HiddenWeakVTables &&
+           Linkage == llvm::GlobalValue::WeakODRLinkage)
+    GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
+  
   return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
 }
 
@@ -562,6 +665,30 @@
   return Flags;
 }
 
+/// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info
+/// for the given Objective-C object type.
+void RTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) {
+  // Drop qualifiers.
+  const Type *T = OT->getBaseType().getTypePtr();
+  assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
+
+  // The builtin types are abi::__class_type_infos and don't require
+  // extra fields.
+  if (isa<BuiltinType>(T)) return;
+
+  ObjCInterfaceDecl *Class = cast<ObjCInterfaceType>(T)->getDecl();
+  ObjCInterfaceDecl *Super = Class->getSuperClass();
+
+  // Root classes are also __class_type_info.
+  if (!Super) return;
+
+  QualType SuperTy = CGM.getContext().getObjCInterfaceType(Super);
+
+  // Everything else is single inheritance.
+  llvm::Constant *BaseTypeInfo = RTTIBuilder(CGM).BuildTypeInfo(SuperTy);
+  Fields.push_back(BaseTypeInfo);
+}
+
 /// 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) {
@@ -669,7 +796,7 @@
   //   direct proper base. Each description is of the type:
   //
   //   struct abi::__base_class_type_info {
-	//   public:
+  //   public:
   //     const __class_type_info *__base_type;
   //     long __offset_flags;
   //
@@ -717,18 +844,20 @@
 
 /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
 /// used for pointer types.
-void RTTIBuilder::BuildPointerTypeInfo(const PointerType *Ty) {
-  QualType PointeeTy = Ty->getPointeeType();
+void RTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {  
+  Qualifiers Quals;
+  QualType UnqualifiedPointeeTy = 
+    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
   
   // 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());
+  unsigned Flags = ComputeQualifierFlags(Quals);
 
   // 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))
+  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
     Flags |= PTI_Incomplete;
 
   const llvm::Type *UnsignedIntLTy = 
@@ -739,7 +868,7 @@
   //  __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());
+    RTTIBuilder(CGM).BuildTypeInfo(UnqualifiedPointeeTy);
   Fields.push_back(PointeeTypeInfo);
 }
 
@@ -748,17 +877,21 @@
 void RTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
   QualType PointeeTy = Ty->getPointeeType();
   
+  Qualifiers Quals;
+  QualType UnqualifiedPointeeTy = 
+    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
+  
   // 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());
+  unsigned Flags = ComputeQualifierFlags(Quals);
 
   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))
+  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
     Flags |= PTI_Incomplete;
 
   if (IsIncompleteClassType(ClassType))
@@ -772,7 +905,7 @@
   //   __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());
+    RTTIBuilder(CGM).BuildTypeInfo(UnqualifiedPointeeTy);
   Fields.push_back(PointeeTypeInfo);
 
   // Itanium C++ ABI 2.9.5p9:
@@ -782,12 +915,16 @@
   Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(QualType(ClassType, 0)));
 }
 
-llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty) {
-  if (!getContext().getLangOptions().RTTI) {
+llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,
+                                                       bool ForEH) {
+  // Return a bogus pointer if RTTI is disabled, unless it's for EH.
+  // FIXME: should we even be calling this method if RTTI is disabled
+  // and it's not for EH?
+  if (!ForEH && !getContext().getLangOptions().RTTI) {
     const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
     return llvm::Constant::getNullValue(Int8PtrTy);
   }
-  
+
   return RTTIBuilder(*this).BuildTypeInfo(Ty);
 }
 
diff --git a/lib/CodeGen/CGRecordLayout.h b/lib/CodeGen/CGRecordLayout.h
index 56211b1..965fcc5 100644
--- a/lib/CodeGen/CGRecordLayout.h
+++ b/lib/CodeGen/CGRecordLayout.h
@@ -168,33 +168,43 @@
   /// field no. This info is populated by record builder.
   llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
 
+  // FIXME: Maybe we could use a CXXBaseSpecifier as the key and use a single
+  // map for both virtual and non virtual bases.
+  llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBaseFields;
+
   /// 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;
+  bool IsZeroInitializable : 1;
 
 public:
-  CGRecordLayout(const llvm::Type *T, bool ContainsPointerToDataMember)
-    : LLVMType(T), ContainsPointerToDataMember(ContainsPointerToDataMember) {}
+  CGRecordLayout(const llvm::Type *T, bool IsZeroInitializable)
+    : LLVMType(T), IsZeroInitializable(IsZeroInitializable) {}
 
   /// \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 Check whether this struct can be C++ zero-initialized
+  /// with a zeroinitializer.
+  bool isZeroInitializable() const {
+    return IsZeroInitializable;
   }
 
-  /// \brief Return the BitFieldInfo that corresponds to the field FD.
+  /// \brief Return llvm::StructType element number 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.
+  unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const {
+    assert(NonVirtualBaseFields.count(RD) && "Invalid non-virtual base!");
+    return NonVirtualBaseFields.lookup(RD);
+  }
+
+  /// \brief Return the BitFieldInfo 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
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 6302cf8..ac1c2b5 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/RecordLayout.h"
 #include "CodeGenTypes.h"
+#include "CGCXXABI.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Type.h"
 #include "llvm/Support/Debug.h"
@@ -42,10 +43,12 @@
   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;
+  typedef std::pair<const CXXRecordDecl *, unsigned> LLVMBaseInfo;
+  llvm::SmallVector<LLVMBaseInfo, 16> LLVMNonVirtualBases;
+  
+  /// IsZeroInitializable - Whether this struct can be C++
+  /// zero-initialized with an LLVM zeroinitializer.
+  bool IsZeroInitializable;
 
   /// Packed - Whether the resulting LLVM struct will be packed or not.
   bool Packed;
@@ -81,8 +84,13 @@
   /// 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);
+  /// LayoutNonVirtualBase - layout a single non-virtual base.
+  void LayoutNonVirtualBase(const CXXRecordDecl *BaseDecl,
+                            uint64_t BaseOffset);
+  
+  /// LayoutNonVirtualBases - layout the non-virtual bases of a record decl.
+  void LayoutNonVirtualBases(const CXXRecordDecl *RD, 
+                             const ASTRecordLayout &Layout);
 
   /// LayoutField - layout a single field. Returns false if the operation failed
   /// because the current struct is not packed.
@@ -107,13 +115,14 @@
 
   unsigned getTypeAlignment(const llvm::Type *Ty) const;
 
-  /// CheckForPointerToDataMember - Check if the given type contains a pointer
+  /// CheckZeroInitializable - Check if the given type contains a pointer
   /// to data member.
-  void CheckForPointerToDataMember(QualType T);
+  void CheckZeroInitializable(QualType T);
+  void CheckZeroInitializable(const CXXRecordDecl *RD);
 
 public:
   CGRecordLayoutBuilder(CodeGenTypes &Types)
-    : ContainsPointerToDataMember(false), Packed(false), Types(Types),
+    : IsZeroInitializable(true), Packed(false), Types(Types),
       Alignment(0), AlignmentAsLLVMStruct(1),
       BitsAvailableInLastField(0), NextFieldOffsetInBytes(0) { }
 
@@ -143,6 +152,7 @@
   FieldTypes.clear();
   LLVMFields.clear();
   LLVMBitFields.clear();
+  LLVMNonVirtualBases.clear();
 
   LayoutFields(D);
 }
@@ -301,8 +311,7 @@
     return true;
   }
 
-  // Check if we have a pointer to data member in this field.
-  CheckForPointerToDataMember(D->getType());
+  CheckZeroInitializable(D->getType());
 
   assert(FieldOffset % 8 == 0 && "FieldOffset is not on a byte boundary!");
   uint64_t FieldOffsetInBytes = FieldOffset / 8;
@@ -319,8 +328,9 @@
 
   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)
+    if (const MaxFieldAlignmentAttr *MFAA =
+          RD->getAttr<MaxFieldAlignmentAttr>()) {
+      if (MFAA->getAlignment() != TypeAlignment * 8 && !Packed)
         return false;
     }
   }
@@ -435,16 +445,66 @@
     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());
+void CGRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *BaseDecl,
+                                                 uint64_t BaseOffset) {
+  const ASTRecordLayout &Layout = 
+    Types.getContext().getASTRecordLayout(BaseDecl);
 
-    assert(NextFieldOffsetInBytes == 0 &&
-           "VTable pointer must come first!");
-    AppendField(NextFieldOffsetInBytes, Int8PtrTy->getPointerTo());
+  uint64_t NonVirtualSize = Layout.getNonVirtualSize();
+
+  if (BaseDecl->isEmpty()) {
+    // FIXME: Lay out empty bases.
+    return;
+  }
+
+  CheckZeroInitializable(BaseDecl);
+
+  // FIXME: Actually use a better type than [sizeof(BaseDecl) x i8] when we can.
+  AppendPadding(BaseOffset / 8, 1);
+  
+  // Append the base field.
+  LLVMNonVirtualBases.push_back(LLVMBaseInfo(BaseDecl, FieldTypes.size()));
+
+  AppendBytes(NonVirtualSize / 8);
+}
+
+void
+CGRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD,
+                                             const ASTRecordLayout &Layout) {
+  const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+
+  // Check if we need to add a vtable pointer.
+  if (RD->isDynamicClass()) {
+    if (!PrimaryBase) {
+      const llvm::Type *FunctionType =
+        llvm::FunctionType::get(llvm::Type::getInt32Ty(Types.getLLVMContext()),
+                                /*isVarArg=*/true);
+      const llvm::Type *VTableTy = FunctionType->getPointerTo();
+
+      assert(NextFieldOffsetInBytes == 0 &&
+             "VTable pointer must come first!");
+      AppendField(NextFieldOffsetInBytes, VTableTy->getPointerTo());
+    } else {
+      // FIXME: Handle a virtual primary base.
+      if (!Layout.getPrimaryBaseWasVirtual())
+        LayoutNonVirtualBase(PrimaryBase, 0);
+    }
+  }
+
+  // Layout the non-virtual 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());
+
+    // We've already laid out the primary base.
+    if (BaseDecl == PrimaryBase && !Layout.getPrimaryBaseWasVirtual())
+      continue;
+
+    LayoutNonVirtualBase(BaseDecl, Layout.getBaseClassOffset(BaseDecl));
   }
 }
 
@@ -455,7 +515,7 @@
   const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(D);
 
   if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
-    LayoutBases(RD, Layout);
+    LayoutNonVirtualBases(RD, Layout);
 
   unsigned FieldNo = 0;
 
@@ -542,9 +602,9 @@
   return Types.getTargetData().getABITypeAlignment(Ty);
 }
 
-void CGRecordLayoutBuilder::CheckForPointerToDataMember(QualType T) {
+void CGRecordLayoutBuilder::CheckZeroInitializable(QualType T) {
   // This record already contains a member pointer.
-  if (ContainsPointerToDataMember)
+  if (!IsZeroInitializable)
     return;
 
   // Can only have member pointers if we're compiling C++.
@@ -554,24 +614,29 @@
   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;
-    }
+    if (!Types.getCXXABI().isZeroInitializable(MPT))
+      IsZeroInitializable = false;
   } 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;
+    CheckZeroInitializable(RD);
   }
 }
 
+void CGRecordLayoutBuilder::CheckZeroInitializable(const CXXRecordDecl *RD) {
+  // This record already contains a member pointer.
+  if (!IsZeroInitializable)
+    return;
+
+  // 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.isZeroInitializable())
+    IsZeroInitializable = false;
+}
+
 CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {
   CGRecordLayoutBuilder Builder(*this);
 
@@ -582,15 +647,19 @@
                                                Builder.Packed);
 
   CGRecordLayout *RL =
-    new CGRecordLayout(Ty, Builder.ContainsPointerToDataMember);
+    new CGRecordLayout(Ty, Builder.IsZeroInitializable);
+
+  // Add all the non-virtual base field numbers.
+  RL->NonVirtualBaseFields.insert(Builder.LLVMNonVirtualBases.begin(),
+                                  Builder.LLVMNonVirtualBases.end());
 
   // Add all the field numbers.
-  for (unsigned i = 0, e = Builder.LLVMFields.size(); i != e; ++i)
-    RL->FieldInfo.insert(Builder.LLVMFields[i]);
+  RL->FieldInfo.insert(Builder.LLVMFields.begin(),
+                       Builder.LLVMFields.end());
 
   // Add bitfield info.
-  for (unsigned i = 0, e = Builder.LLVMBitFields.size(); i != e; ++i)
-    RL->BitFields.insert(Builder.LLVMBitFields[i]);
+  RL->BitFields.insert(Builder.LLVMBitFields.begin(),
+                       Builder.LLVMBitFields.end());
 
   // Dump the layout, if requested.
   if (getContext().getLangOptions().DumpRecordLayouts) {
@@ -649,7 +718,7 @@
 void CGRecordLayout::print(llvm::raw_ostream &OS) const {
   OS << "<CGRecordLayout\n";
   OS << "  LLVMType:" << *LLVMType << "\n";
-  OS << "  ContainsPointerToDataMember:" << ContainsPointerToDataMember << "\n";
+  OS << "  IsZeroInitializable:" << IsZeroInitializable << "\n";
   OS << "  BitFields:[\n";
 
   // Print bit-field infos in declaration order.
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index a914c80..16145f7 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -30,8 +30,12 @@
 
 void CodeGenFunction::EmitStopPoint(const Stmt *S) {
   if (CGDebugInfo *DI = getDebugInfo()) {
-    DI->setLocation(S->getLocStart());
-    DI->EmitStopPoint(CurFn, Builder);
+    if (isa<DeclStmt>(S))
+      DI->setLocation(S->getLocEnd());
+    else
+      DI->setLocation(S->getLocStart());
+    DI->UpdateLineDirectiveRegion(Builder);
+    DI->EmitStopPoint(Builder);
   }
 }
 
@@ -149,11 +153,11 @@
   CGDebugInfo *DI = getDebugInfo();
   if (DI) {
     DI->setLocation(S.getLBracLoc());
-    DI->EmitRegionStart(CurFn, Builder);
+    DI->EmitRegionStart(Builder);
   }
 
   // Keep track of the current cleanup stack depth.
-  CleanupScope Scope(*this);
+  RunCleanupsScope Scope(*this);
 
   for (CompoundStmt::const_body_iterator I = S.body_begin(),
        E = S.body_end()-GetLast; I != E; ++I)
@@ -161,7 +165,7 @@
 
   if (DI) {
     DI->setLocation(S.getRBracLoc());
-    DI->EmitRegionEnd(CurFn, Builder);
+    DI->EmitRegionEnd(Builder);
   }
 
   RValue RV;
@@ -192,7 +196,7 @@
   // 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())
+  if (!EHStack.empty())
     return;
 
   // Can only simplify direct branches.
@@ -215,18 +219,6 @@
     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())
@@ -253,8 +245,38 @@
   Builder.ClearInsertionPoint();
 }
 
+CodeGenFunction::JumpDest
+CodeGenFunction::getJumpDestForLabel(const LabelStmt *S) {
+  JumpDest &Dest = LabelMap[S];
+  if (Dest.isValid()) return Dest;
+
+  // Create, but don't insert, the new block.
+  Dest = JumpDest(createBasicBlock(S->getName()),
+                  EHScopeStack::stable_iterator::invalid(),
+                  NextCleanupDestIndex++);
+  return Dest;
+}
+
 void CodeGenFunction::EmitLabel(const LabelStmt &S) {
-  EmitBlock(getBasicBlockForLabel(&S));
+  JumpDest &Dest = LabelMap[&S];
+
+  // If we didn't need a forward reference to this label, just go
+  // ahead and create a destination at the current scope.
+  if (!Dest.isValid()) {
+    Dest = getJumpDestInCurrentScope(S.getName());
+
+  // Otherwise, we need to give this label a target depth and remove
+  // it from the branch-fixups list.
+  } else {
+    assert(!Dest.getScopeDepth().isValid() && "already emitted label!");
+    Dest = JumpDest(Dest.getBlock(),
+                    EHStack.stable_begin(),
+                    Dest.getDestIndex());
+
+    ResolveBranchFixups(Dest.getBlock());
+  }
+
+  EmitBlock(Dest.getBlock());
 }
 
 
@@ -270,7 +292,7 @@
   if (HaveInsertPoint())
     EmitStopPoint(&S);
 
-  EmitBranchThroughCleanup(getBasicBlockForLabel(S.getLabel()));
+  EmitBranchThroughCleanup(getJumpDestForLabel(S.getLabel()));
 }
 
 
@@ -295,7 +317,7 @@
 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);
+  RunCleanupsScope ConditionScope(*this);
 
   if (S.getConditionVariable())
     EmitLocalBlockVarDecl(*S.getConditionVariable());
@@ -312,7 +334,7 @@
     // This avoids emitting dead code and simplifies the CFG substantially.
     if (!ContainsLabel(Skipped)) {
       if (Executed) {
-        CleanupScope ExecutedScope(*this);
+        RunCleanupsScope ExecutedScope(*this);
         EmitStmt(Executed);
       }
       return;
@@ -331,7 +353,7 @@
   // Emit the 'then' code.
   EmitBlock(ThenBlock); 
   {
-    CleanupScope ThenScope(*this);
+    RunCleanupsScope ThenScope(*this);
     EmitStmt(S.getThen());
   }
   EmitBranch(ContBlock);
@@ -340,7 +362,7 @@
   if (const Stmt *Else = S.getElse()) {
     EmitBlock(ElseBlock);
     {
-      CleanupScope ElseScope(*this);
+      RunCleanupsScope ElseScope(*this);
       EmitStmt(Else);
     }
     EmitBranch(ContBlock);
@@ -351,20 +373,17 @@
 }
 
 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);
+  // Emit the header for the loop, which will also become
+  // the continue target.
+  JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond");
+  EmitBlock(LoopHeader.getBlock());
 
-  // 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;
+  // Create an exit block for when the condition fails, which will
+  // also become the break target.
+  JumpDest LoopExit = getJumpDestInCurrentScope("while.end");
 
   // Store the blocks to use for break and continue.
-  BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader));
+  BreakContinueStack.push_back(BreakContinue(LoopExit, LoopHeader));
 
   // C++ [stmt.while]p2:
   //   When the condition of a while statement is a declaration, the
@@ -373,18 +392,10 @@
   //   [...]
   //   The object created in a condition is destroyed and created
   //   with each iteration of the loop.
-  CleanupScope ConditionScope(*this);
+  RunCleanupsScope ConditionScope(*this);
 
-  if (S.getConditionVariable()) {
+  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
@@ -399,61 +410,63 @@
       EmitBoolCondBranch = false;
 
   // As long as the condition is true, go to the loop body.
-  if (EmitBoolCondBranch)
-    Builder.CreateCondBr(BoolCondVal, LoopBody, EffectiveExitBlock);
+  llvm::BasicBlock *LoopBody = createBasicBlock("while.body");
+  if (EmitBoolCondBranch) {
+    llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
+    if (ConditionScope.requiresCleanups())
+      ExitBlock = createBasicBlock("while.exit");
+
+    Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
+
+    if (ExitBlock != LoopExit.getBlock()) {
+      EmitBlock(ExitBlock);
+      EmitBranchThroughCleanup(LoopExit);
+    }
+  }
  
-  // Emit the loop body.
+  // Emit the loop body.  We have to emit this in a cleanup scope
+  // because it might be a singleton DeclStmt.
   {
-    CleanupScope BodyScope(*this);
+    RunCleanupsScope 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);
+  // Immediately force cleanup.
+  ConditionScope.ForceCleanup();
 
-    // 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);
-  }
+  // Branch to the loop header again.
+  EmitBranch(LoopHeader.getBlock());
 
   // Emit the exit block.
-  EmitBlock(ExitBlock, true);
-
+  EmitBlock(LoopExit.getBlock(), true);
 
   // The LoopHeader typically is just a branch if we skipped emitting
   // a branch, try to erase it.
-  if (!EmitBoolCondBranch && !CleanupBlock)
-    SimplifyForwardingBlocks(LoopHeader);
+  if (!EmitBoolCondBranch)
+    SimplifyForwardingBlocks(LoopHeader.getBlock());
 }
 
 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");
+  JumpDest LoopExit = getJumpDestInCurrentScope("do.end");
+  JumpDest LoopCond = getJumpDestInCurrentScope("do.cond");
 
   // Store the blocks to use for break and continue.
-  BreakContinueStack.push_back(BreakContinue(AfterDo, DoCond));
+  BreakContinueStack.push_back(BreakContinue(LoopExit, LoopCond));
 
-  // Emit the body of the loop into the block.
-  EmitStmt(S.getBody());
+  // Emit the body of the loop.
+  llvm::BasicBlock *LoopBody = createBasicBlock("do.body");
+  EmitBlock(LoopBody);
+  {
+    RunCleanupsScope BodyScope(*this);
+    EmitStmt(S.getBody());
+  }
 
   BreakContinueStack.pop_back();
 
-  EmitBlock(DoCond);
+  EmitBlock(LoopCond.getBlock());
 
   // C99 6.8.5.2: "The evaluation of the controlling expression takes place
   // after each execution of the loop body."
@@ -472,49 +485,55 @@
 
   // As long as the condition is true, iterate the loop.
   if (EmitBoolCondBranch)
-    Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo);
+    Builder.CreateCondBr(BoolCondVal, LoopBody, LoopExit.getBlock());
 
   // Emit the exit block.
-  EmitBlock(AfterDo);
+  EmitBlock(LoopExit.getBlock());
 
   // The DoCond block typically is just a branch if we skipped
   // emitting a branch, try to erase it.
   if (!EmitBoolCondBranch)
-    SimplifyForwardingBlocks(DoCond);
+    SimplifyForwardingBlocks(LoopCond.getBlock());
 }
 
 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);
+  JumpDest LoopExit = getJumpDestInCurrentScope("for.end");
+
+  RunCleanupsScope ForScope(*this);
+
+  CGDebugInfo *DI = getDebugInfo();
+  if (DI) {
+    DI->setLocation(S.getSourceRange().getBegin());
+    DI->EmitRegionStart(Builder);
+  }
 
   // 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;
+  // If there's an increment, the continue scope will be overwritten
+  // later.
+  JumpDest Continue = getJumpDestInCurrentScope("for.cond");
+  llvm::BasicBlock *CondBlock = Continue.getBlock();
   EmitBlock(CondBlock);
 
   // Create a cleanup scope for the condition variable cleanups.
-  CleanupScope ConditionScope(*this);
+  RunCleanupsScope ConditionScope(*this);
   
   llvm::Value *BoolCondVal = 0;
   if (S.getCond()) {
     // If the for statement has a condition scope, emit the local variable
     // declaration.
+    llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
     if (S.getConditionVariable()) {
       EmitLocalBlockVarDecl(*S.getConditionVariable());
-      
-      if (ConditionScope.requiresCleanups()) {
-        CondCleanup = createBasicBlock("for.cond.cleanup");
-        EffectiveExitBlock = CondCleanup;
-      }
     }
+
+    // If there are any cleanups between here and the loop-exit scope,
+    // create a block to stage a loop exit along.
+    if (ForScope.requiresCleanups())
+      ExitBlock = createBasicBlock("for.cond.cleanup");
     
     // As long as the condition is true, iterate the loop.
     llvm::BasicBlock *ForBody = createBasicBlock("for.body");
@@ -522,7 +541,12 @@
     // 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);
+    Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock);
+
+    if (ExitBlock != LoopExit.getBlock()) {
+      EmitBlock(ExitBlock);
+      EmitBranchThroughCleanup(LoopExit);
+    }
 
     EmitBlock(ForBody);
   } else {
@@ -531,57 +555,42 @@
   }
 
   // If the for loop doesn't have an increment we can just use the
-  // condition as the continue block.
-  llvm::BasicBlock *ContinueBlock;
+  // condition as the continue block.  Otherwise we'll need to create
+  // a block for it (in the current scope, i.e. in the scope of the
+  // condition), and that we will become our continue block.
   if (S.getInc())
-    ContinueBlock = IncBlock = createBasicBlock("for.inc");
-  else
-    ContinueBlock = CondBlock;
+    Continue = getJumpDestInCurrentScope("for.inc");
 
   // 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);
-  }
+  BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
 
   {
     // Create a separate cleanup scope for the body, in case it is not
     // a compound statement.
-    CleanupScope BodyScope(*this);
+    RunCleanupsScope BodyScope(*this);
     EmitStmt(S.getBody());
   }
 
+  // If there is an increment, emit it next.
+  if (S.getInc()) {
+    EmitBlock(Continue.getBlock());
+    EmitStmt(S.getInc());
+  }
+
   BreakContinueStack.pop_back();
 
-  // If there is an increment, emit it next.
-  if (S.getInc()) {
-    EmitBlock(IncBlock);
-    EmitStmt(S.getInc());
-  }
+  ConditionScope.ForceCleanup();
+  EmitBranch(CondBlock);
 
-  // Finally, branch back up to the condition for the next iteration.
-  if (CondCleanup) {
-    // Branch to the cleanup block.
-    EmitBranch(CondCleanup);
+  ForScope.ForceCleanup();
 
-    // 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);
+    DI->EmitRegionEnd(Builder);
   }
 
   // Emit the fall-through block.
-  EmitBlock(AfterFor, true);
+  EmitBlock(LoopExit.getBlock(), true);
 }
 
 void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) {
@@ -604,7 +613,20 @@
 
   // FIXME: Clean this up by using an LValue for ReturnTemp,
   // EmitStoreThroughLValue, and EmitAnyExpr.
-  if (!ReturnValue) {
+  if (S.getNRVOCandidate() && S.getNRVOCandidate()->isNRVOVariable() &&
+      !Target.useGlobalsForAutomaticVariables()) {
+    // Apply the named return value optimization for this return statement,
+    // which means doing nothing: the appropriate result has already been
+    // constructed into the NRVO variable.
+    
+    // If there is an NRVO flag for this variable, set it to 1 into indicate
+    // that the cleanup code should not destroy the variable.
+    if (llvm::Value *NRVOFlag = NRVOFlags[S.getNRVOCandidate()]) {
+      const llvm::Type *BoolTy = llvm::Type::getInt1Ty(VMContext);
+      llvm::Value *One = llvm::ConstantInt::get(BoolTy, 1);
+      Builder.CreateStore(One, NRVOFlag);
+    }
+  } else if (!ReturnValue) {
     // Make sure not to return anything, but evaluate the expression
     // for side effects.
     if (RV)
@@ -614,7 +636,7 @@
   } 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);
+    RValue Result = EmitReferenceBindingToExpr(RV, /*InitializedDecl=*/0);
     Builder.CreateStore(Result.getScalarVal(), ReturnValue);
   } else if (!hasAggregateLLVMType(RV->getType())) {
     Builder.CreateStore(EmitScalarExpr(RV), ReturnValue);
@@ -649,7 +671,7 @@
   if (HaveInsertPoint())
     EmitStopPoint(&S);
 
-  llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock;
+  JumpDest Block = BreakContinueStack.back().BreakBlock;
   EmitBranchThroughCleanup(Block);
 }
 
@@ -662,7 +684,7 @@
   if (HaveInsertPoint())
     EmitStopPoint(&S);
 
-  llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock;
+  JumpDest Block = BreakContinueStack.back().ContinueBlock;
   EmitBranchThroughCleanup(Block);
 }
 
@@ -771,7 +793,9 @@
 }
 
 void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
-  CleanupScope ConditionScope(*this);
+  JumpDest SwitchExit = getJumpDestInCurrentScope("sw.epilog");
+
+  RunCleanupsScope ConditionScope(*this);
 
   if (S.getConditionVariable())
     EmitLocalBlockVarDecl(*S.getConditionVariable());
@@ -786,7 +810,6 @@
   // 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;
@@ -796,12 +819,11 @@
 
   // All break statements jump to NextBlock. If BreakContinueStack is non empty
   // then reuse last ContinueBlock.
-  llvm::BasicBlock *ContinueBlock = 0;
+  JumpDest OuterContinue;
   if (!BreakContinueStack.empty())
-    ContinueBlock = BreakContinueStack.back().ContinueBlock;
+    OuterContinue = BreakContinueStack.back().ContinueBlock;
 
-  // Ensure any vlas created between there and here, are undone
-  BreakContinueStack.push_back(BreakContinue(NextBlock, ContinueBlock));
+  BreakContinueStack.push_back(BreakContinue(SwitchExit, OuterContinue));
 
   // Emit switch body.
   EmitStmt(S.getBody());
@@ -812,15 +834,24 @@
   // been chained on top.
   SwitchInsn->setSuccessor(0, CaseRangeBlock);
 
-  // If a default was never emitted then reroute any jumps to it and
-  // discard.
+  // If a default was never emitted:
   if (!DefaultBlock->getParent()) {
-    DefaultBlock->replaceAllUsesWith(NextBlock);
-    delete DefaultBlock;
+    // If we have cleanups, emit the default block so that there's a
+    // place to jump through the cleanups from.
+    if (ConditionScope.requiresCleanups()) {
+      EmitBlock(DefaultBlock);
+
+    // Otherwise, just forward the default block to the switch end.
+    } else {
+      DefaultBlock->replaceAllUsesWith(SwitchExit.getBlock());
+      delete DefaultBlock;
+    }
   }
 
+  ConditionScope.ForceCleanup();
+
   // Emit continuation.
-  EmitBlock(NextBlock, true);
+  EmitBlock(SwitchExit.getBlock(), true);
 
   SwitchInsn = SavedSwitchInsn;
   CaseRangeBlock = SavedCRBlock;
@@ -830,16 +861,24 @@
 SimplifyConstraint(const char *Constraint, const TargetInfo &Target,
                  llvm::SmallVectorImpl<TargetInfo::ConstraintInfo> *OutCons=0) {
   std::string Result;
+  std::string tmp;
 
   while (*Constraint) {
     switch (*Constraint) {
     default:
-      Result += Target.convertConstraint(*Constraint);
+      tmp = Target.convertConstraint(*Constraint);
+      if (Result.find(tmp) == std::string::npos) // Combine unique constraints
+        Result += tmp;
       break;
     // Ignore these
     case '*':
     case '?':
     case '!':
+    case '=': // Will see this and the following in mult-alt constraints.
+    case '+':
+      break;
+    case ',':                 // FIXME - Until the back-end properly supports
+              return Result;  // multiple alternative constraints, we stop here.
       break;
     case 'g':
       Result += "imr";
@@ -863,40 +902,50 @@
   return Result;
 }
 
-llvm::Value* CodeGenFunction::EmitAsmInput(const AsmStmt &S,
-                                         const TargetInfo::ConstraintInfo &Info,
-                                           const Expr *InputExpr,
-                                           std::string &ConstraintStr) {
+llvm::Value*
+CodeGenFunction::EmitAsmInputLValue(const AsmStmt &S,
+                                    const TargetInfo::ConstraintInfo &Info,
+                                    LValue InputValue, QualType InputType,
+                                    std::string &ConstraintStr) {
   llvm::Value *Arg;
   if (Info.allowsRegister() || !Info.allowsMemory()) {
-    if (!CodeGenFunction::hasAggregateLLVMType(InputExpr->getType())) {
-      Arg = EmitScalarExpr(InputExpr);
+    if (!CodeGenFunction::hasAggregateLLVMType(InputType)) {
+      Arg = EmitLoadOfLValue(InputValue, InputType).getScalarVal();
     } else {
-      InputExpr = InputExpr->IgnoreParenNoopCasts(getContext());
-      LValue Dest = EmitLValue(InputExpr);
-
-      const llvm::Type *Ty = ConvertType(InputExpr->getType());
+      const llvm::Type *Ty = ConvertType(InputType);
       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));
+        Arg = Builder.CreateLoad(Builder.CreateBitCast(InputValue.getAddress(),
+                                                       Ty));
       } else {
-        Arg = Dest.getAddress();
+        Arg = InputValue.getAddress();
         ConstraintStr += '*';
       }
     }
   } else {
-    InputExpr = InputExpr->IgnoreParenNoopCasts(getContext());
-    LValue Dest = EmitLValue(InputExpr);
-    Arg = Dest.getAddress();
+    Arg = InputValue.getAddress();
     ConstraintStr += '*';
   }
 
   return Arg;
 }
 
+llvm::Value* CodeGenFunction::EmitAsmInput(const AsmStmt &S,
+                                         const TargetInfo::ConstraintInfo &Info,
+                                           const Expr *InputExpr,
+                                           std::string &ConstraintStr) {
+  if (Info.allowsRegister() || !Info.allowsMemory())
+    if (!CodeGenFunction::hasAggregateLLVMType(InputExpr->getType()))
+      return EmitScalarExpr(InputExpr);
+
+  InputExpr = InputExpr->IgnoreParenNoopCasts(getContext());
+  LValue Dest = EmitLValue(InputExpr);
+  return EmitAsmInputLValue(S, Info, Dest, InputExpr->getType(), ConstraintStr);
+}
+
 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.
@@ -1006,7 +1055,8 @@
       InOutConstraints += ',';
 
       const Expr *InputExpr = S.getOutputExpr(i);
-      llvm::Value *Arg = EmitAsmInput(S, Info, InputExpr, InOutConstraints);
+      llvm::Value *Arg = EmitAsmInputLValue(S, Info, Dest, InputExpr->getType(),
+                                            InOutConstraints);
 
       if (Info.allowsRegister())
         InOutConstraints += llvm::utostr(i);
@@ -1049,8 +1099,7 @@
           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));
+          Arg = Builder.CreatePtrToInt(Arg, IntPtrTy);
         const llvm::Type *OutputTy = ConvertType(OutputType);
         if (isa<llvm::IntegerType>(OutputTy))
           Arg = Builder.CreateZExt(Arg, OutputTy);
@@ -1115,7 +1164,7 @@
   // call.
   unsigned LocID = S.getAsmString()->getLocStart().getRawEncoding();
   llvm::Value *LocIDC =
-    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), LocID);
+    llvm::ConstantInt::get(Int32Ty, LocID);
   Result->setMetadata("srcloc", llvm::MDNode::get(VMContext, &LocIDC, 1));
 
   // Extract all of the register value results from the asm.
diff --git a/lib/CodeGen/CGTemporaries.cpp b/lib/CodeGen/CGTemporaries.cpp
index d6d3be5..dfb8dc6 100644
--- a/lib/CodeGen/CGTemporaries.cpp
+++ b/lib/CodeGen/CGTemporaries.cpp
@@ -15,14 +15,47 @@
 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");
+namespace {
+  struct DestroyTemporary : EHScopeStack::Cleanup {
+    const CXXTemporary *Temporary;
+    llvm::Value *Addr;
+    llvm::Value *CondPtr;
 
+    DestroyTemporary(const CXXTemporary *Temporary, llvm::Value *Addr,
+                     llvm::Value *CondPtr)
+      : Temporary(Temporary), Addr(Addr), CondPtr(CondPtr) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      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 (CondPtr) {
+        llvm::BasicBlock *CondBlock =
+          CGF.createBasicBlock("temp.cond-dtor.call");
+        CondEnd = CGF.createBasicBlock("temp.cond-dtor.cont");
+
+        llvm::Value *Cond = CGF.Builder.CreateLoad(CondPtr);
+        CGF.Builder.CreateCondBr(Cond, CondBlock, CondEnd);
+        CGF.EmitBlock(CondBlock);
+      }
+
+      CGF.EmitCXXDestructorCall(Temporary->getDestructor(),
+                                Dtor_Complete, /*ForVirtualBase=*/false,
+                                Addr);
+
+      if (CondPtr) {
+        // Reset the condition to false.
+        CGF.Builder.CreateStore(CGF.Builder.getFalse(), CondPtr);
+        CGF.EmitBlock(CondEnd);
+      }
+    }
+  };
+}
+
+/// Emits all the code to cause the given temporary to be cleaned up.
+void CodeGenFunction::EmitCXXTemporary(const CXXTemporary *Temporary,
+                                       llvm::Value *Ptr) {
   llvm::AllocaInst *CondPtr = 0;
 
   // Check if temporaries need to be conditional. If so, we'll create a
@@ -35,84 +68,11 @@
     InitTempAlloca(CondPtr, llvm::ConstantInt::getFalse(VMContext));
 
     // Now set it to true.
-    Builder.CreateStore(llvm::ConstantInt::getTrue(VMContext), CondPtr);
+    Builder.CreateStore(Builder.getTrue(), 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();
+  EHStack.pushCleanup<DestroyTemporary>(NormalAndEHCleanup,
+                                        Temporary, Ptr, CondPtr);
 }
 
 RValue
@@ -120,40 +80,13 @@
                                             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,
+  RunCleanupsScope Scope(*this);
+  return 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;
+  RunCleanupsScope Scope(*this);
+  return EmitLValue(E->getSubExpr());
 }
diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp
index 68bb655..61c7423 100644
--- a/lib/CodeGen/CGVTT.cpp
+++ b/lib/CodeGen/CGVTT.cpp
@@ -43,7 +43,7 @@
 
   /// SubVTTIndicies - The sub-VTT indices for the bases of the most derived
   /// class.
-  llvm::DenseMap<const CXXRecordDecl *, uint64_t> SubVTTIndicies;
+  llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
 
   /// SecondaryVirtualPointerIndices - The secondary virtual pointer indices of
   /// all subobjects of the most derived class.
@@ -116,8 +116,7 @@
   }
   
   /// getSubVTTIndicies - Returns a reference to the sub-VTT indices.
-  const llvm::DenseMap<const CXXRecordDecl *, uint64_t> &
-  getSubVTTIndicies() const {
+  const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
     return SubVTTIndicies;
   }
   
@@ -341,7 +340,7 @@
 
   if (!IsPrimaryVTT) {
     // Remember the sub-VTT index.
-    SubVTTIndicies[RD] = VTTComponents.size();
+    SubVTTIndicies[Base] = VTTComponents.size();
   }
 
   AddressPointsMapTy AddressPoints;
@@ -379,7 +378,7 @@
 
   D1(printf("vtt %s\n", RD->getNameAsCString()));
 
-  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
+  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
   if (GV == 0 || GV->isDeclaration()) {
     const llvm::Type *Int8PtrTy = 
       llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
@@ -435,25 +434,25 @@
 }
 
 uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD, 
-                                        const CXXRecordDecl *Base) {
-  ClassPairTy ClassPair(RD, Base);
+                                        BaseSubobject Base) {
+  BaseSubobjectPairTy ClassSubobjectPair(RD, Base);
 
-  SubVTTIndiciesMapTy::iterator I = SubVTTIndicies.find(ClassPair);
+  SubVTTIndiciesMapTy::iterator I = SubVTTIndicies.find(ClassSubobjectPair);
   if (I != SubVTTIndicies.end())
     return I->second;
   
   VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
 
-  for (llvm::DenseMap<const CXXRecordDecl *, uint64_t>::const_iterator I =
+  for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
        Builder.getSubVTTIndicies().begin(), 
        E = Builder.getSubVTTIndicies().end(); I != E; ++I) {
     // Insert all indices.
-    ClassPairTy ClassPair(RD, I->first);
+    BaseSubobjectPairTy ClassSubobjectPair(RD, I->first);
     
-    SubVTTIndicies.insert(std::make_pair(ClassPair, I->second));
+    SubVTTIndicies.insert(std::make_pair(ClassSubobjectPair, I->second));
   }
     
-  I = SubVTTIndicies.find(ClassPair);
+  I = SubVTTIndicies.find(ClassSubobjectPair);
   assert(I != SubVTTIndicies.end() && "Did not find index!");
   
   return I->second;
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index 159753a..22701c2 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -15,6 +15,7 @@
 #include "CodeGenFunction.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/RecordLayout.h"
+#include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/Support/Compiler.h"
@@ -87,112 +88,61 @@
   /// MostDerivedClassLayout - the AST record layout of the most derived class.
   const ASTRecordLayout &MostDerivedClassLayout;
 
-  /// BaseSubobjectMethodPairTy - Uniquely identifies a member function
+  /// MethodBaseOffsetPairTy - Uniquely identifies a member function
   /// in a base subobject.
-  typedef std::pair<BaseSubobject, const CXXMethodDecl *>
-    BaseSubobjectMethodPairTy;
-  
-  typedef llvm::DenseMap<BaseSubobjectMethodPairTy,
+  typedef std::pair<const CXXMethodDecl *, uint64_t> MethodBaseOffsetPairTy;
+
+  typedef llvm::DenseMap<MethodBaseOffsetPairTy,
                          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;
+  /// SubobjectsToOffsetsMapTy - A mapping from a base subobject (represented
+  /// as a record decl and a subobject number) and its offsets in the most
+  /// derived class as well as the layout class.
+  typedef llvm::DenseMap<std::pair<const CXXRecordDecl *, unsigned>, 
+                         uint64_t> SubobjectOffsetMapTy;
 
-  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;
+  typedef llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCountMapTy;
   
-  /// 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);
+  /// ComputeBaseOffsets - Compute the offsets for all base subobjects of the
+  /// given base.
+  void ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual,
+                          uint64_t OffsetInLayoutClass,
+                          SubobjectOffsetMapTy &SubobjectOffsets,
+                          SubobjectOffsetMapTy &SubobjectLayoutClassOffsets,
+                          SubobjectCountMapTy &SubobjectCounts);
 
-  /// 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);
+  typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
   
-  static void MergeSubobjectOffsets(const SubobjectOffsetsMapTy &NewOffsets,
-                                    SubobjectOffsetsMapTy &Offsets);
-
+  /// 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,
+            VisitedVirtualBasesSetTy& VisitedVirtualBases);
+  
 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)) && 
+  /// the subobject with the given base offset. 
+  OverriderInfo getOverrider(const CXXMethodDecl *MD, 
+                             uint64_t BaseOffset) const {
+    assert(OverridersMap.count(std::make_pair(MD, BaseOffset)) && 
            "Did not find overrider!");
     
-    return OverridersMap.lookup(std::make_pair(Base, MD));
+    return OverridersMap.lookup(std::make_pair(MD, BaseOffset));
   }
   
-  /// 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();
+    VisitedVirtualBasesSetTy VisitedVirtualBases;
+    dump(llvm::errs(), BaseSubobject(MostDerivedClass, 0), VisitedVirtualBases);
   }
   
-  /// 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
@@ -204,56 +154,59 @@
   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();
+
+  // Compute base offsets.
+  SubobjectOffsetMapTy SubobjectOffsets;
+  SubobjectOffsetMapTy SubobjectLayoutClassOffsets;
+  SubobjectCountMapTy SubobjectCounts;
+  ComputeBaseOffsets(BaseSubobject(MostDerivedClass, 0), /*IsVirtual=*/false,
+                     MostDerivedClassOffset, SubobjectOffsets, 
+                     SubobjectLayoutClassOffsets, SubobjectCounts);
+
+  // Get the the final overriders.
+  CXXFinalOverriderMap FinalOverriders;
+  MostDerivedClass->getFinalOverriders(FinalOverriders);
+
+  for (CXXFinalOverriderMap::const_iterator I = FinalOverriders.begin(),
+       E = FinalOverriders.end(); I != E; ++I) {
+    const CXXMethodDecl *MD = I->first;
+    const OverridingMethods& Methods = I->second;
+
+    for (OverridingMethods::const_iterator I = Methods.begin(),
+         E = Methods.end(); I != E; ++I) {
+      unsigned SubobjectNumber = I->first;
+      assert(SubobjectOffsets.count(std::make_pair(MD->getParent(), 
+                                                   SubobjectNumber)) &&
+             "Did not find subobject offset!");
+      
+      uint64_t BaseOffset = SubobjectOffsets[std::make_pair(MD->getParent(),
+                                                            SubobjectNumber)];
+
+      assert(I->second.size() == 1 && "Final overrider is not unique!");
+      const UniqueVirtualMethod &Method = I->second.front();
+
+      const CXXRecordDecl *OverriderRD = Method.Method->getParent();
+      assert(SubobjectLayoutClassOffsets.count(
+             std::make_pair(OverriderRD, Method.Subobject))
+             && "Did not find subobject offset!");
+      uint64_t OverriderOffset =
+        SubobjectLayoutClassOffsets[std::make_pair(OverriderRD, 
+                                                   Method.Subobject)];
+
+      OverriderInfo& Overrider = OverridersMap[std::make_pair(MD, BaseOffset)];
+      assert(!Overrider.Method && "Overrider should not exist yet!");
+      
+      Overrider.Offset = OverriderOffset;
+      Overrider.Method = Method.Method;
+    }
+  }
 
 #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) {
@@ -365,153 +318,64 @@
   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) {
+FinalOverriders::ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual,
+                              uint64_t OffsetInLayoutClass,
+                              SubobjectOffsetMapTy &SubobjectOffsets,
+                              SubobjectOffsetMapTy &SubobjectLayoutClassOffsets,
+                              SubobjectCountMapTy &SubobjectCounts) {
   const CXXRecordDecl *RD = Base.getBase();
-  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
   
-  SubobjectOffsetsMapTy NewOffsets;
+  unsigned SubobjectNumber = 0;
+  if (!IsVirtual)
+    SubobjectNumber = ++SubobjectCounts[RD];
+
+  // Set up the subobject to offset mapping.
+  assert(!SubobjectOffsets.count(std::make_pair(RD, SubobjectNumber))
+         && "Subobject offset already exists!");
+  assert(!SubobjectLayoutClassOffsets.count(std::make_pair(RD, SubobjectNumber)) 
+         && "Subobject offset already exists!");
+
+  SubobjectOffsets[std::make_pair(RD, SubobjectNumber)] =
+    Base.getBaseOffset();
+  SubobjectLayoutClassOffsets[std::make_pair(RD, SubobjectNumber)] =
+    OffsetInLayoutClass;
   
+  // Traverse our 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());
-    
-    // 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);
-      
+      // Check if we've visited this virtual base before.
+      if (SubobjectOffsets.count(std::make_pair(BaseDecl, 0)))
+        continue;
+
       const ASTRecordLayout &LayoutClassLayout =
         Context.getASTRecordLayout(LayoutClass);
+
+      BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
       BaseOffsetInLayoutClass = 
         LayoutClassLayout.getVBaseClassOffset(BaseDecl);
     } else {
-      BaseOffset = Layout.getBaseClassOffset(BaseDecl) + Base.getBaseOffset();
-      BaseOffsetInLayoutClass = Layout.getBaseClassOffset(BaseDecl) +
-        OffsetInLayoutClass;
-    }
+      const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+      uint64_t Offset = Layout.getBaseClassOffset(BaseDecl);
     
-    // 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);
+      BaseOffset = Base.getBaseOffset() + Offset;
+      BaseOffsetInLayoutClass = OffsetInLayoutClass + Offset;
+    }
+
+    ComputeBaseOffsets(BaseSubobject(BaseDecl, BaseOffset), I->isVirtual(),
+                       BaseOffsetInLayoutClass, SubobjectOffsets,
+                       SubobjectLayoutClassOffsets, SubobjectCounts);
   }
-
-  /// 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) {
+void FinalOverriders::dump(llvm::raw_ostream &Out, BaseSubobject Base,
+                           VisitedVirtualBasesSetTy &VisitedVirtualBases) {
   const CXXRecordDecl *RD = Base.getBase();
   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
 
@@ -537,7 +401,7 @@
         Base.getBaseOffset();
     }
 
-    dump(Out, BaseSubobject(BaseDecl, BaseOffset));
+    dump(Out, BaseSubobject(BaseDecl, BaseOffset), VisitedVirtualBases);
   }
 
   Out << "Final overriders for (" << RD->getQualifiedNameAsString() << ", ";
@@ -551,17 +415,17 @@
     if (!MD->isVirtual())
       continue;
   
-    OverriderInfo Overrider = getOverrider(Base, MD);
+    OverriderInfo Overrider = getOverrider(MD, Base.getBaseOffset());
 
     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;
+    BaseOffset Offset;
+    if (!Overrider.Method->isPure())
+      Offset = ComputeReturnAdjustmentBaseOffset(Context, Overrider.Method, MD);
 
+    if (!Offset.isEmpty()) {
       Out << " [ret-adj: ";
       if (Offset.VirtualBase)
         Out << Offset.VirtualBase->getQualifiedNameAsString() << " vbase, ";
@@ -1013,7 +877,7 @@
     if (Overriders) {
       // Get the final overrider.
       FinalOverriders::OverriderInfo Overrider = 
-        Overriders->getOverrider(Base, MD);
+        Overriders->getOverrider(MD, Base.getBaseOffset());
       
       /// The vcall offset is the offset from the virtual base to the object 
       /// where the function was overridden.
@@ -1390,8 +1254,7 @@
     
     // Get the final overrider for this method.
     FinalOverriders::OverriderInfo Overrider =
-      Overriders.getOverrider(BaseSubobject(MD->getParent(), 
-                                            MethodInfo.BaseOffset), MD);
+      Overriders.getOverrider(MD, MethodInfo.BaseOffset);
     
     // Check if we need an adjustment at all.
     if (MethodInfo.BaseOffsetInLayoutClass == Overrider.Offset) {
@@ -1763,7 +1626,7 @@
 
     // Get the final overrider.
     FinalOverriders::OverriderInfo Overrider = 
-      Overriders.getOverrider(Base, MD);
+      Overriders.getOverrider(MD, Base.getBaseOffset());
 
     // 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
@@ -1828,8 +1691,12 @@
     }
     
     // Check if this overrider needs a return adjustment.
-    BaseOffset ReturnAdjustmentOffset = 
-      Overriders.getReturnAdjustmentOffset(Base, MD);
+    // We don't want to do this for pure virtual member functions.
+    BaseOffset ReturnAdjustmentOffset;
+    if (!OverriderMD->isPure()) {
+      ReturnAdjustmentOffset = 
+        ComputeReturnAdjustmentBaseOffset(Context, OverriderMD, MD);
+    }
 
     ReturnAdjustment ReturnAdjustment = 
       ComputeReturnAdjustment(ReturnAdjustmentOffset);
@@ -2548,7 +2415,7 @@
     getMangleContext().mangleThunk(MD, Thunk, Name);
   
   const llvm::Type *Ty = getTypes().GetFunctionTypeForVTable(MD);
-  return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl());
+  return GetOrCreateLLVMFunction(Name, Ty, GD);
 }
 
 static llvm::Value *PerformTypeAdjustment(CodeGenFunction &CGF,
@@ -2594,6 +2461,54 @@
   return CGF.Builder.CreateBitCast(V, Ptr->getType());
 }
 
+static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD,
+                               const ThunkInfo &Thunk, llvm::Function *Fn) {
+  CGM.setGlobalVisibility(Fn, MD);
+
+  if (!CGM.getCodeGenOpts().HiddenWeakVTables)
+    return;
+
+  // If the thunk has weak/linkonce linkage, but the function must be
+  // emitted in every translation unit that references it, then we can
+  // emit its thunks with hidden visibility, since its thunks must be
+  // emitted when the function is.
+
+  // This follows CodeGenModule::setTypeVisibility; see the comments
+  // there for explanation.
+
+  if ((Fn->getLinkage() != llvm::GlobalVariable::LinkOnceODRLinkage &&
+       Fn->getLinkage() != llvm::GlobalVariable::WeakODRLinkage) ||
+      Fn->getVisibility() != llvm::GlobalVariable::DefaultVisibility)
+    return;
+
+  if (MD->hasAttr<VisibilityAttr>())
+    return;
+
+  switch (MD->getTemplateSpecializationKind()) {
+  case TSK_ExplicitInstantiationDefinition:
+  case TSK_ExplicitInstantiationDeclaration:
+    return;
+
+  case TSK_Undeclared:
+    break;
+
+  case TSK_ExplicitSpecialization:
+  case TSK_ImplicitInstantiation:
+    if (!CGM.getCodeGenOpts().HiddenWeakTemplateVTables)
+      return;
+    break;
+  }
+
+  // If there's an explicit definition, and that definition is
+  // out-of-line, then we can't assume that all users will have a
+  // definition to emit.
+  const FunctionDecl *Def = 0;
+  if (MD->hasBody(Def) && Def->isOutOfLine())
+    return;
+
+  Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
+}
+
 void CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD,
                                     const ThunkInfo &Thunk) {
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
@@ -2641,10 +2556,9 @@
        E = MD->param_end(); I != E; ++I) {
     ParmVarDecl *Param = *I;
     QualType ArgType = Param->getType();
+    RValue Arg = EmitDelegateCallArg(Param);
     
-    // 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));
+    CallArgs.push_back(std::make_pair(Arg, ArgType));
   }
 
   // Get our callee.
@@ -2657,8 +2571,15 @@
     CGM.getTypes().getFunctionInfo(ResultType, CallArgs,
                                    FPT->getExtInfo());
   
+  // Determine whether we have a return value slot to use.
+  ReturnValueSlot Slot;
+  if (!ResultType->isVoidType() &&
+      FnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect &&
+      hasAggregateLLVMType(CurFnInfo->getReturnType()))
+    Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified());
+  
   // Now emit our call.
-  RValue RV = EmitCall(FnInfo, Callee, ReturnValueSlot(), CallArgs, MD);
+  RValue RV = EmitCall(FnInfo, Callee, Slot, CallArgs, MD);
   
   if (!Thunk.Return.isEmpty()) {
     // Emit the return adjustment.
@@ -2701,19 +2622,16 @@
     RV = RValue::get(ReturnValue);
   }
 
-  if (!ResultType->isVoidType())
+  if (!ResultType->isVoidType() && Slot.isNull())
     EmitReturnOfRValue(RV, ResultType);
 
   FinishFunction();
 
-  // Destroy the 'this' declaration.
-  CXXThisDecl->Destroy(getContext());
-  
   // Set the right linkage.
-  Fn->setLinkage(CGM.getFunctionLinkage(MD));
+  CGM.setFunctionLinkage(MD, Fn);
   
   // Set the right visibility.
-  CGM.setGlobalVisibility(Fn, MD);
+  setThunkVisibility(CGM, MD, Thunk, Fn);
 }
 
 void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk)
@@ -2769,7 +2687,7 @@
   const CXXRecordDecl *RD = MD->getParent();
   
   // Compute VTable related info for this class.
-  ComputeVTableRelatedInformation(RD);
+  ComputeVTableRelatedInformation(RD, false);
   
   ThunksMapTy::const_iterator I = Thunks.find(MD);
   if (I == Thunks.end()) {
@@ -2782,18 +2700,30 @@
     EmitThunk(GD, ThunkInfoVector[I]);
 }
 
-void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) {
-  uint64_t *&LayoutData = VTableLayoutMap[RD];
+void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD,
+                                                     bool RequireVTable) {
+  VTableLayoutData &Entry = VTableLayoutMap[RD];
+
+  // We may need to generate a definition for this vtable.
+  if (RequireVTable && !Entry.getInt()) {
+    if (!isKeyFunctionInAnotherTU(CGM.getContext(), RD) &&
+        RD->getTemplateSpecializationKind()
+          != TSK_ExplicitInstantiationDeclaration)
+      CGM.DeferredVTables.push_back(RD);
+
+    Entry.setInt(true);
+  }
   
   // Check if we've computed this information before.
-  if (LayoutData)
+  if (Entry.getPointer())
     return;
-      
+
   VTableBuilder Builder(*this, RD, 0, /*MostDerivedClassIsVirtual=*/0, RD);
 
   // Add the VTable layout.
   uint64_t NumVTableComponents = Builder.getNumVTableComponents();
-  LayoutData = new uint64_t[NumVTableComponents + 1];
+  uint64_t *LayoutData = new uint64_t[NumVTableComponents + 1];
+  Entry.setPointer(LayoutData);
 
   // Store the number of components.
   LayoutData[0] = NumVTableComponents;
@@ -3008,7 +2938,7 @@
   CGM.getMangleContext().mangleCXXVTable(RD, OutName);
   llvm::StringRef Name = OutName.str();
 
-  ComputeVTableRelatedInformation(RD);
+  ComputeVTableRelatedInformation(RD, true);
   
   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
   llvm::ArrayType *ArrayType = 
@@ -3042,6 +2972,9 @@
   
   // Set the correct linkage.
   VTable->setLinkage(Linkage);
+  
+  // Set the right visibility.
+  CGM.setTypeVisibility(VTable, RD, /*ForRTTI*/ false);
 }
 
 llvm::GlobalVariable *
@@ -3119,49 +3052,3 @@
       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
index bc113ec..abcafd6 100644
--- a/lib/CodeGen/CGVTables.h
+++ b/lib/CodeGen/CGVTables.h
@@ -207,8 +207,12 @@
   
   /// Thunks - Contains all thunks that a given method decl will need.
   ThunksMapTy Thunks;
-  
-  typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t *> VTableLayoutMapTy;
+
+  // The layout entry and a bool indicating whether we've actually emitted
+  // the vtable.
+  typedef llvm::PointerIntPair<uint64_t *, 1, bool> VTableLayoutData;
+  typedef llvm::DenseMap<const CXXRecordDecl *, VTableLayoutData>
+    VTableLayoutMapTy;
   
   /// VTableLayoutMap - Stores the vtable layout for all record decls.
   /// The layout is stored as an array of 64-bit integers, where the first
@@ -216,8 +220,8 @@
   /// integers are the vtable components.
   VTableLayoutMapTy VTableLayoutMap;
 
-  typedef llvm::DenseMap<std::pair<const CXXRecordDecl *, 
-                                   BaseSubobject>, uint64_t> AddressPointsMapTy;
+  typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy;
+  typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> AddressPointsMapTy;
   
   /// Address points - Address points for all vtables.
   AddressPointsMapTy AddressPoints;
@@ -237,24 +241,22 @@
   uint64_t getNumVTableComponents(const CXXRecordDecl *RD) const {
     assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
     
-    return VTableLayoutMap.lookup(RD)[0];
+    return VTableLayoutMap.lookup(RD).getPointer()[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);
+    uint64_t *Components = VTableLayoutMap.lookup(RD).getPointer();
     return &Components[1];
   }
 
-  typedef llvm::DenseMap<ClassPairTy, uint64_t> SubVTTIndiciesMapTy;
+  typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> SubVTTIndiciesMapTy;
   
   /// SubVTTIndicies - Contains indices into the various sub-VTTs.
   SubVTTIndiciesMapTy SubVTTIndicies;
 
-   
-  typedef llvm::DenseMap<std::pair<const CXXRecordDecl *, 
-                                   BaseSubobject>, uint64_t>
+  typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t>
     SecondaryVirtualPointerIndicesMapTy;
 
   /// SecondaryVirtualPointerIndices - Contains the secondary virtual pointer
@@ -274,13 +276,11 @@
   /// 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);
+  void ComputeVTableRelatedInformation(const CXXRecordDecl *RD,
+                                       bool VTableRequired);
 
   /// CreateVTableInitializer - Create a vtable initializer for the given record
   /// decl.
@@ -301,7 +301,7 @@
 				       const CXXRecordDecl *RD) {
     assert (RD->isDynamicClass() && "Non dynamic classes have no key.");
     const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD);
-    return KeyFunction && !KeyFunction->getBody();
+    return KeyFunction && !KeyFunction->hasBody();
   }
 
   /// needsVTTParameter - Return whether the given global decl needs a VTT
@@ -311,7 +311,7 @@
 
   /// 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);
+  uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base);
   
   /// getSecondaryVirtualPointerIndex - Return the index in the VTT where the
   /// virtual pointer for the given subobject is located.
@@ -351,11 +351,10 @@
                              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);
 
+  /// EmitThunks - Emit the associated thunks for the given global decl.
+  void EmitThunks(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.
diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h
index e7343e2..f57ecd2 100644
--- a/lib/CodeGen/CGValue.h
+++ b/lib/CodeGen/CGValue.h
@@ -15,6 +15,7 @@
 #ifndef CLANG_CODEGEN_CGVALUE_H
 #define CLANG_CODEGEN_CGVALUE_H
 
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/Type.h"
 
 namespace llvm {
@@ -34,69 +35,64 @@
 /// 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;
+  enum Flavor { Scalar, Complex, Aggregate };
 
-  bool Volatile:1;
+  // Stores first value and flavor.
+  llvm::PointerIntPair<llvm::Value *, 2, Flavor> V1;
+  // Stores second value and volatility.
+  llvm::PointerIntPair<llvm::Value *, 1, bool> V2;
+
 public:
+  bool isScalar() const { return V1.getInt() == Scalar; }
+  bool isComplex() const { return V1.getInt() == Complex; }
+  bool isAggregate() const { return V1.getInt() == Aggregate; }
 
-  bool isScalar() const { return Flavor == Scalar; }
-  bool isComplex() const { return Flavor == Complex; }
-  bool isAggregate() const { return Flavor == Aggregate; }
-
-  bool isVolatileQualified() const { return Volatile; }
+  bool isVolatileQualified() const { return V2.getInt(); }
 
   /// getScalarVal() - Return the Value* of this scalar value.
   llvm::Value *getScalarVal() const {
     assert(isScalar() && "Not a scalar!");
-    return V1;
+    return V1.getPointer();
   }
 
   /// 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);
+    return std::make_pair(V1.getPointer(), V2.getPointer());
   }
 
   /// getAggregateAddr() - Return the Value* of the address of the aggregate.
   llvm::Value *getAggregateAddr() const {
     assert(isAggregate() && "Not an aggregate!");
-    return V1;
+    return V1.getPointer();
   }
 
   static RValue get(llvm::Value *V) {
     RValue ER;
-    ER.V1 = V;
-    ER.Flavor = Scalar;
-    ER.Volatile = false;
+    ER.V1.setPointer(V);
+    ER.V1.setInt(Scalar);
+    ER.V2.setInt(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;
+    ER.V1.setPointer(V1);
+    ER.V2.setPointer(V2);
+    ER.V1.setInt(Complex);
+    ER.V2.setInt(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;
+    return getComplex(C.first, C.second);
   }
   // 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) {
+  static RValue getAggregate(llvm::Value *V, bool Volatile = false) {
     RValue ER;
-    ER.V1 = V;
-    ER.Flavor = Aggregate;
-    ER.Volatile = Vol;
+    ER.V1.setPointer(V);
+    ER.V1.setInt(Aggregate);
+    ER.V2.setInt(Volatile);
     return ER;
   }
 };
@@ -141,6 +137,9 @@
   // 'const' is unused here
   Qualifiers Quals;
 
+  /// The alignment to use when accessing this lvalue.
+  unsigned short Alignment;
+
   // objective-c's ivar
   bool Ivar:1;
   
@@ -153,15 +152,20 @@
 
   // Lvalue is a global reference of an objective-c object
   bool GlobalObjCRef : 1;
+  
+  // Lvalue is a thread local reference
+  bool ThreadLocalRef : 1;
 
   Expr *BaseIvarExp;
 private:
-  void SetQualifiers(Qualifiers Quals) {
+  void Initialize(Qualifiers Quals, unsigned Alignment = 0) {
     this->Quals = Quals;
-    
-    // FIXME: Convenient place to set objc flags to 0. This should really be
-    // done in a user-defined constructor instead.
+    this->Alignment = Alignment;
+    assert(this->Alignment == Alignment && "Alignment exceeds allowed max!");
+
+    // Initialize Objective-C flags.
     this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
+    this->ThreadLocalRef = false;
     this->BaseIvarExp = 0;
   }
 
@@ -180,30 +184,36 @@
   }
 
   bool isObjCIvar() const { return Ivar; }
+  void setObjCIvar(bool Value) { Ivar = Value; }
+
   bool isObjCArray() const { return ObjIsArray; }
+  void setObjCArray(bool Value) { ObjIsArray = Value; }
+
   bool isNonGC () const { return NonGC; }
+  void setNonGC(bool Value) { NonGC = Value; }
+
   bool isGlobalObjCRef() const { return GlobalObjCRef; }
-  bool isObjCWeak() const { return Quals.getObjCGCAttr() == Qualifiers::Weak; }
-  bool isObjCStrong() const { return Quals.getObjCGCAttr() == Qualifiers::Strong; }
+  void setGlobalObjCRef(bool Value) { GlobalObjCRef = Value; }
+
+  bool isThreadLocalRef() const { return ThreadLocalRef; }
+  void setThreadLocalRef(bool Value) { ThreadLocalRef = Value;}
+
+  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; }
 
+  const Qualifiers &getQuals() const { return Quals; }
+  Qualifiers &getQuals() { return Quals; }
+
   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;
-  }
+  unsigned getAlignment() const { return Alignment; }
 
   // simple lvalue
   llvm::Value *getAddress() const { assert(isSimple()); return V; }
@@ -241,11 +251,15 @@
     return KVCRefExpr;
   }
 
-  static LValue MakeAddr(llvm::Value *V, Qualifiers Quals) {
+  static LValue MakeAddr(llvm::Value *V, QualType T, unsigned Alignment,
+                         ASTContext &Context) {
+    Qualifiers Quals = Context.getCanonicalType(T).getQualifiers();
+    Quals.setObjCGCAttr(Context.getObjCGCAttrKind(T));
+
     LValue R;
     R.LVType = Simple;
     R.V = V;
-    R.SetQualifiers(Quals);
+    R.Initialize(Quals, Alignment);
     return R;
   }
 
@@ -255,7 +269,7 @@
     R.LVType = VectorElt;
     R.V = Vec;
     R.VectorIdx = Idx;
-    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
+    R.Initialize(Qualifiers::fromCVRMask(CVR));
     return R;
   }
 
@@ -265,7 +279,7 @@
     R.LVType = ExtVectorElt;
     R.V = Vec;
     R.VectorElts = Elts;
-    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
+    R.Initialize(Qualifiers::fromCVRMask(CVR));
     return R;
   }
 
@@ -281,7 +295,7 @@
     R.LVType = BitField;
     R.V = BaseValue;
     R.BitFieldInfo = &Info;
-    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
+    R.Initialize(Qualifiers::fromCVRMask(CVR));
     return R;
   }
 
@@ -293,7 +307,7 @@
     LValue R;
     R.LVType = PropertyRef;
     R.PropertyRefExpr = E;
-    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
+    R.Initialize(Qualifiers::fromCVRMask(CVR));
     return R;
   }
 
@@ -302,7 +316,7 @@
     LValue R;
     R.LVType = KVCRef;
     R.KVCRefExpr = E;
-    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
+    R.Initialize(Qualifiers::fromCVRMask(CVR));
     return R;
   }
 };
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index dfd2a39..b5a2329 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -1,6 +1,7 @@
 set(LLVM_NO_RTTI 1)
 
 add_clang_library(clangCodeGen
+  BackendUtil.cpp
   CGBlocks.cpp
   CGBuiltin.cpp
   CGCall.cpp
@@ -25,10 +26,16 @@
   CGTemporaries.cpp
   CGVTables.cpp
   CGVTT.cpp
+  CodeGenAction.cpp
   CodeGenFunction.cpp
   CodeGenModule.cpp
   CodeGenTypes.cpp
+  ItaniumCXXABI.cpp
   Mangle.cpp
+  MicrosoftCXXABI.cpp
   ModuleBuilder.cpp
   TargetInfo.cpp
   )
+
+add_dependencies(clangCodeGen ClangAttrClasses ClangAttrList ClangDeclNodes
+                 ClangStmtNodes)
diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp
new file mode 100644
index 0000000..51c55a1
--- /dev/null
+++ b/lib/CodeGen/CodeGenAction.cpp
@@ -0,0 +1,348 @@
+//===--- 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/CodeGen/CodeGenAction.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/CodeGen/BackendUtil.h"
+#include "clang/CodeGen/ModuleBuilder.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/IRReader.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/Timer.h"
+using namespace clang;
+using namespace llvm;
+
+namespace {
+  class BackendConsumer : public ASTConsumer {
+    Diagnostic &Diags;
+    BackendAction Action;
+    const CodeGenOptions &CodeGenOpts;
+    const TargetOptions &TargetOpts;
+    llvm::raw_ostream *AsmOutStream;
+    ASTContext *Context;
+
+    Timer LLVMIRGeneration;
+
+    llvm::OwningPtr<CodeGenerator> Gen;
+
+    llvm::OwningPtr<llvm::Module> TheModule;
+
+  public:
+    BackendConsumer(BackendAction action, Diagnostic &_Diags,
+                    const CodeGenOptions &compopts,
+                    const TargetOptions &targetopts, bool TimePasses,
+                    const std::string &infile, llvm::raw_ostream *OS,
+                    LLVMContext &C) :
+      Diags(_Diags),
+      Action(action),
+      CodeGenOpts(compopts),
+      TargetOpts(targetopts),
+      AsmOutStream(OS),
+      LLVMIRGeneration("LLVM IR Generation Time"),
+      Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)) {
+      llvm::TimePassesIsEnabled = TimePasses;
+    }
+
+    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());
+
+      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();
+      }
+
+      // Silently ignore if we weren't initialized for some reason.
+      if (!TheModule)
+        return;
+
+      // 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");
+
+      // 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);
+
+      EmitBackendOutput(Diags, CodeGenOpts, TargetOpts,
+                        TheModule.get(), Action, AsmOutStream);
+      
+      Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);
+    }
+
+    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);
+    }
+
+    virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {
+      Gen->HandleVTable(RD, DefinitionRequired);
+    }
+
+    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);
+  };
+}
+
+/// 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);
+
+  // If the SMDiagnostic has an inline asm source location, translate it.
+  FullSourceLoc Loc;
+  if (D.getLoc() != SMLoc())
+    Loc = ConvertBackendLocation(D, Context->getSourceManager());
+  
+
+  // If this problem has clang-level source location information, report the
+  // issue as being an error in the source with a note showing the instantiated
+  // code.
+  if (LocCookie.isValid()) {
+    Diags.Report(FullSourceLoc(LocCookie, Context->getSourceManager()),
+                 diag::err_fe_inline_asm).AddString(Message);
+    
+    if (D.getLoc().isValid())
+      Diags.Report(Loc, diag::note_fe_inline_asm_here);
+    return;
+  }
+  
+  // Otherwise, report the backend error as occuring in the generated .s file.
+  // If Loc is invalid, we still need to report the error, it just gets no
+  // location info.
+  Diags.Report(Loc, diag::err_fe_inline_asm).AddString(Message);
+}
+
+//
+
+CodeGenAction::CodeGenAction(unsigned _Act) : Act(_Act) {}
+
+CodeGenAction::~CodeGenAction() {}
+
+bool CodeGenAction::hasIRSupport() const { return true; }
+
+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();
+}
+
+static raw_ostream *GetOutputStream(CompilerInstance &CI,
+                                    llvm::StringRef InFile,
+                                    BackendAction Action) {
+  switch (Action) {
+  case Backend_EmitAssembly:
+    return CI.createDefaultOutputFile(false, InFile, "s");
+  case Backend_EmitLL:
+    return CI.createDefaultOutputFile(false, InFile, "ll");
+  case Backend_EmitBC:
+    return CI.createDefaultOutputFile(true, InFile, "bc");
+  case Backend_EmitNothing:
+    return 0;
+  case Backend_EmitMCNull:
+  case Backend_EmitObj:
+    return CI.createDefaultOutputFile(true, InFile, "o");
+  }
+
+  assert(0 && "Invalid action!");
+  return 0;
+}
+
+ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI,
+                                              llvm::StringRef InFile) {
+  BackendAction BA = static_cast<BackendAction>(Act);
+  llvm::OwningPtr<llvm::raw_ostream> OS(GetOutputStream(CI, InFile, BA));
+  if (BA != Backend_EmitNothing && !OS)
+    return 0;
+
+  return new BackendConsumer(BA, CI.getDiagnostics(),
+                             CI.getCodeGenOpts(), CI.getTargetOpts(),
+                             CI.getFrontendOpts().ShowTimers, InFile, OS.take(),
+                             CI.getLLVMContext());
+}
+
+void CodeGenAction::ExecuteAction() {
+  // If this is an IR file, we have to treat it specially.
+  if (getCurrentFileKind() == IK_LLVM_IR) {
+    BackendAction BA = static_cast<BackendAction>(Act);
+    CompilerInstance &CI = getCompilerInstance();
+    raw_ostream *OS = GetOutputStream(CI, getCurrentFile(), BA);
+    if (BA != Backend_EmitNothing && !OS)
+      return;
+
+    bool Invalid;
+    SourceManager &SM = CI.getSourceManager();
+    const llvm::MemoryBuffer *MainFile = SM.getBuffer(SM.getMainFileID(),
+                                                      &Invalid);
+    if (Invalid)
+      return;
+
+    // FIXME: This is stupid, IRReader shouldn't take ownership.
+    llvm::MemoryBuffer *MainFileCopy =
+      llvm::MemoryBuffer::getMemBufferCopy(MainFile->getBuffer(),
+                                           getCurrentFile().c_str());
+
+    llvm::SMDiagnostic Err;
+    TheModule.reset(ParseIR(MainFileCopy, Err, CI.getLLVMContext()));
+    if (!TheModule) {
+      // Translate from the diagnostic info to the SourceManager location.
+      SourceLocation Loc = SM.getLocation(
+        SM.getFileEntryForID(SM.getMainFileID()), Err.getLineNo(),
+        Err.getColumnNo() + 1);
+
+      // Get a custom diagnostic for the error. We strip off a leading
+      // diagnostic code if there is one.
+      llvm::StringRef Msg = Err.getMessage();
+      if (Msg.startswith("error: "))
+        Msg = Msg.substr(7);
+      unsigned DiagID = CI.getDiagnostics().getCustomDiagID(Diagnostic::Error,
+                                                            Msg);
+
+      CI.getDiagnostics().Report(FullSourceLoc(Loc, SM), DiagID);
+      return;
+    }
+
+    EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(),
+                      CI.getTargetOpts(), TheModule.get(),
+                      BA, OS);
+    return;
+  }
+
+  // Otherwise follow the normal AST path.
+  this->ASTFrontendAction::ExecuteAction();
+}
+
+//
+
+EmitAssemblyAction::EmitAssemblyAction()
+  : CodeGenAction(Backend_EmitAssembly) {}
+
+EmitBCAction::EmitBCAction() : CodeGenAction(Backend_EmitBC) {}
+
+EmitLLVMAction::EmitLLVMAction() : CodeGenAction(Backend_EmitLL) {}
+
+EmitLLVMOnlyAction::EmitLLVMOnlyAction() : CodeGenAction(Backend_EmitNothing) {}
+
+EmitCodeGenOnlyAction::EmitCodeGenOnlyAction() : CodeGenAction(Backend_EmitMCNull) {}
+
+EmitObjAction::EmitObjAction() : CodeGenAction(Backend_EmitObj) {}
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 110a8dc..13ad034 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -14,13 +14,16 @@
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "CGDebugInfo.h"
+#include "CGException.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 "clang/Frontend/CodeGenOptions.h"
 #include "llvm/Target/TargetData.h"
+#include "llvm/Intrinsics.h"
 using namespace clang;
 using namespace CodeGen;
 
@@ -28,15 +31,24 @@
   : BlockFunction(cgm, *this, Builder), CGM(cgm),
     Target(CGM.getContext().Target),
     Builder(cgm.getModule().getContext()),
-    DebugInfo(0), IndirectBranch(0),
-    SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0),
+    NormalCleanupDest(0), EHCleanupDest(0), NextCleanupDestIndex(1),
+    ExceptionSlot(0), DebugInfo(0), IndirectBranch(0),
+    SwitchInsn(0), CaseRangeBlock(0),
+    DidCallStackSave(false), UnreachableBlock(0),
     CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0),
-    ConditionalBranchLevel(0), TerminateHandler(0), TrapBB(0),
-    UniqueAggrDestructorCount(0) {
-  LLVMIntTy = ConvertType(getContext().IntTy);
+    ConditionalBranchLevel(0), TerminateLandingPad(0), TerminateHandler(0),
+    TrapBB(0) {
+      
+  // Get some frequently used types.
   LLVMPointerWidth = Target.getPointerWidth(0);
+  llvm::LLVMContext &LLVMContext = CGM.getLLVMContext();
+  IntPtrTy = llvm::IntegerType::get(LLVMContext, LLVMPointerWidth);
+  Int32Ty  = llvm::Type::getInt32Ty(LLVMContext);
+  Int64Ty  = llvm::Type::getInt64Ty(LLVMContext);
+      
   Exceptions = getContext().getLangOptions().Exceptions;
   CatchUndefined = getContext().getLangOptions().CatchUndefined;
+  CGM.getMangleContext().startNewFunction();
 }
 
 ASTContext &CodeGenFunction::getContext() const {
@@ -44,14 +56,6 @@
 }
 
 
-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!");
@@ -73,7 +77,7 @@
 
 bool CodeGenFunction::hasAggregateLLVMType(QualType T) {
   return T->isRecordType() || T->isArrayType() || T->isAnyComplexType() ||
-    T->isMemberFunctionPointerType();
+    T->isObjCObjectType();
 }
 
 void CodeGenFunction::EmitReturnBlock() {
@@ -86,25 +90,26 @@
 
     // 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;
+    if (CurBB->empty() || ReturnBlock.getBlock()->use_empty()) {
+      ReturnBlock.getBlock()->replaceAllUsesWith(CurBB);
+      delete ReturnBlock.getBlock();
     } else
-      EmitBlock(ReturnBlock);
+      EmitBlock(ReturnBlock.getBlock());
     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()) {
+  if (ReturnBlock.getBlock()->hasOneUse()) {
     llvm::BranchInst *BI =
-      dyn_cast<llvm::BranchInst>(*ReturnBlock->use_begin());
-    if (BI && BI->isUnconditional() && BI->getSuccessor(0) == ReturnBlock) {
+      dyn_cast<llvm::BranchInst>(*ReturnBlock.getBlock()->use_begin());
+    if (BI && BI->isUnconditional() &&
+        BI->getSuccessor(0) == ReturnBlock.getBlock()) {
       // Reset insertion point and delete the branch.
       Builder.SetInsertPoint(BI->getParent());
       BI->eraseFromParent();
-      delete ReturnBlock;
+      delete ReturnBlock.getBlock();
       return;
     }
   }
@@ -113,29 +118,37 @@
   // unless it has uses. However, we still need a place to put the debug
   // region.end for now.
 
-  EmitBlock(ReturnBlock);
+  EmitBlock(ReturnBlock.getBlock());
+}
+
+static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) {
+  if (!BB) return;
+  if (!BB->use_empty())
+    return CGF.CurFn->getBasicBlockList().push_back(BB);
+  delete BB;
 }
 
 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();
 
+  EmitFunctionInstrumentation("__cyg_profile_func_exit");
+
   // Emit debug descriptor for function end.
   if (CGDebugInfo *DI = getDebugInfo()) {
     DI->setLocation(EndLoc);
-    DI->EmitRegionEnd(CurFn, Builder);
+    DI->EmitFunctionEnd(Builder);
   }
 
-  EmitFunctionEpilog(*CurFnInfo, ReturnValue);
+  EmitFunctionEpilog(*CurFnInfo);
   EmitEndEHSpec(CurCodeDecl);
 
+  assert(EHStack.empty() &&
+         "did not remove all scopes from cleanup stack!");
+
   // If someone did an indirect goto, emit the indirect goto block at the end of
   // the function.
   if (IndirectBranch) {
@@ -157,6 +170,54 @@
       PN->eraseFromParent();
     }
   }
+
+  EmitIfUsed(*this, RethrowBlock.getBlock());
+  EmitIfUsed(*this, TerminateLandingPad);
+  EmitIfUsed(*this, TerminateHandler);
+  EmitIfUsed(*this, UnreachableBlock);
+
+  if (CGM.getCodeGenOpts().EmitDeclMetadata)
+    EmitDeclMetadata();
+}
+
+/// ShouldInstrumentFunction - Return true if the current function should be
+/// instrumented with __cyg_profile_func_* calls
+bool CodeGenFunction::ShouldInstrumentFunction() {
+  if (!CGM.getCodeGenOpts().InstrumentFunctions)
+    return false;
+  if (CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>())
+    return false;
+  return true;
+}
+
+/// EmitFunctionInstrumentation - Emit LLVM code to call the specified
+/// instrumentation function with the current function and the call site, if
+/// function instrumentation is enabled.
+void CodeGenFunction::EmitFunctionInstrumentation(const char *Fn) {
+  if (!ShouldInstrumentFunction())
+    return;
+
+  const llvm::PointerType *PointerTy;
+  const llvm::FunctionType *FunctionTy;
+  std::vector<const llvm::Type*> ProfileFuncArgs;
+
+  // void __cyg_profile_func_{enter,exit} (void *this_fn, void *call_site);
+  PointerTy = llvm::Type::getInt8PtrTy(VMContext);
+  ProfileFuncArgs.push_back(PointerTy);
+  ProfileFuncArgs.push_back(PointerTy);
+  FunctionTy = llvm::FunctionType::get(
+    llvm::Type::getVoidTy(VMContext),
+    ProfileFuncArgs, false);
+
+  llvm::Constant *F = CGM.CreateRuntimeFunction(FunctionTy, Fn);
+  llvm::CallInst *CallSite = Builder.CreateCall(
+    CGM.getIntrinsic(llvm::Intrinsic::returnaddress, 0, 0),
+    llvm::ConstantInt::get(Int32Ty, 0),
+    "callsite");
+
+  Builder.CreateCall2(F,
+                      llvm::ConstantExpr::getBitCast(CurFn, PointerTy),
+                      CallSite);
 }
 
 void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
@@ -186,14 +247,12 @@
   // 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);
+  llvm::Value *Undef = llvm::UndefValue::get(Int32Ty);
+  AllocaInsertPt = new llvm::BitCastInst(Undef, Int32Ty, "", EntryBB);
   if (Builder.isNamePreserving())
     AllocaInsertPt->setName("allocapt");
 
-  ReturnBlock = createBasicBlock("return");
+  ReturnBlock = getJumpDestInCurrentScope("return");
 
   Builder.SetInsertPoint(EntryBB);
 
@@ -208,6 +267,8 @@
     DI->EmitFunctionStart(GD, FnType, CurFn, Builder);
   }
 
+  EmitFunctionInstrumentation("__cyg_profile_func_enter");
+
   // FIXME: Leaked.
   // CC info is ignored, hopefully?
   CurFnInfo = &CGM.getTypes().getFunctionInfo(FnRetTy, Args,
@@ -246,15 +307,25 @@
 
 void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args) {
   const FunctionDecl *FD = cast<FunctionDecl>(CurGD.getDecl());
+  assert(FD->getBody());
+  EmitStmt(FD->getBody());
+}
 
-  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);
-  }
+/// Tries to mark the given function nounwind based on the
+/// non-existence of any throwing calls within it.  We believe this is
+/// lightweight enough to do at -O0.
+static void TryMarkNoThrow(llvm::Function *F) {
+  // LLVM treats 'nounwind' on a function as part of the type, so we
+  // can't do this on functions that can be overwritten.
+  if (F->mayBeOverridden()) return;
+
+  for (llvm::Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
+    for (llvm::BasicBlock::iterator
+           BI = FI->begin(), BE = FI->end(); BI != BE; ++BI)
+      if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(&*BI))
+        if (!Call->doesNotThrow())
+          return;
+  F->setDoesNotThrow(true);
 }
 
 void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) {
@@ -316,13 +387,10 @@
   // 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());
+  // If we haven't marked the function nothrow through other means, do
+  // a quick pass now to see if we can.
+  if (!CurFn->doesNotThrow())
+    TryMarkNoThrow(CurFn);
 }
 
 /// ContainsLabel - Return true if the statement contains a label in it.  If
@@ -387,7 +455,7 @@
 
   if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
     // Handle X && Y in a condition.
-    if (CondBOp->getOpcode() == BinaryOperator::LAnd) {
+    if (CondBOp->getOpcode() == BO_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) {
@@ -414,7 +482,7 @@
       EndConditionalBranch();
 
       return;
-    } else if (CondBOp->getOpcode() == BinaryOperator::LOr) {
+    } else if (CondBOp->getOpcode() == BO_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) {
@@ -446,7 +514,7 @@
 
   if (const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) {
     // br(!x, t, f) -> br(x, f, t)
-    if (CondUOp->getOpcode() == UnaryOperator::LNot)
+    if (CondUOp->getOpcode() == UO_LNot)
       return EmitBranchOnBoolExpr(CondUOp->getSubExpr(), FalseBlock, TrueBlock);
   }
 
@@ -479,30 +547,67 @@
   CGM.ErrorUnsupported(S, Type, OmitOnError);
 }
 
-void CodeGenFunction::EmitMemSetToZero(llvm::Value *DestPtr, QualType Ty) {
-  const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
+void
+CodeGenFunction::EmitNullInitialization(llvm::Value *DestPtr, QualType Ty) {
+  // Ignore empty classes in C++.
+  if (getContext().getLangOptions().CPlusPlus) {
+    if (const RecordType *RT = Ty->getAs<RecordType>()) {
+      if (cast<CXXRecordDecl>(RT->getDecl())->isEmpty())
+        return;
+    }
+  }
+
+  // Cast the dest ptr to the appropriate i8 pointer type.
+  unsigned DestAS =
+    cast<llvm::PointerType>(DestPtr->getType())->getAddressSpace();
+  const llvm::Type *BP =
+    llvm::Type::getInt8PtrTy(VMContext, DestAS);
   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);
+  uint64_t Size = TypeInfo.first;
+  unsigned Align = TypeInfo.second;
 
   // Don't bother emitting a zero-byte memset.
-  if (TypeInfo.first == 0)
+  if (Size == 0)
     return;
 
-  // FIXME: Handle variable sized types.
-  const llvm::Type *IntPtr = llvm::IntegerType::get(VMContext,
-                                                    LLVMPointerWidth);
+  llvm::ConstantInt *SizeVal = llvm::ConstantInt::get(IntPtrTy, Size / 8);
+  llvm::ConstantInt *AlignVal = Builder.getInt32(Align / 8);
 
-  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));
+  // If the type contains a pointer to data member we can't memset it to zero.
+  // Instead, create a null constant and copy it to the destination.
+  if (!CGM.getTypes().isZeroInitializable(Ty)) {
+    llvm::Constant *NullConstant = CGM.EmitNullConstant(Ty);
+
+    llvm::GlobalVariable *NullVariable = 
+      new llvm::GlobalVariable(CGM.getModule(), NullConstant->getType(),
+                               /*isConstant=*/true, 
+                               llvm::GlobalVariable::PrivateLinkage,
+                               NullConstant, llvm::Twine());
+    llvm::Value *SrcPtr =
+      Builder.CreateBitCast(NullVariable, Builder.getInt8PtrTy());
+
+    // FIXME: variable-size types?
+
+    // Get and call the appropriate llvm.memcpy overload.
+    llvm::Constant *Memcpy =
+      CGM.getMemCpyFn(DestPtr->getType(), SrcPtr->getType(), IntPtrTy);
+    Builder.CreateCall5(Memcpy, DestPtr, SrcPtr, SizeVal, AlignVal,
+                        /*volatile*/ Builder.getFalse());
+    return;
+  } 
+  
+  // Otherwise, just memset the whole thing to zero.  This is legal
+  // because in LLVM, all default initializers (other than the ones we just
+  // handled above) are guaranteed to have a bit pattern of all zeros.
+
+  // FIXME: Handle variable sized types.
+  Builder.CreateCall5(CGM.getMemSetFn(BP, IntPtrTy), DestPtr,
+                      Builder.getInt8(0),
+                      SizeVal, AlignVal, /*volatile*/ Builder.getFalse());
 }
 
 llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelStmt *L) {
@@ -510,7 +615,7 @@
   if (IndirectBranch == 0)
     GetIndirectGotoBlock();
   
-  llvm::BasicBlock *BB = getBasicBlockForLabel(L);
+  llvm::BasicBlock *BB = getJumpDestForLabel(L).getBlock();
   
   // Make sure the indirect branch includes all of the address-taken blocks.
   IndirectBranch->addDestination(BB);
@@ -582,233 +687,686 @@
 }
 
 llvm::Value* CodeGenFunction::EmitVAListRef(const Expr* E) {
-  if (CGM.getContext().getBuiltinVaListType()->isArrayType()) {
+  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));
+/// Pops cleanup blocks until the given savepoint is reached.
+void CodeGenFunction::PopCleanupBlocks(EHScopeStack::stable_iterator Old) {
+  assert(Old.isValid());
+
+  while (EHStack.stable_begin() != Old) {
+    EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.begin());
+
+    // As long as Old strictly encloses the scope's enclosing normal
+    // cleanup, we're going to emit another normal cleanup which
+    // fallthrough can propagate through.
+    bool FallThroughIsBranchThrough =
+      Old.strictlyEncloses(Scope.getEnclosingNormalCleanup());
+
+    PopCleanupBlock(FallThroughIsBranchThrough);
+  }
 }
 
-void CodeGenFunction::EmitCleanupBlocks(size_t OldCleanupStackSize) {
-  assert(CleanupEntries.size() >= OldCleanupStackSize &&
-         "Cleanup stack mismatch!");
-
-  while (CleanupEntries.size() > OldCleanupStackSize)
-    EmitCleanupBlock();
+static llvm::BasicBlock *CreateNormalEntry(CodeGenFunction &CGF,
+                                           EHCleanupScope &Scope) {
+  assert(Scope.isNormalCleanup());
+  llvm::BasicBlock *Entry = Scope.getNormalBlock();
+  if (!Entry) {
+    Entry = CGF.createBasicBlock("cleanup");
+    Scope.setNormalBlock(Entry);
+  }
+  return Entry;
 }
 
-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;
-    }
+static llvm::BasicBlock *CreateEHEntry(CodeGenFunction &CGF,
+                                       EHCleanupScope &Scope) {
+  assert(Scope.isEHCleanup());
+  llvm::BasicBlock *Entry = Scope.getEHBlock();
+  if (!Entry) {
+    Entry = CGF.createBasicBlock("eh.cleanup");
+    Scope.setEHBlock(Entry);
   }
-
-  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);
+  return Entry;
 }
 
-void CodeGenFunction::EmitCleanupBlock() {
-  CleanupBlockInfo Info = PopCleanupBlock();
+/// Transitions the terminator of the given exit-block of a cleanup to
+/// be a cleanup switch.
+static llvm::SwitchInst *TransitionToCleanupSwitch(CodeGenFunction &CGF,
+                                                   llvm::BasicBlock *Block) {
+  // If it's a branch, turn it into a switch whose default
+  // destination is its original target.
+  llvm::TerminatorInst *Term = Block->getTerminator();
+  assert(Term && "can't transition block without terminator");
 
-  if (Info.EHOnly) {
-    // FIXME: Add this to the exceptional edge
-    if (Info.CleanupBlock->getNumUses() == 0)
-      delete Info.CleanupBlock;
+  if (llvm::BranchInst *Br = dyn_cast<llvm::BranchInst>(Term)) {
+    assert(Br->isUnconditional());
+    llvm::LoadInst *Load =
+      new llvm::LoadInst(CGF.getNormalCleanupDestSlot(), "cleanup.dest", Term);
+    llvm::SwitchInst *Switch =
+      llvm::SwitchInst::Create(Load, Br->getSuccessor(0), 4, Block);
+    Br->eraseFromParent();
+    return Switch;
+  } else {
+    return cast<llvm::SwitchInst>(Term);
+  }
+}
+
+/// Attempts to reduce a cleanup's entry block to a fallthrough.  This
+/// is basically llvm::MergeBlockIntoPredecessor, except
+/// simplified/optimized for the tighter constraints on cleanup blocks.
+///
+/// Returns the new block, whatever it is.
+static llvm::BasicBlock *SimplifyCleanupEntry(CodeGenFunction &CGF,
+                                              llvm::BasicBlock *Entry) {
+  llvm::BasicBlock *Pred = Entry->getSinglePredecessor();
+  if (!Pred) return Entry;
+
+  llvm::BranchInst *Br = dyn_cast<llvm::BranchInst>(Pred->getTerminator());
+  if (!Br || Br->isConditional()) return Entry;
+  assert(Br->getSuccessor(0) == Entry);
+
+  // If we were previously inserting at the end of the cleanup entry
+  // block, we'll need to continue inserting at the end of the
+  // predecessor.
+  bool WasInsertBlock = CGF.Builder.GetInsertBlock() == Entry;
+  assert(!WasInsertBlock || CGF.Builder.GetInsertPoint() == Entry->end());
+
+  // Kill the branch.
+  Br->eraseFromParent();
+
+  // Merge the blocks.
+  Pred->getInstList().splice(Pred->end(), Entry->getInstList());
+
+  // Kill the entry block.
+  Entry->eraseFromParent();
+
+  if (WasInsertBlock)
+    CGF.Builder.SetInsertPoint(Pred);
+
+  return Pred;
+}
+
+static void EmitCleanup(CodeGenFunction &CGF,
+                        EHScopeStack::Cleanup *Fn,
+                        bool ForEH) {
+  if (ForEH) CGF.EHStack.pushTerminate();
+  Fn->Emit(CGF, ForEH);
+  if (ForEH) CGF.EHStack.popTerminate();
+  assert(CGF.HaveInsertPoint() && "cleanup ended with no insertion point?");
+}
+
+/// Pops a cleanup block.  If the block includes a normal cleanup, the
+/// current insertion point is threaded through the cleanup, as are
+/// any branch fixups on the cleanup.
+void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
+  assert(!EHStack.empty() && "cleanup stack is empty!");
+  assert(isa<EHCleanupScope>(*EHStack.begin()) && "top not a cleanup!");
+  EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.begin());
+  assert(Scope.getFixupDepth() <= EHStack.getNumBranchFixups());
+  assert(Scope.isActive() && "cleanup was still inactive when popped!");
+
+  // Check whether we need an EH cleanup.  This is only true if we've
+  // generated a lazy EH cleanup block.
+  bool RequiresEHCleanup = Scope.hasEHBranches();
+
+  // Check the three conditions which might require a normal cleanup:
+
+  // - whether there are branch fix-ups through this cleanup
+  unsigned FixupDepth = Scope.getFixupDepth();
+  bool HasFixups = EHStack.getNumBranchFixups() != FixupDepth;
+
+  // - whether there are branch-throughs or branch-afters
+  bool HasExistingBranches = Scope.hasBranches();
+
+  // - whether there's a fallthrough
+  llvm::BasicBlock *FallthroughSource = Builder.GetInsertBlock();
+  bool HasFallthrough = (FallthroughSource != 0);
+
+  bool RequiresNormalCleanup = false;
+  if (Scope.isNormalCleanup() &&
+      (HasFixups || HasExistingBranches || HasFallthrough)) {
+    RequiresNormalCleanup = true;
+  }
+
+  // If we don't need the cleanup at all, we're done.
+  if (!RequiresNormalCleanup && !RequiresEHCleanup) {
+    EHStack.popCleanup(); // safe because there are no fixups
+    assert(EHStack.getNumBranchFixups() == 0 ||
+           EHStack.hasNormalCleanups());
     return;
   }
 
-  //  Scrub debug location info.
-  for (llvm::BasicBlock::iterator LBI = Info.CleanupBlock->begin(),
-         LBE = Info.CleanupBlock->end(); LBI != LBE; ++LBI)
-    Builder.SetInstDebugLocation(LBI);
+  // Copy the cleanup emission data out.  Note that SmallVector
+  // guarantees maximal alignment for its buffer regardless of its
+  // type parameter.
+  llvm::SmallVector<char, 8*sizeof(void*)> CleanupBuffer;
+  CleanupBuffer.reserve(Scope.getCleanupSize());
+  memcpy(CleanupBuffer.data(),
+         Scope.getCleanupBuffer(), Scope.getCleanupSize());
+  CleanupBuffer.set_size(Scope.getCleanupSize());
+  EHScopeStack::Cleanup *Fn =
+    reinterpret_cast<EHScopeStack::Cleanup*>(CleanupBuffer.data());
 
-  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);
+  // We want to emit the EH cleanup after the normal cleanup, but go
+  // ahead and do the setup for the EH cleanup while the scope is still
+  // alive.
+  llvm::BasicBlock *EHEntry = 0;
+  llvm::SmallVector<llvm::Instruction*, 2> EHInstsToAppend;
+  if (RequiresEHCleanup) {
+    EHEntry = CreateEHEntry(*this, Scope);
 
-  if (Info.SwitchBlock)
-    EmitBlock(Info.SwitchBlock);
-  if (Info.EndBlock)
-    EmitBlock(Info.EndBlock);
+    // Figure out the branch-through dest if necessary.
+    llvm::BasicBlock *EHBranchThroughDest = 0;
+    if (Scope.hasEHBranchThroughs()) {
+      assert(Scope.getEnclosingEHCleanup() != EHStack.stable_end());
+      EHScope &S = *EHStack.find(Scope.getEnclosingEHCleanup());
+      EHBranchThroughDest = CreateEHEntry(*this, cast<EHCleanupScope>(S));
+    }
+
+    // If we have exactly one branch-after and no branch-throughs, we
+    // can dispatch it without a switch.
+    if (!Scope.hasEHBranchThroughs() &&
+        Scope.getNumEHBranchAfters() == 1) {
+      assert(!EHBranchThroughDest);
+
+      // TODO: remove the spurious eh.cleanup.dest stores if this edge
+      // never went through any switches.
+      llvm::BasicBlock *BranchAfterDest = Scope.getEHBranchAfterBlock(0);
+      EHInstsToAppend.push_back(llvm::BranchInst::Create(BranchAfterDest));
+    
+    // Otherwise, if we have any branch-afters, we need a switch.
+    } else if (Scope.getNumEHBranchAfters()) {
+      // The default of the switch belongs to the branch-throughs if
+      // they exist.
+      llvm::BasicBlock *Default =
+        (EHBranchThroughDest ? EHBranchThroughDest : getUnreachableBlock());
+
+      const unsigned SwitchCapacity = Scope.getNumEHBranchAfters();
+
+      llvm::LoadInst *Load =
+        new llvm::LoadInst(getEHCleanupDestSlot(), "cleanup.dest");
+      llvm::SwitchInst *Switch =
+        llvm::SwitchInst::Create(Load, Default, SwitchCapacity);
+
+      EHInstsToAppend.push_back(Load);
+      EHInstsToAppend.push_back(Switch);
+
+      for (unsigned I = 0, E = Scope.getNumEHBranchAfters(); I != E; ++I)
+        Switch->addCase(Scope.getEHBranchAfterIndex(I),
+                        Scope.getEHBranchAfterBlock(I));
+
+    // Otherwise, we have only branch-throughs; jump to the next EH
+    // cleanup.
+    } else {
+      assert(EHBranchThroughDest);
+      EHInstsToAppend.push_back(llvm::BranchInst::Create(EHBranchThroughDest));
+    }
+  }
+
+  if (!RequiresNormalCleanup) {
+    EHStack.popCleanup();
+  } else {
+    // As a kindof crazy internal case, branch-through fall-throughs
+    // leave the insertion point set to the end of the last cleanup.
+    bool HasPrebranchedFallthrough =
+      (HasFallthrough && FallthroughSource->getTerminator());
+    assert(!HasPrebranchedFallthrough ||
+           FallthroughSource->getTerminator()->getSuccessor(0)
+             == Scope.getNormalBlock());
+
+    // If we have a fallthrough and no other need for the cleanup,
+    // emit it directly.
+    if (HasFallthrough && !HasPrebranchedFallthrough &&
+        !HasFixups && !HasExistingBranches) {
+
+      // Fixups can cause us to optimistically create a normal block,
+      // only to later have no real uses for it.  Just delete it in
+      // this case.
+      // TODO: we can potentially simplify all the uses after this.
+      if (Scope.getNormalBlock()) {
+        Scope.getNormalBlock()->replaceAllUsesWith(getUnreachableBlock());
+        delete Scope.getNormalBlock();
+      }
+
+      EHStack.popCleanup();
+
+      EmitCleanup(*this, Fn, /*ForEH*/ false);
+
+    // Otherwise, the best approach is to thread everything through
+    // the cleanup block and then try to clean up after ourselves.
+    } else {
+      // Force the entry block to exist.
+      llvm::BasicBlock *NormalEntry = CreateNormalEntry(*this, Scope);
+
+      // If there's a fallthrough, we need to store the cleanup
+      // destination index.  For fall-throughs this is always zero.
+      if (HasFallthrough && !HasPrebranchedFallthrough)
+        Builder.CreateStore(Builder.getInt32(0), getNormalCleanupDestSlot());
+
+      // Emit the entry block.  This implicitly branches to it if we
+      // have fallthrough.  All the fixups and existing branches should
+      // already be branched to it.
+      EmitBlock(NormalEntry);
+
+      bool HasEnclosingCleanups =
+        (Scope.getEnclosingNormalCleanup() != EHStack.stable_end());
+
+      // Compute the branch-through dest if we need it:
+      //   - if there are branch-throughs threaded through the scope
+      //   - if fall-through is a branch-through
+      //   - if there are fixups that will be optimistically forwarded
+      //     to the enclosing cleanup
+      llvm::BasicBlock *BranchThroughDest = 0;
+      if (Scope.hasBranchThroughs() ||
+          (HasFallthrough && FallthroughIsBranchThrough) ||
+          (HasFixups && HasEnclosingCleanups)) {
+        assert(HasEnclosingCleanups);
+        EHScope &S = *EHStack.find(Scope.getEnclosingNormalCleanup());
+        BranchThroughDest = CreateNormalEntry(*this, cast<EHCleanupScope>(S));
+      }
+
+      llvm::BasicBlock *FallthroughDest = 0;
+      llvm::SmallVector<llvm::Instruction*, 2> InstsToAppend;
+
+      // If there's exactly one branch-after and no other threads,
+      // we can route it without a switch.
+      if (!Scope.hasBranchThroughs() && !HasFixups && !HasFallthrough &&
+          Scope.getNumBranchAfters() == 1) {
+        assert(!BranchThroughDest);
+
+        // TODO: clean up the possibly dead stores to the cleanup dest slot.
+        llvm::BasicBlock *BranchAfter = Scope.getBranchAfterBlock(0);
+        InstsToAppend.push_back(llvm::BranchInst::Create(BranchAfter));
+
+      // Build a switch-out if we need it:
+      //   - if there are branch-afters threaded through the scope
+      //   - if fall-through is a branch-after
+      //   - if there are fixups that have nowhere left to go and
+      //     so must be immediately resolved
+      } else if (Scope.getNumBranchAfters() ||
+                 (HasFallthrough && !FallthroughIsBranchThrough) ||
+                 (HasFixups && !HasEnclosingCleanups)) {
+
+        llvm::BasicBlock *Default =
+          (BranchThroughDest ? BranchThroughDest : getUnreachableBlock());
+
+        // TODO: base this on the number of branch-afters and fixups
+        const unsigned SwitchCapacity = 10;
+
+        llvm::LoadInst *Load =
+          new llvm::LoadInst(getNormalCleanupDestSlot(), "cleanup.dest");
+        llvm::SwitchInst *Switch =
+          llvm::SwitchInst::Create(Load, Default, SwitchCapacity);
+
+        InstsToAppend.push_back(Load);
+        InstsToAppend.push_back(Switch);
+
+        // Branch-after fallthrough.
+        if (HasFallthrough && !FallthroughIsBranchThrough) {
+          FallthroughDest = createBasicBlock("cleanup.cont");
+          Switch->addCase(Builder.getInt32(0), FallthroughDest);
+        }
+
+        for (unsigned I = 0, E = Scope.getNumBranchAfters(); I != E; ++I) {
+          Switch->addCase(Scope.getBranchAfterIndex(I),
+                          Scope.getBranchAfterBlock(I));
+        }
+
+        if (HasFixups && !HasEnclosingCleanups)
+          ResolveAllBranchFixups(Switch);
+      } else {
+        // We should always have a branch-through destination in this case.
+        assert(BranchThroughDest);
+        InstsToAppend.push_back(llvm::BranchInst::Create(BranchThroughDest));
+      }
+
+      // We're finally ready to pop the cleanup.
+      EHStack.popCleanup();
+      assert(EHStack.hasNormalCleanups() == HasEnclosingCleanups);
+
+      EmitCleanup(*this, Fn, /*ForEH*/ false);
+
+      // Append the prepared cleanup prologue from above.
+      llvm::BasicBlock *NormalExit = Builder.GetInsertBlock();
+      for (unsigned I = 0, E = InstsToAppend.size(); I != E; ++I)
+        NormalExit->getInstList().push_back(InstsToAppend[I]);
+
+      // Optimistically hope that any fixups will continue falling through.
+      for (unsigned I = FixupDepth, E = EHStack.getNumBranchFixups();
+           I < E; ++I) {
+        BranchFixup &Fixup = CGF.EHStack.getBranchFixup(I);
+        if (!Fixup.Destination) continue;
+        if (!Fixup.OptimisticBranchBlock) {
+          new llvm::StoreInst(Builder.getInt32(Fixup.DestinationIndex),
+                              getNormalCleanupDestSlot(),
+                              Fixup.InitialBranch);
+          Fixup.InitialBranch->setSuccessor(0, NormalEntry);
+        }
+        Fixup.OptimisticBranchBlock = NormalExit;
+      }
+      
+      if (FallthroughDest)
+        EmitBlock(FallthroughDest);
+      else if (!HasFallthrough)
+        Builder.ClearInsertionPoint();
+
+      // Check whether we can merge NormalEntry into a single predecessor.
+      // This might invalidate (non-IR) pointers to NormalEntry.
+      llvm::BasicBlock *NewNormalEntry =
+        SimplifyCleanupEntry(*this, NormalEntry);
+
+      // If it did invalidate those pointers, and NormalEntry was the same
+      // as NormalExit, go back and patch up the fixups.
+      if (NewNormalEntry != NormalEntry && NormalEntry == NormalExit)
+        for (unsigned I = FixupDepth, E = EHStack.getNumBranchFixups();
+               I < E; ++I)
+          CGF.EHStack.getBranchFixup(I).OptimisticBranchBlock = NewNormalEntry;
+    }
+  }
+
+  assert(EHStack.hasNormalCleanups() || EHStack.getNumBranchFixups() == 0);
+
+  // Emit the EH cleanup if required.
+  if (RequiresEHCleanup) {
+    CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
+
+    EmitBlock(EHEntry);
+    EmitCleanup(*this, Fn, /*ForEH*/ true);
+
+    // Append the prepared cleanup prologue from above.
+    llvm::BasicBlock *EHExit = Builder.GetInsertBlock();
+    for (unsigned I = 0, E = EHInstsToAppend.size(); I != E; ++I)
+      EHExit->getInstList().push_back(EHInstsToAppend[I]);
+
+    Builder.restoreIP(SavedIP);
+
+    SimplifyCleanupEntry(*this, EHEntry);
+  }
 }
 
-void CodeGenFunction::AddBranchFixup(llvm::BranchInst *BI) {
-  assert(!CleanupEntries.empty() &&
-         "Trying to add branch fixup without cleanup block!");
+/// Terminate the current block by emitting a branch which might leave
+/// the current cleanup-protected scope.  The target scope may not yet
+/// be known, in which case this will require a fixup.
+///
+/// As a side-effect, this method clears the insertion point.
+void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) {
+  assert(Dest.getScopeDepth().encloses(EHStack.getInnermostNormalCleanup())
+         && "stale jump destination");
 
-  // 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);
+  // Create the branch.
+  llvm::BranchInst *BI = Builder.CreateBr(Dest.getBlock());
 
+  // Calculate the innermost active normal cleanup.
+  EHScopeStack::stable_iterator
+    TopCleanup = EHStack.getInnermostActiveNormalCleanup();
+
+  // If we're not in an active normal cleanup scope, or if the
+  // destination scope is within the innermost active normal cleanup
+  // scope, we don't need to worry about fixups.
+  if (TopCleanup == EHStack.stable_end() ||
+      TopCleanup.encloses(Dest.getScopeDepth())) { // works for invalid
+    Builder.ClearInsertionPoint();
+    return;
+  }
+
+  // If we can't resolve the destination cleanup scope, just add this
+  // to the current cleanup scope as a branch fixup.
+  if (!Dest.getScopeDepth().isValid()) {
+    BranchFixup &Fixup = EHStack.addBranchFixup();
+    Fixup.Destination = Dest.getBlock();
+    Fixup.DestinationIndex = Dest.getDestIndex();
+    Fixup.InitialBranch = BI;
+    Fixup.OptimisticBranchBlock = 0;
+
+    Builder.ClearInsertionPoint();
+    return;
+  }
+
+  // Otherwise, thread through all the normal cleanups in scope.
+
+  // Store the index at the start.
+  llvm::ConstantInt *Index = Builder.getInt32(Dest.getDestIndex());
+  new llvm::StoreInst(Index, getNormalCleanupDestSlot(), BI);
+
+  // Adjust BI to point to the first cleanup block.
+  {
+    EHCleanupScope &Scope =
+      cast<EHCleanupScope>(*EHStack.find(TopCleanup));
+    BI->setSuccessor(0, CreateNormalEntry(*this, Scope));
+  }
+
+  // Add this destination to all the scopes involved.
+  EHScopeStack::stable_iterator I = TopCleanup;
+  EHScopeStack::stable_iterator E = Dest.getScopeDepth();
+  if (E.strictlyEncloses(I)) {
+    while (true) {
+      EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(I));
+      assert(Scope.isNormalCleanup());
+      I = Scope.getEnclosingNormalCleanup();
+
+      // If this is the last cleanup we're propagating through, tell it
+      // that there's a resolved jump moving through it.
+      if (!E.strictlyEncloses(I)) {
+        Scope.addBranchAfter(Index, Dest.getBlock());
+        break;
+      }
+
+      // Otherwise, tell the scope that there's a jump propoagating
+      // through it.  If this isn't new information, all the rest of
+      // the work has been done before.
+      if (!Scope.addBranchThrough(Dest.getBlock()))
+        break;
+    }
+  }
+  
   Builder.ClearInsertionPoint();
+}
 
-  // The stack is empty, no need to do any cleanup.
-  if (CleanupEntries.empty())
+void CodeGenFunction::EmitBranchThroughEHCleanup(UnwindDest Dest) {
+  // We should never get invalid scope depths for an UnwindDest; that
+  // implies that the destination wasn't set up correctly.
+  assert(Dest.getScopeDepth().isValid() && "invalid scope depth on EH dest?");
+
+  if (!HaveInsertPoint())
     return;
 
-  if (!Dest->getParent()) {
-    // We are trying to branch to a block that hasn't been inserted yet.
-    AddBranchFixup(BI);
+  // Create the branch.
+  llvm::BranchInst *BI = Builder.CreateBr(Dest.getBlock());
+
+  // Calculate the innermost active cleanup.
+  EHScopeStack::stable_iterator
+    InnermostCleanup = EHStack.getInnermostActiveEHCleanup();
+
+  // If the destination is in the same EH cleanup scope as us, we
+  // don't need to thread through anything.
+  if (InnermostCleanup.encloses(Dest.getScopeDepth())) {
+    Builder.ClearInsertionPoint();
     return;
   }
+  assert(InnermostCleanup != EHStack.stable_end());
 
-  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;
+  // Store the index at the start.
+  llvm::ConstantInt *Index = Builder.getInt32(Dest.getDestIndex());
+  new llvm::StoreInst(Index, getEHCleanupDestSlot(), BI);
+
+  // Adjust BI to point to the first cleanup block.
+  {
+    EHCleanupScope &Scope =
+      cast<EHCleanupScope>(*EHStack.find(InnermostCleanup));
+    BI->setSuccessor(0, CreateEHEntry(*this, Scope));
+  }
+  
+  // Add this destination to all the scopes involved.
+  for (EHScopeStack::stable_iterator
+         I = InnermostCleanup, E = Dest.getScopeDepth(); ; ) {
+    assert(E.strictlyEncloses(I));
+    EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(I));
+    assert(Scope.isEHCleanup());
+    I = Scope.getEnclosingEHCleanup();
+
+    // If this is the last cleanup we're propagating through, add this
+    // as a branch-after.
+    if (I == E) {
+      Scope.addEHBranchAfter(Index, Dest.getBlock());
+      break;
+    }
+
+    // Otherwise, add it as a branch-through.  If this isn't new
+    // information, all the rest of the work has been done before.
+    if (!Scope.addEHBranchThrough(Dest.getBlock()))
+      break;
+  }
+  
+  Builder.ClearInsertionPoint();
+}
+
+/// All the branch fixups on the EH stack have propagated out past the
+/// outermost normal cleanup; resolve them all by adding cases to the
+/// given switch instruction.
+void CodeGenFunction::ResolveAllBranchFixups(llvm::SwitchInst *Switch) {
+  llvm::SmallPtrSet<llvm::BasicBlock*, 4> CasesAdded;
+
+  for (unsigned I = 0, E = EHStack.getNumBranchFixups(); I != E; ++I) {
+    // Skip this fixup if its destination isn't set or if we've
+    // already treated it.
+    BranchFixup &Fixup = EHStack.getBranchFixup(I);
+    if (Fixup.Destination == 0) continue;
+    if (!CasesAdded.insert(Fixup.Destination)) continue;
+
+    Switch->addCase(Builder.getInt32(Fixup.DestinationIndex),
+                    Fixup.Destination);
   }
 
-  assert(I->second < CleanupEntries.size() &&
-         "Trying to branch into cleanup region");
+  EHStack.clearFixups();
+}
 
-  if (I->second == CleanupEntries.size() - 1) {
-    // We have a branch to a block in the same scope.
-    return;
+void CodeGenFunction::ResolveBranchFixups(llvm::BasicBlock *Block) {
+  assert(Block && "resolving a null target block");
+  if (!EHStack.getNumBranchFixups()) return;
+
+  assert(EHStack.hasNormalCleanups() &&
+         "branch fixups exist with no normal cleanups on stack");
+
+  llvm::SmallPtrSet<llvm::BasicBlock*, 4> ModifiedOptimisticBlocks;
+  bool ResolvedAny = false;
+
+  for (unsigned I = 0, E = EHStack.getNumBranchFixups(); I != E; ++I) {
+    // Skip this fixup if its destination doesn't match.
+    BranchFixup &Fixup = EHStack.getBranchFixup(I);
+    if (Fixup.Destination != Block) continue;
+
+    Fixup.Destination = 0;
+    ResolvedAny = true;
+
+    // If it doesn't have an optimistic branch block, LatestBranch is
+    // already pointing to the right place.
+    llvm::BasicBlock *BranchBB = Fixup.OptimisticBranchBlock;
+    if (!BranchBB)
+      continue;
+
+    // Don't process the same optimistic branch block twice.
+    if (!ModifiedOptimisticBlocks.insert(BranchBB))
+      continue;
+
+    llvm::SwitchInst *Switch = TransitionToCleanupSwitch(*this, BranchBB);
+
+    // Add a case to the switch.
+    Switch->addCase(Builder.getInt32(Fixup.DestinationIndex), Block);
   }
 
-  AddBranchFixup(BI);
+  if (ResolvedAny)
+    EHStack.popNullFixups();
+}
+
+/// Activate a cleanup that was created in an inactivated state.
+void CodeGenFunction::ActivateCleanup(EHScopeStack::stable_iterator C) {
+  assert(C != EHStack.stable_end() && "activating bottom of stack?");
+  EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(C));
+  assert(!Scope.isActive() && "double activation");
+
+  // Calculate whether the cleanup was used:
+  bool Used = false;
+
+  //   - as a normal cleanup
+  if (Scope.isNormalCleanup()) {
+    bool NormalUsed = false;
+    if (Scope.getNormalBlock()) {
+      NormalUsed = true;
+    } else {
+      // Check whether any enclosed cleanups were needed.
+      for (EHScopeStack::stable_iterator
+             I = EHStack.getInnermostNormalCleanup(); I != C; ) {
+        assert(C.strictlyEncloses(I));
+        EHCleanupScope &S = cast<EHCleanupScope>(*EHStack.find(I));
+        if (S.getNormalBlock()) {
+          NormalUsed = true;
+          break;
+        }
+        I = S.getEnclosingNormalCleanup();
+      }
+    }
+
+    if (NormalUsed)
+      Used = true;
+    else
+      Scope.setActivatedBeforeNormalUse(true);
+  }
+
+  //  - as an EH cleanup
+  if (Scope.isEHCleanup()) {
+    bool EHUsed = false;
+    if (Scope.getEHBlock()) {
+      EHUsed = true;
+    } else {
+      // Check whether any enclosed cleanups were needed.
+      for (EHScopeStack::stable_iterator
+             I = EHStack.getInnermostEHCleanup(); I != C; ) {
+        assert(C.strictlyEncloses(I));
+        EHCleanupScope &S = cast<EHCleanupScope>(*EHStack.find(I));
+        if (S.getEHBlock()) {
+          EHUsed = true;
+          break;
+        }
+        I = S.getEnclosingEHCleanup();
+      }
+    }
+
+    if (EHUsed)
+      Used = true;
+    else
+      Scope.setActivatedBeforeEHUse(true);
+  }
+  
+  llvm::AllocaInst *Var = EHCleanupScope::activeSentinel();
+  if (Used) {
+    Var = CreateTempAlloca(Builder.getInt1Ty());
+    InitTempAlloca(Var, Builder.getFalse());
+  }
+  Scope.setActiveVar(Var);
+}
+
+llvm::Value *CodeGenFunction::getNormalCleanupDestSlot() {
+  if (!NormalCleanupDest)
+    NormalCleanupDest =
+      CreateTempAlloca(Builder.getInt32Ty(), "cleanup.dest.slot");
+  return NormalCleanupDest;
+}
+
+llvm::Value *CodeGenFunction::getEHCleanupDestSlot() {
+  if (!EHCleanupDest)
+    EHCleanupDest =
+      CreateTempAlloca(Builder.getInt32Ty(), "eh.cleanup.dest.slot");
+  return EHCleanupDest;
+}
+
+void CodeGenFunction::EmitDeclRefExprDbgValue(const DeclRefExpr *E, 
+                                              llvm::ConstantInt *Init) {
+  assert (Init && "Invalid DeclRefExpr initializer!");
+  if (CGDebugInfo *Dbg = getDebugInfo())
+    Dbg->EmitGlobalVariable(E->getDecl(), Init, Builder);
 }
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index e4e98ef..f54a011 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -32,13 +32,16 @@
 namespace llvm {
   class BasicBlock;
   class LLVMContext;
+  class MDNode;
   class Module;
   class SwitchInst;
   class Twine;
   class Value;
+  class CallSite;
 }
 
 namespace clang {
+  class APValue;
   class ASTContext;
   class CXXDestructorDecl;
   class CXXTryStmt;
@@ -66,6 +69,337 @@
   class CGDebugInfo;
   class CGFunctionInfo;
   class CGRecordLayout;
+  class CGBlockInfo;
+
+/// A branch fixup.  These are required when emitting a goto to a
+/// label which hasn't been emitted yet.  The goto is optimistically
+/// emitted as a branch to the basic block for the label, and (if it
+/// occurs in a scope with non-trivial cleanups) a fixup is added to
+/// the innermost cleanup.  When a (normal) cleanup is popped, any
+/// unresolved fixups in that scope are threaded through the cleanup.
+struct BranchFixup {
+  /// The block containing the terminator which needs to be modified
+  /// into a switch if this fixup is resolved into the current scope.
+  /// If null, LatestBranch points directly to the destination.
+  llvm::BasicBlock *OptimisticBranchBlock;
+
+  /// The ultimate destination of the branch.
+  ///
+  /// This can be set to null to indicate that this fixup was
+  /// successfully resolved.
+  llvm::BasicBlock *Destination;
+
+  /// The destination index value.
+  unsigned DestinationIndex;
+
+  /// The initial branch of the fixup.
+  llvm::BranchInst *InitialBranch;
+};
+
+enum CleanupKind {
+  EHCleanup = 0x1,
+  NormalCleanup = 0x2,
+  NormalAndEHCleanup = EHCleanup | NormalCleanup,
+
+  InactiveCleanup = 0x4,
+  InactiveEHCleanup = EHCleanup | InactiveCleanup,
+  InactiveNormalCleanup = NormalCleanup | InactiveCleanup,
+  InactiveNormalAndEHCleanup = NormalAndEHCleanup | InactiveCleanup
+};
+
+/// A stack of scopes which respond to exceptions, including cleanups
+/// and catch blocks.
+class EHScopeStack {
+public:
+  /// A saved depth on the scope stack.  This is necessary because
+  /// pushing scopes onto the stack invalidates iterators.
+  class stable_iterator {
+    friend class EHScopeStack;
+
+    /// Offset from StartOfData to EndOfBuffer.
+    ptrdiff_t Size;
+
+    stable_iterator(ptrdiff_t Size) : Size(Size) {}
+
+  public:
+    static stable_iterator invalid() { return stable_iterator(-1); }
+    stable_iterator() : Size(-1) {}
+
+    bool isValid() const { return Size >= 0; }
+
+    /// Returns true if this scope encloses I.
+    /// Returns false if I is invalid.
+    /// This scope must be valid.
+    bool encloses(stable_iterator I) const { return Size <= I.Size; }
+
+    /// Returns true if this scope strictly encloses I: that is,
+    /// if it encloses I and is not I.
+    /// Returns false is I is invalid.
+    /// This scope must be valid.
+    bool strictlyEncloses(stable_iterator I) const { return Size < I.Size; }
+
+    friend bool operator==(stable_iterator A, stable_iterator B) {
+      return A.Size == B.Size;
+    }
+    friend bool operator!=(stable_iterator A, stable_iterator B) {
+      return A.Size != B.Size;
+    }
+  };
+
+  /// Information for lazily generating a cleanup.  Subclasses must be
+  /// POD-like: cleanups will not be destructed, and they will be
+  /// allocated on the cleanup stack and freely copied and moved
+  /// around.
+  ///
+  /// Cleanup implementations should generally be declared in an
+  /// anonymous namespace.
+  class Cleanup {
+  public:
+    // Anchor the construction vtable.  We use the destructor because
+    // gcc gives an obnoxious warning if there are virtual methods
+    // with an accessible non-virtual destructor.  Unfortunately,
+    // declaring this destructor makes it non-trivial, but there
+    // doesn't seem to be any other way around this warning.
+    //
+    // This destructor will never be called.
+    virtual ~Cleanup();
+
+    /// Emit the cleanup.  For normal cleanups, this is run in the
+    /// same EH context as when the cleanup was pushed, i.e. the
+    /// immediately-enclosing context of the cleanup scope.  For
+    /// EH cleanups, this is run in a terminate context.
+    ///
+    // \param IsForEHCleanup true if this is for an EH cleanup, false
+    ///  if for a normal cleanup.
+    virtual void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) = 0;
+  };
+
+private:
+  // The implementation for this class is in CGException.h and
+  // CGException.cpp; the definition is here because it's used as a
+  // member of CodeGenFunction.
+
+  /// The start of the scope-stack buffer, i.e. the allocated pointer
+  /// for the buffer.  All of these pointers are either simultaneously
+  /// null or simultaneously valid.
+  char *StartOfBuffer;
+
+  /// The end of the buffer.
+  char *EndOfBuffer;
+
+  /// The first valid entry in the buffer.
+  char *StartOfData;
+
+  /// The innermost normal cleanup on the stack.
+  stable_iterator InnermostNormalCleanup;
+
+  /// The innermost EH cleanup on the stack.
+  stable_iterator InnermostEHCleanup;
+
+  /// The number of catches on the stack.
+  unsigned CatchDepth;
+
+  /// The current EH destination index.  Reset to FirstCatchIndex
+  /// whenever the last EH cleanup is popped.
+  unsigned NextEHDestIndex;
+  enum { FirstEHDestIndex = 1 };
+
+  /// The current set of branch fixups.  A branch fixup is a jump to
+  /// an as-yet unemitted label, i.e. a label for which we don't yet
+  /// know the EH stack depth.  Whenever we pop a cleanup, we have
+  /// to thread all the current branch fixups through it.
+  ///
+  /// Fixups are recorded as the Use of the respective branch or
+  /// switch statement.  The use points to the final destination.
+  /// When popping out of a cleanup, these uses are threaded through
+  /// the cleanup and adjusted to point to the new cleanup.
+  ///
+  /// Note that branches are allowed to jump into protected scopes
+  /// in certain situations;  e.g. the following code is legal:
+  ///     struct A { ~A(); }; // trivial ctor, non-trivial dtor
+  ///     goto foo;
+  ///     A a;
+  ///    foo:
+  ///     bar();
+  llvm::SmallVector<BranchFixup, 8> BranchFixups;
+
+  char *allocate(size_t Size);
+
+  void *pushCleanup(CleanupKind K, size_t DataSize);
+
+public:
+  EHScopeStack() : StartOfBuffer(0), EndOfBuffer(0), StartOfData(0),
+                   InnermostNormalCleanup(stable_end()),
+                   InnermostEHCleanup(stable_end()),
+                   CatchDepth(0), NextEHDestIndex(FirstEHDestIndex) {}
+  ~EHScopeStack() { delete[] StartOfBuffer; }
+
+  // Variadic templates would make this not terrible.
+
+  /// Push a lazily-created cleanup on the stack.
+  template <class T>
+  void pushCleanup(CleanupKind Kind) {
+    void *Buffer = pushCleanup(Kind, sizeof(T));
+    Cleanup *Obj = new(Buffer) T();
+    (void) Obj;
+  }
+
+  /// Push a lazily-created cleanup on the stack.
+  template <class T, class A0>
+  void pushCleanup(CleanupKind Kind, A0 a0) {
+    void *Buffer = pushCleanup(Kind, sizeof(T));
+    Cleanup *Obj = new(Buffer) T(a0);
+    (void) Obj;
+  }
+
+  /// Push a lazily-created cleanup on the stack.
+  template <class T, class A0, class A1>
+  void pushCleanup(CleanupKind Kind, A0 a0, A1 a1) {
+    void *Buffer = pushCleanup(Kind, sizeof(T));
+    Cleanup *Obj = new(Buffer) T(a0, a1);
+    (void) Obj;
+  }
+
+  /// Push a lazily-created cleanup on the stack.
+  template <class T, class A0, class A1, class A2>
+  void pushCleanup(CleanupKind Kind, A0 a0, A1 a1, A2 a2) {
+    void *Buffer = pushCleanup(Kind, sizeof(T));
+    Cleanup *Obj = new(Buffer) T(a0, a1, a2);
+    (void) Obj;
+  }
+
+  /// Push a lazily-created cleanup on the stack.
+  template <class T, class A0, class A1, class A2, class A3>
+  void pushCleanup(CleanupKind Kind, A0 a0, A1 a1, A2 a2, A3 a3) {
+    void *Buffer = pushCleanup(Kind, sizeof(T));
+    Cleanup *Obj = new(Buffer) T(a0, a1, a2, a3);
+    (void) Obj;
+  }
+
+  /// Push a lazily-created cleanup on the stack.
+  template <class T, class A0, class A1, class A2, class A3, class A4>
+  void pushCleanup(CleanupKind Kind, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
+    void *Buffer = pushCleanup(Kind, sizeof(T));
+    Cleanup *Obj = new(Buffer) T(a0, a1, a2, a3, a4);
+    (void) Obj;
+  }
+
+  /// Pops a cleanup scope off the stack.  This should only be called
+  /// by CodeGenFunction::PopCleanupBlock.
+  void popCleanup();
+
+  /// Push a set of catch handlers on the stack.  The catch is
+  /// uninitialized and will need to have the given number of handlers
+  /// set on it.
+  class EHCatchScope *pushCatch(unsigned NumHandlers);
+
+  /// Pops a catch scope off the stack.
+  void popCatch();
+
+  /// Push an exceptions filter on the stack.
+  class EHFilterScope *pushFilter(unsigned NumFilters);
+
+  /// Pops an exceptions filter off the stack.
+  void popFilter();
+
+  /// Push a terminate handler on the stack.
+  void pushTerminate();
+
+  /// Pops a terminate handler off the stack.
+  void popTerminate();
+
+  /// Determines whether the exception-scopes stack is empty.
+  bool empty() const { return StartOfData == EndOfBuffer; }
+
+  bool requiresLandingPad() const {
+    return (CatchDepth || hasEHCleanups());
+  }
+
+  /// Determines whether there are any normal cleanups on the stack.
+  bool hasNormalCleanups() const {
+    return InnermostNormalCleanup != stable_end();
+  }
+
+  /// Returns the innermost normal cleanup on the stack, or
+  /// stable_end() if there are no normal cleanups.
+  stable_iterator getInnermostNormalCleanup() const {
+    return InnermostNormalCleanup;
+  }
+  stable_iterator getInnermostActiveNormalCleanup() const; // CGException.h
+
+  /// Determines whether there are any EH cleanups on the stack.
+  bool hasEHCleanups() const {
+    return InnermostEHCleanup != stable_end();
+  }
+
+  /// Returns the innermost EH cleanup on the stack, or stable_end()
+  /// if there are no EH cleanups.
+  stable_iterator getInnermostEHCleanup() const {
+    return InnermostEHCleanup;
+  }
+  stable_iterator getInnermostActiveEHCleanup() const; // CGException.h
+
+  /// An unstable reference to a scope-stack depth.  Invalidated by
+  /// pushes but not pops.
+  class iterator;
+
+  /// Returns an iterator pointing to the innermost EH scope.
+  iterator begin() const;
+
+  /// Returns an iterator pointing to the outermost EH scope.
+  iterator end() const;
+
+  /// Create a stable reference to the top of the EH stack.  The
+  /// returned reference is valid until that scope is popped off the
+  /// stack.
+  stable_iterator stable_begin() const {
+    return stable_iterator(EndOfBuffer - StartOfData);
+  }
+
+  /// Create a stable reference to the bottom of the EH stack.
+  static stable_iterator stable_end() {
+    return stable_iterator(0);
+  }
+
+  /// Translates an iterator into a stable_iterator.
+  stable_iterator stabilize(iterator it) const;
+
+  /// Finds the nearest cleanup enclosing the given iterator.
+  /// Returns stable_iterator::invalid() if there are no such cleanups.
+  stable_iterator getEnclosingEHCleanup(iterator it) const;
+
+  /// Turn a stable reference to a scope depth into a unstable pointer
+  /// to the EH stack.
+  iterator find(stable_iterator save) const;
+
+  /// Removes the cleanup pointed to by the given stable_iterator.
+  void removeCleanup(stable_iterator save);
+
+  /// Add a branch fixup to the current cleanup scope.
+  BranchFixup &addBranchFixup() {
+    assert(hasNormalCleanups() && "adding fixup in scope without cleanups");
+    BranchFixups.push_back(BranchFixup());
+    return BranchFixups.back();
+  }
+
+  unsigned getNumBranchFixups() const { return BranchFixups.size(); }
+  BranchFixup &getBranchFixup(unsigned I) {
+    assert(I < getNumBranchFixups());
+    return BranchFixups[I];
+  }
+
+  /// Pops lazily-removed fixups from the end of the list.  This
+  /// should only be called by procedures which have just popped a
+  /// cleanup or resolved one or more fixups.
+  void popNullFixups();
+
+  /// Clears the branch-fixups list.  This should only be called by
+  /// CodeGenFunction::ResolveAllBranchFixups.
+  void clearFixups() { BranchFixups.clear(); }
+
+  /// Gets the next EH destination index.
+  unsigned getNextEHDestIndex() { return NextEHDestIndex++; }
+};
 
 /// CodeGenFunction - This class organizes the per-function state that is used
 /// while generating LLVM code.
@@ -73,6 +407,46 @@
   CodeGenFunction(const CodeGenFunction&); // DO NOT IMPLEMENT
   void operator=(const CodeGenFunction&);  // DO NOT IMPLEMENT
 public:
+  /// A jump destination is an abstract label, branching to which may
+  /// require a jump out through normal cleanups.
+  struct JumpDest {
+    JumpDest() : Block(0), ScopeDepth(), Index(0) {}
+    JumpDest(llvm::BasicBlock *Block,
+             EHScopeStack::stable_iterator Depth,
+             unsigned Index)
+      : Block(Block), ScopeDepth(Depth), Index(Index) {}
+
+    bool isValid() const { return Block != 0; }
+    llvm::BasicBlock *getBlock() const { return Block; }
+    EHScopeStack::stable_iterator getScopeDepth() const { return ScopeDepth; }
+    unsigned getDestIndex() const { return Index; }
+    
+  private:
+    llvm::BasicBlock *Block;
+    EHScopeStack::stable_iterator ScopeDepth;
+    unsigned Index;
+  };
+
+  /// An unwind destination is an abstract label, branching to which
+  /// may require a jump out through EH cleanups.
+  struct UnwindDest {
+    UnwindDest() : Block(0), ScopeDepth(), Index(0) {}
+    UnwindDest(llvm::BasicBlock *Block,
+               EHScopeStack::stable_iterator Depth,
+               unsigned Index)
+      : Block(Block), ScopeDepth(Depth), Index(Index) {}
+
+    bool isValid() const { return Block != 0; }
+    llvm::BasicBlock *getBlock() const { return Block; }
+    EHScopeStack::stable_iterator getScopeDepth() const { return ScopeDepth; }
+    unsigned getDestIndex() const { return Index; }
+
+  private:
+    llvm::BasicBlock *Block;
+    EHScopeStack::stable_iterator ScopeDepth;
+    unsigned Index;
+  };
+
   CodeGenModule &CGM;  // Per-module state.
   const TargetInfo &Target;
 
@@ -92,154 +466,113 @@
   GlobalDecl CurGD;
 
   /// ReturnBlock - Unified return block.
-  llvm::BasicBlock *ReturnBlock;
+  JumpDest ReturnBlock;
+
   /// ReturnValue - The temporary alloca to hold the return value. This is null
   /// iff the function has no return value.
   llvm::Value *ReturnValue;
 
+  /// RethrowBlock - Unified rethrow block.
+  UnwindDest RethrowBlock;
+
   /// 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;
+  // intptr_t, i32, i64
+  const llvm::IntegerType *IntPtrTy, *Int32Ty, *Int64Ty;
   uint32_t LLVMPointerWidth;
 
   bool Exceptions;
   bool CatchUndefined;
+  
+  /// \brief A mapping from NRVO variables to the flags used to indicate
+  /// when the NRVO has been applied to this variable.
+  llvm::DenseMap<const VarDecl *, llvm::Value *> NRVOFlags;
+
+  EHScopeStack EHStack;
+
+  /// i32s containing the indexes of the cleanup destinations.
+  llvm::AllocaInst *NormalCleanupDest;
+  llvm::AllocaInst *EHCleanupDest;
+
+  unsigned NextCleanupDestIndex;
+
+  /// The exception slot.  All landing pads write the current
+  /// exception pointer into this alloca.
+  llvm::Value *ExceptionSlot;
+
+  /// Emits a landing pad for the current EH stack.
+  llvm::BasicBlock *EmitLandingPad();
+
+  llvm::BasicBlock *getInvokeDestImpl();
+
 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) {}
+  // A struct holding information about a finally block's IR
+  // generation.  For now, doesn't actually hold anything.
+  struct FinallyInfo {
   };
 
-  /// 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 {
+  FinallyInfo EnterFinallyBlock(const Stmt *Stmt,
+                                llvm::Constant *BeginCatchFn,
+                                llvm::Constant *EndCatchFn,
+                                llvm::Constant *RethrowFn);
+  void ExitFinallyBlock(FinallyInfo &FinallyInfo);
+
+  /// PushDestructorCleanup - Push a cleanup to call the
+  /// complete-object destructor of an object of the given type at the
+  /// given address.  Does nothing if T is not a C++ class type with a
+  /// non-trivial destructor.
+  void PushDestructorCleanup(QualType T, llvm::Value *Addr);
+
+  /// PushDestructorCleanup - Push a cleanup to call the
+  /// complete-object variant of the given destructor on the object at
+  /// the given address.
+  void PushDestructorCleanup(const CXXDestructorDecl *Dtor,
+                             llvm::Value *Addr);
+
+  /// PopCleanupBlock - Will pop the cleanup entry on the stack and
+  /// process all branch fixups.
+  void PopCleanupBlock(bool FallThroughIsBranchThrough = false);
+
+  void ActivateCleanup(EHScopeStack::stable_iterator Cleanup);
+
+  /// \brief Enters a new scope for capturing cleanups, all of which
+  /// will be executed once the scope is exited.
+  class RunCleanupsScope {
     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;
+    EHScopeStack::stable_iterator CleanupStackDepth;
     bool OldDidCallStackSave;
     bool PerformCleanup;
 
-    CleanupScope(const CleanupScope &); // DO NOT IMPLEMENT
-    CleanupScope &operator=(const CleanupScope &); // DO NOT IMPLEMENT
+    RunCleanupsScope(const RunCleanupsScope &); // DO NOT IMPLEMENT
+    RunCleanupsScope &operator=(const RunCleanupsScope &); // DO NOT IMPLEMENT
 
   public:
     /// \brief Enter a new cleanup scope.
-    explicit CleanupScope(CodeGenFunction &CGF) 
+    explicit RunCleanupsScope(CodeGenFunction &CGF) 
       : CGF(CGF), PerformCleanup(true) 
     {
-      CleanupStackDepth = CGF.CleanupEntries.size();
+      CleanupStackDepth = CGF.EHStack.stable_begin();
       OldDidCallStackSave = CGF.DidCallStackSave;
     }
 
     /// \brief Exit this cleanup scope, emitting any accumulated
     /// cleanups.
-    ~CleanupScope() {
+    ~RunCleanupsScope() {
       if (PerformCleanup) {
         CGF.DidCallStackSave = OldDidCallStackSave;
-        CGF.EmitCleanupBlocks(CleanupStackDepth);
+        CGF.PopCleanupBlocks(CleanupStackDepth);
       }
     }
 
     /// \brief Determine whether this scope requires any cleanups.
     bool requiresCleanups() const {
-      return CGF.CleanupEntries.size() > CleanupStackDepth;
+      return CGF.EHStack.stable_begin() != CleanupStackDepth;
     }
 
     /// \brief Force the emission of cleanups now, instead of waiting
@@ -247,42 +580,48 @@
     void ForceCleanup() {
       assert(PerformCleanup && "Already forced cleanup");
       CGF.DidCallStackSave = OldDidCallStackSave;
-      CGF.EmitCleanupBlocks(CleanupStackDepth);
+      CGF.PopCleanupBlocks(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();
-    }
-  };
 
+  /// PopCleanupBlocks - Takes the old cleanup stack size and emits
+  /// the cleanup blocks that have been added.
+  void PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize);
 
-  /// EmitCleanupBlocks - Takes the old cleanup stack size and emits the cleanup
-  /// blocks that have been added.
-  void EmitCleanupBlocks(size_t OldCleanupStackSize);
+  void ResolveAllBranchFixups(llvm::SwitchInst *Switch);
+  void ResolveBranchFixups(llvm::BasicBlock *Target);
 
-  /// 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);
+  /// The given basic block lies in the current EH scope, but may be a
+  /// target of a potentially scope-crossing jump; get a stable handle
+  /// to which we can perform this jump later.
+  JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target) {
+    return JumpDest(Target,
+                    EHStack.getInnermostNormalCleanup(),
+                    NextCleanupDestIndex++);
+  }
+
+  /// The given basic block lies in the current EH scope, but may be a
+  /// target of a potentially scope-crossing jump; get a stable handle
+  /// to which we can perform this jump later.
+  JumpDest getJumpDestInCurrentScope(const char *Name = 0) {
+    return getJumpDestInCurrentScope(createBasicBlock(Name));
+  }
+
+  /// EmitBranchThroughCleanup - Emit a branch from the current insert
+  /// block through the normal cleanup handling code (if any) and then
+  /// on to \arg Dest.
+  void EmitBranchThroughCleanup(JumpDest Dest);
+
+  /// EmitBranchThroughEHCleanup - Emit a branch from the current
+  /// insert block through the EH cleanup handling code (if any) and
+  /// then on to \arg Dest.
+  void EmitBranchThroughEHCleanup(UnwindDest Dest);
+
+  /// getRethrowDest - Returns the unified outermost-scope rethrow
+  /// destination.
+  UnwindDest getRethrowDest();
 
   /// BeginConditionalBranch - Should be called before a conditional part of an
   /// expression is emitted. For example, before the RHS of the expression below
@@ -319,16 +658,16 @@
   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;
+  llvm::DenseMap<const LabelStmt*, JumpDest> 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) {}
+    BreakContinue(JumpDest Break, JumpDest Continue)
+      : BreakBlock(Break), ContinueBlock(Continue) {}
 
-    llvm::BasicBlock *BreakBlock;
-    llvm::BasicBlock *ContinueBlock;
+    JumpDest BreakBlock;
+    JumpDest ContinueBlock;
   };
   llvm::SmallVector<BreakContinue, 8> BreakContinueStack;
 
@@ -340,10 +679,6 @@
   /// 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,
@@ -356,44 +691,9 @@
   /// 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;
+  /// A block containing a single 'unreachable' instruction.  Created
+  /// lazily by getUnreachableBlock().
+  llvm::BasicBlock *UnreachableBlock;
 
   /// CXXThisDecl - When generating code for a C++ member function,
   /// this will hold the implicit 'this' declaration.
@@ -406,31 +706,6 @@
   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.
@@ -446,18 +721,35 @@
   /// number that holds the value.
   unsigned getByRefValueLLVMField(const ValueDecl *VD) const;
 
+  llvm::BasicBlock *TerminateLandingPad;
   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; }
+  /// Returns a pointer to the function's exception object slot, which
+  /// is assigned in every landing pad.
+  llvm::Value *getExceptionSlot();
+
+  llvm::Value *getNormalCleanupDestSlot();
+  llvm::Value *getEHCleanupDestSlot();
+
+  llvm::BasicBlock *getUnreachableBlock() {
+    if (!UnreachableBlock) {
+      UnreachableBlock = createBasicBlock("unreachable");
+      new llvm::UnreachableInst(getLLVMContext(), UnreachableBlock);
+    }
+    return UnreachableBlock;
+  }
+
+  llvm::BasicBlock *getInvokeDest() {
+    if (!EHStack.requiresLandingPad()) return 0;
+    return getInvokeDestImpl();
+  }
 
   llvm::LLVMContext &getLLVMContext() { return VMContext; }
 
@@ -473,6 +765,8 @@
   /// GenerateObjCGetter - Synthesize an Objective-C property getter function.
   void GenerateObjCGetter(ObjCImplementationDecl *IMP,
                           const ObjCPropertyImplDecl *PID);
+  void GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
+                                  ObjCMethodDecl *MD, bool ctor);
 
   /// GenerateObjCSetter - Synthesize an Objective-C property setter function
   /// for the given property.
@@ -487,24 +781,26 @@
 
   llvm::Value *BuildBlockLiteralTmp(const BlockExpr *);
   llvm::Constant *BuildDescriptorBlockDecl(const BlockExpr *,
-                                           bool BlockHasCopyDispose,
-                                           CharUnits Size,
+                                           const CGBlockInfo &Info,
                                            const llvm::StructType *,
+                                           llvm::Constant *BlockVarLayout,
                                            std::vector<HelperInfo> *);
 
-  llvm::Function *GenerateBlockFunction(const BlockExpr *BExpr,
-                                        const BlockInfo& Info,
+  llvm::Function *GenerateBlockFunction(GlobalDecl GD,
+                                        const BlockExpr *BExpr,
+                                        CGBlockInfo &Info,
                                         const Decl *OuterFuncDecl,
-                                  llvm::DenseMap<const Decl*, llvm::Value*> ldm,
-                                        CharUnits &Size, CharUnits &Align,
-                      llvm::SmallVector<const Expr *, 8> &subBlockDeclRefDecls,
-                                        bool &subBlockHasCopyDispose);
+                                        llvm::Constant *& BlockVarLayout,
+                                  llvm::DenseMap<const Decl*, llvm::Value*> ldm);
 
-  void BlockForwardSelf();
   llvm::Value *LoadBlockStruct();
 
-  CharUnits AllocateBlockDecl(const BlockDeclRefExpr *E);
-  llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E);
+  void AllocateBlockCXXThisPointer(const CXXThisExpr *E);
+  void AllocateBlockDecl(const BlockDeclRefExpr *E);
+  llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E) {
+    return GetAddrOfBlockDecl(E->getDecl(), E->isByRef());
+  }
+  llvm::Value *GetAddrOfBlockDecl(const ValueDecl *D, bool ByRef);
   const llvm::Type *BuildByRefType(const ValueDecl *D);
 
   void GenerateCode(GlobalDecl GD, llvm::Function *Fn);
@@ -528,19 +824,22 @@
   /// 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);
+  void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type,
+                        FunctionArgList &Args);
 
   /// InitializeVTablePointer - Initialize the vtable pointer of the given
   /// subobject.
   ///
   void InitializeVTablePointer(BaseSubobject Base, 
                                const CXXRecordDecl *NearestVBase,
+                               uint64_t OffsetFromNearestVBase,
                                llvm::Constant *VTable,
                                const CXXRecordDecl *VTableClass);
 
   typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
   void InitializeVTablePointers(BaseSubobject Base, 
                                 const CXXRecordDecl *NearestVBase,
+                                uint64_t OffsetFromNearestVBase,
                                 bool BaseIsNonVirtualPrimaryBase,
                                 llvm::Constant *VTable,
                                 const CXXRecordDecl *VTableClass,
@@ -549,14 +848,20 @@
   void InitializeVTablePointers(const CXXRecordDecl *ClassDecl);
 
 
-  void SynthesizeCXXCopyConstructor(const FunctionArgList &Args);
-  void SynthesizeCXXCopyAssignment(const FunctionArgList &Args);
+  /// EnterDtorCleanups - Enter the cleanups necessary to complete the
+  /// given phase of destruction for a destructor.  The end result
+  /// should call destructors on members and base classes in reverse
+  /// order of their construction.
+  void EnterDtorCleanups(const CXXDestructorDecl *Dtor, CXXDtorType Type);
 
-  /// 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);
+  /// ShouldInstrumentFunction - Return true if the current function should be
+  /// instrumented with __cyg_profile_func_* calls
+  bool ShouldInstrumentFunction();
+
+  /// EmitFunctionInstrumentation - Emit LLVM code to call the specified
+  /// instrumentation function with the current function and the call site, if
+  /// function instrumentation is enabled.
+  void EmitFunctionInstrumentation(const char *Fn);
 
   /// EmitFunctionProlog - Emit the target specific LLVM code to load the
   /// arguments for the given function. This is also responsible for naming the
@@ -567,7 +872,7 @@
 
   /// EmitFunctionEpilog - Emit the target specific LLVM code to return the
   /// given temporary.
-  void EmitFunctionEpilog(const CGFunctionInfo &FI, llvm::Value *ReturnValue);
+  void EmitFunctionEpilog(const CGFunctionInfo &FI);
 
   /// EmitStartEHSpec - Emit the start of the exception spec.
   void EmitStartEHSpec(const Decl *D);
@@ -575,7 +880,12 @@
   /// EmitEndEHSpec - Emit the end of the exception spec.
   void EmitEndEHSpec(const Decl *D);
 
-  /// getTerminateHandler - Return a handler that just calls terminate.
+  /// getTerminateLandingPad - Return a landing pad that just calls terminate.
+  llvm::BasicBlock *getTerminateLandingPad();
+
+  /// getTerminateHandler - Return a handler (not a landing pad, just
+  /// a catch handler) that just calls terminate.  This is used when
+  /// a terminate scope encloses a try.
   llvm::BasicBlock *getTerminateHandler();
 
   const llvm::Type *ConvertTypeForMem(QualType T);
@@ -608,7 +918,7 @@
 
   /// getBasicBlockForLabel - Return the LLVM basicblock that the specified
   /// label maps to.
-  llvm::BasicBlock *getBasicBlockForLabel(const LabelStmt *S);
+  JumpDest getJumpDestForLabel(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
@@ -659,10 +969,8 @@
   //                                  Helpers
   //===--------------------------------------------------------------------===//
 
-  Qualifiers MakeQualifiers(QualType T) {
-    Qualifiers Quals = getContext().getCanonicalType(T).getQualifiers();
-    Quals.setObjCGCAttr(getContext().getObjCGCAttrKind(T));
-    return Quals;
+  LValue MakeAddrLValue(llvm::Value *V, QualType T, unsigned Alignment = 0) {
+    return LValue::MakeAddr(V, T, Alignment, getContext());
   }
 
   /// CreateTempAlloca - This creates a alloca and inserts it into the entry
@@ -679,11 +987,11 @@
   /// 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");
+  llvm::AllocaInst *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");
+  llvm::AllocaInst *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.
@@ -721,8 +1029,6 @@
   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);
@@ -740,8 +1046,10 @@
   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);
+  /// EmitNullInitialization - Generate code to set a value of the given type to
+  /// null, If the type contains data member pointers, they will be initialized
+  /// to -1 in accordance with the Itanium C++ ABI.
+  void EmitNullInitialization(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.
@@ -782,53 +1090,29 @@
                                         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, 
+                                     CastExpr::path_const_iterator PathBegin,
+                                     CastExpr::path_const_iterator PathEnd,
                                      bool NullCheckValue);
 
   llvm::Value *GetAddressOfDerivedClass(llvm::Value *Value,
                                         const CXXRecordDecl *Derived,
-                                        const CXXBaseSpecifierArray &BasePath,
+                                        CastExpr::path_const_iterator PathBegin,
+                                        CastExpr::path_const_iterator PathEnd,
                                         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,
+                              bool ForVirtualBase, llvm::Value *This,
                               CallExpr::const_arg_iterator ArgBeg,
                               CallExpr::const_arg_iterator ArgEnd);
 
@@ -836,13 +1120,15 @@
                                   const ConstantArrayType *ArrayTy,
                                   llvm::Value *ArrayPtr,
                                   CallExpr::const_arg_iterator ArgBeg,
-                                  CallExpr::const_arg_iterator ArgEnd);
+                                  CallExpr::const_arg_iterator ArgEnd,
+                                  bool ZeroInitialization = false);
   
   void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
                                   llvm::Value *NumElements,
                                   llvm::Value *ArrayPtr,
                                   CallExpr::const_arg_iterator ArgBeg,
-                                  CallExpr::const_arg_iterator ArgEnd);
+                                  CallExpr::const_arg_iterator ArgEnd,
+                                  bool ZeroInitialization = false);
 
   void EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
                                  const ArrayType *Array,
@@ -852,15 +1138,17 @@
                                  llvm::Value *NumElements,
                                  llvm::Value *This);
 
-  llvm::Constant *GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
-                                                const ArrayType *Array,
-                                                llvm::Value *This);
+  llvm::Function *GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
+                                                  const ArrayType *Array,
+                                                  llvm::Value *This);
 
   void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type,
-                             llvm::Value *This);
+                             bool ForVirtualBase, llvm::Value *This);
+  
+  void EmitNewArrayInitializer(const CXXNewExpr *E, llvm::Value *NewPtr,
+                               llvm::Value *NumElements);
 
-  void PushCXXTemporary(const CXXTemporary *Temporary, llvm::Value *Ptr);
-  void PopCXXTemporary();
+  void EmitCXXTemporary(const CXXTemporary *Temporary, llvm::Value *Ptr);
 
   llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E);
   void EmitCXXDeleteExpr(const CXXDeleteExpr *E);
@@ -891,10 +1179,13 @@
   /// This function can be called with a null (unreachable) insert point.
   void EmitBlockVarDecl(const VarDecl &D);
 
+  typedef void SpecialInitFn(CodeGenFunction &Init, const VarDecl &D,
+                             llvm::Value *Address);
+
   /// EmitLocalBlockVarDecl - Emit a local block variable declaration.
   ///
   /// This function can be called with a null (unreachable) insert point.
-  void EmitLocalBlockVarDecl(const VarDecl &D);
+  void EmitLocalBlockVarDecl(const VarDecl &D, SpecialInitFn *SpecialInit = 0);
 
   void EmitStaticBlockVarDecl(const VarDecl &D,
                               llvm::GlobalValue::LinkageTypes Linkage);
@@ -954,13 +1245,9 @@
   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);
+  llvm::Constant *getUnwindResumeOrRethrowFn();
+  void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
+  void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
 
   void EmitCXXTryStmt(const CXXTryStmt &S);
   
@@ -1010,13 +1297,13 @@
   /// care to appropriately convert from the memory representation to
   /// the LLVM value representation.
   llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
-                                QualType Ty);
+                                unsigned Alignment, 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);
+                         bool Volatile, unsigned Alignment, 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
@@ -1056,7 +1343,6 @@
   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);
@@ -1066,10 +1352,13 @@
   LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E);
   LValue EmitConditionalOperatorLValue(const ConditionalOperator *E);
   LValue EmitCastLValue(const CastExpr *E);
-  LValue EmitNullInitializationLValue(const CXXZeroInitValueExpr *E);
+  LValue EmitNullInitializationLValue(const CXXScalarValueInitExpr *E);
   
   llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,
                               const ObjCIvarDecl *Ivar);
+  LValue EmitLValueForAnonRecordField(llvm::Value* Base,
+                                      const FieldDecl* Field,
+                                      unsigned CVRQualifiers);
   LValue EmitLValueForField(llvm::Value* Base, const FieldDecl* Field,
                             unsigned CVRQualifiers);
   
@@ -1101,7 +1390,8 @@
   LValue EmitObjCSuperExprLValue(const ObjCSuperExpr *E);
   LValue EmitStmtExprLValue(const StmtExpr *E);
   LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E);
-  
+  LValue EmitObjCSelectorLValue(const ObjCSelectorExpr *E);
+  void   EmitDeclRefExprDbgValue(const DeclRefExpr *E, llvm::ConstantInt *Init);
   //===--------------------------------------------------------------------===//
   //                         Scalar Expression Emission
   //===--------------------------------------------------------------------===//
@@ -1116,7 +1406,8 @@
                   llvm::Value *Callee,
                   ReturnValueSlot ReturnValue,
                   const CallArgList &Args,
-                  const Decl *TargetDecl = 0);
+                  const Decl *TargetDecl = 0,
+                  llvm::Instruction **callOrInvoke = 0);
 
   RValue EmitCall(QualType FnType, llvm::Value *Callee,
                   ReturnValueSlot ReturnValue,
@@ -1126,6 +1417,11 @@
   RValue EmitCallExpr(const CallExpr *E, 
                       ReturnValueSlot ReturnValue = ReturnValueSlot());
 
+  llvm::CallSite EmitCallOrInvoke(llvm::Value *Callee,
+                                  llvm::Value * const *ArgBegin,
+                                  llvm::Value * const *ArgEnd,
+                                  const llvm::Twine &Name = "");
+
   llvm::Value *BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This,
                                 const llvm::Type *Ty);
   llvm::Value *BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type, 
@@ -1158,22 +1454,35 @@
   llvm::Value *EmitTargetBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
 
   llvm::Value *EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
+  llvm::Value *EmitNeonCall(llvm::Function *F, 
+                            llvm::SmallVectorImpl<llvm::Value*> &O,
+                            const char *name, bool splat = false,
+                            unsigned shift = 0, bool rightshift = false);
+  llvm::Value *EmitNeonSplat(llvm::Value *V, llvm::Constant *Idx,
+                             bool widen = false);
+  llvm::Value *EmitNeonShiftVector(llvm::Value *V, const llvm::Type *Ty,
+                                   bool negateForRightShift);
+  
   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);
+  RValue EmitObjCMessageExpr(const ObjCMessageExpr *E,
+                             ReturnValueSlot Return = ReturnValueSlot());
+  RValue EmitObjCPropertyGet(const Expr *E,
+                             ReturnValueSlot Return = ReturnValueSlot());
+  RValue EmitObjCSuperPropertyGet(const Expr *Exp, const Selector &S,
+                                  ReturnValueSlot Return = ReturnValueSlot());
   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);
+  RValue EmitReferenceBindingToExpr(const Expr* E, 
+                                    const NamedDecl *InitializedDecl);
 
   //===--------------------------------------------------------------------===//
   //                           Expression Emission
@@ -1269,7 +1578,7 @@
   /// GenerateCXXGlobalDtorFunc - Generates code for destroying global
   /// variables.
   void GenerateCXXGlobalDtorFunc(llvm::Function *Fn,
-                                 const std::vector<std::pair<llvm::Constant*,
+                                 const std::vector<std::pair<llvm::WeakVH,
                                    llvm::Constant*> > &DtorsAndObjects);
 
   void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, const VarDecl *D);
@@ -1306,13 +1615,17 @@
 
   /// 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();
+  llvm::BasicBlock *getTrapBB();
   
   /// EmitCallArg - Emit a single call argument.
   RValue EmitCallArg(const Expr *E, QualType ArgType);
 
-private:
+  /// EmitDelegateCallArg - We are performing a delegate call; that
+  /// is, the current function is delegating to another one.  Produce
+  /// a r-value suitable for passing the given parameter.
+  RValue EmitDelegateCallArg(const VarDecl *Param);
 
+private:
   void EmitReturnOfRValue(RValue RV, QualType Ty);
 
   /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty
@@ -1335,12 +1648,10 @@
                             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);
+  llvm::Value* EmitAsmInputLValue(const AsmStmt &S,
+                                  const TargetInfo::ConstraintInfo &Info,
+                                  LValue InputValue, QualType InputType,
+                                  std::string &ConstraintStr);
 
   /// EmitCallArgs - Emit call arguments for a function.
   /// The CallArgTypeInfo parameter is used for iterating over the known
@@ -1385,9 +1696,40 @@
   const TargetCodeGenInfo &getTargetHooks() const {
     return CGM.getTargetCodeGenInfo();
   }
+
+  void EmitDeclMetadata();
 };
 
-
+/// CGBlockInfo - Information to generate a block literal.
+class CGBlockInfo {
+public:
+  /// Name - The name of the block, kindof.
+  const char *Name;
+    
+  /// DeclRefs - Variables from parent scopes that have been
+  /// imported into this block.
+  llvm::SmallVector<const BlockDeclRefExpr *, 8> DeclRefs;
+    
+  /// InnerBlocks - This block and the blocks it encloses.
+  llvm::SmallPtrSet<const DeclContext *, 4> InnerBlocks;
+    
+  /// CXXThisRef - Non-null if 'this' was required somewhere, in
+  /// which case this is that expression.
+  const CXXThisExpr *CXXThisRef;
+    
+  /// NeedsObjCSelf - True if something in this block has an implicit
+  /// reference to 'self'.
+  bool NeedsObjCSelf;
+    
+  /// These are initialized by GenerateBlockFunction.
+  bool BlockHasCopyDispose;
+  CharUnits BlockSize;
+  CharUnits BlockAlign;
+  llvm::SmallVector<const Expr*, 8> BlockLayout;
+    
+  CGBlockInfo(const char *Name);
+};
+  
 }  // end namespace CodeGen
 }  // end namespace clang
 
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 599df96..d8e12e7 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -18,11 +18,12 @@
 #include "CGObjCRuntime.h"
 #include "Mangle.h"
 #include "TargetInfo.h"
-#include "clang/CodeGen/CodeGenOptions.h"
+#include "clang/Frontend/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/DeclTemplate.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/Diagnostic.h"
@@ -40,6 +41,17 @@
 using namespace clang;
 using namespace CodeGen;
 
+static CGCXXABI &createCXXABI(CodeGenModule &CGM) {
+  switch (CGM.getContext().Target.getCXXABI()) {
+  case CXXABI_ARM: return *CreateARMCXXABI(CGM);
+  case CXXABI_Itanium: return *CreateItaniumCXXABI(CGM);
+  case CXXABI_Microsoft: return *CreateMicrosoftCXXABI(CGM);
+  }
+
+  llvm_unreachable("invalid C++ ABI kind");
+  return *CreateItaniumCXXABI(CGM);
+}
+
 
 CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
                              llvm::Module &M, const llvm::TargetData &TD,
@@ -47,11 +59,15 @@
   : 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()) {
+    ABI(createCXXABI(*this)), 
+    Types(C, M, TD, getTargetCodeGenInfo().getABIInfo(), ABI),
+    VTables(*this), Runtime(0),
+    CFConstantStringClassRef(0), NSConstantStringClassRef(0),
+    VMContext(M.getContext()),
+    NSConcreteGlobalBlockDecl(0), NSConcreteStackBlockDecl(0),
+    NSConcreteGlobalBlock(0), NSConcreteStackBlock(0),
+    BlockObjectAssignDecl(0), BlockObjectDisposeDecl(0),
+    BlockObjectAssign(0), BlockObjectDispose(0){
 
   if (!Features.ObjC1)
     Runtime = 0;
@@ -68,6 +84,7 @@
 
 CodeGenModule::~CodeGenModule() {
   delete Runtime;
+  delete &ABI;
   delete DebugInfo;
 }
 
@@ -91,6 +108,9 @@
   EmitCtorList(GlobalDtors, "llvm.global_dtors");
   EmitAnnotations();
   EmitLLVMUsed();
+
+  if (getCodeGenOpts().EmitDeclMetadata)
+    EmitDeclMetadata();
 }
 
 bool CodeGenModule::isTargetDarwin() const {
@@ -125,24 +145,57 @@
 LangOptions::VisibilityMode
 CodeGenModule::getDeclVisibilityMode(const Decl *D) const {
   if (const VarDecl *VD = dyn_cast<VarDecl>(D))
-    if (VD->getStorageClass() == VarDecl::PrivateExtern)
+    if (VD->getStorageClass() == SC_PrivateExtern)
       return LangOptions::Hidden;
 
   if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>()) {
     switch (attr->getVisibility()) {
     default: assert(0 && "Unknown visibility!");
-    case VisibilityAttr::DefaultVisibility:
+    case VisibilityAttr::Default:
       return LangOptions::Default;
-    case VisibilityAttr::HiddenVisibility:
+    case VisibilityAttr::Hidden:
       return LangOptions::Hidden;
-    case VisibilityAttr::ProtectedVisibility:
+    case VisibilityAttr::Protected:
       return LangOptions::Protected;
     }
   }
+  
+  if (getLangOptions().CPlusPlus) {
+    // Entities subject to an explicit instantiation declaration get default
+    // visibility.
+    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+      if (Function->getTemplateSpecializationKind()
+                                        == TSK_ExplicitInstantiationDeclaration)
+        return LangOptions::Default;
+    } else if (const ClassTemplateSpecializationDecl *ClassSpec
+                              = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+      if (ClassSpec->getSpecializationKind()
+                                        == TSK_ExplicitInstantiationDeclaration)
+        return LangOptions::Default;
+    } else if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
+      if (Record->getTemplateSpecializationKind()
+                                        == TSK_ExplicitInstantiationDeclaration)
+        return LangOptions::Default;
+    } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
+      if (Var->isStaticDataMember() &&
+          (Var->getTemplateSpecializationKind()
+                                      == TSK_ExplicitInstantiationDeclaration))
+        return LangOptions::Default;
+    }
 
-  // This decl should have the same visibility as its parent.
+    // If -fvisibility-inlines-hidden was provided, then inline C++ member
+    // functions get "hidden" visibility by default.
+    if (getLangOptions().InlineVisibilityHidden)
+      if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
+        if (Method->isInlined())
+          return LangOptions::Hidden;
+  }
+           
+  // If this decl is contained in a class, it should have the same visibility
+  // as the parent class.
   if (const DeclContext *DC = D->getDeclContext()) 
-    return getDeclVisibilityMode(cast<Decl>(DC));
+    if (DC->isRecord())
+      return getDeclVisibilityMode(cast<Decl>(DC));
 
   return getLangOptions().getVisibilityMode();
 }
@@ -166,32 +219,105 @@
   }
 }
 
-void CodeGenModule::getMangledName(MangleBuffer &Buffer, GlobalDecl GD) {
-  const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
+/// Set the symbol visibility of type information (vtable and RTTI)
+/// associated with the given type.
+void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV,
+                                      const CXXRecordDecl *RD,
+                                      bool IsForRTTI) const {
+  setGlobalVisibility(GV, RD);
 
-  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());
+  if (!CodeGenOpts.HiddenWeakVTables)
     return;
+
+  // We want to drop the visibility to hidden for weak type symbols.
+  // This isn't possible if there might be unresolved references
+  // elsewhere that rely on this symbol being visible.
+
+  // This should be kept roughly in sync with setThunkVisibility
+  // in CGVTables.cpp.
+
+  // Preconditions.
+  if (GV->getLinkage() != llvm::GlobalVariable::WeakODRLinkage ||
+      GV->getVisibility() != llvm::GlobalVariable::DefaultVisibility)
+    return;
+
+  // Don't override an explicit visibility attribute.
+  if (RD->hasAttr<VisibilityAttr>())
+    return;
+
+  switch (RD->getTemplateSpecializationKind()) {
+  // We have to disable the optimization if this is an EI definition
+  // because there might be EI declarations in other shared objects.
+  case TSK_ExplicitInstantiationDefinition:
+  case TSK_ExplicitInstantiationDeclaration:
+    return;
+
+  // Every use of a non-template class's type information has to emit it.
+  case TSK_Undeclared:
+    break;
+
+  // In theory, implicit instantiations can ignore the possibility of
+  // an explicit instantiation declaration because there necessarily
+  // must be an EI definition somewhere with default visibility.  In
+  // practice, it's possible to have an explicit instantiation for
+  // an arbitrary template class, and linkers aren't necessarily able
+  // to deal with mixed-visibility symbols.
+  case TSK_ExplicitSpecialization:
+  case TSK_ImplicitInstantiation:
+    if (!CodeGenOpts.HiddenWeakTemplateVTables)
+      return;
+    break;
   }
 
-  getMangleContext().mangleName(ND, Buffer.getBuffer());
+  // If there's a key function, there may be translation units
+  // that don't have the key function's definition.  But ignore
+  // this if we're emitting RTTI under -fno-rtti.
+  if (!IsForRTTI || Features.RTTI)
+    if (Context.getKeyFunction(RD))
+      return;
+
+  // Otherwise, drop the visibility to hidden.
+  GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
+}
+
+llvm::StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
+  const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
+
+  llvm::StringRef &Str = MangledDeclNames[GD.getCanonicalDecl()];
+  if (!Str.empty())
+    return Str;
+
+  if (!getMangleContext().shouldMangleDeclName(ND)) {
+    IdentifierInfo *II = ND->getIdentifier();
+    assert(II && "Attempt to mangle unnamed decl.");
+
+    Str = II->getName();
+    return Str;
+  }
+  
+  llvm::SmallString<256> Buffer;
+  if (const CXXConstructorDecl *D = dyn_cast<CXXConstructorDecl>(ND))
+    getMangleContext().mangleCXXCtor(D, GD.getCtorType(), Buffer);
+  else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))
+    getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Buffer);
+  else if (const BlockDecl *BD = dyn_cast<BlockDecl>(ND))
+    getMangleContext().mangleBlock(GD, BD, Buffer);
+  else
+    getMangleContext().mangleName(ND, Buffer);
+
+  // Allocate space for the mangled name.
+  size_t Length = Buffer.size();
+  char *Name = MangledNamesAllocator.Allocate<char>(Length);
+  std::copy(Buffer.begin(), Buffer.end(), Name);
+  
+  Str = llvm::StringRef(Name, Length);
+  
+  return Str;
+}
+
+void CodeGenModule::getMangledName(GlobalDecl GD, MangleBuffer &Buffer,
+                                   const BlockDecl *BD) {
+  getMangleContext().mangleBlock(GD, BD, Buffer.getBuffer());
 }
 
 llvm::GlobalValue *CodeGenModule::GetGlobalValue(llvm::StringRef Name) {
@@ -260,109 +386,43 @@
   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);
+  GVALinkage Linkage = getContext().GetGVALinkageForFunction(D);
 
-  if (Linkage == GVA_Internal) {
+  if (Linkage == GVA_Internal)
     return llvm::Function::InternalLinkage;
-  } else if (D->hasAttr<DLLExportAttr>()) {
+  
+  if (D->hasAttr<DLLExportAttr>())
     return llvm::Function::DLLExportLinkage;
-  } else if (D->hasAttr<WeakAttr>()) {
+  
+  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.
+  
+  // In C99 mode, 'inline' functions are guaranteed to have a strong
+  // definition somewhere else, so we can use available_externally linkage.
+  if (Linkage == GVA_C99Inline)
     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.
+  
+  // 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.
+  if (Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation)
     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.
+  
+  // 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.
+  if (Linkage == GVA_ExplicitTemplateInstantiation)
     return llvm::Function::WeakODRLinkage;
-  } else {
-    assert(Linkage == GVA_StrongExternal);
-    // Otherwise, we have strong external linkage.
-    return llvm::Function::ExternalLinkage;
-  }
+  
+  // Otherwise, we have strong external linkage.
+  assert(Linkage == GVA_StrongExternal);
+  return llvm::Function::ExternalLinkage;
 }
 
 
@@ -372,7 +432,6 @@
 /// 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);
 }
 
@@ -403,12 +462,10 @@
   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));
-  }
+  unsigned alignment = D->getMaxAlignment() / Context.getCharWidth();
+  if (alignment)
+    F->setAlignment(alignment);
+
   // C++ ABI requires 2-byte alignment for member functions.
   if (F->getAlignment() < 2 && isa<CXXMethodDecl>(D))
     F->setAlignment(2);
@@ -515,17 +572,26 @@
     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);
+    // Check to see if we've already emitted this.  This is necessary
+    // for a couple of reasons: first, decls can end up in the
+    // deferred-decls queue multiple times, and second, decls can end
+    // up with definitions in unusual ways (e.g. by an extern inline
+    // function acquiring a strong function redefinition).  Just
+    // ignore these cases.
+    //
+    // TODO: That said, looking this up multiple times is very wasteful.
+    llvm::StringRef Name = getMangledName(D);
     llvm::GlobalValue *CGRef = GetGlobalValue(Name);
     assert(CGRef && "Deferred decl wasn't referenced?");
 
     if (!CGRef->isDeclaration())
       continue;
 
+    // GlobalAlias::isDeclaration() defers to the aliasee, but for our
+    // purposes an alias counts as a definition.
+    if (isa<llvm::GlobalAlias>(CGRef))
+      continue;
+
     // Otherwise, emit the definition and move on to the next one.
     EmitGlobalDefinition(D);
   }
@@ -579,74 +645,11 @@
 }
 
 bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
-  // Never defer when EmitAllDecls is specified or the decl has
-  // attribute used.
-  if (Features.EmitAllDecls || Global->hasAttr<UsedAttr>())
+  // Never defer when EmitAllDecls is specified.
+  if (Features.EmitAllDecls)
     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;
+  return !getContext().DeclMustBeEmitted(Global);
 }
 
 llvm::Constant *CodeGenModule::GetWeakRefReference(const ValueDecl *VD) {
@@ -687,6 +690,15 @@
 
   // Ignore declarations, they will be emitted on their first use.
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
+    if (FD->getIdentifier()) {
+      llvm::StringRef Name = FD->getName();
+      if (Name == "_Block_object_assign") {
+        BlockObjectAssignDecl = FD;
+      } else if (Name == "_Block_object_dispose") {
+        BlockObjectDisposeDecl = FD;
+      }
+    }
+
     // Forward declarations are emitted lazily on first use.
     if (!FD->isThisDeclarationADefinition())
       return;
@@ -694,6 +706,16 @@
     const VarDecl *VD = cast<VarDecl>(Global);
     assert(VD->isFileVarDecl() && "Cannot emit local var decl as global.");
 
+    if (VD->getIdentifier()) {
+      llvm::StringRef Name = VD->getName();
+      if (Name == "_NSConcreteGlobalBlock") {
+        NSConcreteGlobalBlockDecl = VD;
+      } else if (Name == "_NSConcreteStackBlock") {
+        NSConcreteStackBlockDecl = VD;
+      }
+    }
+
+
     if (VD->isThisDeclarationADefinition() != VarDecl::Definition)
       return;
   }
@@ -705,11 +727,18 @@
     EmitGlobalDefinition(GD);
     return;
   }
+
+  // If we're deferring emission of a C++ variable with an
+  // initializer, remember the order in which it appeared in the file.
+  if (getLangOptions().CPlusPlus && isa<VarDecl>(Global) &&
+      cast<VarDecl>(Global)->hasInit()) {
+    DelayedCXXInitPosition[Global] = CXXGlobalInits.size();
+    CXXGlobalInits.push_back(0);
+  }
   
   // If the value has already been used, add it directly to the
   // DeferredDeclsToEmit list.
-  MangleBuffer MangledName;
-  getMangledName(MangledName, GD);
+  llvm::StringRef MangledName = getMangledName(GD);
   if (GetGlobalValue(MangledName))
     DeferredDeclsToEmit.push_back(GD);
   else {
@@ -727,17 +756,28 @@
                                  Context.getSourceManager(),
                                  "Generating code for declaration");
   
-  if (isa<CXXMethodDecl>(D))
-    getVTables().EmitVTableRelatedData(GD);
+  if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+    // At -O0, don't generate IR for functions with available_externally 
+    // linkage.
+    if (CodeGenOpts.OptimizationLevel == 0 && 
+        !Function->hasAttr<AlwaysInlineAttr>() &&
+        getFunctionLinkage(Function) 
+                                  == llvm::Function::AvailableExternallyLinkage)
+      return;
 
-  if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
-    return EmitCXXConstructor(CD, GD.getCtorType());
+    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
+      if (Method->isVirtual())
+        getVTables().EmitThunks(GD);
+
+      if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Method))
+        return EmitCXXConstructor(CD, GD.getCtorType());
   
-  if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D))
-    return EmitCXXDestructor(DD, GD.getDtorType());
+      if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(Method))
+        return EmitCXXDestructor(DD, GD.getDtorType());
+    }
 
-  if (isa<FunctionDecl>(D))
     return EmitGlobalFunctionDefinition(GD);
+  }
   
   if (const VarDecl *VD = dyn_cast<VarDecl>(D))
     return EmitGlobalVarDefinition(VD);
@@ -779,12 +819,17 @@
   // 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);
+
+  const llvm::FunctionType *FTy;
+  if (isa<llvm::FunctionType>(Ty)) {
+    FTy = cast<llvm::FunctionType>(Ty);
+  } else {
+    FTy = 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 *F = llvm::Function::Create(FTy,
                                              llvm::Function::ExternalLinkage,
                                              MangledName, &getModule());
   assert(F->getName() == MangledName && "name was uniqued!");
@@ -826,7 +871,14 @@
     }
   }
 
-  return F;
+  // Make sure the result is of the requested type.
+  if (!IsIncompleteFunction) {
+    assert(F->getType()->getElementType() == Ty);
+    return F;
+  }
+
+  const llvm::Type *PTy = llvm::PointerType::getUnqual(Ty);
+  return llvm::ConstantExpr::getBitCast(F, PTy);
 }
 
 /// GetAddrOfFunction - Return the address of the given function.  If Ty is
@@ -837,8 +889,8 @@
   // 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);
+  
+  llvm::StringRef MangledName = getMangledName(GD);
   return GetOrCreateLLVMFunction(MangledName, Ty, GD);
 }
 
@@ -913,7 +965,7 @@
     GV->setConstant(DeclIsConstantGlobal(Context, D));
 
     // FIXME: Merge with other attribute handling code.
-    if (D->getStorageClass() == VarDecl::PrivateExtern)
+    if (D->getStorageClass() == SC_PrivateExtern)
       GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
 
     if (D->hasAttr<WeakAttr>() ||
@@ -941,8 +993,7 @@
   const llvm::PointerType *PTy =
     llvm::PointerType::get(Ty, ASTTy.getAddressSpace());
 
-  MangleBuffer MangledName;
-  getMangledName(MangledName, D);
+  llvm::StringRef MangledName = getMangledName(D);
   return GetOrCreateLLVMGlobal(MangledName, PTy, D);
 }
 
@@ -961,8 +1012,7 @@
     // 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);
+    llvm::StringRef MangledName = getMangledName(D);
     if (!GetGlobalValue(MangledName)) {
       DeferredDecls[MangledName] = D;
       return;
@@ -973,6 +1023,11 @@
   EmitGlobalVarDefinition(D);
 }
 
+void CodeGenModule::EmitVTable(CXXRecordDecl *Class, bool DefinitionRequired) {
+  if (DefinitionRequired)
+    getVTables().GenerateClassData(getVTableLinkage(Class), Class);
+}
+
 llvm::GlobalVariable::LinkageTypes 
 CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
   if (RD->isInAnonymousNamespace() || !RD->hasLinkage())
@@ -983,7 +1038,7 @@
     // If this class has a key function, use that to determine the linkage of
     // the vtable.
     const FunctionDecl *Def = 0;
-    if (KeyFunction->getBody(Def))
+    if (KeyFunction->hasBody(Def))
       KeyFunction = cast<CXXMethodDecl>(Def);
     
     switch (KeyFunction->getTemplateSpecializationKind()) {
@@ -1024,47 +1079,6 @@
   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());
@@ -1090,10 +1104,12 @@
     assert(!ASTTy->isIncompleteType() && "Unexpected incomplete type");
     Init = EmitNullConstant(D->getType());
   } else {
-    Init = EmitConstantExpr(InitExpr, D->getType());
-
+    Init = EmitConstantExpr(InitExpr, D->getType());       
     if (!Init) {
       QualType T = InitExpr->getType();
+      if (D->getType()->isReferenceType())
+        T = D->getType();
+      
       if (getLangOptions().CPlusPlus) {
         EmitCXXGlobalVarDeclInitFunc(D);
         Init = EmitNullConstant(T);
@@ -1102,6 +1118,11 @@
         ErrorUnsupported(D, "static initializer");
         Init = llvm::UndefValue::get(getTypes().ConvertType(T));
       }
+    } else {
+      // We don't need an initializer, so remove the entry for the delayed
+      // initializer position (just in case this entry was delayed).
+      if (getLangOptions().CPlusPlus)
+        DelayedCXXInitPosition.erase(D);
     }
   }
 
@@ -1163,7 +1184,7 @@
   GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
 
   // Set the llvm linkage type as appropriate.
-  GVALinkage Linkage = GetLinkageForVariable(getContext(), D);
+  GVALinkage Linkage = getContext().GetGVALinkageForVariable(D);
   if (Linkage == GVA_Internal)
     GV->setLinkage(llvm::Function::InternalLinkage);
   else if (D->hasAttr<DLLImportAttr>())
@@ -1182,7 +1203,8 @@
     GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage);   
   else if (!getLangOptions().CPlusPlus && !CodeGenOpts.NoCommon &&
            !D->hasExternalStorage() && !D->getInit() &&
-           !D->getAttr<SectionAttr>()) {
+           !D->getAttr<SectionAttr>() && !D->isThreadSpecified()) {
+    // Thread local vars aren't considered common linkage.
     GV->setLinkage(llvm::GlobalVariable::CommonLinkage);
     // common vars aren't constant even if declared const.
     GV->setConstant(false);
@@ -1221,6 +1243,7 @@
     // 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);
+    if (!CI) continue; // FIXME: when we allow Invoke, just do CallSite CS(*I)
     llvm::CallSite CS(CI);
     if (!CI || !CS.isCallee(I)) continue;
 
@@ -1322,6 +1345,7 @@
   }
 
   llvm::Function *Fn = cast<llvm::Function>(Entry);
+  setFunctionLinkage(D, Fn);
 
   CodeGenFunction(*this).GenerateCode(D, Fn);
 
@@ -1339,8 +1363,7 @@
   const AliasAttr *AA = D->getAttr<AliasAttr>();
   assert(AA && "Not an alias?");
 
-  MangleBuffer MangledName;
-  getMangledName(MangledName, GD);
+  llvm::StringRef MangledName = getMangledName(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.
@@ -1381,7 +1404,7 @@
                                                           Entry->getType()));
     Entry->eraseFromParent();
   } else {
-    GA->setName(MangledName.getString());
+    GA->setName(MangledName);
   }
 
   // Set attributes which are particular to an alias; this is a
@@ -1390,7 +1413,7 @@
   if (D->hasAttr<DLLExportAttr>()) {
     if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
       // The dllexport attribute is ignored for undefined symbols.
-      if (FD->getBody())
+      if (FD->hasBody())
         GA->setLinkage(llvm::Function::DLLExportLinkage);
     } else {
       GA->setLinkage(llvm::Function::DLLExportLinkage);
@@ -1456,18 +1479,18 @@
                          bool TargetIsLSB,
                          bool &IsUTF16,
                          unsigned &StringLength) {
-  unsigned NumBytes = Literal->getByteLength();
+  llvm::StringRef String = Literal->getString();
+  unsigned NumBytes = String.size();
 
   // Check for simple case.
   if (!Literal->containsNonAsciiOrNull()) {
     StringLength = NumBytes;
-    return Map.GetOrCreateValue(llvm::StringRef(Literal->getStrData(),
-                                                StringLength));
+    return Map.GetOrCreateValue(String);
   }
 
   // Otherwise, convert the UTF8 literals into a byte string.
   llvm::SmallVector<UTF16, 128> ToBuf(NumBytes);
-  const UTF8 *FromPtr = (UTF8 *)Literal->getStrData();
+  const UTF8 *FromPtr = (UTF8 *)String.data();
   UTF16 *ToPtr = &ToBuf[0];
 
   ConversionResult Result = ConvertUTF8toUTF16(&FromPtr, FromPtr + NumBytes,
@@ -1480,8 +1503,7 @@
     // this duplicate code.
     assert(Result == sourceIllegal && "UTF-8 to UTF-16 conversion failed");
     StringLength = NumBytes;
-    return Map.GetOrCreateValue(llvm::StringRef(Literal->getStrData(),
-                                                StringLength));
+    return Map.GetOrCreateValue(String);
   }
 
   // ConvertUTF8toUTF16 returns the length in ToPtr.
@@ -1681,20 +1703,17 @@
 /// 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;
 
+  std::string Str = E->getString().str();
   Str.resize(RealLen, '\0');
 
   return Str;
@@ -1809,6 +1828,39 @@
   }
 }
 
+/// EmitObjCIvarInitializations - Emit information for ivar initialization
+/// for an implementation.
+void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) {
+  if (!Features.NeXTRuntime || D->getNumIvarInitializers() == 0)
+    return;
+  DeclContext* DC = const_cast<DeclContext*>(dyn_cast<DeclContext>(D));
+  assert(DC && "EmitObjCIvarInitializations - null DeclContext");
+  IdentifierInfo *II = &getContext().Idents.get(".cxx_destruct");
+  Selector cxxSelector = getContext().Selectors.getSelector(0, &II);
+  ObjCMethodDecl *DTORMethod = ObjCMethodDecl::Create(getContext(), 
+                                                  D->getLocation(),
+                                                  D->getLocation(), cxxSelector,
+                                                  getContext().VoidTy, 0, 
+                                                  DC, true, false, true, false,
+                                                  ObjCMethodDecl::Required);
+  D->addInstanceMethod(DTORMethod);
+  CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, DTORMethod, false);
+  
+  II = &getContext().Idents.get(".cxx_construct");
+  cxxSelector = getContext().Selectors.getSelector(0, &II);
+  // The constructor returns 'self'.
+  ObjCMethodDecl *CTORMethod = ObjCMethodDecl::Create(getContext(), 
+                                                D->getLocation(),
+                                                D->getLocation(), cxxSelector,
+                                                getContext().getObjCIdType(), 0, 
+                                                DC, true, false, true, false,
+                                                ObjCMethodDecl::Required);
+  D->addInstanceMethod(CTORMethod);
+  CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, CTORMethod, true);
+  
+
+}
+
 /// 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();
@@ -1888,9 +1940,16 @@
   // Forward declarations, no (immediate) code generation.
   case Decl::ObjCClass:
   case Decl::ObjCForwardProtocol:
-  case Decl::ObjCCategory:
   case Decl::ObjCInterface:
     break;
+  
+    case Decl::ObjCCategory: {
+      ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
+      if (CD->IsClassExtension() && CD->hasSynthBitfield())
+        Context.ResetObjCLayout(CD->getClassInterface());
+      break;
+    }
+      
 
   case Decl::ObjCProtocol:
     Runtime->GenerateProtocol(cast<ObjCProtocolDecl>(D));
@@ -1904,7 +1963,10 @@
 
   case Decl::ObjCImplementation: {
     ObjCImplementationDecl *OMD = cast<ObjCImplementationDecl>(D);
+    if (Features.ObjCNonFragileABI2 && OMD->hasSynthBitfield())
+      Context.ResetObjCLayout(OMD->getClassInterface());
     EmitObjCPropertyImplementations(OMD);
+    EmitObjCIvarInitializations(OMD);
     Runtime->GenerateClass(OMD);
     break;
   }
@@ -1942,3 +2004,158 @@
     assert(isa<TypeDecl>(D) && "Unsupported decl kind");
   }
 }
+
+/// Turns the given pointer into a constant.
+static llvm::Constant *GetPointerConstant(llvm::LLVMContext &Context,
+                                          const void *Ptr) {
+  uintptr_t PtrInt = reinterpret_cast<uintptr_t>(Ptr);
+  const llvm::Type *i64 = llvm::Type::getInt64Ty(Context);
+  return llvm::ConstantInt::get(i64, PtrInt);
+}
+
+static void EmitGlobalDeclMetadata(CodeGenModule &CGM,
+                                   llvm::NamedMDNode *&GlobalMetadata,
+                                   GlobalDecl D,
+                                   llvm::GlobalValue *Addr) {
+  if (!GlobalMetadata)
+    GlobalMetadata =
+      CGM.getModule().getOrInsertNamedMetadata("clang.global.decl.ptrs");
+
+  // TODO: should we report variant information for ctors/dtors?
+  llvm::Value *Ops[] = {
+    Addr,
+    GetPointerConstant(CGM.getLLVMContext(), D.getDecl())
+  };
+  GlobalMetadata->addOperand(llvm::MDNode::get(CGM.getLLVMContext(), Ops, 2));
+}
+
+/// Emits metadata nodes associating all the global values in the
+/// current module with the Decls they came from.  This is useful for
+/// projects using IR gen as a subroutine.
+///
+/// Since there's currently no way to associate an MDNode directly
+/// with an llvm::GlobalValue, we create a global named metadata
+/// with the name 'clang.global.decl.ptrs'.
+void CodeGenModule::EmitDeclMetadata() {
+  llvm::NamedMDNode *GlobalMetadata = 0;
+
+  // StaticLocalDeclMap
+  for (llvm::DenseMap<GlobalDecl,llvm::StringRef>::iterator
+         I = MangledDeclNames.begin(), E = MangledDeclNames.end();
+       I != E; ++I) {
+    llvm::GlobalValue *Addr = getModule().getNamedValue(I->second);
+    EmitGlobalDeclMetadata(*this, GlobalMetadata, I->first, Addr);
+  }
+}
+
+/// Emits metadata nodes for all the local variables in the current
+/// function.
+void CodeGenFunction::EmitDeclMetadata() {
+  if (LocalDeclMap.empty()) return;
+
+  llvm::LLVMContext &Context = getLLVMContext();
+
+  // Find the unique metadata ID for this name.
+  unsigned DeclPtrKind = Context.getMDKindID("clang.decl.ptr");
+
+  llvm::NamedMDNode *GlobalMetadata = 0;
+
+  for (llvm::DenseMap<const Decl*, llvm::Value*>::iterator
+         I = LocalDeclMap.begin(), E = LocalDeclMap.end(); I != E; ++I) {
+    const Decl *D = I->first;
+    llvm::Value *Addr = I->second;
+
+    if (llvm::AllocaInst *Alloca = dyn_cast<llvm::AllocaInst>(Addr)) {
+      llvm::Value *DAddr = GetPointerConstant(getLLVMContext(), D);
+      Alloca->setMetadata(DeclPtrKind, llvm::MDNode::get(Context, &DAddr, 1));
+    } else if (llvm::GlobalValue *GV = dyn_cast<llvm::GlobalValue>(Addr)) {
+      GlobalDecl GD = GlobalDecl(cast<VarDecl>(D));
+      EmitGlobalDeclMetadata(CGM, GlobalMetadata, GD, GV);
+    }
+  }
+}
+
+///@name Custom Runtime Function Interfaces
+///@{
+//
+// FIXME: These can be eliminated once we can have clients just get the required
+// AST nodes from the builtin tables.
+
+llvm::Constant *CodeGenModule::getBlockObjectDispose() {
+  if (BlockObjectDispose)
+    return BlockObjectDispose;
+
+  // If we saw an explicit decl, use that.
+  if (BlockObjectDisposeDecl) {
+    return BlockObjectDispose = GetAddrOfFunction(
+      BlockObjectDisposeDecl,
+      getTypes().GetFunctionType(BlockObjectDisposeDecl));
+  }
+
+  // Otherwise construct the function by hand.
+  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);
+  return BlockObjectDispose =
+    CreateRuntimeFunction(FTy, "_Block_object_dispose");
+}
+
+llvm::Constant *CodeGenModule::getBlockObjectAssign() {
+  if (BlockObjectAssign)
+    return BlockObjectAssign;
+
+  // If we saw an explicit decl, use that.
+  if (BlockObjectAssignDecl) {
+    return BlockObjectAssign = GetAddrOfFunction(
+      BlockObjectAssignDecl,
+      getTypes().GetFunctionType(BlockObjectAssignDecl));
+  }
+
+  // Otherwise construct the function by hand.
+  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);
+  return BlockObjectAssign =
+    CreateRuntimeFunction(FTy, "_Block_object_assign");
+}
+
+llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() {
+  if (NSConcreteGlobalBlock)
+    return NSConcreteGlobalBlock;
+
+  // If we saw an explicit decl, use that.
+  if (NSConcreteGlobalBlockDecl) {
+    return NSConcreteGlobalBlock = GetAddrOfGlobalVar(
+      NSConcreteGlobalBlockDecl,
+      getTypes().ConvertType(NSConcreteGlobalBlockDecl->getType()));
+  }
+
+  // Otherwise construct the variable by hand.
+  return NSConcreteGlobalBlock = CreateRuntimeVariable(
+    PtrToInt8Ty, "_NSConcreteGlobalBlock");
+}
+
+llvm::Constant *CodeGenModule::getNSConcreteStackBlock() {
+  if (NSConcreteStackBlock)
+    return NSConcreteStackBlock;
+
+  // If we saw an explicit decl, use that.
+  if (NSConcreteStackBlockDecl) {
+    return NSConcreteStackBlock = GetAddrOfGlobalVar(
+      NSConcreteStackBlockDecl,
+      getTypes().ConvertType(NSConcreteStackBlockDecl->getType()));
+  }
+
+  // Otherwise construct the variable by hand.
+  return NSConcreteStackBlock = CreateRuntimeVariable(
+    PtrToInt8Ty, "_NSConcreteStackBlock");
+}
+
+///@}
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index b0abc49..cd00f43 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -22,6 +22,7 @@
 #include "CGCall.h"
 #include "CGCXX.h"
 #include "CGVTables.h"
+#include "CGCXXABI.h"
 #include "CodeGenTypes.h"
 #include "GlobalDecl.h"
 #include "Mangle.h"
@@ -74,6 +75,25 @@
   class CGObjCRuntime;
   class MangleBuffer;
   
+  struct OrderGlobalInits {
+    unsigned int priority;
+    unsigned int lex_order;
+    OrderGlobalInits(unsigned int p, unsigned int l) 
+      : priority(p), lex_order(l) {}
+    
+    bool operator==(const OrderGlobalInits &RHS) const {
+      return priority == RHS.priority &&
+             lex_order == RHS.lex_order;
+    }
+    
+    bool operator<(const OrderGlobalInits &RHS) const {
+      if (priority < RHS.priority)
+        return true;
+      
+      return priority == RHS.priority && lex_order < RHS.lex_order;
+    }
+  };
+  
 /// CodeGenModule - This class organizes the cross-function state that is used
 /// while generating LLVM code.
 class CodeGenModule : public BlockModule {
@@ -89,8 +109,8 @@
   const llvm::TargetData &TheTargetData;
   mutable const TargetCodeGenInfo *TheTargetCodeGenInfo;
   Diagnostic &Diags;
+  CGCXXABI &ABI;
   CodeGenTypes Types;
-  MangleContext MangleCtx;
 
   /// VTables - Holds information about C++ vtables.
   CodeGenVTables VTables;
@@ -129,6 +149,10 @@
   /// priorities to be emitted when the translation unit is complete.
   CtorList GlobalDtors;
 
+  /// MangledDeclNames - A map of canonical GlobalDecls to their mangled names.
+  llvm::DenseMap<GlobalDecl, llvm::StringRef> MangledDeclNames;
+  llvm::BumpPtrAllocator MangledNamesAllocator;
+  
   std::vector<llvm::Constant*> Annotations;
 
   llvm::StringMap<llvm::Constant*> CFConstantStringMap;
@@ -139,9 +163,21 @@
   /// before main.
   std::vector<llvm::Constant*> CXXGlobalInits;
 
+  /// When a C++ decl with an initializer is deferred, null is
+  /// appended to CXXGlobalInits, and the index of that null is placed
+  /// here so that the initializer will be performed in the correct
+  /// order.
+  llvm::DenseMap<const Decl*, unsigned> DelayedCXXInitPosition;
+  
+  /// - Global variables with initializers whose order of initialization
+  /// is set by init_priority attribute.
+  
+  llvm::SmallVector<std::pair<OrderGlobalInits, llvm::Function*>, 8> 
+    PrioritizedCXXGlobalInits;
+
   /// CXXGlobalDtors - Global destructor functions and arguments that need to
   /// run on termination.
-  std::vector<std::pair<llvm::Constant*,llvm::Constant*> > CXXGlobalDtors;
+  std::vector<std::pair<llvm::WeakVH,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.
@@ -155,6 +191,21 @@
   void createObjCRuntime();
 
   llvm::LLVMContext &VMContext;
+
+  /// @name Cache for Blocks Runtime Globals
+  /// @{
+
+  const VarDecl *NSConcreteGlobalBlockDecl;
+  const VarDecl *NSConcreteStackBlockDecl;
+  llvm::Constant *NSConcreteGlobalBlock;
+  llvm::Constant *NSConcreteStackBlock;
+
+  const FunctionDecl *BlockObjectAssignDecl;
+  const FunctionDecl *BlockObjectDisposeDecl;
+  llvm::Constant *BlockObjectAssign;
+  llvm::Constant *BlockObjectDispose;
+
+  /// @}
 public:
   CodeGenModule(ASTContext &C, const CodeGenOptions &CodeGenOpts,
                 llvm::Module &M, const llvm::TargetData &TD, Diagnostic &Diags);
@@ -175,6 +226,9 @@
   /// been configured.
   bool hasObjCRuntime() { return !!Runtime; }
 
+  /// getCXXABI() - Return a reference to the configured C++ ABI.
+  CGCXXABI &getCXXABI() { return ABI; }
+
   llvm::Value *getStaticLocalDeclAddress(const VarDecl *VD) {
     return StaticLocalDeclMap[VD];
   }
@@ -189,12 +243,14 @@
   const LangOptions &getLangOptions() const { return Features; }
   llvm::Module &getModule() const { return TheModule; }
   CodeGenTypes &getTypes() { return Types; }
-  MangleContext &getMangleContext() { return MangleCtx; }
+  MangleContext &getMangleContext() {
+    return ABI.getMangleContext();
+  }
   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;
+  const TargetCodeGenInfo &getTargetCodeGenInfo();
   bool isTargetDarwin() const;
 
   /// getDeclVisibilityMode - Compute the visibility of the decl \arg D.
@@ -204,6 +260,11 @@
   /// GlobalValue.
   void setGlobalVisibility(llvm::GlobalValue *GV, const Decl *D) const;
 
+  /// setTypeVisibility - Set the visibility for the given global
+  /// value which holds information about a type.
+  void setTypeVisibility(llvm::GlobalValue *GV, const CXXRecordDecl *D,
+                         bool IsForRTTI) const;
+
   llvm::Constant *GetAddrOfGlobal(GlobalDecl GD) {
     if (isa<CXXConstructorDecl>(GD.getDecl()))
       return GetAddrOfCXXConstructor(cast<CXXConstructorDecl>(GD.getDecl()),
@@ -232,7 +293,7 @@
 
   /// GetAddrOfRTTIDescriptor - Get the address of the RTTI descriptor 
   /// for the given type.
-  llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty);
+  llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false);
 
   /// GetAddrOfThunk - Get the address of the thunk for the given global decl.
   llvm::Constant *GetAddrOfThunk(GlobalDecl GD, const ThunkInfo &Thunk);
@@ -244,7 +305,8 @@
   /// a class. Returns null if the offset is 0. 
   llvm::Constant *
   GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl,
-                               const CXXBaseSpecifierArray &BasePath);
+                               CastExpr::path_const_iterator PathBegin,
+                               CastExpr::path_const_iterator PathEnd);
   
   /// GetStringForStringLiteral - Return the appropriate bytes for a string
   /// literal, properly padded to match the literal type. If only the address of
@@ -330,7 +392,9 @@
 
   /// AddCXXDtorEntry - Add a destructor and object to add to the C++ global
   /// destructor function.
-  void AddCXXDtorEntry(llvm::Constant *DtorFn, llvm::Constant *Object);
+  void AddCXXDtorEntry(llvm::Constant *DtorFn, llvm::Constant *Object) {
+    CXXGlobalDtors.push_back(std::make_pair(DtorFn, Object));
+  }
 
   /// CreateRuntimeFunction - Create a new runtime function with the specified
   /// type and name.
@@ -341,6 +405,16 @@
   llvm::Constant *CreateRuntimeVariable(const llvm::Type *Ty,
                                         llvm::StringRef Name);
 
+  ///@name Custom Blocks Runtime Interfaces
+  ///@{
+
+  llvm::Constant *getNSConcreteGlobalBlock();
+  llvm::Constant *getNSConcreteStackBlock();
+  llvm::Constant *getBlockObjectAssign();
+  llvm::Constant *getBlockObjectDispose();
+
+  ///@}
+
   void UpdateCompletedType(const TagDecl *TD) {
     // Make sure that this type is translated.
     Types.UpdateCompletedType(TD);
@@ -360,8 +434,6 @@
   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
@@ -393,9 +465,13 @@
   /// 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
+  /// ReturnTypeUsesSRet - Return true iff the given type uses 'sret' when used
   /// as a return type.
-  bool ReturnTypeUsesSret(const CGFunctionInfo &FI);
+  bool ReturnTypeUsesSRet(const CGFunctionInfo &FI);
+
+  /// ReturnTypeUsesSret - Return true iff the given type uses 'fpret' when used
+  /// as a return type.
+  bool ReturnTypeUsesFPRet(QualType ResultType);
 
   /// ConstructAttributeList - Get the LLVM attributes and calling convention to
   /// use for a particular function type.
@@ -411,29 +487,20 @@
                               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);
+  llvm::StringRef getMangledName(GlobalDecl GD);
+  void getMangledName(GlobalDecl GD, MangleBuffer &Buffer, const BlockDecl *BD);
 
   void EmitTentativeDefinition(const VarDecl *D);
 
-  enum GVALinkage {
-    GVA_Internal,
-    GVA_C99Inline,
-    GVA_CXXInline,
-    GVA_StrongExternal,
-    GVA_TemplateInstantiation,
-    GVA_ExplicitTemplateInstantiation
-  };
+  void EmitVTable(CXXRecordDecl *Class, bool DefinitionRequired);
 
   llvm::GlobalVariable::LinkageTypes
   getFunctionLinkage(const FunctionDecl *FD);
 
+  void setFunctionLinkage(const FunctionDecl *FD, llvm::GlobalValue *V) {
+    V->setLinkage(getFunctionLinkage(FD));
+  }
+
   /// getVTableLinkage - Return the appropriate linkage for the vtable, VTT,
   /// and type information of the given class.
   static llvm::GlobalVariable::LinkageTypes 
@@ -482,6 +549,7 @@
   void EmitGlobalVarDefinition(const VarDecl *D);
   void EmitAliasDefinition(GlobalDecl GD);
   void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);
+  void EmitObjCIvarInitializations(ObjCImplementationDecl *D);
 
   // C++ related functions.
 
@@ -542,6 +610,8 @@
   /// references to global which may otherwise be optimized out.
   void EmitLLVMUsed(void);
 
+  void EmitDeclMetadata();
+
   /// 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.
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index f53dd83..5ab65c5 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -13,6 +13,7 @@
 
 #include "CodeGenTypes.h"
 #include "CGCall.h"
+#include "CGCXXABI.h"
 #include "CGRecordLayout.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
@@ -26,9 +27,10 @@
 using namespace CodeGen;
 
 CodeGenTypes::CodeGenTypes(ASTContext &Ctx, llvm::Module& M,
-                           const llvm::TargetData &TD, const ABIInfo &Info)
+                           const llvm::TargetData &TD, const ABIInfo &Info,
+                           CGCXXABI &CXXABI)
   : Context(Ctx), Target(Ctx.Target), TheModule(M), TheTargetData(TD),
-    TheABIInfo(Info) {
+    TheABIInfo(Info), TheCXXABI(CXXABI) {
 }
 
 CodeGenTypes::~CodeGenTypes() {
@@ -42,11 +44,13 @@
     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,
+/// HandleLateResolvedPointers - For top-level ConvertType calls, this handles
+/// pointers that are referenced but have not been converted yet.  This is used
+/// to handle cyclic structures properly.
+void CodeGenTypes::HandleLateResolvedPointers() {
+  assert(!PointersToResolve.empty() && "No pointers to resolve!");
+  
+  // Any pointers that were converted deferred 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.
@@ -59,7 +63,21 @@
     const llvm::Type *NT = ConvertTypeForMemRecursive(P.first);
     P.second->refineAbstractTypeTo(NT);
   }
+}
 
+
+/// ConvertType - Convert the specified type to its LLVM form.
+const llvm::Type *CodeGenTypes::ConvertType(QualType T, bool IsRecursive) {
+  const llvm::Type *Result = ConvertTypeRecursive(T);
+  
+  // If this is a top-level call to ConvertType and sub-conversions caused
+  // pointers to get lazily built as opaque types, resolve the pointers, which
+  // might cause Result to be merged away.
+  if (!IsRecursive && !PointersToResolve.empty()) {
+    llvm::PATypeHolder ResultHandle = Result;
+    HandleLateResolvedPointers();
+    Result = ResultHandle;
+  }
   return Result;
 }
 
@@ -80,21 +98,12 @@
   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);
+const llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T, bool IsRecursive){
+  const llvm::Type *R = ConvertType(T, IsRecursive);
 
   // If this is a non-bool type, don't map it.
   if (!R->isIntegerTy(1))
@@ -108,7 +117,7 @@
 
 // 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 TagType *CodeGenTypes::VerifyFuncTypeComplete(const Type* T) {
   const FunctionType *FT = cast<FunctionType>(T);
   if (const TagType* TT = FT->getResultType()->getAs<TagType>())
     if (!TT->getDecl()->isDefinition())
@@ -201,7 +210,7 @@
     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);
+      return llvm::Type::getInt8Ty(getLLVMContext());
 
     case BuiltinType::Bool:
       // Note that we always return bool as i1 for use as a scalar type.
@@ -233,7 +242,7 @@
 
     case BuiltinType::NullPtr: {
       // Model std::nullptr_t as i8*
-      const llvm::Type *Ty = llvm::IntegerType::get(getLLVMContext(), 8);
+      const llvm::Type *Ty = llvm::Type::getInt8Ty(getLLVMContext());
       return llvm::PointerType::getUnqual(Ty);
     }
         
@@ -284,7 +293,8 @@
     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);
+    return llvm::ArrayType::get(ConvertTypeForMemRecursive(A.getElementType()),
+                                0);
   }
   case Type::ConstantArray: {
     const ConstantArrayType &A = cast<ConstantArrayType>(Ty);
@@ -299,8 +309,12 @@
   }
   case Type::FunctionNoProto:
   case Type::FunctionProto: {
-    // First, check whether we can build the full function type.
-    if (const TagType* TT = VerifyFuncTypeComplete(&Ty)) {
+    // First, check whether we can build the full function type.  If the
+    // function type depends on an incomplete type (e.g. a struct or enum), we
+    // cannot lower the function type.  Instead, turn it into an Opaque pointer
+    // and have UpdateCompletedType revisit the function type when/if the opaque
+    // argument type is defined.
+    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());
@@ -309,19 +323,30 @@
       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 CGFunctionInfo *FI;
+    bool isVariadic;
+    if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(&Ty)) {
+      FI = &getFunctionInfo(
+                   CanQual<FunctionProtoType>::CreateUnsafe(QualType(FPT, 0)),
+                            true /*Recursive*/);
+      isVariadic = FPT->isVariadic();
+    } else {
+      const FunctionNoProtoType *FNPT = cast<FunctionNoProtoType>(&Ty);
+      FI = &getFunctionInfo(
+                CanQual<FunctionNoProtoType>::CreateUnsafe(QualType(FNPT, 0)),
+                            true /*Recursive*/);
+      isVariadic = true;
+    }
 
-    const FunctionNoProtoType *FNPT = cast<FunctionNoProtoType>(&Ty);
-    return GetFunctionType(getFunctionInfo(
-                CanQual<FunctionNoProtoType>::CreateUnsafe(QualType(FNPT,0))),
-                           true);
+    return GetFunctionType(*FI, isVariadic, true);
   }
 
+  case Type::ObjCObject:
+    return ConvertTypeRecursive(cast<ObjCObjectType>(Ty).getBaseType());
+
   case Type::ObjCInterface: {
     // Objective-C interfaces are always opaque (outside of the
     // runtime, which can do whatever it likes); we never refine
@@ -377,17 +402,7 @@
   }
 
   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;
+    return getCXXABI().ConvertMemberPointerType(cast<MemberPointerType>(&Ty));
   }
   }
 
@@ -467,3 +482,35 @@
   assert(Layout && "Unable to find record layout information for type");
   return *Layout;
 }
+
+bool CodeGenTypes::isZeroInitializable(QualType T) {
+  // No need to check for member pointers when not compiling C++.
+  if (!Context.getLangOptions().CPlusPlus)
+    return true;
+  
+  T = Context.getBaseElementType(T);
+  
+  // Records are non-zero-initializable if they contain any
+  // non-zero-initializable subobjects.
+  if (const RecordType *RT = T->getAs<RecordType>()) {
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+    return isZeroInitializable(RD);
+  }
+
+  // We have to ask the ABI about member pointers.
+  if (const MemberPointerType *MPT = T->getAs<MemberPointerType>())
+    return getCXXABI().isZeroInitializable(MPT);
+  
+  // Everything else is okay.
+  return true;
+}
+
+bool CodeGenTypes::isZeroInitializable(const CXXRecordDecl *RD) {
+  
+  // FIXME: It would be better if there was a way to explicitly compute the
+  // record layout instead of converting to a type.
+  ConvertTagDeclType(RD);
+  
+  const CGRecordLayout &Layout = getCGRecordLayout(RD);
+  return Layout.isZeroInitializable();
+}
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index 10e71e2..dac235f 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -14,13 +14,12 @@
 #ifndef CLANG_CODEGEN_CODEGENTYPES_H
 #define CLANG_CODEGEN_CODEGENTYPES_H
 
+#include "CGCall.h"
+#include "GlobalDecl.h"
 #include "llvm/Module.h"
 #include "llvm/ADT/DenseMap.h"
 #include <vector>
 
-#include "CGCall.h"
-#include "GlobalDecl.h"
-
 namespace llvm {
   class FunctionType;
   class Module;
@@ -51,6 +50,7 @@
   typedef CanQual<Type> CanQualType;
 
 namespace CodeGen {
+  class CGCXXABI;
   class CGRecordLayout;
 
 /// CodeGenTypes - This class organizes the cross-module state that is used
@@ -61,6 +61,7 @@
   llvm::Module& TheModule;
   const llvm::TargetData& TheTargetData;
   const ABIInfo& TheABIInfo;
+  CGCXXABI &TheCXXABI;
 
   llvm::SmallVector<std::pair<QualType,
                               llvm::OpaqueType *>, 8>  PointersToResolve;
@@ -94,34 +95,48 @@
   /// is available only for ConvertType(). CovertType() is preferred
   /// interface to convert type T into a llvm::Type.
   const llvm::Type *ConvertNewType(QualType T);
+  
+  /// HandleLateResolvedPointers - For top-level ConvertType calls, this handles
+  /// pointers that are referenced but have not been converted yet.  This is
+  /// used to handle cyclic structures properly.
+  void HandleLateResolvedPointers();
+
 public:
   CodeGenTypes(ASTContext &Ctx, llvm::Module &M, const llvm::TargetData &TD,
-               const ABIInfo &Info);
+               const ABIInfo &Info, CGCXXABI &CXXABI);
   ~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; }
+  CGCXXABI &getCXXABI() const { return TheCXXABI; }
   llvm::LLVMContext &getLLVMContext() { return TheModule.getContext(); }
 
   /// ConvertType - Convert type T into a llvm::Type.
-  const llvm::Type *ConvertType(QualType T);
+  const llvm::Type *ConvertType(QualType T, bool IsRecursive = false);
   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);
+  const llvm::Type *ConvertTypeForMem(QualType T, bool IsRecursive = false);
+  const llvm::Type *ConvertTypeForMemRecursive(QualType T) {
+    return ConvertTypeForMem(T, true);
+  }
 
   /// GetFunctionType - Get the LLVM function type for \arg Info.
   const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info,
-                                            bool IsVariadic);
+                                            bool IsVariadic,
+                                            bool IsRecursive = false);
 
   const llvm::FunctionType *GetFunctionType(GlobalDecl GD);
 
+  /// VerifyFuncTypeComplete - Utility to check whether a function type can
+  /// be converted to an LLVM type (i.e. doesn't depend on an incomplete tag
+  /// type).
+  static const TagType *VerifyFuncTypeComplete(const Type* T);
 
   /// GetFunctionTypeForVTable - Get the LLVM function type for use in a vtable,
   /// given a CXXMethodDecl. If the method to has an incomplete return type, 
@@ -150,8 +165,11 @@
     return getFunctionInfo(Ty->getResultType(), Args,
                            Ty->getExtInfo());
   }
-  const CGFunctionInfo &getFunctionInfo(CanQual<FunctionProtoType> Ty);
-  const CGFunctionInfo &getFunctionInfo(CanQual<FunctionNoProtoType> Ty);
+
+  const CGFunctionInfo &getFunctionInfo(CanQual<FunctionProtoType> Ty,
+                                        bool IsRecursive = false);
+  const CGFunctionInfo &getFunctionInfo(CanQual<FunctionNoProtoType> Ty,
+                                        bool IsRecursive = false);
 
   // getFunctionInfo - Get the function info for a member function.
   const CGFunctionInfo &getFunctionInfo(const CXXRecordDecl *RD,
@@ -172,7 +190,8 @@
   /// \param ArgTys - must all actually be canonical as params
   const CGFunctionInfo &getFunctionInfo(CanQualType RetTy,
                                const llvm::SmallVectorImpl<CanQualType> &ArgTys,
-                                        const FunctionType::ExtInfo &Info);
+                                        const FunctionType::ExtInfo &Info,
+                                        bool IsRecursive = false);
 
   /// \brief Compute a new LLVM record layout object for the given record.
   CGRecordLayout *ComputeRecordLayout(const RecordDecl *D);
@@ -185,7 +204,16 @@
   /// 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);
+  void GetExpandedTypes(QualType Ty, std::vector<const llvm::Type*> &ArgTys,
+                        bool IsRecursive);
+  
+  /// IsZeroInitializable - Return whether a type can be
+  /// zero-initialized (in the C++ sense) with an LLVM zeroinitializer.
+  bool isZeroInitializable(QualType T);
+  
+  /// IsZeroInitializable - Return whether a record type can be
+  /// zero-initialized (in the C++ sense) with an LLVM zeroinitializer.
+  bool isZeroInitializable(const CXXRecordDecl *RD);
 };
 
 }  // end namespace CodeGen
diff --git a/lib/CodeGen/GlobalDecl.h b/lib/CodeGen/GlobalDecl.h
index b8a98d7..26dea40 100644
--- a/lib/CodeGen/GlobalDecl.h
+++ b/lib/CodeGen/GlobalDecl.h
@@ -36,7 +36,7 @@
 
     Value.setPointer(D);
   }
-  
+
 public:
   GlobalDecl() {}
 
@@ -50,6 +50,14 @@
   GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
   : Value(D, Type) {}
 
+  GlobalDecl getCanonicalDecl() const {
+    GlobalDecl CanonGD;
+    CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
+    CanonGD.Value.setInt(Value.getInt());
+    
+    return CanonGD;
+  }
+
   const Decl *getDecl() const { return Value.getPointer(); }
 
   CXXCtorType getCtorType() const {
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
new file mode 100644
index 0000000..354e72f
--- /dev/null
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -0,0 +1,588 @@
+//===------- ItaniumCXXABI.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 C++ code generation targetting the Itanium C++ ABI.  The class
+// in this file generates structures that follow the Itanium C++ ABI, which is
+// documented at:
+//  http://www.codesourcery.com/public/cxx-abi/abi.html
+//  http://www.codesourcery.com/public/cxx-abi/abi-eh.html
+//
+// It also supports the closely-related ARM ABI, documented at:
+// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGCXXABI.h"
+#include "CGRecordLayout.h"
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "Mangle.h"
+#include <clang/AST/Type.h>
+#include <llvm/Target/TargetData.h>
+#include <llvm/Value.h>
+
+using namespace clang;
+using namespace CodeGen;
+
+namespace {
+class ItaniumCXXABI : public CodeGen::CGCXXABI {
+private:
+  const llvm::IntegerType *PtrDiffTy;
+protected:
+  CodeGen::MangleContext MangleCtx;
+  bool IsARM;
+
+  // It's a little silly for us to cache this.
+  const llvm::IntegerType *getPtrDiffTy() {
+    if (!PtrDiffTy) {
+      QualType T = CGM.getContext().getPointerDiffType();
+      const llvm::Type *Ty = CGM.getTypes().ConvertTypeRecursive(T);
+      PtrDiffTy = cast<llvm::IntegerType>(Ty);
+    }
+    return PtrDiffTy;
+  }
+
+public:
+  ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) :
+    CGCXXABI(CGM), PtrDiffTy(0), MangleCtx(CGM.getContext(), CGM.getDiags()),
+    IsARM(IsARM) { }
+
+  CodeGen::MangleContext &getMangleContext() {
+    return MangleCtx;
+  }
+
+  bool isZeroInitializable(const MemberPointerType *MPT);
+
+  const llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
+
+  llvm::Value *EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
+                                               llvm::Value *&This,
+                                               llvm::Value *MemFnPtr,
+                                               const MemberPointerType *MPT);
+
+  llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
+                                           const CastExpr *E,
+                                           llvm::Value *Src);
+
+  llvm::Constant *EmitMemberPointerConversion(llvm::Constant *C,
+                                              const CastExpr *E);
+
+  llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
+
+  llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD);
+  llvm::Constant *EmitMemberPointer(const FieldDecl *FD);
+
+  llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
+                                           llvm::Value *L,
+                                           llvm::Value *R,
+                                           const MemberPointerType *MPT,
+                                           bool Inequality);
+
+  llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
+                                          llvm::Value *Addr,
+                                          const MemberPointerType *MPT);
+};
+
+class ARMCXXABI : public ItaniumCXXABI {
+public:
+  ARMCXXABI(CodeGen::CodeGenModule &CGM) : ItaniumCXXABI(CGM, /*ARM*/ true) {}
+};
+}
+
+CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) {
+  return new ItaniumCXXABI(CGM);
+}
+
+CodeGen::CGCXXABI *CodeGen::CreateARMCXXABI(CodeGenModule &CGM) {
+  return new ARMCXXABI(CGM);
+}
+
+const llvm::Type *
+ItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
+  if (MPT->isMemberDataPointer())
+    return getPtrDiffTy();
+  else
+    return llvm::StructType::get(CGM.getLLVMContext(),
+                                 getPtrDiffTy(), getPtrDiffTy(), NULL);
+}
+
+/// In the Itanium and ARM ABIs, method pointers have the form:
+///   struct { ptrdiff_t ptr; ptrdiff_t adj; } memptr;
+///
+/// In the Itanium ABI:
+///  - method pointers are virtual if (memptr.ptr & 1) is nonzero
+///  - the this-adjustment is (memptr.adj)
+///  - the virtual offset is (memptr.ptr - 1)
+///
+/// In the ARM ABI:
+///  - method pointers are virtual if (memptr.adj & 1) is nonzero
+///  - the this-adjustment is (memptr.adj >> 1)
+///  - the virtual offset is (memptr.ptr)
+/// ARM uses 'adj' for the virtual flag because Thumb functions
+/// may be only single-byte aligned.
+///
+/// If the member is virtual, the adjusted 'this' pointer points
+/// to a vtable pointer from which the virtual offset is applied.
+///
+/// If the member is non-virtual, memptr.ptr is the address of
+/// the function to call.
+llvm::Value *
+ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
+                                               llvm::Value *&This,
+                                               llvm::Value *MemFnPtr,
+                                               const MemberPointerType *MPT) {
+  CGBuilderTy &Builder = CGF.Builder;
+
+  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::IntegerType *ptrdiff = getPtrDiffTy();
+  llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(ptrdiff, 1);
+
+  llvm::BasicBlock *FnVirtual = CGF.createBasicBlock("memptr.virtual");
+  llvm::BasicBlock *FnNonVirtual = CGF.createBasicBlock("memptr.nonvirtual");
+  llvm::BasicBlock *FnEnd = CGF.createBasicBlock("memptr.end");
+
+  // Extract memptr.adj, which is in the second field.
+  llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1, "memptr.adj");
+
+  // Compute the true adjustment.
+  llvm::Value *Adj = RawAdj;
+  if (IsARM)
+    Adj = Builder.CreateAShr(Adj, ptrdiff_1, "memptr.adj.shifted");
+
+  // Apply the adjustment and cast back to the original struct type
+  // for consistency.
+  llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy());
+  Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
+  This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted");
+  
+  // Load the function pointer.
+  llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0, "memptr.ptr");
+  
+  // If the LSB in the function pointer is 1, the function pointer points to
+  // a virtual function.
+  llvm::Value *IsVirtual;
+  if (IsARM)
+    IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
+  else
+    IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
+  IsVirtual = Builder.CreateIsNotNull(IsVirtual, "memptr.isvirtual");
+  Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
+
+  // In the virtual path, the adjustment left 'This' pointing to the
+  // vtable of the correct base subobject.  The "function pointer" is an
+  // offset within the vtable (+1 for the virtual flag on non-ARM).
+  CGF.EmitBlock(FnVirtual);
+
+  // Cast the adjusted this to a pointer to vtable pointer and load.
+  const llvm::Type *VTableTy = Builder.getInt8PtrTy();
+  llvm::Value *VTable = Builder.CreateBitCast(This, VTableTy->getPointerTo());
+  VTable = Builder.CreateLoad(VTable, "memptr.vtable");
+
+  // Apply the offset.
+  llvm::Value *VTableOffset = FnAsInt;
+  if (!IsARM) VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
+  VTable = Builder.CreateGEP(VTable, VTableOffset);
+
+  // Load the virtual function to call.
+  VTable = Builder.CreateBitCast(VTable, FTy->getPointerTo()->getPointerTo());
+  llvm::Value *VirtualFn = Builder.CreateLoad(VTable, "memptr.virtualfn");
+  CGF.EmitBranch(FnEnd);
+
+  // In the non-virtual path, the function pointer is actually a
+  // function pointer.
+  CGF.EmitBlock(FnNonVirtual);
+  llvm::Value *NonVirtualFn =
+    Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(), "memptr.nonvirtualfn");
+  
+  // We're done.
+  CGF.EmitBlock(FnEnd);
+  llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo());
+  Callee->reserveOperandSpace(2);
+  Callee->addIncoming(VirtualFn, FnVirtual);
+  Callee->addIncoming(NonVirtualFn, FnNonVirtual);
+  return Callee;
+}
+
+/// Perform a derived-to-base or base-to-derived member pointer conversion.
+///
+/// Obligatory offset/adjustment diagram:
+///         <-- offset -->          <-- adjustment -->
+///   |--------------------------|----------------------|--------------------|
+///   ^Derived address point     ^Base address point    ^Member address point
+///
+/// So when converting a base member pointer to a derived member pointer,
+/// we add the offset to the adjustment because the address point has
+/// decreased;  and conversely, when converting a derived MP to a base MP
+/// we subtract the offset from the adjustment because the address point
+/// has increased.
+///
+/// The standard forbids (at compile time) conversion to and from
+/// virtual bases, which is why we don't have to consider them here.
+///
+/// The standard forbids (at run time) casting a derived MP to a base
+/// MP when the derived MP does not point to a member of the base.
+/// This is why -1 is a reasonable choice for null data member
+/// pointers.
+llvm::Value *
+ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
+                                           const CastExpr *E,
+                                           llvm::Value *Src) {
+  assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
+         E->getCastKind() == CK_BaseToDerivedMemberPointer);
+
+  if (isa<llvm::Constant>(Src))
+    return EmitMemberPointerConversion(cast<llvm::Constant>(Src), E);
+
+  CGBuilderTy &Builder = CGF.Builder;
+
+  const MemberPointerType *SrcTy =
+    E->getSubExpr()->getType()->getAs<MemberPointerType>();
+  const MemberPointerType *DestTy = E->getType()->getAs<MemberPointerType>();
+
+  const CXXRecordDecl *SrcDecl = SrcTy->getClass()->getAsCXXRecordDecl();
+  const CXXRecordDecl *DestDecl = DestTy->getClass()->getAsCXXRecordDecl();
+
+  bool DerivedToBase =
+    E->getCastKind() == CK_DerivedToBaseMemberPointer;
+
+  const CXXRecordDecl *BaseDecl, *DerivedDecl;
+  if (DerivedToBase)
+    DerivedDecl = SrcDecl, BaseDecl = DestDecl;
+  else
+    BaseDecl = SrcDecl, DerivedDecl = DestDecl;
+
+  llvm::Constant *Adj = 
+    CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
+                                         E->path_begin(),
+                                         E->path_end());
+  if (!Adj) return Src;
+
+  // For member data pointers, this is just a matter of adding the
+  // offset if the source is non-null.
+  if (SrcTy->isMemberDataPointer()) {
+    llvm::Value *Dst;
+    if (DerivedToBase)
+      Dst = Builder.CreateNSWSub(Src, Adj, "adj");
+    else
+      Dst = Builder.CreateNSWAdd(Src, Adj, "adj");
+
+    // Null check.
+    llvm::Value *Null = llvm::Constant::getAllOnesValue(Src->getType());
+    llvm::Value *IsNull = Builder.CreateICmpEQ(Src, Null, "memptr.isnull");
+    return Builder.CreateSelect(IsNull, Src, Dst);
+  }
+
+  // The this-adjustment is left-shifted by 1 on ARM.
+  if (IsARM) {
+    uint64_t Offset = cast<llvm::ConstantInt>(Adj)->getZExtValue();
+    Offset <<= 1;
+    Adj = llvm::ConstantInt::get(Adj->getType(), Offset);
+  }
+
+  llvm::Value *SrcAdj = Builder.CreateExtractValue(Src, 1, "src.adj");
+  llvm::Value *DstAdj;
+  if (DerivedToBase)
+    DstAdj = Builder.CreateNSWSub(SrcAdj, Adj, "adj");
+  else
+    DstAdj = Builder.CreateNSWAdd(SrcAdj, Adj, "adj");
+
+  return Builder.CreateInsertValue(Src, DstAdj, 1);
+}
+
+llvm::Constant *
+ItaniumCXXABI::EmitMemberPointerConversion(llvm::Constant *C,
+                                           const CastExpr *E) {
+  const MemberPointerType *SrcTy = 
+    E->getSubExpr()->getType()->getAs<MemberPointerType>();
+  const MemberPointerType *DestTy = 
+    E->getType()->getAs<MemberPointerType>();
+
+  bool DerivedToBase =
+    E->getCastKind() == CK_DerivedToBaseMemberPointer;
+
+  const CXXRecordDecl *DerivedDecl;
+  if (DerivedToBase)
+    DerivedDecl = SrcTy->getClass()->getAsCXXRecordDecl();
+  else
+    DerivedDecl = DestTy->getClass()->getAsCXXRecordDecl();
+
+  // Calculate the offset to the base class.
+  llvm::Constant *Offset = 
+    CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
+                                     E->path_begin(),
+                                     E->path_end());
+  // If there's no offset, we're done.
+  if (!Offset) return C;
+
+  // If the source is a member data pointer, we have to do a null
+  // check and then add the offset.  In the common case, we can fold
+  // away the offset.
+  if (SrcTy->isMemberDataPointer()) {
+    assert(C->getType() == getPtrDiffTy());
+
+    // If it's a constant int, just create a new constant int.
+    if (llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(C)) {
+      int64_t Src = CI->getSExtValue();
+
+      // Null converts to null.
+      if (Src == -1) return CI;
+
+      // Otherwise, just add the offset.
+      int64_t OffsetV = cast<llvm::ConstantInt>(Offset)->getSExtValue();
+      int64_t Dst = (DerivedToBase ? Src - OffsetV : Src + OffsetV);
+      return llvm::ConstantInt::get(CI->getType(), Dst, /*signed*/ true);
+    }
+
+    // Otherwise, we have to form a constant select expression.
+    llvm::Constant *Null = llvm::Constant::getAllOnesValue(C->getType());
+
+    llvm::Constant *IsNull =
+      llvm::ConstantExpr::getICmp(llvm::ICmpInst::ICMP_EQ, C, Null);
+
+    llvm::Constant *Dst;
+    if (DerivedToBase)
+      Dst = llvm::ConstantExpr::getNSWSub(C, Offset);
+    else
+      Dst = llvm::ConstantExpr::getNSWAdd(C, Offset);
+
+    return llvm::ConstantExpr::getSelect(IsNull, Null, Dst);
+  }
+
+  // The this-adjustment is left-shifted by 1 on ARM.
+  if (IsARM) {
+    int64_t OffsetV = cast<llvm::ConstantInt>(Offset)->getSExtValue();
+    OffsetV <<= 1;
+    Offset = llvm::ConstantInt::get(Offset->getType(), OffsetV);
+  }
+
+  llvm::ConstantStruct *CS = cast<llvm::ConstantStruct>(C);
+
+  llvm::Constant *Values[2] = { CS->getOperand(0), 0 };
+  if (DerivedToBase)
+    Values[1] = llvm::ConstantExpr::getSub(CS->getOperand(1), Offset);
+  else
+    Values[1] = llvm::ConstantExpr::getAdd(CS->getOperand(1), Offset);
+
+  return llvm::ConstantStruct::get(CGM.getLLVMContext(), Values, 2,
+                                   /*Packed=*/false);
+}        
+
+
+llvm::Constant *
+ItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
+  const llvm::Type *ptrdiff_t = getPtrDiffTy();
+
+  // Itanium C++ ABI 2.3:
+  //   A NULL pointer is represented as -1.
+  if (MPT->isMemberDataPointer()) 
+    return llvm::ConstantInt::get(ptrdiff_t, -1ULL, /*isSigned=*/true);
+
+  llvm::Constant *Zero = llvm::ConstantInt::get(ptrdiff_t, 0);
+  llvm::Constant *Values[2] = { Zero, Zero };
+  return llvm::ConstantStruct::get(CGM.getLLVMContext(), Values, 2,
+                                   /*Packed=*/false);
+}
+
+llvm::Constant *ItaniumCXXABI::EmitMemberPointer(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
+
+  QualType ClassType = CGM.getContext().getTypeDeclType(FD->getParent());
+  const llvm::StructType *ClassLTy =
+    cast<llvm::StructType>(CGM.getTypes().ConvertType(ClassType));
+
+  const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(FD->getParent());
+  unsigned FieldNo = RL.getLLVMFieldNo(FD);
+  uint64_t Offset = 
+    CGM.getTargetData().getStructLayout(ClassLTy)->getElementOffset(FieldNo);
+
+  return llvm::ConstantInt::get(getPtrDiffTy(), Offset);
+}
+
+llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
+  assert(MD->isInstance() && "Member function must not be static!");
+  MD = MD->getCanonicalDecl();
+
+  CodeGenTypes &Types = CGM.getTypes();
+  const llvm::Type *ptrdiff_t = getPtrDiffTy();
+
+  // Get the function pointer (or index if this is a virtual function).
+  llvm::Constant *MemPtr[2];
+  if (MD->isVirtual()) {
+    uint64_t Index = CGM.getVTables().getMethodVTableIndex(MD);
+
+    // FIXME: We shouldn't use / 8 here.
+    uint64_t PointerWidthInBytes =
+      CGM.getContext().Target.getPointerWidth(0) / 8;
+    uint64_t VTableOffset = (Index * PointerWidthInBytes);
+
+    if (IsARM) {
+      // ARM C++ ABI 3.2.1:
+      //   This ABI specifies that adj contains twice the this
+      //   adjustment, plus 1 if the member function is virtual. The
+      //   least significant bit of adj then makes exactly the same
+      //   discrimination as the least significant bit of ptr does for
+      //   Itanium.
+      MemPtr[0] = llvm::ConstantInt::get(ptrdiff_t, VTableOffset);
+      MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 1);
+    } else {
+      // Itanium C++ ABI 2.3:
+      //   For a virtual function, [the pointer field] is 1 plus the
+      //   virtual table offset (in bytes) of the function,
+      //   represented as a ptrdiff_t.
+      MemPtr[0] = llvm::ConstantInt::get(ptrdiff_t, VTableOffset + 1);
+      MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 0);
+    }
+  } else {
+    const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+    const llvm::Type *Ty;
+    // Check whether the function has a computable LLVM signature.
+    if (!CodeGenTypes::VerifyFuncTypeComplete(FPT)) {
+      // The function has a computable LLVM signature; use the correct type.
+      Ty = Types.GetFunctionType(Types.getFunctionInfo(MD), FPT->isVariadic());
+    } else {
+      // Use an arbitrary non-function type to tell GetAddrOfFunction that the
+      // function type is incomplete.
+      Ty = ptrdiff_t;
+    }
+
+    llvm::Constant *Addr = CGM.GetAddrOfFunction(MD, Ty);
+    MemPtr[0] = llvm::ConstantExpr::getPtrToInt(Addr, ptrdiff_t);
+    MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 0);
+  }
+  
+  return llvm::ConstantStruct::get(CGM.getLLVMContext(),
+                                   MemPtr, 2, /*Packed=*/false);
+}
+
+/// The comparison algorithm is pretty easy: the member pointers are
+/// the same if they're either bitwise identical *or* both null.
+///
+/// ARM is different here only because null-ness is more complicated.
+llvm::Value *
+ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
+                                           llvm::Value *L,
+                                           llvm::Value *R,
+                                           const MemberPointerType *MPT,
+                                           bool Inequality) {
+  CGBuilderTy &Builder = CGF.Builder;
+
+  llvm::ICmpInst::Predicate Eq;
+  llvm::Instruction::BinaryOps And, Or;
+  if (Inequality) {
+    Eq = llvm::ICmpInst::ICMP_NE;
+    And = llvm::Instruction::Or;
+    Or = llvm::Instruction::And;
+  } else {
+    Eq = llvm::ICmpInst::ICMP_EQ;
+    And = llvm::Instruction::And;
+    Or = llvm::Instruction::Or;
+  }
+
+  // Member data pointers are easy because there's a unique null
+  // value, so it just comes down to bitwise equality.
+  if (MPT->isMemberDataPointer())
+    return Builder.CreateICmp(Eq, L, R);
+
+  // For member function pointers, the tautologies are more complex.
+  // The Itanium tautology is:
+  //   (L == R) <==> (L.ptr == R.ptr && (L.ptr == 0 || L.adj == R.adj))
+  // The ARM tautology is:
+  //   (L == R) <==> (L.ptr == R.ptr &&
+  //                  (L.adj == R.adj ||
+  //                   (L.ptr == 0 && ((L.adj|R.adj) & 1) == 0)))
+  // The inequality tautologies have exactly the same structure, except
+  // applying De Morgan's laws.
+  
+  llvm::Value *LPtr = Builder.CreateExtractValue(L, 0, "lhs.memptr.ptr");
+  llvm::Value *RPtr = Builder.CreateExtractValue(R, 0, "rhs.memptr.ptr");
+
+  // This condition tests whether L.ptr == R.ptr.  This must always be
+  // true for equality to hold.
+  llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr, "cmp.ptr");
+
+  // This condition, together with the assumption that L.ptr == R.ptr,
+  // tests whether the pointers are both null.  ARM imposes an extra
+  // condition.
+  llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
+  llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero, "cmp.ptr.null");
+
+  // This condition tests whether L.adj == R.adj.  If this isn't
+  // true, the pointers are unequal unless they're both null.
+  llvm::Value *LAdj = Builder.CreateExtractValue(L, 1, "lhs.memptr.adj");
+  llvm::Value *RAdj = Builder.CreateExtractValue(R, 1, "rhs.memptr.adj");
+  llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj, "cmp.adj");
+
+  // Null member function pointers on ARM clear the low bit of Adj,
+  // so the zero condition has to check that neither low bit is set.
+  if (IsARM) {
+    llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
+
+    // Compute (l.adj | r.adj) & 1 and test it against zero.
+    llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj");
+    llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
+    llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
+                                                      "cmp.or.adj");
+    EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
+  }
+
+  // Tie together all our conditions.
+  llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
+  Result = Builder.CreateBinOp(And, PtrEq, Result,
+                               Inequality ? "memptr.ne" : "memptr.eq");
+  return Result;
+}
+
+llvm::Value *
+ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
+                                          llvm::Value *MemPtr,
+                                          const MemberPointerType *MPT) {
+  CGBuilderTy &Builder = CGF.Builder;
+
+  /// For member data pointers, this is just a check against -1.
+  if (MPT->isMemberDataPointer()) {
+    assert(MemPtr->getType() == getPtrDiffTy());
+    llvm::Value *NegativeOne =
+      llvm::Constant::getAllOnesValue(MemPtr->getType());
+    return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool");
+  }
+  
+  // In Itanium, a member function pointer is null if 'ptr' is null.
+  llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0, "memptr.ptr");
+
+  llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
+  llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero, "memptr.tobool");
+
+  // In ARM, it's that, plus the low bit of 'adj' must be zero.
+  if (IsARM) {
+    llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
+    llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj");
+    llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit");
+    llvm::Value *IsNotVirtual = Builder.CreateICmpEQ(VirtualBit, Zero,
+                                                     "memptr.notvirtual");
+    Result = Builder.CreateAnd(Result, IsNotVirtual);
+  }
+
+  return Result;
+}
+
+/// The Itanium ABI requires non-zero initialization only for data
+/// member pointers, for which '0' is a valid offset.
+bool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
+  return MPT->getPointeeType()->isFunctionType();
+}
diff --git a/lib/CodeGen/Makefile b/lib/CodeGen/Makefile
index 3cea6bb..6032dff 100644
--- a/lib/CodeGen/Makefile
+++ b/lib/CodeGen/Makefile
@@ -12,14 +12,8 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
+CLANG_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
+include $(CLANG_LEVEL)/Makefile
 
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
index cb32570..c06b4fc 100644
--- a/lib/CodeGen/Mangle.cpp
+++ b/lib/CodeGen/Mangle.cpp
@@ -36,6 +36,67 @@
 using namespace clang;
 using namespace CodeGen;
 
+MiscNameMangler::MiscNameMangler(MangleContext &C,
+                                 llvm::SmallVectorImpl<char> &Res)
+  : Context(C), Out(Res) { }
+
+void MiscNameMangler::mangleBlock(GlobalDecl GD, const BlockDecl *BD) {
+  // Mangle the context of the block.
+  // FIXME: We currently mimic GCC's mangling scheme, which leaves much to be
+  // desired. Come up with a better mangling scheme.
+  const DeclContext *DC = BD->getDeclContext();
+  while (isa<BlockDecl>(DC) || isa<EnumDecl>(DC))
+    DC = DC->getParent();
+  if (DC->isFunctionOrMethod()) {
+    Out << "__";
+    if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC))
+      mangleObjCMethodName(Method);
+    else {
+      const NamedDecl *ND = cast<NamedDecl>(DC);
+      if (IdentifierInfo *II = ND->getIdentifier())
+        Out << II->getName();
+      else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND)) {
+        llvm::SmallString<64> Buffer;
+        Context.mangleCXXDtor(D, GD.getDtorType(), Buffer);
+        Out << Buffer;
+      }
+      else if (const CXXConstructorDecl *D = dyn_cast<CXXConstructorDecl>(ND)) {
+        llvm::SmallString<64> Buffer;
+        Context.mangleCXXCtor(D, GD.getCtorType(), Buffer);
+        Out << Buffer;
+      }
+      else {
+        // FIXME: We were doing a mangleUnqualifiedName() before, but that's
+        // a private member of a class that will soon itself be private to the
+        // Itanium C++ ABI object. What should we do now? Right now, I'm just
+        // calling the mangleName() method on the MangleContext; is there a
+        // better way?
+        llvm::SmallString<64> Buffer;
+        Context.mangleName(ND, Buffer);
+        Out << Buffer;
+      }
+    }
+    Out << "_block_invoke_" << Context.getBlockId(BD, true);
+  } else {
+    Out << "__block_global_" << Context.getBlockId(BD, false);
+  }
+}
+
+void MiscNameMangler::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();
+}
+
 namespace {
 
 static const DeclContext *GetLocalClassFunctionDeclContext(
@@ -74,19 +135,24 @@
   const CXXMethodDecl *Structor;
   unsigned StructorType;
 
+  /// SeqID - The next subsitution sequence number.
+  unsigned SeqID;
+
   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) { }
+    : Context(C), Out(Res), Structor(0), StructorType(0), SeqID(0) { }
   CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res,
                  const CXXConstructorDecl *D, CXXCtorType Type)
-    : Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type) { }
+    : Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type),
+    SeqID(0) { }
   CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res,
                  const CXXDestructorDecl *D, CXXDtorType Type)
-    : Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type) { }
+    : Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type),
+    SeqID(0) { }
 
 #if MANGLE_CHECKER
   ~CXXNameMangler() {
@@ -103,14 +169,18 @@
 
   void mangle(const NamedDecl *D, llvm::StringRef Prefix = "_Z");
   void mangleCallOffset(int64_t NonVirtual, int64_t Virtual);
+  void mangleNumber(const llvm::APSInt &I);
   void mangleNumber(int64_t Number);
+  void mangleFloat(const llvm::APFloat &F);
   void mangleFunctionEncoding(const FunctionDecl *FD);
   void mangleName(const NamedDecl *ND);
   void mangleType(QualType T);
-
+  void mangleNameOrStandardSubstitution(const NamedDecl *ND);
+  
 private:
   bool mangleSubstitution(const NamedDecl *ND);
   bool mangleSubstitution(QualType T);
+  bool mangleSubstitution(TemplateName Template);
   bool mangleSubstitution(uintptr_t Ptr);
 
   bool mangleStandardSubstitution(const NamedDecl *ND);
@@ -121,6 +191,7 @@
     addSubstitution(reinterpret_cast<uintptr_t>(ND));
   }
   void addSubstitution(QualType T);
+  void addSubstitution(TemplateName Template);
   void addSubstitution(uintptr_t Ptr);
 
   void mangleUnresolvedScope(NestedNameSpecifier *Qualifier);
@@ -138,6 +209,7 @@
                              unsigned KnownArity);
   void mangleUnscopedName(const NamedDecl *ND);
   void mangleUnscopedTemplateName(const TemplateDecl *ND);
+  void mangleUnscopedTemplateName(TemplateName);
   void mangleSourceName(const IdentifierInfo *II);
   void mangleLocalName(const NamedDecl *ND);
   void mangleNestedName(const NamedDecl *ND, const DeclContext *DC,
@@ -160,6 +232,7 @@
 #include "clang/AST/TypeNodes.def"
 
   void mangleType(const TagType*);
+  void mangleType(TemplateName);
   void mangleBareFunctionType(const FunctionType *T,
                               bool MangleReturnType);
 
@@ -168,11 +241,11 @@
                         NestedNameSpecifier *Qualifier,
                         DeclarationName Name,
                         unsigned KnownArity);
-  void mangleCalledExpression(const Expr *E, unsigned KnownArity);
-  void mangleExpression(const Expr *E);
+  void mangleExpression(const Expr *E, unsigned Arity = UnknownArity);
   void mangleCXXCtorType(CXXCtorType T);
   void mangleCXXDtorType(CXXDtorType T);
 
+  void mangleTemplateArgs(const ExplicitTemplateArgumentList &TemplateArgs);
   void mangleTemplateArgs(TemplateName Template,
                           const TemplateArgument *TemplateArgs,
                           unsigned NumTemplateArgs);  
@@ -224,13 +297,17 @@
   if (!FD) {
     const DeclContext *DC = D->getDeclContext();
     // Check for extern variable declared locally.
-    if (isa<FunctionDecl>(DC) && D->hasLinkage())
+    if (DC->isFunctionOrMethod() && D->hasLinkage())
       while (!DC->isNamespace() && !DC->isTranslationUnit())
         DC = DC->getParent();
     if (DC->isTranslationUnit() && D->getLinkage() != InternalLinkage)
       return false;
   }
 
+  // Class members are always mangled.
+  if (D->getDeclContext()->isRecord())
+    return true;
+
   // C functions and "main" are not mangled.
   if ((FD && FD->isMain()) || isInCLinkageSpecification(D))
     return false;
@@ -302,12 +379,6 @@
   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();
@@ -316,15 +387,21 @@
   return DC;
 }
 
+/// isStd - Return whether a given namespace is the 'std' namespace.
+static bool isStd(const NamespaceDecl *NS) {
+  if (!IgnoreLinkageSpecDecls(NS->getParent())->isTranslationUnit())
+    return false;
+  
+  const IdentifierInfo *II = NS->getOriginalNamespace()->getIdentifier();
+  return II && II->isStr("std");
+}
+
 // 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));
 }
 
@@ -431,6 +508,46 @@
   addSubstitution(ND);
 }
 
+void CXXNameMangler::mangleUnscopedTemplateName(TemplateName Template) {
+  //     <unscoped-template-name> ::= <unscoped-name>
+  //                              ::= <substitution>
+  if (TemplateDecl *TD = Template.getAsTemplateDecl())
+    return mangleUnscopedTemplateName(TD);
+  
+  if (mangleSubstitution(Template))
+    return;
+
+  // FIXME: How to cope with operators here?
+  DependentTemplateName *Dependent = Template.getAsDependentTemplateName();
+  assert(Dependent && "Not a dependent template name?");
+  if (!Dependent->isIdentifier()) {
+    // 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);
+    return;
+  }
+  
+  mangleSourceName(Dependent->getIdentifier());
+  addSubstitution(Template);
+}
+
+void CXXNameMangler::mangleFloat(const llvm::APFloat &F) {
+  // TODO: avoid this copy with careful stream management.
+  llvm::SmallString<20> Buffer;
+  F.bitcastToAPInt().toString(Buffer, 16, false);
+  Out.write(Buffer.data(), Buffer.size());
+}
+
+void CXXNameMangler::mangleNumber(const llvm::APSInt &Value) {
+  if (Value.isSigned() && Value.isNegative()) {
+    Out << 'n';
+    Value.abs().print(Out, true);
+  } else
+    Value.print(Out, Value.isSigned());
+}
+
 void CXXNameMangler::mangleNumber(int64_t Number) {
   //  <number> ::= [n] <non-negative decimal integer>
   if (Number < 0) {
@@ -513,6 +630,28 @@
   mangleUnqualifiedName(0, Name, KnownArity);
 }
 
+static const FieldDecl *FindFirstNamedDataMember(const RecordDecl *RD) {
+  assert(RD->isAnonymousStructOrUnion() &&
+         "Expected anonymous struct or union!");
+  
+  for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+       I != E; ++I) {
+    const FieldDecl *FD = *I;
+    
+    if (FD->getIdentifier())
+      return FD;
+    
+    if (const RecordType *RT = FD->getType()->getAs<RecordType>()) {
+      if (const FieldDecl *NamedDataMember = 
+          FindFirstNamedDataMember(RT->getDecl()))
+        return NamedDataMember;
+    }
+  }
+
+  // We didn't find a named data member.
+  return 0;
+}
+
 void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
                                            DeclarationName Name,
                                            unsigned KnownArity) {
@@ -545,6 +684,32 @@
       }
     }
 
+    if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+      // We must have an anonymous union or struct declaration.
+      const RecordDecl *RD = 
+        cast<RecordDecl>(VD->getType()->getAs<RecordType>()->getDecl());
+      
+      // Itanium C++ ABI 5.1.2:
+      //
+      //   For the purposes of mangling, the name of an anonymous union is
+      //   considered to be the name of the first named data member found by a
+      //   pre-order, depth-first, declaration-order walk of the data members of
+      //   the anonymous union. If there is no such data member (i.e., if all of
+      //   the data members in the union are unnamed), then there is no way for
+      //   a program to refer to the anonymous union, and there is therefore no
+      //   need to mangle its name.
+      const FieldDecl *FD = FindFirstNamedDataMember(RD);
+
+      // It's actually possible for various reasons for us to get here
+      // with an empty anonymous struct / union.  Fortunately, it
+      // doesn't really matter what name we generate.
+      if (!FD) break;
+      assert(FD->getIdentifier() && "Data member name isn't an identifier!");
+      
+      mangleSourceName(FD->getIdentifier());
+      break;
+    }
+    
     // We must have an anonymous struct.
     const TagDecl *TD = cast<TagDecl>(ND);
     if (const TypedefDecl *D = TD->getTypedefForAnonDecl()) {
@@ -686,8 +851,9 @@
   const DeclContext *DC = ND->getDeclContext();
   Out << 'Z';
 
-  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC))
-    mangleObjCMethodName(MD);
+  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC)) {
+   mangleObjCMethodName(MD);
+  }
   else if (const DeclContext *CDC = GetLocalClassFunctionDeclContext(DC)) {
     mangleFunctionEncoding(cast<FunctionDecl>(CDC));
     Out << 'E';
@@ -724,6 +890,14 @@
   if (DC->isTranslationUnit())
     return;
 
+  if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {
+    manglePrefix(DC->getParent(), NoFunction);    
+    llvm::SmallString<64> Name;
+    Context.mangleBlock(GlobalDecl(), Block, Name);
+    Out << Name.size() << Name;
+    return;
+  }
+  
   if (mangleSubstitution(cast<NamedDecl>(DC)))
     return;
 
@@ -734,8 +908,10 @@
     TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
     mangleTemplateArgs(*TemplateParameters, *TemplateArgs);
   }
-  else if(NoFunction && isa<FunctionDecl>(DC))
+  else if(NoFunction && (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)))
     return;
+  else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC))
+    mangleObjCMethodName(Method);
   else {
     manglePrefix(DC->getParent(), NoFunction);
     mangleUnqualifiedName(cast<NamedDecl>(DC));
@@ -764,15 +940,7 @@
   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);
-  }
+  mangleUnscopedTemplateName(Template);
 }
 
 void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND) {
@@ -797,6 +965,53 @@
   addSubstitution(ND);
 }
 
+/// Mangles a template name under the production <type>.  Required for
+/// template template arguments.
+///   <type> ::= <class-enum-type>
+///          ::= <template-param>
+///          ::= <substitution>
+void CXXNameMangler::mangleType(TemplateName TN) {
+  if (mangleSubstitution(TN))
+    return;
+      
+  TemplateDecl *TD = 0;
+
+  switch (TN.getKind()) {
+  case TemplateName::QualifiedTemplate:
+    TD = TN.getAsQualifiedTemplateName()->getTemplateDecl();
+    goto HaveDecl;
+
+  case TemplateName::Template:
+    TD = TN.getAsTemplateDecl();
+    goto HaveDecl;
+
+  HaveDecl:
+    if (isa<TemplateTemplateParmDecl>(TD))
+      mangleTemplateParameter(cast<TemplateTemplateParmDecl>(TD)->getIndex());
+    else
+      mangleName(TD);
+    break;
+
+  case TemplateName::OverloadedTemplate:
+    llvm_unreachable("can't mangle an overloaded template name as a <type>");
+    break;
+
+  case TemplateName::DependentTemplate: {
+    const DependentTemplateName *Dependent = TN.getAsDependentTemplateName();
+    assert(Dependent->isIdentifier());
+
+    // <class-enum-type> ::= <name>
+    // <name> ::= <nested-name>
+    mangleUnresolvedScope(Dependent->getQualifier());
+    mangleSourceName(Dependent->getIdentifier());
+    break;
+  }
+
+  }
+
+  addSubstitution(TN);
+}
+
 void
 CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
   switch (OO) {
@@ -809,24 +1024,21 @@
   //              ::= da        # delete[]
   case OO_Array_Delete: Out << "da"; break;
   //              ::= ps        # + (unary)
-  //              ::= pl        # +
+  //              ::= pl        # + (binary or unknown)
   case OO_Plus:
-    assert((Arity == 1 || Arity == 2) && "Invalid arity!");
     Out << (Arity == 1? "ps" : "pl"); break;
   //              ::= ng        # - (unary)
-  //              ::= mi        # -
+  //              ::= mi        # - (binary or unknown)
   case OO_Minus:
-    assert((Arity == 1 || Arity == 2) && "Invalid arity!");
     Out << (Arity == 1? "ng" : "mi"); break;
   //              ::= ad        # & (unary)
-  //              ::= an        # &
+  //              ::= an        # & (binary or unknown)
   case OO_Amp:
-    assert((Arity == 1 || Arity == 2) && "Invalid arity!");
     Out << (Arity == 1? "ad" : "an"); break;
   //              ::= de        # * (unary)
-  //              ::= ml        # *
+  //              ::= ml        # * (binary or unknown)
   case OO_Star:
-    assert((Arity == 1 || Arity == 2) && "Invalid arity!");
+    // Use binary when unknown.
     Out << (Arity == 1? "de" : "ml"); break;
   //              ::= co        # ~
   case OO_Tilde: Out << "co"; break;
@@ -918,22 +1130,25 @@
   if (Quals.hasConst())
     Out << 'K';
 
+  if (Quals.hasAddressSpace()) {
+    // Extension:
+    //
+    //   <type> ::= U <address-space-number>
+    // 
+    // where <address-space-number> is a source name consisting of 'AS' 
+    // followed by the address space <number>.
+    llvm::SmallString<64> ASString;
+    ASString = "AS" + llvm::utostr_32(Quals.getAddressSpace());
+    Out << 'U' << ASString.size() << ASString;
+  }
+  
   // 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();
+  llvm::SmallString<64> Buffer;
+  MiscNameMangler(Context, Buffer).mangleObjCMethodName(MD);
+  Out << Buffer;
 }
 
 void CXXNameMangler::mangleType(QualType T) {
@@ -969,6 +1184,11 @@
     addSubstitution(T);
 }
 
+void CXXNameMangler::mangleNameOrStandardSubstitution(const NamedDecl *ND) {
+  if (!mangleStandardSubstitution(ND))
+    mangleName(ND);
+}
+
 void CXXNameMangler::mangleType(const BuiltinType *T) {
   //  <type>         ::= <builtin-type>
   //  <builtin-type> ::= v  # void
@@ -1059,7 +1279,8 @@
   if (MangleReturnType)
     mangleType(Proto->getResultType());
 
-  if (Proto->getNumArgs() == 0) {
+  if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) {
+    //   <builtin-type> ::= v   # void
     Out << 'v';
     return;
   }
@@ -1125,6 +1346,22 @@
   if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(PointeeType)) {
     mangleQualifiers(Qualifiers::fromCVRMask(FPT->getTypeQuals()));
     mangleType(FPT);
+    
+    // Itanium C++ ABI 5.1.8:
+    //
+    //   The type of a non-static member function is considered to be different,
+    //   for the purposes of substitution, from the type of a namespace-scope or
+    //   static member function whose type appears similar. The types of two
+    //   non-static member functions are considered to be different, for the
+    //   purposes of substitution, if the functions are members of different
+    //   classes. In other words, for the purposes of substitution, the class of 
+    //   which the function is a member is considered part of the type of 
+    //   function.
+
+    // We increment the SeqID here to emulate adding an entry to the
+    // substitution table. We can't actually add it because we don't want this
+    // particular function type to be substituted.
+    ++SeqID;
   } else
     mangleType(PointeeType);
 }
@@ -1134,8 +1371,6 @@
   mangleTemplateParameter(T->getIndex());
 }
 
-// FIXME: <type> ::= <template-template-param> <template-args>
-
 // <type> ::= P <type>   # pointer-to
 void CXXNameMangler::mangleType(const PointerType *T) {
   Out << 'P';
@@ -1165,12 +1400,20 @@
 }
 
 // GNU extension: vector types
-// <type>        ::= <vector-type>
-// <vector-type> ::= Dv <positive dimension number> _ <element type>
-//               ::= Dv [<dimension expression>] _ <element type>
+// <type>                  ::= <vector-type>
+// <vector-type>           ::= Dv <positive dimension number> _
+//                                    <extended element type>
+//                         ::= Dv [<dimension expression>] _ <element type>
+// <extended element type> ::= <element type>
+//                         ::= p # AltiVec vector pixel
 void CXXNameMangler::mangleType(const VectorType *T) {
   Out << "Dv" << T->getNumElements() << '_';
-  mangleType(T->getElementType());
+  if (T->getAltiVecSpecific() == VectorType::Pixel)
+    Out << 'p';
+  else if (T->getAltiVecSpecific() == VectorType::Bool)
+    Out << 'b';
+  else
+    mangleType(T->getElementType());
 }
 void CXXNameMangler::mangleType(const ExtVectorType *T) {
   mangleType(static_cast<const VectorType*>(T));
@@ -1186,6 +1429,12 @@
   mangleSourceName(T->getDecl()->getIdentifier());
 }
 
+void CXXNameMangler::mangleType(const ObjCObjectType *T) {
+  // We don't allow overloading by different protocol qualification,
+  // so mangling them isn't necessary.
+  mangleType(T->getBaseType());
+}
+
 void CXXNameMangler::mangleType(const BlockPointerType *T) {
   Out << "U13block_pointer";
   mangleType(T->getPointeeType());
@@ -1199,17 +1448,44 @@
 }
 
 void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {
-  TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl();
-  assert(TD && "FIXME: Support dependent template names!");
-
-  mangleName(TD, T->getArgs(), T->getNumArgs());
+  if (TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl()) {
+    mangleName(TD, T->getArgs(), T->getNumArgs());
+  } else {
+    if (mangleSubstitution(QualType(T, 0)))
+      return;
+    
+    mangleTemplatePrefix(T->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(T->getTemplateName(), T->getArgs(), T->getNumArgs());
+    addSubstitution(QualType(T, 0));
+  }
 }
 
 void CXXNameMangler::mangleType(const DependentNameType *T) {
   // Typename types are always nested
   Out << 'N';
   mangleUnresolvedScope(T->getQualifier());
-  mangleSourceName(T->getIdentifier());
+  mangleSourceName(T->getIdentifier());    
+  Out << 'E';
+}
+
+void CXXNameMangler::mangleType(const DependentTemplateSpecializationType *T) {
+  // Dependently-scoped template types are always nested
+  Out << 'N';
+
+  // TODO: avoid making this TemplateName.
+  TemplateName Prefix =
+    getASTContext().getDependentTemplateName(T->getQualifier(),
+                                             T->getIdentifier());
+  mangleTemplatePrefix(Prefix);
+
+  // 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(Prefix, T->getArgs(), T->getNumArgs());    
   Out << 'E';
 }
 
@@ -1259,33 +1535,12 @@
     // Boolean values are encoded as 0/1.
     Out << (Value.getBoolValue() ? '1' : '0');
   } else {
-    if (Value.isNegative())
-      Out << 'n';
-    Value.abs().print(Out, false);
+    mangleNumber(Value);
   }
   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.
@@ -1301,14 +1556,14 @@
   mangleUnresolvedName(Qualifier, Member, Arity);
 }
 
-void CXXNameMangler::mangleExpression(const Expr *E) {
+void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
   // <expression> ::= <unary operator-name> <expression>
   //              ::= <binary operator-name> <expression> <expression>
   //              ::= <trinary operator-name> <expression> <expression> <expression>
-  //              ::= cl <expression>* E	     # call
+  //              ::= 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)
+  //              ::= st <type>                      # sizeof (a type)
   //              ::= at <type>                      # alignof (a type)
   //              ::= <template-param>
   //              ::= <function-param>
@@ -1324,11 +1579,45 @@
 #define EXPR(Type, Base)
 #define STMT(Type, Base) \
   case Expr::Type##Class:
-#include "clang/AST/StmtNodes.def"
+#include "clang/AST/StmtNodes.inc"
+    // fallthrough
+
+  // These all can only appear in local or variable-initialization
+  // contexts and so should never appear in a mangling.
+  case Expr::AddrLabelExprClass:
+  case Expr::BlockDeclRefExprClass:
+  case Expr::CXXThisExprClass:
+  case Expr::DesignatedInitExprClass:
+  case Expr::ImplicitValueInitExprClass:
+  case Expr::InitListExprClass:
+  case Expr::ParenListExprClass:
+  case Expr::CXXScalarValueInitExprClass:
     llvm_unreachable("unexpected statement kind");
     break;
 
-  default: {
+  // FIXME: invent manglings for all these.
+  case Expr::BlockExprClass:
+  case Expr::CXXPseudoDestructorExprClass:
+  case Expr::ChooseExprClass:
+  case Expr::CompoundLiteralExprClass:
+  case Expr::ExtVectorElementExprClass:
+  case Expr::ObjCEncodeExprClass:
+  case Expr::ObjCImplicitSetterGetterRefExprClass:
+  case Expr::ObjCIsaExprClass:
+  case Expr::ObjCIvarRefExprClass:
+  case Expr::ObjCMessageExprClass:
+  case Expr::ObjCPropertyRefExprClass:
+  case Expr::ObjCProtocolExprClass:
+  case Expr::ObjCSelectorExprClass:
+  case Expr::ObjCStringLiteralClass:
+  case Expr::ObjCSuperExprClass:
+  case Expr::OffsetOfExprClass:
+  case Expr::PredefinedExprClass:
+  case Expr::ShuffleVectorExprClass:
+  case Expr::StmtExprClass:
+  case Expr::TypesCompatibleExprClass:
+  case Expr::UnaryTypeTraitExprClass:
+  case Expr::VAArgExprClass: {
     // As bad as this diagnostic is, it's better than crashing.
     Diagnostic &Diags = Context.getDiags();
     unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Error,
@@ -1340,21 +1629,46 @@
     break;
   }
 
+  case Expr::CXXDefaultArgExprClass:
+    mangleExpression(cast<CXXDefaultArgExpr>(E)->getExpr(), Arity);
+    break;
+
+  case Expr::CXXMemberCallExprClass: // fallthrough
   case Expr::CallExprClass: {
     const CallExpr *CE = cast<CallExpr>(E);
     Out << "cl";
-    mangleCalledExpression(CE->getCallee(), CE->getNumArgs());
+    mangleExpression(CE->getCallee(), CE->getNumArgs());
     for (unsigned I = 0, N = CE->getNumArgs(); I != N; ++I)
       mangleExpression(CE->getArg(I));
     Out << 'E';
     break;
   }
 
+  case Expr::CXXNewExprClass: {
+    // Proposal from David Vandervoorde, 2010.06.30
+    const CXXNewExpr *New = cast<CXXNewExpr>(E);
+    if (New->isGlobalNew()) Out << "gs";
+    Out << (New->isArray() ? "na" : "nw");
+    for (CXXNewExpr::const_arg_iterator I = New->placement_arg_begin(),
+           E = New->placement_arg_end(); I != E; ++I)
+      mangleExpression(*I);
+    Out << '_';
+    mangleType(New->getAllocatedType());
+    if (New->hasInitializer()) {
+      Out << "pi";
+      for (CXXNewExpr::const_arg_iterator I = New->constructor_arg_begin(),
+             E = New->constructor_arg_end(); I != E; ++I)
+        mangleExpression(*I);
+    }
+    Out << 'E';
+    break;
+  }
+
   case Expr::MemberExprClass: {
     const MemberExpr *ME = cast<MemberExpr>(E);
     mangleMemberExpr(ME->getBase(), ME->isArrow(),
                      ME->getQualifier(), ME->getMemberDecl()->getDeclName(),
-                     UnknownArity);
+                     Arity);
     break;
   }
 
@@ -1362,7 +1676,9 @@
     const UnresolvedMemberExpr *ME = cast<UnresolvedMemberExpr>(E);
     mangleMemberExpr(ME->getBase(), ME->isArrow(),
                      ME->getQualifier(), ME->getMemberName(),
-                     UnknownArity);
+                     Arity);
+    if (ME->hasExplicitTemplateArgs())
+      mangleTemplateArgs(ME->getExplicitTemplateArgs());
     break;
   }
 
@@ -1371,7 +1687,9 @@
       = cast<CXXDependentScopeMemberExpr>(E);
     mangleMemberExpr(ME->getBase(), ME->isArrow(),
                      ME->getQualifier(), ME->getMember(),
-                     UnknownArity);
+                     Arity);
+    if (ME->hasExplicitTemplateArgs())
+      mangleTemplateArgs(ME->getExplicitTemplateArgs());
     break;
   }
 
@@ -1380,7 +1698,9 @@
     // using something as close as possible to the original lookup
     // expression.
     const UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(E);
-    mangleUnresolvedName(ULE->getQualifier(), ULE->getName(), UnknownArity);
+    mangleUnresolvedName(ULE->getQualifier(), ULE->getName(), Arity);
+    if (ULE->hasExplicitTemplateArgs())
+      mangleTemplateArgs(ULE->getExplicitTemplateArgs());
     break;
   }
 
@@ -1423,6 +1743,43 @@
     break;
   }
 
+  case Expr::CXXThrowExprClass: {
+    const CXXThrowExpr *TE = cast<CXXThrowExpr>(E);
+
+    // Proposal from David Vandervoorde, 2010.06.30
+    if (TE->getSubExpr()) {
+      Out << "tw";
+      mangleExpression(TE->getSubExpr());
+    } else {
+      Out << "tr";
+    }
+    break;
+  }
+
+  case Expr::CXXTypeidExprClass: {
+    const CXXTypeidExpr *TIE = cast<CXXTypeidExpr>(E);
+
+    // Proposal from David Vandervoorde, 2010.06.30
+    if (TIE->isTypeOperand()) {
+      Out << "ti";
+      mangleType(TIE->getTypeOperand());
+    } else {
+      Out << "te";
+      mangleExpression(TIE->getExprOperand());
+    }
+    break;
+  }
+
+  case Expr::CXXDeleteExprClass: {
+    const CXXDeleteExpr *DE = cast<CXXDeleteExpr>(E);
+
+    // Proposal from David Vandervoorde, 2010.06.30
+    if (DE->isGlobalDelete()) Out << "gs";
+    Out << (DE->isArrayForm() ? "da" : "dl");
+    mangleExpression(DE->getArgument());
+    break;
+  }
+
   case Expr::UnaryOperatorClass: {
     const UnaryOperator *UO = cast<UnaryOperator>(E);
     mangleOperatorName(UnaryOperator::getOverloadedOperator(UO->getOpcode()),
@@ -1431,6 +1788,18 @@
     break;
   }
 
+  case Expr::ArraySubscriptExprClass: {
+    const ArraySubscriptExpr *AE = cast<ArraySubscriptExpr>(E);
+
+    // Array subscript is treated as a syntactically wierd form of
+    // binary operator.
+    Out << "ix";
+    mangleExpression(AE->getLHS());
+    mangleExpression(AE->getRHS());
+    break;
+  }
+
+  case Expr::CompoundAssignOperatorClass: // fallthrough
   case Expr::BinaryOperatorClass: {
     const BinaryOperator *BO = cast<BinaryOperator>(E);
     mangleOperatorName(BinaryOperator::getOverloadedOperator(BO->getOpcode()),
@@ -1444,13 +1813,13 @@
     const ConditionalOperator *CO = cast<ConditionalOperator>(E);
     mangleOperatorName(OO_Conditional, /*Arity=*/3);
     mangleExpression(CO->getCond());
-    mangleExpression(CO->getLHS());
-    mangleExpression(CO->getRHS());
+    mangleExpression(CO->getLHS(), Arity);
+    mangleExpression(CO->getRHS(), Arity);
     break;
   }
 
   case Expr::ImplicitCastExprClass: {
-    mangleExpression(cast<ImplicitCastExpr>(E)->getSubExpr());
+    mangleExpression(cast<ImplicitCastExpr>(E)->getSubExpr(), Arity);
     break;
   }
 
@@ -1478,7 +1847,7 @@
   }
 
   case Expr::ParenExprClass:
-    mangleExpression(cast<ParenExpr>(E)->getSubExpr());
+    mangleExpression(cast<ParenExpr>(E)->getSubExpr(), Arity);
     break;
 
   case Expr::DeclRefExprClass: {
@@ -1492,6 +1861,12 @@
       Out << 'E';
       break;
 
+    case Decl::EnumConstant: {
+      const EnumConstantDecl *ED = cast<EnumConstantDecl>(D);
+      mangleIntegerLiteral(ED->getType(), ED->getInitVal());
+      break;
+    }
+
     case Decl::NonTypeTemplateParm: {
       const NonTypeTemplateParmDecl *PD = cast<NonTypeTemplateParmDecl>(D);
       mangleTemplateParameter(PD->getIndex());
@@ -1520,13 +1895,13 @@
     }
     assert(QTy && "Qualifier was not type!");
 
-    // ::= sr <type> <unqualified-name>                   # dependent name
+    // ::= sr <type> <unqualified-name>                  # dependent name
+    // ::= sr <type> <unqualified-name> <template-args>  # dependent template-id
     Out << "sr";
     mangleType(QualType(QTy, 0));
-
-    assert(DRE->getDeclName().getNameKind() == DeclarationName::Identifier &&
-           "Unhandled decl name kind!");
-    mangleSourceName(DRE->getDeclName().getAsIdentifierInfo());
+    mangleUnqualifiedName(0, DRE->getDeclName(), Arity);
+    if (DRE->hasExplicitTemplateArgs())
+      mangleTemplateArgs(DRE->getExplicitTemplateArgs());
 
     break;
   }
@@ -1540,19 +1915,14 @@
     break;
 
   case Expr::CXXExprWithTemporariesClass:
-    mangleExpression(cast<CXXExprWithTemporaries>(E)->getSubExpr());
+    mangleExpression(cast<CXXExprWithTemporaries>(E)->getSubExpr(), Arity);
     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());
-
+    mangleFloat(FL->getValue());
     Out << 'E';
     break;
   }
@@ -1570,17 +1940,60 @@
     Out << 'E';
     break;
 
-  case Expr::IntegerLiteralClass:
-    mangleIntegerLiteral(E->getType(),
-                         llvm::APSInt(cast<IntegerLiteral>(E)->getValue()));
+  case Expr::IntegerLiteralClass: {
+    llvm::APSInt Value(cast<IntegerLiteral>(E)->getValue());
+    if (E->getType()->isSignedIntegerType())
+      Value.setIsSigned(true);
+    mangleIntegerLiteral(E->getType(), Value);
     break;
+  }
+
+  case Expr::ImaginaryLiteralClass: {
+    const ImaginaryLiteral *IE = cast<ImaginaryLiteral>(E);
+    // Mangle as if a complex literal.
+    // Proposal from David Vandervoorde, 2010.06.30.
+    Out << 'L';
+    mangleType(E->getType());
+    if (const FloatingLiteral *Imag =
+          dyn_cast<FloatingLiteral>(IE->getSubExpr())) {
+      // Mangle a floating-point zero of the appropriate type.
+      mangleFloat(llvm::APFloat(Imag->getValue().getSemantics()));
+      Out << '_';
+      mangleFloat(Imag->getValue());
+    } else {
+      Out << '0' << '_';
+      llvm::APSInt Value(cast<IntegerLiteral>(IE->getSubExpr())->getValue());
+      if (IE->getSubExpr()->getType()->isSignedIntegerType())
+        Value.setIsSigned(true);
+      mangleNumber(Value);
+    }
+    Out << 'E';
+    break;
+  }
+
+  case Expr::StringLiteralClass: {
+    // Revised proposal from David Vandervoorde, 2010.07.15.
+    Out << 'L';
+    assert(isa<ConstantArrayType>(E->getType()));
+    mangleType(E->getType());
+    Out << 'E';
+    break;
+  }
+
+  case Expr::GNUNullExprClass:
+    // FIXME: should this really be mangled the same as nullptr?
+    // fallthrough
+
+  case Expr::CXXNullPtrLiteralExprClass: {
+    // Proposal from David Vandervoorde, 2010.06.30, as
+    // modified by ABI list discussion.
+    Out << "LDnE";
+    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
@@ -1617,6 +2030,15 @@
   }
 }
 
+void CXXNameMangler::mangleTemplateArgs(
+                          const ExplicitTemplateArgumentList &TemplateArgs) {
+  // <template-args> ::= I <template-arg>+ E
+  Out << 'I';
+  for (unsigned I = 0, E = TemplateArgs.NumTemplateArgs; I != E; ++I)
+    mangleTemplateArg(0, TemplateArgs.getTemplateArgs()[I].getArgument());
+  Out << 'E';
+}
+
 void CXXNameMangler::mangleTemplateArgs(TemplateName Template,
                                         const TemplateArgument *TemplateArgs,
                                         unsigned NumTemplateArgs) {
@@ -1664,9 +2086,8 @@
     mangleType(A.getAsType());
     break;
   case TemplateArgument::Template:
-    assert(A.getAsTemplate().getAsTemplateDecl() &&
-           "Can't get dependent template names here");
-    mangleName(A.getAsTemplate().getAsTemplateDecl());
+    // This is mangled as <type>.
+    mangleType(A.getAsTemplate());
     break;
   case TemplateArgument::Expression:
     Out << 'X';
@@ -1743,6 +2164,15 @@
   return mangleSubstitution(TypePtr);
 }
 
+bool CXXNameMangler::mangleSubstitution(TemplateName Template) {
+  if (TemplateDecl *TD = Template.getAsTemplateDecl())
+    return mangleSubstitution(TD);
+  
+  Template = Context.getASTContext().getCanonicalTemplateName(Template);
+  return mangleSubstitution(
+                      reinterpret_cast<uintptr_t>(Template.getAsVoidPointer()));
+}
+
 bool CXXNameMangler::mangleSubstitution(uintptr_t Ptr) {
   llvm::DenseMap<uintptr_t, unsigned>::iterator I = Substitutions.find(Ptr);
   if (I == Substitutions.end())
@@ -1763,7 +2193,7 @@
     while (SeqID) {
       assert(BufferPtr > Buffer && "Buffer overflow!");
 
-      unsigned char c = static_cast<unsigned char>(SeqID) % 36;
+      char c = static_cast<char>(SeqID % 36);
 
       *--BufferPtr =  (c < 10 ? '0' + c : 'A' + c - 10);
       SeqID /= 36;
@@ -1921,11 +2351,17 @@
   addSubstitution(TypePtr);
 }
 
-void CXXNameMangler::addSubstitution(uintptr_t Ptr) {
-  unsigned SeqID = Substitutions.size();
+void CXXNameMangler::addSubstitution(TemplateName Template) {
+  if (TemplateDecl *TD = Template.getAsTemplateDecl())
+    return addSubstitution(TD);
+  
+  Template = Context.getASTContext().getCanonicalTemplateName(Template);
+  addSubstitution(reinterpret_cast<uintptr_t>(Template.getAsVoidPointer()));
+}
 
+void CXXNameMangler::addSubstitution(uintptr_t Ptr) {
   assert(!Substitutions.count(Ptr) && "Substitution already exists!");
-  Substitutions[Ptr] = SeqID;
+  Substitutions[Ptr] = SeqID++;
 }
 
 //
@@ -1965,6 +2401,12 @@
   Mangler.mangle(D);
 }
 
+void MangleContext::mangleBlock(GlobalDecl GD, const BlockDecl *BD,
+                                llvm::SmallVectorImpl<char> &Res) {
+  MiscNameMangler Mangler(*this, Res);
+  Mangler.mangleBlock(GD, BD);
+}
+
 void MangleContext::mangleThunk(const CXXMethodDecl *MD,
                                 const ThunkInfo &Thunk,
                                 llvm::SmallVectorImpl<char> &Res) {
@@ -2022,12 +2464,21 @@
   Mangler.mangleName(D);
 }
 
+void MangleContext::mangleReferenceTemporary(const VarDecl *D,
+                                             llvm::SmallVectorImpl<char> &Res) {
+  // We match the GCC mangling here.
+  //  <special-name> ::= GR <object name>
+  CXXNameMangler Mangler(*this, Res);
+  Mangler.getStream() << "_ZGR";
+  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);
+  Mangler.mangleNameOrStandardSubstitution(RD);
 }
 
 void MangleContext::mangleCXXVTT(const CXXRecordDecl *RD,
@@ -2035,7 +2486,7 @@
   // <special-name> ::= TT <type>  # VTT structure
   CXXNameMangler Mangler(*this, Res);
   Mangler.getStream() << "_ZTT";
-  Mangler.mangleName(RD);
+  Mangler.mangleNameOrStandardSubstitution(RD);
 }
 
 void MangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
@@ -2044,10 +2495,10 @@
   // <special-name> ::= TC <type> <offset number> _ <base type>
   CXXNameMangler Mangler(*this, Res);
   Mangler.getStream() << "_ZTC";
-  Mangler.mangleName(RD);
+  Mangler.mangleNameOrStandardSubstitution(RD);
   Mangler.getStream() << Offset;
   Mangler.getStream() << '_';
-  Mangler.mangleName(Type);
+  Mangler.mangleNameOrStandardSubstitution(Type);
 }
 
 void MangleContext::mangleCXXRTTI(QualType Ty,
diff --git a/lib/CodeGen/Mangle.h b/lib/CodeGen/Mangle.h
index da3626f..139f6c0 100644
--- a/lib/CodeGen/Mangle.h
+++ b/lib/CodeGen/Mangle.h
@@ -19,18 +19,22 @@
 #define LLVM_CLANG_CODEGEN_MANGLE_H
 
 #include "CGCXX.h"
+#include "GlobalDecl.h"
 #include "clang/AST/Type.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
 
 namespace clang {
   class ASTContext;
+  class BlockDecl;
   class CXXConstructorDecl;
   class CXXDestructorDecl;
   class CXXMethodDecl;
   class FunctionDecl;
   class NamedDecl;
+  class ObjCMethodDecl;
   class VarDecl;
 
 namespace CodeGen {
@@ -63,7 +67,7 @@
   llvm::StringRef String;
   llvm::SmallString<256> Buffer;
 };
-   
+
 /// MangleContext - Context for tracking state which persists across multiple
 /// calls to the C++ name mangler.
 class MangleContext {
@@ -73,16 +77,22 @@
   llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
   unsigned Discriminator;
   llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
+  llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
+  llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
   
 public:
   explicit MangleContext(ASTContext &Context,
                          Diagnostic &Diags)
     : Context(Context), Diags(Diags) { }
 
+  virtual ~MangleContext() { }
+
   ASTContext &getASTContext() const { return Context; }
 
   Diagnostic &getDiags() const { return Diags; }
 
+  void startNewFunction() { LocalBlockIds.clear(); }
+  
   uint64_t getAnonymousStructId(const TagDecl *TD) {
     std::pair<llvm::DenseMap<const TagDecl *,
       uint64_t>::iterator, bool> Result =
@@ -90,31 +100,45 @@
     return Result.first->second;
   }
 
+  unsigned getBlockId(const BlockDecl *BD, bool Local) {
+    llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
+      = Local? LocalBlockIds : GlobalBlockIds;
+    std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
+      Result = BlockIds.insert(std::make_pair(BD, BlockIds.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,
+  virtual bool shouldMangleDeclName(const NamedDecl *D);
+  virtual void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
+  virtual void mangleThunk(const CXXMethodDecl *MD,
+                          const ThunkInfo &Thunk,
                           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> &);
-  
+  virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
+                                  const ThisAdjustment &ThisAdjustment,
+                                  llvm::SmallVectorImpl<char> &);
+  virtual void mangleGuardVariable(const VarDecl *D,
+                                   llvm::SmallVectorImpl<char> &);
+  virtual void mangleReferenceTemporary(const VarDecl *D,
+                                        llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXVTable(const CXXRecordDecl *RD,
+                               llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXVTT(const CXXRecordDecl *RD,
+                            llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
+                                   const CXXRecordDecl *Type,
+                                   llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
+                             llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
+                             llvm::SmallVectorImpl<char> &);
+  void mangleBlock(GlobalDecl GD,
+                   const BlockDecl *BD, llvm::SmallVectorImpl<char> &);
+
   void mangleInitDiscriminator() {
     Discriminator = 0;
   }
@@ -130,7 +154,23 @@
   }
   /// @}
 };
+
+/// MiscNameMangler - Mangles Objective-C method names and blocks.
+class MiscNameMangler {
+  MangleContext &Context;
+  llvm::raw_svector_ostream Out;
   
+  ASTContext &getASTContext() const { return Context.getASTContext(); }
+
+public:
+  MiscNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res);
+
+  llvm::raw_svector_ostream &getStream() { return Out; }
+  
+  void mangleBlock(GlobalDecl GD, const BlockDecl *BD);
+  void mangleObjCMethodName(const ObjCMethodDecl *MD);
+};
+
 }
 }
 
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp
new file mode 100644
index 0000000..f894f66
--- /dev/null
+++ b/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -0,0 +1,1189 @@
+//===--- MicrosoftCXXABI.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 C++ code generation targetting the Microsoft Visual C++ ABI.
+// The class in this file generates structures that follow the Microsoft
+// Visual C++ ABI, which is actually not very well documented at all outside
+// of Microsoft.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGCXXABI.h"
+#include "CodeGenModule.h"
+#include "Mangle.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ExprCXX.h"
+#include "CGVTables.h"
+
+using namespace clang;
+using namespace CodeGen;
+
+namespace {
+
+/// MicrosoftCXXNameMangler - Manage the mangling of a single name for the
+/// Microsoft Visual C++ ABI.
+class MicrosoftCXXNameMangler {
+  MangleContext &Context;
+  llvm::raw_svector_ostream Out;
+
+  ASTContext &getASTContext() const { return Context.getASTContext(); }
+
+public:
+  MicrosoftCXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res)
+  : Context(C), Out(Res) { }
+
+  void mangle(const NamedDecl *D, llvm::StringRef Prefix = "?");
+  void mangleName(const NamedDecl *ND);
+  void mangleFunctionEncoding(const FunctionDecl *FD);
+  void mangleVariableEncoding(const VarDecl *VD);
+  void mangleNumber(int64_t Number);
+  void mangleType(QualType T);
+
+private:
+  void mangleUnqualifiedName(const NamedDecl *ND) {
+    mangleUnqualifiedName(ND, ND->getDeclName());
+  }
+  void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name);
+  void mangleSourceName(const IdentifierInfo *II);
+  void manglePostfix(const DeclContext *DC, bool NoFunction=false);
+  void mangleOperatorName(OverloadedOperatorKind OO);
+  void mangleQualifiers(Qualifiers Quals, bool IsMember);
+
+  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 mangleType(const FunctionType *T, const FunctionDecl *D,
+                  bool IsStructor, bool IsInstMethod);
+  void mangleType(const ArrayType *T, bool IsGlobal);
+  void mangleExtraDimensions(QualType T);
+  void mangleFunctionClass(const FunctionDecl *FD);
+  void mangleCallingConvention(const FunctionType *T);
+  void mangleThrowSpecification(const FunctionProtoType *T);
+
+};
+
+/// MicrosoftMangleContext - Overrides the default MangleContext for the
+/// Microsoft Visual C++ ABI.
+class MicrosoftMangleContext : public MangleContext {
+public:
+  MicrosoftMangleContext(ASTContext &Context,
+                         Diagnostic &Diags) : MangleContext(Context, Diags) { }
+  virtual bool shouldMangleDeclName(const NamedDecl *D);
+  virtual void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
+  virtual void mangleThunk(const CXXMethodDecl *MD,
+                           const ThunkInfo &Thunk,
+                           llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
+                                  const ThisAdjustment &ThisAdjustment,
+                                  llvm::SmallVectorImpl<char> &);
+  virtual void mangleGuardVariable(const VarDecl *D,
+                                   llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXVTable(const CXXRecordDecl *RD,
+                               llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXVTT(const CXXRecordDecl *RD,
+                            llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
+                                   const CXXRecordDecl *Type,
+                                   llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
+                             llvm::SmallVectorImpl<char> &);
+  virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
+                             llvm::SmallVectorImpl<char> &);
+};
+
+class MicrosoftCXXABI : public CGCXXABI {
+  MicrosoftMangleContext MangleCtx;
+public:
+  MicrosoftCXXABI(CodeGenModule &CGM)
+    : CGCXXABI(CGM), MangleCtx(CGM.getContext(), CGM.getDiags()) {}
+
+  MicrosoftMangleContext &getMangleContext() {
+    return MangleCtx;
+  }
+};
+
+}
+
+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 MicrosoftMangleContext::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 internal linkage are not mangled.
+  if (!FD) {
+    const DeclContext *DC = D->getDeclContext();
+    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 MicrosoftCXXNameMangler::mangle(const NamedDecl *D,
+                                     llvm::StringRef Prefix) {
+  // MSVC doesn't mangle C++ names the same way it mangles extern "C" names.
+  // Therefore it's really important that we don't decorate the
+  // name with leading underscores or leading/trailing at signs. So, emit a
+  // asm marker at the start so we get the name right.
+  Out << '\01';  // LLVM IR Marker for __asm("foo")
+
+  // 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 << ALA->getLabel();
+    return;
+  }
+
+  // <mangled-name> ::= ? <name> <type-encoding>
+  Out << Prefix;
+  mangleName(D);
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+    mangleFunctionEncoding(FD);
+  else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
+    mangleVariableEncoding(VD);
+  // TODO: Fields? Can MSVC even mangle them?
+}
+
+void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
+  // <type-encoding> ::= <function-class> <function-type>
+
+  // Don't mangle in the type if this isn't a decl we should typically mangle.
+  if (!Context.shouldMangleDeclName(FD))
+    return;
+  
+  // We should never ever see a FunctionNoProtoType at this point.
+  // We don't even know how to mangle their types anyway :).
+  const FunctionProtoType *FT = cast<FunctionProtoType>(FD->getType());
+
+  bool InStructor = false, InInstMethod = false;
+  const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
+  if (MD) {
+    if (MD->isInstance())
+      InInstMethod = true;
+    if (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD))
+      InStructor = true;
+  }
+
+  // First, the function class.
+  mangleFunctionClass(FD);
+
+  mangleType(FT, FD, InStructor, InInstMethod);
+}
+
+void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
+  // <type-encoding> ::= <storage-class> <variable-type>
+  // <storage-class> ::= 0  # private static member
+  //                 ::= 1  # protected static member
+  //                 ::= 2  # public static member
+  //                 ::= 3  # global
+  //                 ::= 4  # static local
+  
+  // The first character in the encoding (after the name) is the storage class.
+  if (VD->isStaticDataMember()) {
+    // If it's a static member, it also encodes the access level.
+    switch (VD->getAccess()) {
+      default:
+      case AS_private: Out << '0'; break;
+      case AS_protected: Out << '1'; break;
+      case AS_public: Out << '2'; break;
+    }
+  }
+  else if (!VD->isStaticLocal())
+    Out << '3';
+  else
+    Out << '4';
+  // Now mangle the type.
+  // <variable-type> ::= <type> <cvr-qualifiers>
+  //                 ::= <type> A # pointers, references, arrays
+  // Pointers and references are odd. The type of 'int * const foo;' gets
+  // mangled as 'QAHA' instead of 'PAHB', for example.
+  QualType Ty = VD->getType();
+  if (Ty->isPointerType() || Ty->isReferenceType()) {
+    mangleType(Ty);
+    Out << 'A';
+  } else if (Ty->isArrayType()) {
+    // Global arrays are funny, too.
+    mangleType(static_cast<ArrayType *>(Ty.getTypePtr()), true);
+    Out << 'A';
+  } else {
+    mangleType(Ty.getLocalUnqualifiedType());
+    mangleQualifiers(Ty.getLocalQualifiers(), false);
+  }
+}
+
+void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) {
+  // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
+  const DeclContext *DC = ND->getDeclContext();
+
+  // Always start with the unqualified name.
+  mangleUnqualifiedName(ND);    
+
+  // 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();
+
+  manglePostfix(DC);
+
+  // Terminate the whole name with an '@'.
+  Out << '@';
+}
+
+void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
+  // <number> ::= [?] <decimal digit> # <= 9
+  //          ::= [?] <hex digit>+ @ # > 9; A = 0, B = 1, etc...
+  if (Number < 0) {
+    Out << '?';
+    Number = -Number;
+  }
+  if (Number >= 1 && Number <= 10) {
+    Out << Number-1;
+  } else {
+    // We have to build up the encoding in reverse order, so it will come
+    // out right when we write it out.
+    char Encoding[16];
+    char *EndPtr = Encoding+sizeof(Encoding);
+    char *CurPtr = EndPtr;
+    while (Number) {
+      *--CurPtr = 'A' + (Number % 16);
+      Number /= 16;
+    }
+    Out.write(CurPtr, EndPtr-CurPtr);
+    Out << '@';
+  }
+}
+
+void
+MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
+                                               DeclarationName Name) {
+  //  <unqualified-name> ::= <operator-name>
+  //                     ::= <ctor-dtor-name>
+  //                     ::= <source-name>
+  switch (Name.getNameKind()) {
+    case DeclarationName::Identifier: {
+      if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
+        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()) {
+          Out << "?A";
+          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;
+      }
+
+      // When VC encounters an anonymous type with no tag and no typedef,
+      // it literally emits '<unnamed-tag>'.
+      Out << "<unnamed-tag>";
+      break;
+    }
+      
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+      assert(false && "Can't mangle Objective-C selector names here!");
+      break;
+      
+    case DeclarationName::CXXConstructorName:
+      assert(false && "Can't mangle constructors yet!");
+      break;
+      
+    case DeclarationName::CXXDestructorName:
+      assert(false && "Can't mangle destructors yet!");
+      break;
+      
+    case DeclarationName::CXXConversionFunctionName:
+      // <operator-name> ::= ?B # (cast)
+      // The target type is encoded as the return type.
+      Out << "?B";
+      break;
+      
+    case DeclarationName::CXXOperatorName:
+      mangleOperatorName(Name.getCXXOverloadedOperator());
+      break;
+      
+    case DeclarationName::CXXLiteralOperatorName:
+      // FIXME: Was this added in VS2010? Does MS even know how to mangle this?
+      assert(false && "Don't know how to mangle literal operators yet!");
+      break;
+      
+    case DeclarationName::CXXUsingDirective:
+      assert(false && "Can't mangle a using directive name!");
+      break;
+  }
+}
+
+void MicrosoftCXXNameMangler::manglePostfix(const DeclContext *DC,
+                                            bool NoFunction) {
+  // <postfix> ::= <unqualified-name> [<postfix>]
+  //           ::= <template-postfix> <template-args> [<postfix>]
+  //           ::= <template-param>
+  //           ::= <substitution> [<postfix>]
+
+  if (!DC) return;
+
+  while (isa<LinkageSpecDecl>(DC))
+    DC = DC->getParent();
+
+  if (DC->isTranslationUnit())
+    return;
+
+  if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
+    llvm::SmallString<64> Name;
+    Context.mangleBlock(GlobalDecl(), BD, Name);
+    Out << Name << '@';
+    return manglePostfix(DC->getParent(), NoFunction);
+  }
+
+  if (NoFunction && (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)))
+    return;
+  else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC))
+    mangleObjCMethodName(Method);
+  else {
+    mangleUnqualifiedName(cast<NamedDecl>(DC));
+    manglePostfix(DC->getParent(), NoFunction);
+  }
+}
+
+void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO) {
+  switch (OO) {
+  //                     ?0 # constructor
+  //                     ?1 # destructor
+  // <operator-name> ::= ?2 # new
+  case OO_New: Out << "?2"; break;
+  // <operator-name> ::= ?3 # delete
+  case OO_Delete: Out << "?3"; break;
+  // <operator-name> ::= ?4 # =
+  case OO_Equal: Out << "?4"; break;
+  // <operator-name> ::= ?5 # >>
+  case OO_GreaterGreater: Out << "?5"; break;
+  // <operator-name> ::= ?6 # <<
+  case OO_LessLess: Out << "?6"; break;
+  // <operator-name> ::= ?7 # !
+  case OO_Exclaim: Out << "?7"; break;
+  // <operator-name> ::= ?8 # ==
+  case OO_EqualEqual: Out << "?8"; break;
+  // <operator-name> ::= ?9 # !=
+  case OO_ExclaimEqual: Out << "?9"; break;
+  // <operator-name> ::= ?A # []
+  case OO_Subscript: Out << "?A"; break;
+  //                     ?B # conversion
+  // <operator-name> ::= ?C # ->
+  case OO_Arrow: Out << "?C"; break;
+  // <operator-name> ::= ?D # *
+  case OO_Star: Out << "?D"; break;
+  // <operator-name> ::= ?E # ++
+  case OO_PlusPlus: Out << "?E"; break;
+  // <operator-name> ::= ?F # --
+  case OO_MinusMinus: Out << "?F"; break;
+  // <operator-name> ::= ?G # -
+  case OO_Minus: Out << "?G"; break;
+  // <operator-name> ::= ?H # +
+  case OO_Plus: Out << "?H"; break;
+  // <operator-name> ::= ?I # &
+  case OO_Amp: Out << "?I"; break;
+  // <operator-name> ::= ?J # ->*
+  case OO_ArrowStar: Out << "?J"; break;
+  // <operator-name> ::= ?K # /
+  case OO_Slash: Out << "?K"; break;
+  // <operator-name> ::= ?L # %
+  case OO_Percent: Out << "?L"; break;
+  // <operator-name> ::= ?M # <
+  case OO_Less: Out << "?M"; break;
+  // <operator-name> ::= ?N # <=
+  case OO_LessEqual: Out << "?N"; break;
+  // <operator-name> ::= ?O # >
+  case OO_Greater: Out << "?O"; break;
+  // <operator-name> ::= ?P # >=
+  case OO_GreaterEqual: Out << "?P"; break;
+  // <operator-name> ::= ?Q # ,
+  case OO_Comma: Out << "?Q"; break;
+  // <operator-name> ::= ?R # ()
+  case OO_Call: Out << "?R"; break;
+  // <operator-name> ::= ?S # ~
+  case OO_Tilde: Out << "?S"; break;
+  // <operator-name> ::= ?T # ^
+  case OO_Caret: Out << "?T"; break;
+  // <operator-name> ::= ?U # |
+  case OO_Pipe: Out << "?U"; break;
+  // <operator-name> ::= ?V # &&
+  case OO_AmpAmp: Out << "?V"; break;
+  // <operator-name> ::= ?W # ||
+  case OO_PipePipe: Out << "?W"; break;
+  // <operator-name> ::= ?X # *=
+  case OO_StarEqual: Out << "?X"; break;
+  // <operator-name> ::= ?Y # +=
+  case OO_PlusEqual: Out << "?Y"; break;
+  // <operator-name> ::= ?Z # -=
+  case OO_MinusEqual: Out << "?Z"; break;
+  // <operator-name> ::= ?_0 # /=
+  case OO_SlashEqual: Out << "?_0"; break;
+  // <operator-name> ::= ?_1 # %=
+  case OO_PercentEqual: Out << "?_1"; break;
+  // <operator-name> ::= ?_2 # >>=
+  case OO_GreaterGreaterEqual: Out << "?_2"; break;
+  // <operator-name> ::= ?_3 # <<=
+  case OO_LessLessEqual: Out << "?_3"; break;
+  // <operator-name> ::= ?_4 # &=
+  case OO_AmpEqual: Out << "?_4"; break;
+  // <operator-name> ::= ?_5 # |=
+  case OO_PipeEqual: Out << "?_5"; break;
+  // <operator-name> ::= ?_6 # ^=
+  case OO_CaretEqual: Out << "?_6"; break;
+  //                     ?_7 # vftable
+  //                     ?_8 # vbtable
+  //                     ?_9 # vcall
+  //                     ?_A # typeof
+  //                     ?_B # local static guard
+  //                     ?_C # string
+  //                     ?_D # vbase destructor
+  //                     ?_E # vector deleting destructor
+  //                     ?_F # default constructor closure
+  //                     ?_G # scalar deleting destructor
+  //                     ?_H # vector constructor iterator
+  //                     ?_I # vector destructor iterator
+  //                     ?_J # vector vbase constructor iterator
+  //                     ?_K # virtual displacement map
+  //                     ?_L # eh vector constructor iterator
+  //                     ?_M # eh vector destructor iterator
+  //                     ?_N # eh vector vbase constructor iterator
+  //                     ?_O # copy constructor closure
+  //                     ?_P<name> # udt returning <name>
+  //                     ?_Q # <unknown>
+  //                     ?_R0 # RTTI Type Descriptor
+  //                     ?_R1 # RTTI Base Class Descriptor at (a,b,c,d)
+  //                     ?_R2 # RTTI Base Class Array
+  //                     ?_R3 # RTTI Class Hierarchy Descriptor
+  //                     ?_R4 # RTTI Complete Object Locator
+  //                     ?_S # local vftable
+  //                     ?_T # local vftable constructor closure
+  // <operator-name> ::= ?_U # new[]
+  case OO_Array_New: Out << "?_U"; break;
+  // <operator-name> ::= ?_V # delete[]
+  case OO_Array_Delete: Out << "?_V"; break;
+    
+  case OO_Conditional:
+    assert(false && "Don't know how to mangle ?:");
+    break;
+    
+  case OO_None:
+  case NUM_OVERLOADED_OPERATORS:
+    assert(false && "Not an overloaded operator");
+    break;
+  }
+}
+
+void MicrosoftCXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
+  // <source name> ::= <identifier> @
+  Out << II->getName() << '@';
+}
+
+void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
+  llvm::SmallString<64> Buffer;
+  MiscNameMangler(Context, Buffer).mangleObjCMethodName(MD);
+  Out << Buffer;
+}
+
+void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
+                                               bool IsMember) {
+  // <cvr-qualifiers> ::= [E] [F] [I] <base-cvr-qualifiers>
+  // 'E' means __ptr64 (32-bit only); 'F' means __unaligned (32/64-bit only);
+  // 'I' means __restrict (32/64-bit).
+  // Note that the MSVC __restrict keyword isn't the same as the C99 restrict
+  // keyword!
+  // <base-cvr-qualifiers> ::= A  # near
+  //                       ::= B  # near const
+  //                       ::= C  # near volatile
+  //                       ::= D  # near const volatile
+  //                       ::= E  # far (16-bit)
+  //                       ::= F  # far const (16-bit)
+  //                       ::= G  # far volatile (16-bit)
+  //                       ::= H  # far const volatile (16-bit)
+  //                       ::= I  # huge (16-bit)
+  //                       ::= J  # huge const (16-bit)
+  //                       ::= K  # huge volatile (16-bit)
+  //                       ::= L  # huge const volatile (16-bit)
+  //                       ::= M <basis> # based
+  //                       ::= N <basis> # based const
+  //                       ::= O <basis> # based volatile
+  //                       ::= P <basis> # based const volatile
+  //                       ::= Q  # near member
+  //                       ::= R  # near const member
+  //                       ::= S  # near volatile member
+  //                       ::= T  # near const volatile member
+  //                       ::= U  # far member (16-bit)
+  //                       ::= V  # far const member (16-bit)
+  //                       ::= W  # far volatile member (16-bit)
+  //                       ::= X  # far const volatile member (16-bit)
+  //                       ::= Y  # huge member (16-bit)
+  //                       ::= Z  # huge const member (16-bit)
+  //                       ::= 0  # huge volatile member (16-bit)
+  //                       ::= 1  # huge const volatile member (16-bit)
+  //                       ::= 2 <basis> # based member
+  //                       ::= 3 <basis> # based const member
+  //                       ::= 4 <basis> # based volatile member
+  //                       ::= 5 <basis> # based const volatile member
+  //                       ::= 6  # near function (pointers only)
+  //                       ::= 7  # far function (pointers only)
+  //                       ::= 8  # near method (pointers only)
+  //                       ::= 9  # far method (pointers only)
+  //                       ::= _A <basis> # based function (pointers only)
+  //                       ::= _B <basis> # based function (far?) (pointers only)
+  //                       ::= _C <basis> # based method (pointers only)
+  //                       ::= _D <basis> # based method (far?) (pointers only)
+  //                       ::= _E # block (Clang)
+  // <basis> ::= 0 # __based(void)
+  //         ::= 1 # __based(segment)?
+  //         ::= 2 <name> # __based(name)
+  //         ::= 3 # ?
+  //         ::= 4 # ?
+  //         ::= 5 # not really based
+  if (!IsMember) {
+    if (!Quals.hasVolatile()) {
+      if (!Quals.hasConst())
+        Out << 'A';
+      else
+        Out << 'B';
+    } else {
+      if (!Quals.hasConst())
+        Out << 'C';
+      else
+        Out << 'D';
+    }
+  } else {
+    if (!Quals.hasVolatile()) {
+      if (!Quals.hasConst())
+        Out << 'Q';
+      else
+        Out << 'R';
+    } else {
+      if (!Quals.hasConst())
+        Out << 'S';
+      else
+        Out << 'T';
+    }
+  }
+
+  // FIXME: For now, just drop all extension qualifiers on the floor.
+}
+
+void MicrosoftCXXNameMangler::mangleType(QualType T) {
+  // Only operate on the canonical type!
+  T = getASTContext().getCanonicalType(T);
+  
+  Qualifiers Quals = T.getLocalQualifiers();
+  if (Quals) {
+    // We have to mangle these now, while we still have enough information.
+    // <pointer-cvr-qualifiers> ::= P  # pointer
+    //                          ::= Q  # const pointer
+    //                          ::= R  # volatile pointer
+    //                          ::= S  # const volatile pointer
+    if (T->isAnyPointerType() || T->isMemberPointerType() ||
+        T->isBlockPointerType()) {
+      if (!Quals.hasVolatile())
+        Out << 'Q';
+      else {
+        if (!Quals.hasConst())
+          Out << 'R';
+        else
+          Out << 'S';
+      }
+    } else
+      // Just emit qualifiers like normal.
+      // NB: When we mangle a pointer/reference type, and the pointee
+      // type has no qualifiers, the lack of qualifier gets mangled
+      // in there.
+      mangleQualifiers(Quals, false);
+  } else if (T->isAnyPointerType() || T->isMemberPointerType() ||
+             T->isBlockPointerType()) {
+    Out << 'P';
+  }
+  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"
+  }
+}
+
+void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T) {
+  //  <type>         ::= <builtin-type>
+  //  <builtin-type> ::= X  # void
+  //                 ::= C  # signed char
+  //                 ::= D  # char
+  //                 ::= E  # unsigned char
+  //                 ::= F  # short
+  //                 ::= G  # unsigned short (or wchar_t if it's not a builtin)
+  //                 ::= H  # int
+  //                 ::= I  # unsigned int
+  //                 ::= J  # long
+  //                 ::= K  # unsigned long
+  //                     L  # <none>
+  //                 ::= M  # float
+  //                 ::= N  # double
+  //                 ::= O  # long double (__float80 is mangled differently)
+  //                 ::= _D # __int8 (yup, it's a distinct type in MSVC)
+  //                 ::= _E # unsigned __int8
+  //                 ::= _F # __int16
+  //                 ::= _G # unsigned __int16
+  //                 ::= _H # __int32
+  //                 ::= _I # unsigned __int32
+  //                 ::= _J # long long, __int64
+  //                 ::= _K # unsigned long long, __int64
+  //                 ::= _L # __int128
+  //                 ::= _M # unsigned __int128
+  //                 ::= _N # bool
+  //                     _O # <array in parameter>
+  //                 ::= _T # __float80 (Intel)
+  //                 ::= _W # wchar_t
+  //                 ::= _Z # __float80 (Digital Mars)
+  switch (T->getKind()) {
+  case BuiltinType::Void: Out << 'X'; break;
+  case BuiltinType::SChar: Out << 'C'; break;
+  case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'D'; break;
+  case BuiltinType::UChar: Out << 'E'; break;
+  case BuiltinType::Short: Out << 'F'; break;
+  case BuiltinType::UShort: Out << 'G'; break;
+  case BuiltinType::Int: Out << 'H'; break;
+  case BuiltinType::UInt: Out << 'I'; break;
+  case BuiltinType::Long: Out << 'J'; break;
+  case BuiltinType::ULong: Out << 'K'; break;
+  case BuiltinType::Float: Out << 'M'; break;
+  case BuiltinType::Double: Out << 'N'; break;
+  // TODO: Determine size and mangle accordingly
+  case BuiltinType::LongDouble: Out << 'O'; break;
+  // TODO: __int8 and friends
+  case BuiltinType::LongLong: Out << "_J"; break;
+  case BuiltinType::ULongLong: Out << "_K"; break;
+  case BuiltinType::Int128: Out << "_L"; break;
+  case BuiltinType::UInt128: Out << "_M"; break;
+  case BuiltinType::Bool: Out << "_N"; break;
+  case BuiltinType::WChar: Out << "_W"; 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 << "PAUobjc_object@@"; break;
+  case BuiltinType::ObjCClass: Out << "PAUobjc_class@@"; break;
+  case BuiltinType::ObjCSel: Out << "PAUobjc_selector@@"; break;
+
+  case BuiltinType::Char16:
+  case BuiltinType::Char32:
+  case BuiltinType::NullPtr:
+    assert(false && "Don't know how to mangle this type");
+    break;
+  }
+}
+
+// <type>          ::= <function-type>
+void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T) {
+  // Structors only appear in decls, so at this point we know it's not a
+  // structor type.
+  // I'll probably have mangleType(MemberPointerType) call the mangleType()
+  // method directly.
+  mangleType(T, NULL, false, false);
+}
+void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T) {
+  llvm_unreachable("Can't mangle K&R function prototypes");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const FunctionType *T,
+                                         const FunctionDecl *D,
+                                         bool IsStructor,
+                                         bool IsInstMethod) {
+  // <function-type> ::= <this-cvr-qualifiers> <calling-convention>
+  //                     <return-type> <argument-list> <throw-spec>
+  const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
+
+  // If this is a C++ instance method, mangle the CVR qualifiers for the
+  // this pointer.
+  if (IsInstMethod)
+    mangleQualifiers(Qualifiers::fromCVRMask(Proto->getTypeQuals()), false);
+
+  mangleCallingConvention(T);
+
+  // <return-type> ::= <type>
+  //               ::= @ # structors (they have no declared return type)
+  if (IsStructor)
+    Out << '@';
+  else
+    mangleType(Proto->getResultType());
+
+  // <argument-list> ::= X # void
+  //                 ::= <type>+ @
+  //                 ::= <type>* Z # varargs
+  if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) {
+    Out << 'X';
+  } else {
+    if (D) {
+      // If we got a decl, use the "types-as-written" to make sure arrays
+      // get mangled right.
+      for (FunctionDecl::param_const_iterator Parm = D->param_begin(),
+           ParmEnd = D->param_end();
+           Parm != ParmEnd; ++Parm)
+        mangleType((*Parm)->getTypeSourceInfo()->getType());
+    } else {
+      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';
+    else
+      Out << '@';
+  }
+
+  mangleThrowSpecification(Proto);
+}
+
+void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
+  // <function-class> ::= A # private: near
+  //                  ::= B # private: far
+  //                  ::= C # private: static near
+  //                  ::= D # private: static far
+  //                  ::= E # private: virtual near
+  //                  ::= F # private: virtual far
+  //                  ::= G # private: thunk near
+  //                  ::= H # private: thunk far
+  //                  ::= I # protected: near
+  //                  ::= J # protected: far
+  //                  ::= K # protected: static near
+  //                  ::= L # protected: static far
+  //                  ::= M # protected: virtual near
+  //                  ::= N # protected: virtual far
+  //                  ::= O # protected: thunk near
+  //                  ::= P # protected: thunk far
+  //                  ::= Q # public: near
+  //                  ::= R # public: far
+  //                  ::= S # public: static near
+  //                  ::= T # public: static far
+  //                  ::= U # public: virtual near
+  //                  ::= V # public: virtual far
+  //                  ::= W # public: thunk near
+  //                  ::= X # public: thunk far
+  //                  ::= Y # global near
+  //                  ::= Z # global far
+  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+    switch (MD->getAccess()) {
+      default:
+      case AS_private:
+        if (MD->isStatic())
+          Out << 'C';
+        else if (MD->isVirtual())
+          Out << 'E';
+        else
+          Out << 'A';
+        break;
+      case AS_protected:
+        if (MD->isStatic())
+          Out << 'K';
+        else if (MD->isVirtual())
+          Out << 'M';
+        else
+          Out << 'I';
+        break;
+      case AS_public:
+        if (MD->isStatic())
+          Out << 'S';
+        else if (MD->isVirtual())
+          Out << 'U';
+        else
+          Out << 'Q';
+    }
+  } else
+    Out << 'Y';
+}
+void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T) {
+  // <calling-convention> ::= A # __cdecl
+  //                      ::= B # __export __cdecl
+  //                      ::= C # __pascal
+  //                      ::= D # __export __pascal
+  //                      ::= E # __thiscall
+  //                      ::= F # __export __thiscall
+  //                      ::= G # __stdcall
+  //                      ::= H # __export __stdcall
+  //                      ::= I # __fastcall
+  //                      ::= J # __export __fastcall
+  // The 'export' calling conventions are from a bygone era
+  // (*cough*Win16*cough*) when functions were declared for export with
+  // that keyword. (It didn't actually export them, it just made them so
+  // that they could be in a DLL and somebody from another module could call
+  // them.)
+  switch (T->getCallConv()) {
+    case CC_Default:
+    case CC_C: Out << 'A'; break;
+    case CC_X86ThisCall: Out << 'E'; break;
+    case CC_X86StdCall: Out << 'G'; break;
+    case CC_X86FastCall: Out << 'I'; break;
+  }
+}
+void MicrosoftCXXNameMangler::mangleThrowSpecification(
+                                                const FunctionProtoType *FT) {
+  // <throw-spec> ::= Z # throw(...) (default)
+  //              ::= @ # throw() or __declspec/__attribute__((nothrow))
+  //              ::= <type>+
+  // NOTE: Since the Microsoft compiler ignores throw specifications, they are
+  // all actually mangled as 'Z'. (They're ignored because their associated
+  // functionality isn't implemented, and probably never will be.)
+  Out << 'Z';
+}
+
+void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T) {
+  assert(false && "Don't know how to mangle UnresolvedUsingTypes yet!");
+}
+
+// <type>        ::= <union-type> | <struct-type> | <class-type> | <enum-type>
+// <union-type>  ::= T <name>
+// <struct-type> ::= U <name>
+// <class-type>  ::= V <name>
+// <enum-type>   ::= W <size> <name>
+void MicrosoftCXXNameMangler::mangleType(const EnumType *T) {
+  mangleType(static_cast<const TagType*>(T));
+}
+void MicrosoftCXXNameMangler::mangleType(const RecordType *T) {
+  mangleType(static_cast<const TagType*>(T));
+}
+void MicrosoftCXXNameMangler::mangleType(const TagType *T) {
+  switch (T->getDecl()->getTagKind()) {
+    case TTK_Union:
+      Out << 'T';
+      break;
+    case TTK_Struct:
+      Out << 'U';
+      break;
+    case TTK_Class:
+      Out << 'V';
+      break;
+    case TTK_Enum:
+      Out << 'W';
+      Out << getASTContext().getTypeSizeInChars(
+                cast<EnumDecl>(T->getDecl())->getIntegerType()).getQuantity();
+      break;
+  }
+  mangleName(T->getDecl());
+}
+
+// <type>       ::= <array-type>
+// <array-type> ::= P <cvr-qualifiers> [Y <dimension-count> <dimension>+]
+//                                                  <element-type> # as global
+//              ::= Q <cvr-qualifiers> [Y <dimension-count> <dimension>+]
+//                                                  <element-type> # as param
+// It's supposed to be the other way around, but for some strange reason, it
+// isn't. Today this behavior is retained for the sole purpose of backwards
+// compatibility.
+void MicrosoftCXXNameMangler::mangleType(const ArrayType *T, bool IsGlobal) {
+  // This isn't a recursive mangling, so now we have to do it all in this
+  // one call.
+  if (IsGlobal)
+    Out << 'P';
+  else
+    Out << 'Q';
+  mangleExtraDimensions(T->getElementType());
+}
+void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T) {
+  mangleType(static_cast<const ArrayType *>(T), false);
+}
+void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T) {
+  mangleType(static_cast<const ArrayType *>(T), false);
+}
+void MicrosoftCXXNameMangler::mangleType(const DependentSizedArrayType *T) {
+  mangleType(static_cast<const ArrayType *>(T), false);
+}
+void MicrosoftCXXNameMangler::mangleType(const IncompleteArrayType *T) {
+  mangleType(static_cast<const ArrayType *>(T), false);
+}
+void MicrosoftCXXNameMangler::mangleExtraDimensions(QualType ElementTy) {
+  llvm::SmallVector<llvm::APInt, 3> Dimensions;
+  for (;;) {
+    if (ElementTy->isConstantArrayType()) {
+      const ConstantArrayType *CAT =
+      static_cast<const ConstantArrayType *>(ElementTy.getTypePtr());
+      Dimensions.push_back(CAT->getSize());
+      ElementTy = CAT->getElementType();
+    } else if (ElementTy->isVariableArrayType()) {
+      assert(false && "Don't know how to mangle VLAs!");
+    } else if (ElementTy->isDependentSizedArrayType()) {
+      // The dependent expression has to be folded into a constant (TODO).
+      assert(false && "Don't know how to mangle dependent-sized arrays!");
+    } else if (ElementTy->isIncompleteArrayType()) continue;
+    else break;
+  }
+  mangleQualifiers(ElementTy.getQualifiers(), false);
+  // If there are any additional dimensions, mangle them now.
+  if (Dimensions.size() > 0) {
+    Out << 'Y';
+    // <dimension-count> ::= <number> # number of extra dimensions
+    mangleNumber(Dimensions.size());
+    for (unsigned Dim = 0; Dim < Dimensions.size(); ++Dim) {
+      mangleNumber(Dimensions[Dim].getLimitedValue());
+    }
+  }
+  mangleType(ElementTy.getLocalUnqualifiedType());
+}
+
+// <type>                   ::= <pointer-to-member-type>
+// <pointer-to-member-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
+//                                                          <class name> <type>
+void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T) {
+  QualType PointeeType = T->getPointeeType();
+  if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(PointeeType)) {
+    Out << '8';
+    mangleName(cast<RecordType>(T->getClass())->getDecl());
+    mangleType(FPT, NULL, false, true);
+  } else {
+    mangleQualifiers(PointeeType.getQualifiers(), true);
+    mangleName(cast<RecordType>(T->getClass())->getDecl());
+    mangleType(PointeeType.getLocalUnqualifiedType());
+  }
+}
+
+void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T) {
+  assert(false && "Don't know how to mangle TemplateTypeParmTypes yet!");
+}
+
+// <type> ::= <pointer-type>
+// <pointer-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers> <type>
+void MicrosoftCXXNameMangler::mangleType(const PointerType *T) {
+  QualType PointeeTy = T->getPointeeType();
+  if (PointeeTy->isArrayType()) {
+    // Pointers to arrays are mangled like arrays.
+    mangleExtraDimensions(T->getPointeeType());
+  } else if (PointeeTy->isFunctionType()) {
+    // Function pointers are special.
+    Out << '6';
+    mangleType(static_cast<const FunctionType *>(PointeeTy.getTypePtr()),
+               NULL, false, false);
+  } else {
+    if (!PointeeTy.hasQualifiers())
+      // Lack of qualifiers is mangled as 'A'.
+      Out << 'A';
+    mangleType(PointeeTy);
+  }
+}
+void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T) {
+  // Object pointers never have qualifiers.
+  Out << 'A';
+  mangleType(T->getPointeeType());
+}
+
+// <type> ::= <reference-type>
+// <reference-type> ::= A <cvr-qualifiers> <type>
+void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T) {
+  Out << 'A';
+  QualType PointeeTy = T->getPointeeType();
+  if (!PointeeTy.hasQualifiers())
+    // Lack of qualifiers is mangled as 'A'.
+    Out << 'A';
+  mangleType(PointeeTy);
+}
+
+void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T) {
+  assert(false && "Don't know how to mangle RValueReferenceTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const ComplexType *T) {
+  assert(false && "Don't know how to mangle ComplexTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const VectorType *T) {
+  assert(false && "Don't know how to mangle VectorTypes yet!");
+}
+void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T) {
+  assert(false && "Don't know how to mangle ExtVectorTypes yet!");
+}
+void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T) {
+  assert(false && "Don't know how to mangle DependentSizedExtVectorTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T) {
+  // ObjC interfaces have structs underlying them.
+  Out << 'U';
+  mangleName(T->getDecl());
+}
+
+void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T) {
+  // We don't allow overloading by different protocol qualification,
+  // so mangling them isn't necessary.
+  mangleType(T->getBaseType());
+}
+
+void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T) {
+  Out << "_E";
+  mangleType(T->getPointeeType());
+}
+
+void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *T) {
+  assert(false && "Don't know how to mangle InjectedClassNameTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T) {
+  assert(false && "Don't know how to mangle TemplateSpecializationTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T) {
+  assert(false && "Don't know how to mangle DependentNameTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(
+                                 const DependentTemplateSpecializationType *T) {
+  assert(false &&
+         "Don't know how to mangle DependentTemplateSpecializationTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T) {
+  assert(false && "Don't know how to mangle TypeOfTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T) {
+  assert(false && "Don't know how to mangle TypeOfExprTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T) {
+  assert(false && "Don't know how to mangle DecltypeTypes yet!");
+}
+
+void MicrosoftMangleContext::mangleName(const NamedDecl *D,
+                                        llvm::SmallVectorImpl<char> &Name) {
+  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");
+
+  MicrosoftCXXNameMangler Mangler(*this, Name);
+  return Mangler.mangle(D);
+}
+void MicrosoftMangleContext::mangleThunk(const CXXMethodDecl *MD,
+                                         const ThunkInfo &Thunk,
+                                         llvm::SmallVectorImpl<char> &) {
+  assert(false && "Can't yet mangle thunks!");
+}
+void MicrosoftMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
+                                                CXXDtorType Type,
+                                                const ThisAdjustment &,
+                                                llvm::SmallVectorImpl<char> &) {
+  assert(false && "Can't yet mangle destructor thunks!");
+}
+void MicrosoftMangleContext::mangleGuardVariable(const VarDecl *D,
+                                                 llvm::SmallVectorImpl<char> &) {
+  assert(false && "Can't yet mangle guard variables!");
+}
+void MicrosoftMangleContext::mangleCXXVTable(const CXXRecordDecl *RD,
+                                             llvm::SmallVectorImpl<char> &) {
+  assert(false && "Can't yet mangle virtual tables!");
+}
+void MicrosoftMangleContext::mangleCXXVTT(const CXXRecordDecl *RD,
+                                          llvm::SmallVectorImpl<char> &) {
+  llvm_unreachable("The MS C++ ABI does not have virtual table tables!");
+}
+void MicrosoftMangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD,
+                                                 int64_t Offset,
+                                                 const CXXRecordDecl *Type,
+                                                 llvm::SmallVectorImpl<char> &) {
+  llvm_unreachable("The MS C++ ABI does not have constructor vtables!");
+}
+void MicrosoftMangleContext::mangleCXXRTTI(QualType T,
+                                           llvm::SmallVectorImpl<char> &) {
+  assert(false && "Can't yet mangle RTTI!");
+}
+void MicrosoftMangleContext::mangleCXXRTTIName(QualType T,
+                                               llvm::SmallVectorImpl<char> &) {
+  assert(false && "Can't yet mangle RTTI names!");
+}
+void MicrosoftMangleContext::mangleCXXCtor(const CXXConstructorDecl *D,
+                                           CXXCtorType Type,
+                                           llvm::SmallVectorImpl<char> &) {
+  assert(false && "Can't yet mangle constructors!");
+}
+void MicrosoftMangleContext::mangleCXXDtor(const CXXDestructorDecl *D,
+                                           CXXDtorType Type,
+                                           llvm::SmallVectorImpl<char> &) {
+  assert(false && "Can't yet mangle destructors!");
+}
+
+CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
+  return new MicrosoftCXXABI(CGM);
+}
+
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
index 1e1edc1..6d9d277 100644
--- a/lib/CodeGen/ModuleBuilder.cpp
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -13,7 +13,7 @@
 
 #include "clang/CodeGen/ModuleBuilder.h"
 #include "CodeGenModule.h"
-#include "clang/CodeGen/CodeGenOptions.h"
+#include "clang/Frontend/CodeGenOptions.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
@@ -89,6 +89,13 @@
 
       Builder->EmitTentativeDefinition(D);
     }
+
+    virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {
+      if (Diags.hasErrorOccurred())
+        return;
+
+      Builder->EmitVTable(RD, DefinitionRequired);
+    }
   };
 }
 
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index e1fdf86..d2bd332 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -17,20 +17,55 @@
 #include "CodeGenFunction.h"
 #include "clang/AST/RecordLayout.h"
 #include "llvm/Type.h"
+#include "llvm/Target/TargetData.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
 using namespace CodeGen;
 
+static void AssignToArrayRange(CodeGen::CGBuilderTy &Builder,
+                               llvm::Value *Array,
+                               llvm::Value *Value,
+                               unsigned FirstIndex,
+                               unsigned LastIndex) {
+  // Alternatively, we could emit this as a loop in the source.
+  for (unsigned I = FirstIndex; I <= LastIndex; ++I) {
+    llvm::Value *Cell = Builder.CreateConstInBoundsGEP1_32(Array, I);
+    Builder.CreateStore(Value, Cell);
+  }
+}
+
+static bool isAggregateTypeForABI(QualType T) {
+  return CodeGenFunction::hasAggregateLLVMType(T) ||
+         T->isMemberFunctionPointerType();
+}
+
 ABIInfo::~ABIInfo() {}
 
+ASTContext &ABIInfo::getContext() const {
+  return CGT.getContext();
+}
+
+llvm::LLVMContext &ABIInfo::getVMContext() const {
+  return CGT.getLLVMContext();
+}
+
+const llvm::TargetData &ABIInfo::getTargetData() const {
+  return CGT.getTargetData();
+}
+
+
 void ABIArgInfo::dump() const {
   llvm::raw_ostream &OS = llvm::errs();
   OS << "(ABIArgInfo Kind=";
   switch (TheKind) {
   case Direct:
-    OS << "Direct";
+    OS << "Direct Type=";
+    if (const llvm::Type *Ty = getCoerceToType())
+      Ty->print(OS);
+    else
+      OS << "null";
     break;
   case Extend:
     OS << "Extend";
@@ -38,10 +73,6 @@
   case Ignore:
     OS << "Ignore";
     break;
-  case Coerce:
-    OS << "Coerce Type=";
-    getCoerceToType()->print(OS);
-    break;
   case Indirect:
     OS << "Indirect Align=" << getIndirectAlign()
        << " Byal=" << getIndirectByVal();
@@ -71,6 +102,17 @@
     while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT))
       FT = AT->getElementType();
 
+  const RecordType *RT = FT->getAs<RecordType>();
+  if (!RT)
+    return false;
+
+  // C++ record fields are never empty, at least in the Itanium ABI.
+  //
+  // FIXME: We should use a predicate for whether this behavior is true in the
+  // current ABI.
+  if (isa<CXXRecordDecl>(RT->getDecl()))
+    return false;
+
   return isEmptyRecord(Context, FT, AllowArrays);
 }
 
@@ -84,6 +126,14 @@
   const RecordDecl *RD = RT->getDecl();
   if (RD->hasFlexibleArrayMember())
     return false;
+
+  // If this is a C++ record, check 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)
+      if (!isEmptyRecord(Context, i->getType(), true))
+        return false;
+
   for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
          i != e; ++i)
     if (!isEmptyField(Context, *i, AllowArrays))
@@ -97,7 +147,7 @@
   const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
   if (!RD)
     return false;
-  
+
   return !RD->hasTrivialDestructor() || !RD->hasTrivialCopyConstructor();
 }
 
@@ -130,6 +180,28 @@
     return 0;
 
   const Type *Found = 0;
+
+  // If this is a C++ record, check 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) {
+      // Ignore empty records.
+      if (isEmptyRecord(Context, i->getType(), true))
+        continue;
+
+      // If we already found an element then this isn't a single-element struct.
+      if (Found)
+        return 0;
+
+      // If this is non-empty and not a single element struct, the composite
+      // cannot be a single element struct.
+      Found = isSingleElementStruct(i->getType(), Context);
+      if (!Found)
+        return 0;
+    }
+  }
+
+  // Check for single element.
   for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
          i != e; ++i) {
     const FieldDecl *FD = *i;
@@ -151,7 +223,7 @@
       FT = AT->getElementType();
     }
 
-    if (!CodeGenFunction::hasAggregateLLVMType(FT)) {
+    if (!isAggregateTypeForABI(FT)) {
       Found = FT.getTypePtr();
     } else {
       Found = isSingleElementStruct(FT, Context);
@@ -164,7 +236,7 @@
 }
 
 static bool is32Or64BitBasicType(QualType Ty, ASTContext &Context) {
-  if (!Ty->getAs<BuiltinType>() && !Ty->isAnyPointerType() &&
+  if (!Ty->getAs<BuiltinType>() && !Ty->hasPointerRepresentation() &&
       !Ty->isAnyComplexType() && !Ty->isEnumeralType() &&
       !Ty->isBlockPointerType())
     return false;
@@ -212,44 +284,23 @@
   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;
+public:
+  DefaultABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
 
-  ABIArgInfo classifyArgumentType(QualType RetTy,
-                                  ASTContext &Context,
-                                  llvm::LLVMContext &VMContext) const;
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType RetTy) const;
 
-  virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
-                           llvm::LLVMContext &VMContext) const {
-    FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context,
-                                            VMContext);
+  virtual void computeInfo(CGFunctionInfo &FI) const {
+    FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
     for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
          it != ie; ++it)
-      it->info = classifyArgumentType(it->type, Context, VMContext);
+      it->info = classifyArgumentType(it->type);
   }
 
   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -258,7 +309,8 @@
 
 class DefaultTargetCodeGenInfo : public TargetCodeGenInfo {
 public:
-  DefaultTargetCodeGenInfo():TargetCodeGenInfo(new DefaultABIInfo()) {}
+  DefaultTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
+    : TargetCodeGenInfo(new DefaultABIInfo(CGT)) {}
 };
 
 llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -266,10 +318,8 @@
   return 0;
 }
 
-ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty,
-                                                ASTContext &Context,
-                                          llvm::LLVMContext &VMContext) const {
-  if (CodeGenFunction::hasAggregateLLVMType(Ty))
+ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const {
+  if (isAggregateTypeForABI(Ty))
     return ABIArgInfo::getIndirect(0);
 
   // Treat an enum type as its underlying type.
@@ -280,9 +330,12 @@
           ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
 }
 
+//===----------------------------------------------------------------------===//
+// X86-32 ABI Implementation
+//===----------------------------------------------------------------------===//
+
 /// X86_32ABIInfo - The X86-32 ABI information.
 class X86_32ABIInfo : public ABIInfo {
-  ASTContext &Context;
   bool IsDarwinVectorABI;
   bool IsSmallStructInRegABI;
 
@@ -294,39 +347,31 @@
 
   /// 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;
+  ABIArgInfo getIndirectResult(QualType Ty, 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;
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType RetTy) const;
 
-  virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
-                           llvm::LLVMContext &VMContext) const {
-    FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context,
-                                            VMContext);
+  virtual void computeInfo(CGFunctionInfo &FI) const {
+    FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
     for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
          it != ie; ++it)
-      it->info = classifyArgumentType(it->type, Context, VMContext);
+      it->info = classifyArgumentType(it->type);
   }
 
   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) {}
+  X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p)
+    : ABIInfo(CGT), 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)) {}
+  X86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p)
+    :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p)) {}
 
   void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
                            CodeGen::CodeGenModule &CGM) const;
@@ -363,10 +408,11 @@
     return true;
   }
 
-  // If this is a builtin, pointer, enum, or complex type, it is ok.
-  if (Ty->getAs<BuiltinType>() || Ty->isAnyPointerType() || 
+  // If this is a builtin, pointer, enum, complex type, member pointer, or
+  // member function pointer it is ok.
+  if (Ty->getAs<BuiltinType>() || Ty->hasPointerRepresentation() ||
       Ty->isAnyComplexType() || Ty->isEnumeralType() ||
-      Ty->isBlockPointerType())
+      Ty->isBlockPointerType() || Ty->isMemberPointerType())
     return true;
 
   // Arrays are treated like records.
@@ -397,153 +443,173 @@
   return true;
 }
 
-ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
-                                            ASTContext &Context,
-                                          llvm::LLVMContext &VMContext) const {
-  if (RetTy->isVoidType()) {
+ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy) const {
+  if (RetTy->isVoidType())
     return ABIArgInfo::getIgnore();
-  } else if (const VectorType *VT = RetTy->getAs<VectorType>()) {
+
+  if (const VectorType *VT = RetTy->getAs<VectorType>()) {
     // On Darwin, some vectors are returned in registers.
     if (IsDarwinVectorABI) {
-      uint64_t Size = Context.getTypeSize(RetTy);
+      uint64_t Size = getContext().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));
+        return ABIArgInfo::getDirect(llvm::VectorType::get(
+                  llvm::Type::getInt64Ty(getVMContext()), 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::getDirect(llvm::IntegerType::get(getVMContext(),
+                                                            Size));
 
       return ABIArgInfo::getIndirect(0);
     }
 
     return ABIArgInfo::getDirect();
-  } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
+  }
+
+  if (isAggregateTypeForABI(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 Type *SeltTy = isSingleElementStruct(RetTy, getContext())) {
       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) &&
+          uint64_t Size = getContext().getTypeSize(RetTy);
+          return ABIArgInfo::getDirect(
+            llvm::IntegerType::get(getVMContext(), (unsigned)Size));
+        }
+
+        if (BT->getKind() == BuiltinType::Float) {
+          assert(getContext().getTypeSize(RetTy) ==
+                 getContext().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) &&
+          return ABIArgInfo::getDirect(llvm::Type::getFloatTy(getVMContext()));
+        }
+
+        if (BT->getKind() == BuiltinType::Double) {
+          assert(getContext().getTypeSize(RetTy) ==
+                 getContext().getTypeSize(SeltTy) &&
                  "Unexpect single element structure size!");
-          return ABIArgInfo::getCoerce(llvm::Type::getDoubleTy(VMContext));
+          return ABIArgInfo::getDirect(llvm::Type::getDoubleTy(getVMContext()));
         }
       } 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);
+        const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(getVMContext());
+        return ABIArgInfo::getDirect(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);
+        uint64_t Size = getContext().getTypeSize(RetTy);
         if (Size == 64 || Size == 128)
           return ABIArgInfo::getIndirect(0);
 
-        return classifyReturnType(QualType(SeltTy, 0), Context, VMContext);
+        return classifyReturnType(QualType(SeltTy, 0));
       }
     }
 
     // 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));
+    if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext())) {
+      uint64_t Size = getContext().getTypeSize(RetTy);
+      return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),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());
   }
+
+  // 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 {
+ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty, 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;
+  unsigned Align = getContext().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 {
+ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty) const {
   // FIXME: Set alignment on indirect arguments.
-  if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
+  if (isAggregateTypeForABI(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);
+        return getIndirectResult(Ty, /*ByVal=*/false);
 
       if (RT->getDecl()->hasFlexibleArrayMember())
-        return getIndirectResult(Ty, Context);
+        return getIndirectResult(Ty);
     }
 
     // Ignore empty structs.
-    if (Ty->isStructureType() && Context.getTypeSize(Ty) == 0)
+    if (Ty->isStructureType() && getContext().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))
+    if (getContext().getTypeSize(Ty) <= 4*32 &&
+        canExpandIndirectArgument(Ty, getContext()))
       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());
+    return getIndirectResult(Ty);
   }
+
+  if (const VectorType *VT = Ty->getAs<VectorType>()) {
+    // On Darwin, some vectors are passed in memory, we handle this by passing
+    // it as an i8/i16/i32/i64.
+    if (IsDarwinVectorABI) {
+      uint64_t Size = getContext().getTypeSize(Ty);
+      if ((Size == 8 || Size == 16 || Size == 32) ||
+          (Size == 64 && VT->getNumElements() == 1))
+        return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
+                                                            Size));
+      return ABIArgInfo::getIndirect(0);
+    }
+    
+    return ABIArgInfo::getDirect();
+  }
+  
+  
+  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,
@@ -562,8 +628,7 @@
   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),
+    Builder.CreateGEP(Addr, llvm::ConstantInt::get(CGF.Int32Ty, Offset),
                       "ap.next");
   Builder.CreateStore(NextAddr, VAListAddrAsBPP);
 
@@ -592,25 +657,19 @@
 
   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);
-  }
+  AssignToArrayRange(Builder, Address, Four8, 0, 8);
 
   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);
-    }
-      
+    AssignToArrayRange(Builder, Address, Sixteen8, 12, 16);
+
   } else {
     // 9 is %eflags, which doesn't get a size on Darwin for some
     // reason.
@@ -620,15 +679,17 @@
     // 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);
-    }
-  }      
+    AssignToArrayRange(Builder, Address, Twelve8, 11, 16);
+  }
 
   return false;
 }
 
+//===----------------------------------------------------------------------===//
+// X86-64 ABI Implementation
+//===----------------------------------------------------------------------===//
+
+
 namespace {
 /// X86_64ABIInfo - The X86_64 ABI information.
 class X86_64ABIInfo : public ABIInfo {
@@ -652,7 +713,7 @@
   /// 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;
+  static Class merge(Class Accum, Class Field);
 
   /// classify - Determine the x86_64 register classes in which the
   /// given type T should be passed.
@@ -675,43 +736,33 @@
   ///
   /// 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;
+  void classify(QualType T, 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;
+  const llvm::Type *Get16ByteVectorType(QualType Ty) const;
+  const llvm::Type *GetSSETypeAtOffset(const llvm::Type *IRType,
+                                       unsigned IROffset, QualType SourceTy,
+                                       unsigned SourceOffset) const;
+  const llvm::Type *GetINTEGERTypeAtOffset(const llvm::Type *IRType,
+                                           unsigned IROffset, QualType SourceTy,
+                                           unsigned SourceOffset) 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;
+  ABIArgInfo getIndirectReturnResult(QualType Ty) 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 getIndirectResult(QualType Ty) const;
 
-  ABIArgInfo classifyReturnType(QualType RetTy,
-                                ASTContext &Context,
-                                llvm::LLVMContext &VMContext) const;
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
 
-  ABIArgInfo classifyArgumentType(QualType Ty,
-                                  ASTContext &Context,
-                                  llvm::LLVMContext &VMContext,
-                                  unsigned &neededInt,
+  ABIArgInfo classifyArgumentType(QualType Ty, unsigned &neededInt,
                                   unsigned &neededSSE) const;
 
 public:
-  virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
-                           llvm::LLVMContext &VMContext) const;
+  X86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
+
+  virtual void computeInfo(CGFunctionInfo &FI) const;
 
   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
                                  CodeGenFunction &CGF) const;
@@ -719,7 +770,8 @@
 
 class X86_64TargetCodeGenInfo : public TargetCodeGenInfo {
 public:
-  X86_64TargetCodeGenInfo():TargetCodeGenInfo(new X86_64ABIInfo()) {}
+  X86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
+    : TargetCodeGenInfo(new X86_64ABIInfo(CGT)) {}
 
   int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
     return 7;
@@ -732,13 +784,10 @@
 
     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);
-    }
+
+    // 0-15 are the 16 integer registers.
+    // 16 is %rip.
+    AssignToArrayRange(Builder, Address, Eight8, 0, 16);
 
     return false;
   }
@@ -746,8 +795,7 @@
 
 }
 
-X86_64ABIInfo::Class X86_64ABIInfo::merge(Class Accum,
-                                          Class Field) const {
+X86_64ABIInfo::Class X86_64ABIInfo::merge(Class Accum, Class Field) {
   // 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
@@ -775,22 +823,19 @@
          "Invalid accumulated classification during merge.");
   if (Accum == Field || Field == NoClass)
     return Accum;
-  else if (Field == Memory)
+  if (Field == Memory)
     return Memory;
-  else if (Accum == NoClass)
+  if (Accum == NoClass)
     return Field;
-  else if (Accum == Integer || Field == Integer)
+  if (Accum == Integer || Field == Integer)
     return Integer;
-  else if (Field == X87 || Field == X87Up || Field == ComplexX87 ||
-           Accum == X87 || Accum == X87Up)
+  if (Field == X87 || Field == X87Up || Field == ComplexX87 ||
+      Accum == X87 || Accum == X87Up)
     return Memory;
-  else
-    return SSE;
+  return SSE;
 }
 
-void X86_64ABIInfo::classify(QualType Ty,
-                             ASTContext &Context,
-                             uint64_t OffsetBase,
+void X86_64ABIInfo::classify(QualType Ty, 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
@@ -823,13 +868,30 @@
     }
     // FIXME: _Decimal32 and _Decimal64 are SSE.
     // FIXME: _float128 and _Decimal128 are (SSE, SSEUp).
-  } else if (const EnumType *ET = Ty->getAs<EnumType>()) {
+    return;
+  }
+
+  if (const EnumType *ET = Ty->getAs<EnumType>()) {
     // Classify the underlying integer type.
-    classify(ET->getDecl()->getIntegerType(), Context, OffsetBase, Lo, Hi);
-  } else if (Ty->hasPointerRepresentation()) {
+    classify(ET->getDecl()->getIntegerType(), OffsetBase, Lo, Hi);
+    return;
+  }
+
+  if (Ty->hasPointerRepresentation()) {
     Current = Integer;
-  } else if (const VectorType *VT = Ty->getAs<VectorType>()) {
-    uint64_t Size = Context.getTypeSize(VT);
+    return;
+  }
+
+  if (Ty->isMemberPointerType()) {
+    if (Ty->isMemberFunctionPointerType())
+      Lo = Hi = Integer;
+    else
+      Current = Integer;
+    return;
+  }
+
+  if (const VectorType *VT = Ty->getAs<VectorType>()) {
+    uint64_t Size = getContext().getTypeSize(VT);
     if (Size == 32) {
       // gcc passes all <4 x char>, <2 x short>, <1 x int>, <1 x
       // float> as integer.
@@ -847,7 +909,10 @@
         return;
 
       // gcc passes <1 x long long> as INTEGER.
-      if (VT->getElementType()->isSpecificBuiltinType(BuiltinType::LongLong))
+      if (VT->getElementType()->isSpecificBuiltinType(BuiltinType::LongLong) ||
+          VT->getElementType()->isSpecificBuiltinType(BuiltinType::ULongLong) ||
+          VT->getElementType()->isSpecificBuiltinType(BuiltinType::Long) ||
+          VT->getElementType()->isSpecificBuiltinType(BuiltinType::ULong))
         Current = Integer;
       else
         Current = SSE;
@@ -860,32 +925,39 @@
       Lo = SSE;
       Hi = SSEUp;
     }
-  } else if (const ComplexType *CT = Ty->getAs<ComplexType>()) {
-    QualType ET = Context.getCanonicalType(CT->getElementType());
+    return;
+  }
 
-    uint64_t Size = Context.getTypeSize(Ty);
-    if (ET->isIntegralType()) {
+  if (const ComplexType *CT = Ty->getAs<ComplexType>()) {
+    QualType ET = getContext().getCanonicalType(CT->getElementType());
+
+    uint64_t Size = getContext().getTypeSize(Ty);
+    if (ET->isIntegralOrEnumerationType()) {
       if (Size <= 64)
         Current = Integer;
       else if (Size <= 128)
         Lo = Hi = Integer;
-    } else if (ET == Context.FloatTy)
+    } else if (ET == getContext().FloatTy)
       Current = SSE;
-    else if (ET == Context.DoubleTy)
+    else if (ET == getContext().DoubleTy)
       Lo = Hi = SSE;
-    else if (ET == Context.LongDoubleTy)
+    else if (ET == getContext().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;
+    uint64_t EB_Imag = (OffsetBase + getContext().getTypeSize(ET)) / 64;
     if (Hi == NoClass && EB_Real != EB_Imag)
       Hi = Lo;
-  } else if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {
+
+    return;
+  }
+
+  if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {
     // Arrays are treated like structures.
 
-    uint64_t Size = Context.getTypeSize(Ty);
+    uint64_t Size = getContext().getTypeSize(Ty);
 
     // AMD64-ABI 3.2.3p2: Rule 1. If the size of an object is larger
     // than two eightbytes, ..., it has class MEMORY.
@@ -896,17 +968,17 @@
     // fields, it has class MEMORY.
     //
     // Only need to check alignment of array base.
-    if (OffsetBase % Context.getTypeAlign(AT->getElementType()))
+    if (OffsetBase % getContext().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 EltSize = getContext().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);
+      classify(AT->getElementType(), Offset, FieldLo, FieldHi);
       Lo = merge(Lo, FieldLo);
       Hi = merge(Hi, FieldHi);
       if (Lo == Memory || Hi == Memory)
@@ -917,8 +989,11 @@
     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);
+    return;
+  }
+
+  if (const RecordType *RT = Ty->getAs<RecordType>()) {
+    uint64_t Size = getContext().getTypeSize(Ty);
 
     // AMD64-ABI 3.2.3p2: Rule 1. If the size of an object is larger
     // than two eightbytes, ..., it has class MEMORY.
@@ -937,7 +1012,7 @@
     if (RD->hasFlexibleArrayMember())
       return;
 
-    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
 
     // Reset Lo class, this will be recomputed.
     Current = NoClass;
@@ -958,16 +1033,12 @@
         // initialized to class NO_CLASS.
         Class FieldLo, FieldHi;
         uint64_t Offset = OffsetBase + Layout.getBaseClassOffset(Base);
-        classify(i->getType(), Context, Offset, FieldLo, FieldHi);
+        classify(i->getType(), 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.
@@ -981,7 +1052,7 @@
       // fields, it has class MEMORY.
       //
       // Note, skip this test for bit-fields, see below.
-      if (!BitField && Offset % Context.getTypeAlign(i->getType())) {
+      if (!BitField && Offset % getContext().getTypeAlign(i->getType())) {
         Lo = Memory;
         return;
       }
@@ -1003,7 +1074,8 @@
           continue;
 
         uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx);
-        uint64_t Size = i->getBitWidth()->EvaluateAsInt(Context).getZExtValue();
+        uint64_t Size =
+          i->getBitWidth()->EvaluateAsInt(getContext()).getZExtValue();
 
         uint64_t EB_Lo = Offset / 64;
         uint64_t EB_Hi = (Offset + Size - 1) / 64;
@@ -1017,7 +1089,7 @@
           FieldHi = EB_Hi ? Integer : NoClass;
         }
       } else
-        classify(i->getType(), Context, Offset, FieldLo, FieldHi);
+        classify(i->getType(), Offset, FieldLo, FieldHi);
       Lo = merge(Lo, FieldLo);
       Hi = merge(Hi, FieldHi);
       if (Lo == Memory || Hi == Memory)
@@ -1043,38 +1115,10 @@
   }
 }
 
-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 {
+ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty) const {
   // If this is a scalar LLVM value then assume LLVM will pass it in the right
   // place naturally.
-  if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
+  if (!isAggregateTypeForABI(Ty)) {
     // Treat an enum type as its underlying type.
     if (const EnumType *EnumTy = Ty->getAs<EnumType>())
       Ty = EnumTy->getDecl()->getIntegerType();
@@ -1086,11 +1130,10 @@
   return ABIArgInfo::getIndirect(0);
 }
 
-ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,
-                                            ASTContext &Context) const {
+ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty) const {
   // If this is a scalar LLVM value then assume LLVM will pass it in the right
   // place naturally.
-  if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
+  if (!isAggregateTypeForABI(Ty)) {
     // Treat an enum type as its underlying type.
     if (const EnumType *EnumTy = Ty->getAs<EnumType>())
       Ty = EnumTy->getDecl()->getIntegerType();
@@ -1105,29 +1148,272 @@
   // 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;
+  unsigned Align = getContext().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 {
+/// Get16ByteVectorType - The ABI specifies that a value should be passed in an
+/// full vector XMM register.  Pick an LLVM IR type that will be passed as a
+/// vector register.
+const llvm::Type *X86_64ABIInfo::Get16ByteVectorType(QualType Ty) const {
+  const llvm::Type *IRType = CGT.ConvertTypeRecursive(Ty);
+
+  // Wrapper structs that just contain vectors are passed just like vectors,
+  // strip them off if present.
+  const llvm::StructType *STy = dyn_cast<llvm::StructType>(IRType);
+  while (STy && STy->getNumElements() == 1) {
+    IRType = STy->getElementType(0);
+    STy = dyn_cast<llvm::StructType>(IRType);
+  }
+
+  // If the preferred type is a 16-byte vector, prefer to pass it.
+  if (const llvm::VectorType *VT = dyn_cast<llvm::VectorType>(IRType)){
+    const llvm::Type *EltTy = VT->getElementType();
+    if (VT->getBitWidth() == 128 &&
+        (EltTy->isFloatTy() || EltTy->isDoubleTy() ||
+         EltTy->isIntegerTy(8) || EltTy->isIntegerTy(16) ||
+         EltTy->isIntegerTy(32) || EltTy->isIntegerTy(64) ||
+         EltTy->isIntegerTy(128)))
+      return VT;
+  }
+
+  return llvm::VectorType::get(llvm::Type::getDoubleTy(getVMContext()), 2);
+}
+
+/// BitsContainNoUserData - Return true if the specified [start,end) bit range
+/// is known to either be off the end of the specified type or being in
+/// alignment padding.  The user type specified is known to be at most 128 bits
+/// in size, and have passed through X86_64ABIInfo::classify with a successful
+/// classification that put one of the two halves in the INTEGER class.
+///
+/// It is conservatively correct to return false.
+static bool BitsContainNoUserData(QualType Ty, unsigned StartBit,
+                                  unsigned EndBit, ASTContext &Context) {
+  // If the bytes being queried are off the end of the type, there is no user
+  // data hiding here.  This handles analysis of builtins, vectors and other
+  // types that don't contain interesting padding.
+  unsigned TySize = (unsigned)Context.getTypeSize(Ty);
+  if (TySize <= StartBit)
+    return true;
+
+  if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {
+    unsigned EltSize = (unsigned)Context.getTypeSize(AT->getElementType());
+    unsigned NumElts = (unsigned)AT->getSize().getZExtValue();
+
+    // Check each element to see if the element overlaps with the queried range.
+    for (unsigned i = 0; i != NumElts; ++i) {
+      // If the element is after the span we care about, then we're done..
+      unsigned EltOffset = i*EltSize;
+      if (EltOffset >= EndBit) break;
+
+      unsigned EltStart = EltOffset < StartBit ? StartBit-EltOffset :0;
+      if (!BitsContainNoUserData(AT->getElementType(), EltStart,
+                                 EndBit-EltOffset, Context))
+        return false;
+    }
+    // If it overlaps no elements, then it is safe to process as padding.
+    return true;
+  }
+
+  if (const RecordType *RT = Ty->getAs<RecordType>()) {
+    const RecordDecl *RD = RT->getDecl();
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+
+    // If this is a C++ record, check 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());
+
+        // If the base is after the span we care about, ignore it.
+        unsigned BaseOffset = (unsigned)Layout.getBaseClassOffset(Base);
+        if (BaseOffset >= EndBit) continue;
+
+        unsigned BaseStart = BaseOffset < StartBit ? StartBit-BaseOffset :0;
+        if (!BitsContainNoUserData(i->getType(), BaseStart,
+                                   EndBit-BaseOffset, Context))
+          return false;
+      }
+    }
+
+    // Verify that no field has data that overlaps the region of interest.  Yes
+    // this could be sped up a lot by being smarter about queried fields,
+    // however we're only looking at structs up to 16 bytes, so we don't care
+    // much.
+    unsigned idx = 0;
+    for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+         i != e; ++i, ++idx) {
+      unsigned FieldOffset = (unsigned)Layout.getFieldOffset(idx);
+
+      // If we found a field after the region we care about, then we're done.
+      if (FieldOffset >= EndBit) break;
+
+      unsigned FieldStart = FieldOffset < StartBit ? StartBit-FieldOffset :0;
+      if (!BitsContainNoUserData(i->getType(), FieldStart, EndBit-FieldOffset,
+                                 Context))
+        return false;
+    }
+
+    // If nothing in this record overlapped the area of interest, then we're
+    // clean.
+    return true;
+  }
+
+  return false;
+}
+
+/// ContainsFloatAtOffset - Return true if the specified LLVM IR type has a
+/// float member at the specified offset.  For example, {int,{float}} has a
+/// float at offset 4.  It is conservatively correct for this routine to return
+/// false.
+static bool ContainsFloatAtOffset(const llvm::Type *IRType, unsigned IROffset,
+                                  const llvm::TargetData &TD) {
+  // Base case if we find a float.
+  if (IROffset == 0 && IRType->isFloatTy())
+    return true;
+
+  // If this is a struct, recurse into the field at the specified offset.
+  if (const llvm::StructType *STy = dyn_cast<llvm::StructType>(IRType)) {
+    const llvm::StructLayout *SL = TD.getStructLayout(STy);
+    unsigned Elt = SL->getElementContainingOffset(IROffset);
+    IROffset -= SL->getElementOffset(Elt);
+    return ContainsFloatAtOffset(STy->getElementType(Elt), IROffset, TD);
+  }
+
+  // If this is an array, recurse into the field at the specified offset.
+  if (const llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(IRType)) {
+    const llvm::Type *EltTy = ATy->getElementType();
+    unsigned EltSize = TD.getTypeAllocSize(EltTy);
+    IROffset -= IROffset/EltSize*EltSize;
+    return ContainsFloatAtOffset(EltTy, IROffset, TD);
+  }
+
+  return false;
+}
+
+
+/// GetSSETypeAtOffset - Return a type that will be passed by the backend in the
+/// low 8 bytes of an XMM register, corresponding to the SSE class.
+const llvm::Type *X86_64ABIInfo::
+GetSSETypeAtOffset(const llvm::Type *IRType, unsigned IROffset,
+                   QualType SourceTy, unsigned SourceOffset) const {
+  // The only three choices we have are either double, <2 x float>, or float. We
+  // pass as float if the last 4 bytes is just padding.  This happens for
+  // structs that contain 3 floats.
+  if (BitsContainNoUserData(SourceTy, SourceOffset*8+32,
+                            SourceOffset*8+64, getContext()))
+    return llvm::Type::getFloatTy(getVMContext());
+
+  // We want to pass as <2 x float> if the LLVM IR type contains a float at
+  // offset+0 and offset+4.  Walk the LLVM IR type to find out if this is the
+  // case.
+  if (ContainsFloatAtOffset(IRType, IROffset, getTargetData()) &&
+      ContainsFloatAtOffset(IRType, IROffset+4, getTargetData()))
+    return llvm::VectorType::get(llvm::Type::getFloatTy(getVMContext()), 2);
+
+  return llvm::Type::getDoubleTy(getVMContext());
+}
+
+
+/// GetINTEGERTypeAtOffset - The ABI specifies that a value should be passed in
+/// an 8-byte GPR.  This means that we either have a scalar or we are talking
+/// about the high or low part of an up-to-16-byte struct.  This routine picks
+/// the best LLVM IR type to represent this, which may be i64 or may be anything
+/// else that the backend will pass in a GPR that works better (e.g. i8, %foo*,
+/// etc).
+///
+/// PrefType is an LLVM IR type that corresponds to (part of) the IR type for
+/// the source type.  IROffset is an offset in bytes into the LLVM IR type that
+/// the 8-byte value references.  PrefType may be null.
+///
+/// SourceTy is the source level type for the entire argument.  SourceOffset is
+/// an offset into this that we're processing (which is always either 0 or 8).
+///
+const llvm::Type *X86_64ABIInfo::
+GetINTEGERTypeAtOffset(const llvm::Type *IRType, unsigned IROffset,
+                       QualType SourceTy, unsigned SourceOffset) const {
+  // If we're dealing with an un-offset LLVM IR type, then it means that we're
+  // returning an 8-byte unit starting with it.  See if we can safely use it.
+  if (IROffset == 0) {
+    // Pointers and int64's always fill the 8-byte unit.
+    if (isa<llvm::PointerType>(IRType) || IRType->isIntegerTy(64))
+      return IRType;
+
+    // If we have a 1/2/4-byte integer, we can use it only if the rest of the
+    // goodness in the source type is just tail padding.  This is allowed to
+    // kick in for struct {double,int} on the int, but not on
+    // struct{double,int,int} because we wouldn't return the second int.  We
+    // have to do this analysis on the source type because we can't depend on
+    // unions being lowered a specific way etc.
+    if (IRType->isIntegerTy(8) || IRType->isIntegerTy(16) ||
+        IRType->isIntegerTy(32)) {
+      unsigned BitWidth = cast<llvm::IntegerType>(IRType)->getBitWidth();
+
+      if (BitsContainNoUserData(SourceTy, SourceOffset*8+BitWidth,
+                                SourceOffset*8+64, getContext()))
+        return IRType;
+    }
+  }
+
+  if (const llvm::StructType *STy = dyn_cast<llvm::StructType>(IRType)) {
+    // If this is a struct, recurse into the field at the specified offset.
+    const llvm::StructLayout *SL = getTargetData().getStructLayout(STy);
+    if (IROffset < SL->getSizeInBytes()) {
+      unsigned FieldIdx = SL->getElementContainingOffset(IROffset);
+      IROffset -= SL->getElementOffset(FieldIdx);
+
+      return GetINTEGERTypeAtOffset(STy->getElementType(FieldIdx), IROffset,
+                                    SourceTy, SourceOffset);
+    }
+  }
+
+  if (const llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(IRType)) {
+    const llvm::Type *EltTy = ATy->getElementType();
+    unsigned EltSize = getTargetData().getTypeAllocSize(EltTy);
+    unsigned EltOffset = IROffset/EltSize*EltSize;
+    return GetINTEGERTypeAtOffset(EltTy, IROffset-EltOffset, SourceTy,
+                                  SourceOffset);
+  }
+
+  // Okay, we don't have any better idea of what to pass, so we pass this in an
+  // integer register that isn't too big to fit the rest of the struct.
+  unsigned TySizeInBytes =
+    (unsigned)getContext().getTypeSizeInChars(SourceTy).getQuantity();
+
+  assert(TySizeInBytes != SourceOffset && "Empty field?");
+
+  // It is always safe to classify this as an integer type up to i64 that
+  // isn't larger than the structure.
+  return llvm::IntegerType::get(getVMContext(),
+                                std::min(TySizeInBytes-SourceOffset, 8U)*8);
+}
+
+ABIArgInfo X86_64ABIInfo::
+classifyReturnType(QualType RetTy) 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);
+  classify(RetTy, 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();
+    if (Hi == NoClass)
+      return ABIArgInfo::getIgnore();
+    // If the low part is just padding, it takes no register, leave ResType
+    // null.
+    assert((Hi == SSE || Hi == Integer || Hi == X87Up) &&
+           "Unknown missing lo part");
+    break;
 
   case SSEUp:
   case X87Up:
@@ -1136,31 +1422,47 @@
     // AMD64-ABI 3.2.3p4: Rule 2. Types of class memory are returned via
     // hidden argument.
   case Memory:
-    return getIndirectReturnResult(RetTy, Context);
+    return getIndirectReturnResult(RetTy);
 
     // 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;
+    ResType = GetINTEGERTypeAtOffset(CGT.ConvertTypeRecursive(RetTy), 0,
+                                     RetTy, 0);
+
+    // If we have a sign or zero extended integer, make sure to return Extend
+    // so that the parameter gets the right LLVM IR attributes.
+    if (Hi == NoClass && isa<llvm::IntegerType>(ResType)) {
+      // Treat an enum type as its underlying type.
+      if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
+        RetTy = EnumTy->getDecl()->getIntegerType();
+
+      if (RetTy->isIntegralOrEnumerationType() &&
+          RetTy->isPromotableIntegerType())
+        return ABIArgInfo::getExtend();
+    }
+    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;
+    ResType = GetSSETypeAtOffset(CGT.ConvertTypeRecursive(RetTy), 0, RetTy, 0);
+    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;
+    ResType = llvm::Type::getX86_FP80Ty(getVMContext());
+    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),
+    ResType = llvm::StructType::get(getVMContext(),
+                                    llvm::Type::getX86_FP80Ty(getVMContext()),
+                                    llvm::Type::getX86_FP80Ty(getVMContext()),
                                     NULL);
     break;
   }
@@ -1173,16 +1475,27 @@
     assert(0 && "Invalid classification for hi word.");
 
   case ComplexX87: // Previously handled.
-  case NoClass: break;
+  case NoClass:
+    break;
 
-  case Integer:
-    ResType = llvm::StructType::get(VMContext, ResType,
-                                    llvm::Type::getInt64Ty(VMContext), NULL);
+  case Integer: {
+    const llvm::Type *HiType =
+      GetINTEGERTypeAtOffset(CGT.ConvertTypeRecursive(RetTy), 8, RetTy, 8);
+    if (Lo == NoClass)  // Return HiType at offset 8 in memory.
+      return ABIArgInfo::getDirect(HiType, 8);
+
+    ResType = llvm::StructType::get(getVMContext(), ResType, HiType, NULL);
     break;
-  case SSE:
-    ResType = llvm::StructType::get(VMContext, ResType,
-                                    llvm::Type::getDoubleTy(VMContext), NULL);
+  }
+  case SSE: {
+    const llvm::Type *HiType =
+      GetSSETypeAtOffset(CGT.ConvertTypeRecursive(RetTy), 8, RetTy, 8);
+    if (Lo == NoClass)  // Return HiType at offset 8 in memory.
+      return ABIArgInfo::getDirect(HiType, 8);
+
+    ResType = llvm::StructType::get(getVMContext(), ResType, HiType,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.
@@ -1190,7 +1503,7 @@
     // 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);
+    ResType = Get16ByteVectorType(RetTy);
     break;
 
     // AMD64-ABI 3.2.3p4: Rule 7. If the class is X87UP, the value is
@@ -1200,26 +1513,28 @@
     // 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);
+    if (Lo != X87) {
+      const llvm::Type *HiType =
+        GetSSETypeAtOffset(CGT.ConvertTypeRecursive(RetTy), 8, RetTy, 8);
+      if (Lo == NoClass)  // Return HiType at offset 8 in memory.
+        return ABIArgInfo::getDirect(HiType, 8);
+
+      ResType = llvm::StructType::get(getVMContext(), ResType, HiType, NULL);
+    }
     break;
   }
 
-  return getCoerceResult(RetTy, ResType, Context);
+  return ABIArgInfo::getDirect(ResType);
 }
 
-ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, ASTContext &Context,
-                                               llvm::LLVMContext &VMContext,
-                                               unsigned &neededInt,
+ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt,
                                                unsigned &neededSSE) const {
   X86_64ABIInfo::Class Lo, Hi;
-  classify(Ty, Context, 0, Lo, Hi);
+  classify(Ty, 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;
@@ -1227,7 +1542,13 @@
   const llvm::Type *ResType = 0;
   switch (Lo) {
   case NoClass:
-    return ABIArgInfo::getIgnore();
+    if (Hi == NoClass)
+      return ABIArgInfo::getIgnore();
+    // If the low part is just padding, it takes no register, leave ResType
+    // null.
+    assert((Hi == SSE || Hi == Integer || Hi == X87Up) &&
+           "Unknown missing lo part");
+    break;
 
     // AMD64-ABI 3.2.3p3: Rule 1. If the class is MEMORY, pass the argument
     // on the stack.
@@ -1237,7 +1558,7 @@
     // COMPLEX_X87, it is passed in memory.
   case X87:
   case ComplexX87:
-    return getIndirectResult(Ty, Context);
+    return getIndirectResult(Ty);
 
   case SSEUp:
   case X87Up:
@@ -1248,7 +1569,22 @@
     // and %r9 is used.
   case Integer:
     ++neededInt;
-    ResType = llvm::Type::getInt64Ty(VMContext);
+
+    // Pick an 8-byte type based on the preferred type.
+    ResType = GetINTEGERTypeAtOffset(CGT.ConvertTypeRecursive(Ty), 0, Ty, 0);
+
+    // If we have a sign or zero extended integer, make sure to return Extend
+    // so that the parameter gets the right LLVM IR attributes.
+    if (Hi == NoClass && isa<llvm::IntegerType>(ResType)) {
+      // Treat an enum type as its underlying type.
+      if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+        Ty = EnumTy->getDecl()->getIntegerType();
+
+      if (Ty->isIntegralOrEnumerationType() &&
+          Ty->isPromotableIntegerType())
+        return ABIArgInfo::getExtend();
+    }
+
     break;
 
     // AMD64-ABI 3.2.3p3: Rule 3. If the class is SSE, the next
@@ -1256,7 +1592,7 @@
     // order from %xmm0 to %xmm7.
   case SSE:
     ++neededSSE;
-    ResType = llvm::Type::getDoubleTy(VMContext);
+    ResType = GetSSETypeAtOffset(CGT.ConvertTypeRecursive(Ty), 0, Ty, 0);
     break;
   }
 
@@ -1271,37 +1607,50 @@
     break;
 
   case NoClass: break;
-  case Integer:
-    ResType = llvm::StructType::get(VMContext, ResType,
-                                    llvm::Type::getInt64Ty(VMContext), NULL);
+
+  case Integer: {
     ++neededInt;
+    // Pick an 8-byte type based on the preferred type.
+    const llvm::Type *HiType =
+      GetINTEGERTypeAtOffset(CGT.ConvertTypeRecursive(Ty), 8, Ty, 8);
+
+    if (Lo == NoClass)  // Pass HiType at offset 8 in memory.
+      return ABIArgInfo::getDirect(HiType, 8);
+
+    ResType = llvm::StructType::get(getVMContext(), ResType, HiType, NULL);
     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;
+  case SSE: {
+    const llvm::Type *HiType =
+      GetSSETypeAtOffset(CGT.ConvertTypeRecursive(Ty), 8, Ty, 8);
 
-    // 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);
+    if (Lo == NoClass)  // Pass HiType at offset 8 in memory.
+      return ABIArgInfo::getDirect(HiType, 8);
+
+    ResType = llvm::StructType::get(getVMContext(), ResType, HiType, NULL);
+    ++neededSSE;
     break;
   }
 
-  return getCoerceResult(Ty, ResType, Context);
+    // 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.  This only happens when 128-bit vectors are passed.
+  case SSEUp:
+    assert(Lo == SSE && "Unexpected SSEUp classification");
+    ResType = Get16ByteVectorType(Ty);
+    break;
+  }
+
+  return ABIArgInfo::getDirect(ResType);
 }
 
-void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context,
-                                llvm::LLVMContext &VMContext) const {
-  FI.getReturnInfo() = classifyReturnType(FI.getReturnType(),
-                                          Context, VMContext);
+void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
+
+  FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
 
   // Keep track of the number of assigned registers.
   unsigned freeIntRegs = 6, freeSSERegs = 8;
@@ -1316,8 +1665,7 @@
   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);
+    it->info = classifyArgumentType(it->type, 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
@@ -1327,7 +1675,7 @@
       freeIntRegs -= neededInt;
       freeSSERegs -= neededSSE;
     } else {
-      it->info = getIndirectResult(it->type, Context);
+      it->info = getIndirectResult(it->type);
     }
   }
 }
@@ -1350,12 +1698,11 @@
 
     // overflow_arg_area = (overflow_arg_area + 15) & ~15;
     llvm::Value *Offset =
-      llvm::ConstantInt::get(llvm::Type::getInt32Ty(CGF.getLLVMContext()), 15);
+      llvm::ConstantInt::get(CGF.Int32Ty, 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);
+                                                    CGF.Int64Ty);
+    llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int64Ty, ~15LL);
     overflow_arg_area =
       CGF.Builder.CreateIntToPtr(CGF.Builder.CreateAnd(AsInt, Mask),
                                  overflow_arg_area->getType(),
@@ -1375,8 +1722,7 @@
 
   uint64_t SizeInBytes = (CGF.getContext().getTypeSize(Ty) + 7) / 8;
   llvm::Value *Offset =
-      llvm::ConstantInt::get(llvm::Type::getInt32Ty(CGF.getLLVMContext()),
-                                               (SizeInBytes + 7)  & ~7);
+      llvm::ConstantInt::get(CGF.Int32Ty, (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);
@@ -1388,8 +1734,6 @@
 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 {
@@ -1399,10 +1743,9 @@
   //   i8* reg_save_area;
   // };
   unsigned neededInt, neededSSE;
-  
+
   Ty = CGF.getContext().getCanonicalType(Ty);
-  ABIArgInfo AI = classifyArgumentType(Ty, CGF.getContext(), VMContext,
-                                       neededInt, neededSSE);
+  ABIArgInfo AI = classifyArgumentType(Ty, neededInt, neededSSE);
 
   // AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
   // in the registers. If not go to step 7.
@@ -1426,21 +1769,16 @@
   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");
+    InRegs = llvm::ConstantInt::get(CGF.Int32Ty, 48 - neededInt * 8);
+    InRegs = CGF.Builder.CreateICmpULE(gp_offset, InRegs, "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");
+      llvm::ConstantInt::get(CGF.Int32Ty, 176 - neededSSE * 16);
+    FitsInFP = CGF.Builder.CreateICmpULE(fp_offset, FitsInFP, "fits_in_fp");
     InRegs = InRegs ? CGF.Builder.CreateAnd(InRegs, FitsInFP) : FitsInFP;
   }
 
@@ -1469,13 +1807,13 @@
                            "reg_save_area");
   if (neededInt && neededSSE) {
     // FIXME: Cleanup.
-    assert(AI.isCoerce() && "Unexpected ABI info for mixed regs");
+    assert(AI.isDirect() && "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()) &&
+    assert((TyLo->isFPOrFPVectorTy() ^ TyHi->isFPOrFPVectorTy()) &&
            "Unexpected ABI info for mixed regs");
     const llvm::Type *PTyLo = llvm::PointerType::getUnqual(TyLo);
     const llvm::Type *PTyHi = llvm::PointerType::getUnqual(TyHi);
@@ -1495,45 +1833,42 @@
     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 {
-    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));
-    }
+    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.CreateConstGEP1_32(RegAddrLo, 16);
+    const llvm::Type *DoubleTy = llvm::Type::getDoubleTy(VMContext);
+    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);
+    llvm::Value *Offset = llvm::ConstantInt::get(CGF.Int32Ty, 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);
+    llvm::Value *Offset = llvm::ConstantInt::get(CGF.Int32Ty, neededSSE * 16);
     CGF.Builder.CreateStore(CGF.Builder.CreateAdd(fp_offset, Offset),
                             fp_offset_p);
   }
@@ -1552,30 +1887,30 @@
   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;
+public:
+  PIC16ABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {}
 
-  ABIArgInfo classifyArgumentType(QualType RetTy,
-                                  ASTContext &Context,
-                                  llvm::LLVMContext &VMContext) const;
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
 
-  virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
-                           llvm::LLVMContext &VMContext) const {
-    FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context,
-                                            VMContext);
+  ABIArgInfo classifyArgumentType(QualType RetTy) const;
+
+  virtual void computeInfo(CGFunctionInfo &FI) const {
+    FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
     for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
          it != ie; ++it)
-      it->info = classifyArgumentType(it->type, Context, VMContext);
+      it->info = classifyArgumentType(it->type);
   }
 
   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -1584,14 +1919,13 @@
 
 class PIC16TargetCodeGenInfo : public TargetCodeGenInfo {
 public:
-  PIC16TargetCodeGenInfo():TargetCodeGenInfo(new PIC16ABIInfo()) {}
+  PIC16TargetCodeGenInfo(CodeGenTypes &CGT)
+    : TargetCodeGenInfo(new PIC16ABIInfo(CGT)) {}
 };
 
 }
 
-ABIArgInfo PIC16ABIInfo::classifyReturnType(QualType RetTy,
-                                            ASTContext &Context,
-                                          llvm::LLVMContext &VMContext) const {
+ABIArgInfo PIC16ABIInfo::classifyReturnType(QualType RetTy) const {
   if (RetTy->isVoidType()) {
     return ABIArgInfo::getIgnore();
   } else {
@@ -1599,14 +1933,12 @@
   }
 }
 
-ABIArgInfo PIC16ABIInfo::classifyArgumentType(QualType Ty,
-                                              ASTContext &Context,
-                                          llvm::LLVMContext &VMContext) const {
+ABIArgInfo PIC16ABIInfo::classifyArgumentType(QualType Ty) const {
   return ABIArgInfo::getDirect();
 }
 
 llvm::Value *PIC16ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                       CodeGenFunction &CGF) const {
+                                     CodeGenFunction &CGF) const {
   const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
   const llvm::Type *BPP = llvm::PointerType::getUnqual(BP);
 
@@ -1635,13 +1967,15 @@
 namespace {
 class PPC32TargetCodeGenInfo : public DefaultTargetCodeGenInfo {
 public:
+  PPC32TargetCodeGenInfo(CodeGenTypes &CGT) : DefaultTargetCodeGenInfo(CGT) {}
+
   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;  
+                               llvm::Value *Address) const;
 };
 
 }
@@ -1661,16 +1995,10 @@
   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);
-  }
+  AssignToArrayRange(Builder, Address, Four8, 0, 31);
 
   // 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);
-  }
+  AssignToArrayRange(Builder, Address, Eight8, 32, 63);
 
   // 64-76 are various 4-byte special-purpose registers:
   // 64: mq
@@ -1679,32 +2007,25 @@
   // 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);
-  }
+  AssignToArrayRange(Builder, Address, Four8, 64, 76);
 
   // 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);
-  }
+  AssignToArrayRange(Builder, Address, Sixteen8, 77, 108);
 
   // 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);
-  }
+  AssignToArrayRange(Builder, Address, Four8, 109, 113);
 
-  return false;  
+  return false;
 }
 
 
+//===----------------------------------------------------------------------===//
 // ARM ABI Implementation
+//===----------------------------------------------------------------------===//
 
 namespace {
 
@@ -1720,21 +2041,15 @@
   ABIKind Kind;
 
 public:
-  ARMABIInfo(ABIKind _Kind) : Kind(_Kind) {}
+  ARMABIInfo(CodeGenTypes &CGT, ABIKind _Kind) : ABIInfo(CGT), Kind(_Kind) {}
 
 private:
   ABIKind getABIKind() const { return Kind; }
 
-  ABIArgInfo classifyReturnType(QualType RetTy,
-                                ASTContext &Context,
-                                llvm::LLVMContext &VMCOntext) const;
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType RetTy) const;
 
-  ABIArgInfo classifyArgumentType(QualType RetTy,
-                                  ASTContext &Context,
-                                  llvm::LLVMContext &VMContext) const;
-
-  virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
-                           llvm::LLVMContext &VMContext) const;
+  virtual void computeInfo(CGFunctionInfo &FI) const;
 
   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
                                  CodeGenFunction &CGF) const;
@@ -1742,8 +2057,8 @@
 
 class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
 public:
-  ARMTargetCodeGenInfo(ARMABIInfo::ABIKind K)
-    :TargetCodeGenInfo(new ARMABIInfo(K)) {}
+  ARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIInfo::ABIKind K)
+    :TargetCodeGenInfo(new ARMABIInfo(CGT, K)) {}
 
   int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
     return 13;
@@ -1752,23 +2067,29 @@
 
 }
 
-void ARMABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context,
-                             llvm::LLVMContext &VMContext) const {
-  FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context,
-                                          VMContext);
+void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {
+  FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
   for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
-       it != ie; ++it) {
-    it->info = classifyArgumentType(it->type, Context, VMContext);
-  }
+       it != ie; ++it)
+    it->info = classifyArgumentType(it->type);
 
-  // ARM always overrides the calling convention.
+  const llvm::Triple &Triple(getContext().Target.getTriple());
+  llvm::CallingConv::ID DefaultCC;
+  if (Triple.getEnvironmentName() == "gnueabi" ||
+      Triple.getEnvironmentName() == "eabi")
+    DefaultCC = llvm::CallingConv::ARM_AAPCS;
+  else
+    DefaultCC = llvm::CallingConv::ARM_APCS;
+
   switch (getABIKind()) {
   case APCS:
-    FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_APCS);
+    if (DefaultCC != llvm::CallingConv::ARM_APCS)
+      FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_APCS);
     break;
 
   case AAPCS:
-    FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_AAPCS);
+    if (DefaultCC != llvm::CallingConv::ARM_AAPCS)
+      FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_AAPCS);
     break;
 
   case AAPCS_VFP:
@@ -1777,10 +2098,8 @@
   }
 }
 
-ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty,
-                                            ASTContext &Context,
-                                          llvm::LLVMContext &VMContext) const {
-  if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
+ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty) const {
+  if (!isAggregateTypeForABI(Ty)) {
     // Treat an enum type as its underlying type.
     if (const EnumType *EnumTy = Ty->getAs<EnumType>())
       Ty = EnumTy->getDecl()->getIntegerType();
@@ -1790,29 +2109,34 @@
   }
 
   // Ignore empty records.
-  if (isEmptyRecord(Context, Ty, true))
+  if (isEmptyRecord(getContext(), Ty, true))
     return ABIArgInfo::getIgnore();
 
+  // Structures with either a non-trivial destructor or a non-trivial
+  // copy constructor are always indirect.
+  if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
+    return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+
   // 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;
+  if (getContext().getTypeAlign(Ty) > 32) {
+    ElemTy = llvm::Type::getInt64Ty(getVMContext());
+    SizeRegs = (getContext().getTypeSize(Ty) + 63) / 64;
   } else {
-    ElemTy = llvm::Type::getInt32Ty(VMContext);
-    SizeRegs = (Context.getTypeSize(Ty) + 31) / 32;
+    ElemTy = llvm::Type::getInt32Ty(getVMContext());
+    SizeRegs = (getContext().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);
+  const llvm::Type* STy = llvm::StructType::get(getVMContext(), LLVMFields,
+                                                true);
+  return ABIArgInfo::getDirect(STy);
 }
 
-static bool isIntegerLikeType(QualType Ty,
-                              ASTContext &Context,
+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
@@ -1882,7 +2206,7 @@
 
     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.
@@ -1897,13 +2221,11 @@
   return true;
 }
 
-ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
-                                          ASTContext &Context,
-                                          llvm::LLVMContext &VMContext) const {
+ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const {
   if (RetTy->isVoidType())
     return ABIArgInfo::getIgnore();
 
-  if (!CodeGenFunction::hasAggregateLLVMType(RetTy)) {
+  if (!isAggregateTypeForABI(RetTy)) {
     // Treat an enum type as its underlying type.
     if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
       RetTy = EnumTy->getDecl()->getIntegerType();
@@ -1912,9 +2234,14 @@
             ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
   }
 
+  // Structures with either a non-trivial destructor or a non-trivial
+  // copy constructor are always indirect.
+  if (isRecordWithNonTrivialDestructorOrCopyConstructor(RetTy))
+    return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+
   // Are we following APCS?
   if (getABIKind() == APCS) {
-    if (isEmptyRecord(Context, RetTy, false))
+    if (isEmptyRecord(getContext(), RetTy, false))
       return ABIArgInfo::getIgnore();
 
     // Complex types are all returned as packed integers.
@@ -1922,18 +2249,18 @@
     // 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)));
+      return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
+                                              getContext().getTypeSize(RetTy)));
 
     // Integer like structures are returned in r0.
-    if (isIntegerLikeType(RetTy, Context, VMContext)) {
+    if (isIntegerLikeType(RetTy, getContext(), getVMContext())) {
       // Return in the smallest viable integer type.
-      uint64_t Size = Context.getTypeSize(RetTy);
+      uint64_t Size = getContext().getTypeSize(RetTy);
       if (Size <= 8)
-        return ABIArgInfo::getCoerce(llvm::Type::getInt8Ty(VMContext));
+        return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
       if (Size <= 16)
-        return ABIArgInfo::getCoerce(llvm::Type::getInt16Ty(VMContext));
-      return ABIArgInfo::getCoerce(llvm::Type::getInt32Ty(VMContext));
+        return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext()));
+      return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
     }
 
     // Otherwise return in memory.
@@ -1942,26 +2269,26 @@
 
   // Otherwise this is an AAPCS variant.
 
-  if (isEmptyRecord(Context, RetTy, true))
+  if (isEmptyRecord(getContext(), RetTy, true))
     return ABIArgInfo::getIgnore();
 
   // Aggregates <= 4 bytes are returned in r0; other aggregates
   // are returned indirectly.
-  uint64_t Size = Context.getTypeSize(RetTy);
+  uint64_t Size = getContext().getTypeSize(RetTy);
   if (Size <= 32) {
     // Return in the smallest viable integer type.
     if (Size <= 8)
-      return ABIArgInfo::getCoerce(llvm::Type::getInt8Ty(VMContext));
+      return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
     if (Size <= 16)
-      return ABIArgInfo::getCoerce(llvm::Type::getInt16Ty(VMContext));
-    return ABIArgInfo::getCoerce(llvm::Type::getInt32Ty(VMContext));
+      return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext()));
+    return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
   }
 
   return ABIArgInfo::getIndirect(0);
 }
 
 llvm::Value *ARMABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                      CodeGenFunction &CGF) const {
+                                   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);
@@ -1977,51 +2304,48 @@
   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),
+    Builder.CreateGEP(Addr, llvm::ConstantInt::get(CGF.Int32Ty, Offset),
                       "ap.next");
   Builder.CreateStore(NextAddr, VAListAddrAsBPP);
 
   return AddrTyped;
 }
 
-ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy,
-                                              ASTContext &Context,
-                                          llvm::LLVMContext &VMContext) const {
-  if (RetTy->isVoidType()) {
+ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) 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());
-  }
+  if (isAggregateTypeForABI(RetTy))
+    return ABIArgInfo::getIndirect(0);
+
+  // 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 {
+public:
+  SystemZABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {}
+
   bool isPromotableIntegerType(QualType Ty) const;
 
-  ABIArgInfo classifyReturnType(QualType RetTy, ASTContext &Context,
-                                llvm::LLVMContext &VMContext) const;
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType RetTy) 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);
+  virtual void computeInfo(CGFunctionInfo &FI) const {
+    FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
     for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
          it != ie; ++it)
-      it->info = classifyArgumentType(it->type, Context, VMContext);
+      it->info = classifyArgumentType(it->type);
   }
 
   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -2030,7 +2354,8 @@
 
 class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
 public:
-  SystemZTargetCodeGenInfo():TargetCodeGenInfo(new SystemZABIInfo()) {}
+  SystemZTargetCodeGenInfo(CodeGenTypes &CGT)
+    : TargetCodeGenInfo(new SystemZABIInfo(CGT)) {}
 };
 
 }
@@ -2062,37 +2387,34 @@
 }
 
 
-ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy,
-                                              ASTContext &Context,
-                                           llvm::LLVMContext &VMContext) const {
-  if (RetTy->isVoidType()) {
+ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {
+  if (RetTy->isVoidType())
     return ABIArgInfo::getIgnore();
-  } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
+  if (isAggregateTypeForABI(RetTy))
     return ABIArgInfo::getIndirect(0);
-  } else {
-    return (isPromotableIntegerType(RetTy) ?
-            ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
-  }
+
+  return (isPromotableIntegerType(RetTy) ?
+          ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
 }
 
-ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty,
-                                                ASTContext &Context,
-                                           llvm::LLVMContext &VMContext) const {
-  if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
+ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
+  if (isAggregateTypeForABI(Ty))
     return ABIArgInfo::getIndirect(0);
-  } else {
-    return (isPromotableIntegerType(Ty) ?
-            ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
-  }
+
+  return (isPromotableIntegerType(Ty) ?
+          ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
 }
 
+//===----------------------------------------------------------------------===//
 // MSP430 ABI Implementation
+//===----------------------------------------------------------------------===//
 
 namespace {
 
 class MSP430TargetCodeGenInfo : public TargetCodeGenInfo {
 public:
-  MSP430TargetCodeGenInfo():TargetCodeGenInfo(new DefaultABIInfo()) {}
+  MSP430TargetCodeGenInfo(CodeGenTypes &CGT)
+    : TargetCodeGenInfo(new DefaultABIInfo(CGT)) {}
   void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
                            CodeGen::CodeGenModule &M) const;
 };
@@ -2123,45 +2445,103 @@
   }
 }
 
-const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() const {
+//===----------------------------------------------------------------------===//
+// MIPS ABI Implementation.  This works for both little-endian and
+// big-endian variants.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class MIPSTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  MIPSTargetCodeGenInfo(CodeGenTypes &CGT)
+    : TargetCodeGenInfo(new DefaultABIInfo(CGT)) {}
+
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
+    return 29;
+  }
+
+  bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+                               llvm::Value *Address) const;
+};
+}
+
+bool
+MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+                                               llvm::Value *Address) const {
+  // This information comes from gcc's implementation, which seems to
+  // as canonical as it gets.
+
+  CodeGen::CGBuilderTy &Builder = CGF.Builder;
+  llvm::LLVMContext &Context = CGF.getLLVMContext();
+
+  // Everything on MIPS is 4 bytes.  Double-precision FP registers
+  // are aliased to pairs of single-precision FP registers.
+  const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);
+  llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
+
+  // 0-31 are the general purpose registers, $0 - $31.
+  // 32-63 are the floating-point registers, $f0 - $f31.
+  // 64 and 65 are the multiply/divide registers, $hi and $lo.
+  // 66 is the (notional, I think) register for signal-handler return.
+  AssignToArrayRange(Builder, Address, Four8, 0, 65);
+
+  // 67-74 are the floating-point status registers, $fcc0 - $fcc7.
+  // They are one bit wide and ignored here.
+
+  // 80-111 are the coprocessor 0 registers, $c0r0 - $c0r31.
+  // (coprocessor 1 is the FP unit)
+  // 112-143 are the coprocessor 2 registers, $c2r0 - $c2r31.
+  // 144-175 are the coprocessor 3 registers, $c3r0 - $c3r31.
+  // 176-181 are the DSP accumulator registers.
+  AssignToArrayRange(Builder, Address, Four8, 80, 181);
+
+  return false;
+}
+
+
+const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
   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());
+  const llvm::Triple &Triple = getContext().Target.getTriple();
   switch (Triple.getArch()) {
   default:
-    return *(TheTargetCodeGenInfo = new DefaultTargetCodeGenInfo);
+    return *(TheTargetCodeGenInfo = new DefaultTargetCodeGenInfo(Types));
+
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+    return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types));
 
   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));
+               new ARMTargetCodeGenInfo(Types, ARMABIInfo::APCS));
 
     return *(TheTargetCodeGenInfo =
-             new ARMTargetCodeGenInfo(ARMABIInfo::AAPCS));
+             new ARMTargetCodeGenInfo(Types, ARMABIInfo::AAPCS));
 
   case llvm::Triple::pic16:
-    return *(TheTargetCodeGenInfo = new PIC16TargetCodeGenInfo());
+    return *(TheTargetCodeGenInfo = new PIC16TargetCodeGenInfo(Types));
 
   case llvm::Triple::ppc:
-    return *(TheTargetCodeGenInfo = new PPC32TargetCodeGenInfo());
+    return *(TheTargetCodeGenInfo = new PPC32TargetCodeGenInfo(Types));
 
   case llvm::Triple::systemz:
-    return *(TheTargetCodeGenInfo = new SystemZTargetCodeGenInfo());
+    return *(TheTargetCodeGenInfo = new SystemZTargetCodeGenInfo(Types));
 
   case llvm::Triple::msp430:
-    return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo());
+    return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo(Types));
 
   case llvm::Triple::x86:
     switch (Triple.getOS()) {
     case llvm::Triple::Darwin:
       return *(TheTargetCodeGenInfo =
-               new X86_32TargetCodeGenInfo(Context, true, true));
+               new X86_32TargetCodeGenInfo(Types, true, true));
     case llvm::Triple::Cygwin:
     case llvm::Triple::MinGW32:
     case llvm::Triple::MinGW64:
@@ -2170,14 +2550,14 @@
     case llvm::Triple::FreeBSD:
     case llvm::Triple::OpenBSD:
       return *(TheTargetCodeGenInfo =
-               new X86_32TargetCodeGenInfo(Context, false, true));
+               new X86_32TargetCodeGenInfo(Types, false, true));
 
     default:
       return *(TheTargetCodeGenInfo =
-               new X86_32TargetCodeGenInfo(Context, false, false));
+               new X86_32TargetCodeGenInfo(Types, false, false));
     }
 
   case llvm::Triple::x86_64:
-    return *(TheTargetCodeGenInfo = new X86_64TargetCodeGenInfo());
+    return *(TheTargetCodeGenInfo = new X86_64TargetCodeGenInfo(Types));
   }
 }
diff --git a/lib/CodeGen/TargetInfo.h b/lib/CodeGen/TargetInfo.h
index f0a7824..9d4cf16 100644
--- a/lib/CodeGen/TargetInfo.h
+++ b/lib/CodeGen/TargetInfo.h
@@ -47,6 +47,16 @@
     virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
                                      CodeGen::CodeGenModule &M) const { }
 
+    /// Determines the size of struct _Unwind_Exception on this platform,
+    /// in 8-bit units.  The Itanium ABI defines this as:
+    ///   struct _Unwind_Exception {
+    ///     uint64 exception_class;
+    ///     _Unwind_Exception_Cleanup_Fn exception_cleanup;
+    ///     uint64 private_1;
+    ///     uint64 private_2;
+    ///   };
+    unsigned getSizeOfUnwindException() const { return 32; }
+
     /// Controls whether __builtin_extend_pointer should sign-extend
     /// pointers to uint64_t or zero-extend them (the default).  Has
     /// no effect for targets:
diff --git a/lib/Driver/Action.cpp b/lib/Driver/Action.cpp
index b9a3306..f34971b 100644
--- a/lib/Driver/Action.cpp
+++ b/lib/Driver/Action.cpp
@@ -30,6 +30,7 @@
   case AssembleJobClass: return "assembler";
   case LinkJobClass: return "linker";
   case LipoJobClass: return "lipo";
+  case DsymutilJobClass: return "dsymutil";
   }
 
   assert(0 && "invalid class");
@@ -79,3 +80,7 @@
 LipoJobAction::LipoJobAction(ActionList &Inputs, types::ID Type)
   : JobAction(LipoJobClass, Inputs, Type) {
 }
+
+DsymutilJobAction::DsymutilJobAction(ActionList &Inputs, types::ID Type)
+  : JobAction(DsymutilJobClass, Inputs, Type) {
+}
diff --git a/lib/Driver/Arg.cpp b/lib/Driver/Arg.cpp
index 7e61a1d..83d0d26 100644
--- a/lib/Driver/Arg.cpp
+++ b/lib/Driver/Arg.cpp
@@ -10,47 +10,59 @@
 #include "clang/Driver/Arg.h"
 #include "clang/Driver/ArgList.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;
 
-Arg::Arg(ArgClass _Kind, const Option *_Opt, unsigned _Index,
-         const Arg *_BaseArg)
-  : Kind(_Kind), Opt(_Opt), BaseArg(_BaseArg), Index(_Index), Claimed(false) {
+Arg::Arg(const Option *_Opt, unsigned _Index, const Arg *_BaseArg)
+  : Opt(_Opt), BaseArg(_BaseArg), Index(_Index),
+    Claimed(false), OwnsValues(false) {
 }
 
-Arg::~Arg() { }
+Arg::Arg(const Option *_Opt, unsigned _Index, 
+         const char *Value0, const Arg *_BaseArg)
+  : Opt(_Opt), BaseArg(_BaseArg), Index(_Index),
+    Claimed(false), OwnsValues(false) {
+  Values.push_back(Value0);
+}
+
+Arg::Arg(const Option *_Opt, unsigned _Index, 
+         const char *Value0, const char *Value1, const Arg *_BaseArg)
+  : Opt(_Opt), BaseArg(_BaseArg), Index(_Index),
+    Claimed(false), OwnsValues(false) {
+  Values.push_back(Value0);
+  Values.push_back(Value1);
+}
+
+Arg::~Arg() {
+  if (OwnsValues) {
+    for (unsigned i = 0, e = Values.size(); i != e; ++i)
+      delete[] Values[i];
+  }
+}
 
 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() << " Values: [";
+  for (unsigned i = 0, e = Values.size(); i != e; ++i) {
+    if (i) llvm::errs() << ", ";
+    llvm::errs() << "'" << Values[i] << "'";
+  }
 
-  llvm::errs() << ">\n";
+  llvm::errs() << "]>\n";
 }
 
 std::string Arg::getAsString(const ArgList &Args) const {
-  std::string Res;
-  llvm::raw_string_ostream OS(Res);
+  llvm::SmallString<256> Res;
+  llvm::raw_svector_ostream OS(Res);
 
   ArgStringList ASL;
   render(Args, ASL);
@@ -74,117 +86,36 @@
     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)
+void Arg::render(const ArgList &Args, ArgStringList &Output) const {
+  switch (getOption().getRenderStyle()) {
+  case Option::RenderValuesStyle:
+    for (unsigned i = 0, e = getNumValues(); i != e; ++i)
       Output.push_back(getValue(Args, i));
+    break;
+
+  case Option::RenderCommaJoinedStyle: {
+    llvm::SmallString<256> Res;
+    llvm::raw_svector_ostream OS(Res);
+    OS << getOption().getName();
+    for (unsigned i = 0, e = getNumValues(); i != e; ++i) {
+      if (i) OS << ',';
+      OS << getValue(Args, i);
+    }
+    Output.push_back(Args.MakeArgString(OS.str()));
+    break;
   }
-}
+ 
+ case Option::RenderJoinedStyle:
+    Output.push_back(Args.GetOrMakeJoinedArgString(
+                       getIndex(), getOption().getName(), getValue(Args, 0)));
+    for (unsigned i = 1, e = getNumValues(); i != e; ++i)
+      Output.push_back(getValue(Args, i));
+    break;
 
-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);
+  case Option::RenderSeparateStyle:
+    Output.push_back(getOption().getName());
+    for (unsigned i = 0, e = getNumValues(); i != e; ++i)
+      Output.push_back(getValue(Args, i));
+    break;
+  }
 }
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp
index 95805b0..9101523 100644
--- a/lib/Driver/ArgList.cpp
+++ b/lib/Driver/ArgList.cpp
@@ -9,12 +9,14 @@
 
 #include "clang/Driver/ArgList.h"
 #include "clang/Driver/Arg.h"
+#include "clang/Driver/DriverDiagnostic.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;
 using namespace clang::driver;
 
 void arg_iterator::SkipToNextArg() {
@@ -34,7 +36,7 @@
 
 //
 
-ArgList::ArgList(arglist_type &_Args) : Args(_Args) {
+ArgList::ArgList() {
 }
 
 ArgList::~ArgList() {
@@ -60,12 +62,14 @@
 }
 
 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;
+  Arg *Res = 0;
+  for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) {
+    if ((*it)->getOption().matches(Id0) ||
+        (*it)->getOption().matches(Id1)) {
+      Res = *it;
+      break;
+    }
+  }
 
   if (Res)
     Res->claim();
@@ -76,24 +80,32 @@
 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);
+  for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) {
+    if ((*it)->getOption().matches(Id0) ||
+        (*it)->getOption().matches(Id1) ||
+        (*it)->getOption().matches(Id2)) {
+      Res = *it;
+      break;
+    }
+  }
 
-  int A0Idx = A0 ? (int) A0->getIndex() : -1;
-  int A1Idx = A1 ? (int) A1->getIndex() : -1;
-  int A2Idx = A2 ? (int) A2->getIndex() : -1;
+  if (Res)
+    Res->claim();
 
-  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;
+  return Res;
+}
+
+Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
+                         OptSpecifier Id2, OptSpecifier Id3) const {
+  Arg *Res = 0;
+  for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) {
+    if ((*it)->getOption().matches(Id0) ||
+        (*it)->getOption().matches(Id1) ||
+        (*it)->getOption().matches(Id2) ||
+        (*it)->getOption().matches(Id3)) {
+      Res = *it;
+      break;
+    }
   }
 
   if (Res)
@@ -108,6 +120,32 @@
   return Default;
 }
 
+llvm::StringRef ArgList::getLastArgValue(OptSpecifier Id,
+                                         llvm::StringRef Default) const {
+  if (Arg *A = getLastArg(Id))
+    return A->getValue(*this);
+  return Default;
+}
+
+int ArgList::getLastArgIntValue(OptSpecifier Id, int Default,
+                                clang::Diagnostic &Diags) const {
+  int Res = Default;
+
+  if (Arg *A = getLastArg(Id)) {
+    if (llvm::StringRef(A->getValue(*this)).getAsInteger(10, Res))
+      Diags.Report(diag::err_drv_invalid_int_value)
+        << A->getAsString(*this) << A->getValue(*this);
+  }
+
+  return Res;
+}
+
+std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
+  llvm::SmallVector<const char *, 16> Values;
+  AddAllArgValues(Values, Id);
+  return std::vector<std::string>(Values.begin(), Values.end());
+}
+
 void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
   if (Arg *A = getLastArg(Id)) {
     A->claim();
@@ -119,8 +157,8 @@
                          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);
+    (*it)->claim();
+    (*it)->render(*this, Output);
   }
 }
 
@@ -128,9 +166,9 @@
                               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));
+    (*it)->claim();
+    for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
+      Output.push_back((*it)->getValue(*this, i));
   }
 }
 
@@ -139,14 +177,14 @@
                                    bool Joined) const {
   for (arg_iterator it = filtered_begin(Id0),
          ie = filtered_end(); it != ie; ++it) {
-    it->claim();
+    (*it)->claim();
 
     if (Joined) {
       Output.push_back(MakeArgString(llvm::StringRef(Translation) +
-                                     it->getValue(*this, 0)));
+                                     (*it)->getValue(*this, 0)));
     } else {
       Output.push_back(Translation);
-      Output.push_back(it->getValue(*this, 0));
+      Output.push_back((*it)->getValue(*this, 0));
     }
   }
 }
@@ -154,7 +192,7 @@
 void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
   for (arg_iterator it = filtered_begin(Id0),
          ie = filtered_end(); it != ie; ++it)
-      it->claim();
+    (*it)->claim();
 }
 
 const char *ArgList::MakeArgString(const llvm::Twine &T) const {
@@ -163,10 +201,21 @@
   return MakeArgString(Str.str());
 }
 
+const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
+                                              llvm::StringRef LHS,
+                                              llvm::StringRef RHS) const {
+  llvm::StringRef Cur = getArgString(Index);
+  if (Cur.size() == LHS.size() + RHS.size() &&
+      Cur.startswith(LHS) && Cur.endswith(RHS))
+    return Cur.data();
+
+  return MakeArgString(LHS + RHS);
+}
+
 //
 
 InputArgList::InputArgList(const char **ArgBegin, const char **ArgEnd)
-  : ArgList(ActualArgs), NumInputArgStrings(ArgEnd - ArgBegin) {
+  : NumInputArgStrings(ArgEnd - ArgBegin) {
   ArgStrings.append(ArgBegin, ArgEnd);
 }
 
@@ -201,9 +250,8 @@
 
 //
 
-DerivedArgList::DerivedArgList(InputArgList &_BaseArgs, bool _OnlyProxy)
-  : ArgList(_OnlyProxy ? _BaseArgs.getArgs() : ActualArgs),
-    BaseArgs(_BaseArgs), OnlyProxy(_OnlyProxy) {
+DerivedArgList::DerivedArgList(const InputArgList &_BaseArgs)
+  : BaseArgs(_BaseArgs) {
 }
 
 DerivedArgList::~DerivedArgList() {
@@ -218,30 +266,33 @@
 }
 
 Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option *Opt) const {
-  Arg *A = new FlagArg(Opt, BaseArgs.MakeIndex(Opt->getName()), BaseArg);
+  Arg *A = new Arg(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);
+  unsigned Index = BaseArgs.MakeIndex(Value);
+  Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index), 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);
+  unsigned Index = BaseArgs.MakeIndex(Opt->getName(), Value);
+  Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index + 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);
+  unsigned Index = BaseArgs.MakeIndex(Opt->getName() + Value.str());
+  Arg *A = new Arg(Opt, Index,
+                   BaseArgs.getArgString(Index) + strlen(Opt->getName()),
+                   BaseArg);
   SynthesizedArgs.push_back(A);
   return A;
 }
diff --git a/lib/Driver/CC1AsOptions.cpp b/lib/Driver/CC1AsOptions.cpp
new file mode 100644
index 0000000..90c69ff
--- /dev/null
+++ b/lib/Driver/CC1AsOptions.cpp
@@ -0,0 +1,39 @@
+//===--- CC1AsOptions.cpp - Clang Assembler 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/CC1AsOptions.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::cc1asoptions;
+
+static const OptTable::Info CC1AsInfoTable[] = {
+#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/CC1AsOptions.inc"
+};
+
+namespace {
+
+class CC1AsOptTable : public OptTable {
+public:
+  CC1AsOptTable()
+    : OptTable(CC1AsInfoTable,
+               sizeof(CC1AsInfoTable) / sizeof(CC1AsInfoTable[0])) {}
+};
+
+}
+
+OptTable *clang::driver::createCC1AsOptTable() {
+  return new CC1AsOptTable();
+}
diff --git a/lib/Driver/CC1Options.cpp b/lib/Driver/CC1Options.cpp
index 0e98bb9..14cf090 100644
--- a/lib/Driver/CC1Options.cpp
+++ b/lib/Driver/CC1Options.cpp
@@ -1,4 +1,4 @@
-//===--- CC1Options.cpp - Clang CC1 Options Table -----------------------*-===//
+//===--- CC1Options.cpp - Clang CC1 Options Table -------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
index 7efcd8a..00d076b 100644
--- a/lib/Driver/CMakeLists.txt
+++ b/lib/Driver/CMakeLists.txt
@@ -5,6 +5,7 @@
   Arg.cpp
   ArgList.cpp
   CC1Options.cpp
+  CC1AsOptions.cpp
   Compilation.cpp
   Driver.cpp
   DriverOptions.cpp
@@ -20,4 +21,5 @@
   Types.cpp
   )
 
-add_dependencies(clangDriver ClangDiagnosticDriver ClangDriverOptions ClangCC1Options)
+add_dependencies(clangDriver ClangAttrList ClangDiagnosticDriver
+                 ClangDriverOptions ClangCC1Options ClangCC1AsOptions)
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index 227f79a..c059afd 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -22,20 +22,22 @@
 #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(const Driver &D, const ToolChain &_DefaultToolChain,
+                         InputArgList *_Args, DerivedArgList *_TranslatedArgs)
+  : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args),
+    TranslatedArgs(_TranslatedArgs) {
 }
 
 Compilation::~Compilation() {
+  delete TranslatedArgs;
   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;
+    if (it->second != TranslatedArgs)
+      delete it->second;
 
   // Free the actions, if built.
   for (ActionList::iterator it = Actions.begin(), ie = Actions.end();
@@ -49,8 +51,11 @@
     TC = &DefaultToolChain;
 
   DerivedArgList *&Entry = TCArgs[std::make_pair(TC, BoundArch)];
-  if (!Entry)
-    Entry = TC->TranslateArgs(*Args, BoundArch);
+  if (!Entry) {
+    Entry = TC->TranslateArgs(*TranslatedArgs, BoundArch);
+    if (!Entry)
+      Entry = TranslatedArgs;
+  }
 
   return *Entry;
 }
@@ -78,10 +83,6 @@
       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
@@ -185,14 +186,6 @@
                             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
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 7371a93..82f9134 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -25,6 +25,7 @@
 
 #include "clang/Basic/Version.h"
 
+#include "llvm/Config/config.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/Support/PrettyStackTrace.h"
@@ -39,16 +40,13 @@
 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,
+Driver::Driver(llvm::StringRef _ClangExecutable,
                llvm::StringRef _DefaultHostTriple,
                llvm::StringRef _DefaultImageName,
                bool IsProduction, bool CXXIsProduction,
                Diagnostic &_Diags)
   : Opts(createDriverOptTable()), Diags(_Diags),
-    Name(_Name), Dir(_Dir), DefaultHostTriple(_DefaultHostTriple),
+    ClangExecutable(_ClangExecutable), DefaultHostTriple(_DefaultHostTriple),
     DefaultImageName(_DefaultImageName),
     DriverTitle("clang \"gcc-compatible\" driver"),
     Host(0),
@@ -71,6 +69,10 @@
       CCCUseClangCXX = false;
   }
 
+  llvm::sys::Path Executable(ClangExecutable);
+  Name = Executable.getBasename();
+  Dir = Executable.getDirname();
+
   // Compute the path to the resource directory.
   llvm::sys::Path P(Dir);
   P.eraseComponent(); // Remove /bin from foo/bin
@@ -110,6 +112,67 @@
   return Args;
 }
 
+DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
+  DerivedArgList *DAL = new DerivedArgList(Args);
+
+  for (ArgList::const_iterator it = Args.begin(),
+         ie = Args.end(); it != ie; ++it) {
+    const Arg *A = *it;
+
+    // Unfortunately, we have to parse some forwarding options (-Xassembler,
+    // -Xlinker, -Xpreprocessor) because we either integrate their functionality
+    // (assembler and preprocessor), or bypass a previous driver ('collect2').
+
+    // Rewrite linker options, to replace --no-demangle with a custom internal
+    // option.
+    if ((A->getOption().matches(options::OPT_Wl_COMMA) ||
+         A->getOption().matches(options::OPT_Xlinker)) &&
+        A->containsValue("--no-demangle")) {
+      // Add the rewritten no-demangle argument.
+      DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_Xlinker__no_demangle));
+
+      // Add the remaining values as Xlinker arguments.
+      for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
+        if (llvm::StringRef(A->getValue(Args, i)) != "--no-demangle")
+          DAL->AddSeparateArg(A, Opts->getOption(options::OPT_Xlinker),
+                              A->getValue(Args, i));
+
+      continue;
+    }
+
+    // Rewrite preprocessor options, to replace -Wp,-MD,FOO which is used by
+    // some build systems. We don't try to be complete here because we don't
+    // care to encourage this usage model.
+    if (A->getOption().matches(options::OPT_Wp_COMMA) &&
+        A->getNumValues() == 2 &&
+        (A->getValue(Args, 0) == llvm::StringRef("-MD") ||
+         A->getValue(Args, 0) == llvm::StringRef("-MMD"))) {
+      // Rewrite to -MD/-MMD along with -MF.
+      if (A->getValue(Args, 0) == llvm::StringRef("-MD"))
+        DAL->AddFlagArg(A, Opts->getOption(options::OPT_MD));
+      else
+        DAL->AddFlagArg(A, Opts->getOption(options::OPT_MMD));
+      DAL->AddSeparateArg(A, Opts->getOption(options::OPT_MF),
+                          A->getValue(Args, 1));
+      continue;
+    }
+
+    DAL->append(*it);
+  }
+
+  // Add a default value of -mlinker-version=, if one was given and the user
+  // didn't specify one.
+#if defined(HOST_LINK_VERSION)
+  if (!Args.hasArg(options::OPT_mlinker_version_EQ)) {
+    DAL->AddJoinedArg(0, Opts->getOption(options::OPT_mlinker_version_EQ),
+                      HOST_LINK_VERSION);
+    DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim();
+  }
+#endif
+
+  return DAL;
+}
+
 Compilation *Driver::BuildCompilation(int argc, const char **argv) {
   llvm::PrettyStackTraceString CrashInfo("Compilation construction");
 
@@ -123,13 +186,15 @@
   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);
 
+  // Ignore -pipe.
+  Args->ClaimAllArgs(options::OPT_pipe);
+
   // Extract -ccc args.
   //
   // FIXME: We need to figure out where this behavior should live. Most of it
@@ -170,35 +235,39 @@
       Cur = Split.second;
     }
   }
+  // FIXME: We shouldn't overwrite the default host triple here, but we have
+  // nowhere else to put this currently.
   if (const Arg *A = Args->getLastArg(options::OPT_ccc_host_triple))
-    HostTriple = A->getValue(*Args);
+    DefaultHostTriple = A->getValue(*Args);
   if (const Arg *A = Args->getLastArg(options::OPT_ccc_install_dir))
-    Dir = A->getValue(*Args);
+    Dir = InstalledDir = A->getValue(*Args);
   if (const Arg *A = Args->getLastArg(options::OPT_B))
     PrefixDir = A->getValue(*Args);
 
-  Host = GetHostInfo(HostTriple);
+  Host = GetHostInfo(DefaultHostTriple.c_str());
+
+  // Perform the default argument translations.
+  DerivedArgList *TranslatedArgs = TranslateInputArgs(*Args);
 
   // The compilation takes ownership of Args.
-  Compilation *C = new Compilation(*this, *Host->CreateToolChain(*Args), Args);
+  Compilation *C = new Compilation(*this, *Host->CreateToolChain(*Args), Args,
+                                   TranslatedArgs);
 
   // FIXME: This behavior shouldn't be here.
   if (CCCPrintOptions) {
-    PrintOptions(C->getArgs());
+    PrintOptions(C->getInputArgs());
     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).
+  // Construct the list of abstract actions to perform for this compilation.
   if (Host->useDriverDriver())
-    BuildUniversalActions(C->getArgs(), C->getActions());
+    BuildUniversalActions(C->getDefaultToolChain(), C->getArgs(),
+                          C->getActions());
   else
-    BuildActions(C->getArgs(), C->getActions());
+    BuildActions(C->getDefaultToolChain(), C->getArgs(), C->getActions());
 
   if (CCCPrintActions) {
     PrintActions(*C);
@@ -227,28 +296,31 @@
   // 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))
+  // If the command succeeded, we are done.
+  if (Res == 0)
+    return Res;
+
+  // Otherwise, remove result files as well.
+  if (!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();
+  //
+  // 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 Tool &FailingTool = FailingCommand->getCreator();
 
-    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;
-    }
+  if (!FailingCommand->getCreator().hasGoodDiagnostics() || Res != 1) {
+    // FIXME: See FIXME above regarding result code interpretation.
+    if (Res < 0)
+      Diag(clang::diag::err_drv_command_signalled)
+        << FailingTool.getShortName() << -Res;
+    else
+      Diag(clang::diag::err_drv_command_failed)
+        << FailingTool.getShortName() << Res;
   }
 
   return Res;
@@ -271,8 +343,6 @@
   }
 }
 
-// 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);
@@ -291,8 +361,16 @@
   OS << "Thread model: " << "posix" << '\n';
 }
 
+/// PrintDiagnosticCategories - Implement the --print-diagnostic-categories
+/// option.
+static void PrintDiagnosticCategories(llvm::raw_ostream &OS) {
+  for (unsigned i = 1; // Skip the empty category.
+       const char *CategoryName = Diagnostic::getCategoryNameFromID(i); ++i)
+    OS << i << ',' << CategoryName << '\n';
+}
+
 bool Driver::HandleImmediateArgs(const Compilation &C) {
-  // The order these options are handled in in gcc is all over the place, but we
+  // The order these options are handled 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)) {
@@ -300,6 +378,11 @@
     return false;
   }
 
+  if (C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) {
+    PrintDiagnosticCategories(llvm::outs());
+    return false;
+  }
+
   if (C.getArgs().hasArg(options::OPT__help) ||
       C.getArgs().hasArg(options::OPT__help_hidden)) {
     PrintHelp(C.getArgs().hasArg(options::OPT__help_hidden));
@@ -441,7 +524,21 @@
     PrintActions1(C, *it, Ids);
 }
 
-void Driver::BuildUniversalActions(const ArgList &Args,
+/// \brief Check whether the given input tree contains any compilation (or
+/// assembly) actions.
+static bool ContainsCompileAction(const Action *A) {
+  if (isa<CompileJobAction>(A) || isa<AssembleJobAction>(A))
+    return true;
+
+  for (Action::const_iterator it = A->begin(), ie = A->end(); it != ie; ++it)
+    if (ContainsCompileAction(*it))
+      return true;
+
+  return false;
+}
+
+void Driver::BuildUniversalActions(const ToolChain &TC,
+                                   const ArgList &Args,
                                    ActionList &Actions) const {
   llvm::PrettyStackTraceString CrashInfo("Building universal build actions");
   // Collect the list of architectures. Duplicates are allowed, but should only
@@ -486,9 +583,10 @@
   }
 
   ActionList SingleActions;
-  BuildActions(Args, SingleActions);
+  BuildActions(TC, Args, SingleActions);
 
-  // Add in arch binding and lipo (if necessary) for every top level action.
+  // Add in arch bindings for every top level action, as well as lipo and
+  // dsymutil steps if needed.
   for (unsigned i = 0, e = SingleActions.size(); i != e; ++i) {
     Action *Act = SingleActions[i];
 
@@ -515,10 +613,28 @@
       Actions.append(Inputs.begin(), Inputs.end());
     else
       Actions.push_back(new LipoJobAction(Inputs, Act->getType()));
+
+    // Add a 'dsymutil' step if necessary, when debug info is enabled and we
+    // have a compile input. We need to run 'dsymutil' ourselves in such cases
+    // because the debug info will refer to a temporary object file which is
+    // will be removed at the end of the compilation process.
+    if (Act->getType() == types::TY_Image) {
+      Arg *A = Args.getLastArg(options::OPT_g_Group);
+      if (A && !A->getOption().matches(options::OPT_g0) &&
+          !A->getOption().matches(options::OPT_gstabs) &&
+          ContainsCompileAction(Actions.back())) {
+        ActionList Inputs;
+        Inputs.push_back(Actions.back());
+        Actions.pop_back();
+
+        Actions.push_back(new DsymutilJobAction(Inputs, types::TY_dSYM));
+      }
+    }
   }
 }
 
-void Driver::BuildActions(const ArgList &Args, ActionList &Actions) const {
+void Driver::BuildActions(const ToolChain &TC, const ArgList &Args,
+                          ActionList &Actions) const {
   llvm::PrettyStackTraceString CrashInfo("Building compilation actions");
   // Start by constructing the list of inputs and their types.
 
@@ -558,7 +674,7 @@
           // 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);
+            Ty = TC.LookupTypeForExtension(Ext + 1);
 
           if (Ty == types::TY_INVALID)
             Ty = types::TY_Object;
@@ -767,7 +883,7 @@
     } 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;
+        Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
       return new CompileJobAction(Input, Output);
     } else {
       return new CompileJobAction(Input, types::TY_PP_Asm);
@@ -783,16 +899,6 @@
 
 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);
 
@@ -832,7 +938,6 @@
     InputInfo II;
     BuildJobsForAction(C, A, &C.getDefaultToolChain(),
                        /*BoundArch*/0,
-                       /*CanAcceptPipe*/ true,
                        /*AtTopLevel*/ true,
                        /*LinkingOutput*/ LinkingOutput,
                        II);
@@ -889,9 +994,16 @@
   // 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,
+
+  // FIXME: This doesn't belong here, but ideally we will support static soon
+  // anyway.
+  bool HasStatic = (C.getArgs().hasArg(options::OPT_mkernel) ||
+                    C.getArgs().hasArg(options::OPT_static) ||
+                    C.getArgs().hasArg(options::OPT_fapple_kext));
+  bool IsIADefault = (TC->IsIntegratedAssemblerDefault() && !HasStatic);
+  if (C.getArgs().hasFlag(options::OPT_integrated_as,
                          options::OPT_no_integrated_as,
-                         TC->IsIntegratedAssemblerDefault()) &&
+                         IsIADefault) &&
       !C.getArgs().hasArg(options::OPT_save_temps) &&
       isa<AssembleJobAction>(JA) &&
       Inputs->size() == 1 && isa<CompileJobAction>(*Inputs->begin())) {
@@ -923,23 +1035,17 @@
                                 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)) {
+    if (Input.getOption().matches(options::OPT_INPUT)) {
       const char *Name = Input.getValue(C.getArgs());
       Result = InputInfo(Name, A->getType(), Name);
     } else
@@ -955,7 +1061,7 @@
       TC = Host->CreateToolChain(C.getArgs(), BAA->getArchName());
 
     BuildJobsForAction(C, *BAA->begin(), TC, BAA->getArchName(),
-                       CanAcceptPipe, AtTopLevel, LinkingOutput, Result);
+                       AtTopLevel, LinkingOutput, Result);
     return;
   }
 
@@ -965,57 +1071,34 @@
   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.
+    // Treat dsymutil sub-jobs as being at the top-level too, they shouldn't get
+    // temporary output names.
     //
-    // 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;
-  }
+    // FIXME: Clean this up.
+    bool SubJobAtTopLevel = false;
+    if (AtTopLevel && isa<DsymutilJobAction>(A))
+      SubJobAtTopLevel = 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();
+    InputInfo II;
+    BuildJobsForAction(C, *it, TC, BoundArch,
+                       SubJobAtTopLevel, LinkingOutput, II);
+    InputInfos.push_back(II);
   }
 
   // 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.
+  // ... except dsymutil actions, which use their actual input as the base
+  // input.
+  if (JA->getType() == types::TY_dSYM)
+    BaseInput = InputInfos[0].getFilename();
+
+  // Determine the place to write output to, if any.
   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);
@@ -1031,7 +1114,7 @@
     }
     llvm::errs() << "], output: " << Result.getAsString() << "\n";
   } else {
-    T.ConstructJob(C, *JA, *Dest, Result, InputInfos,
+    T.ConstructJob(C, *JA, Result, InputInfos,
                    C.getArgsForToolChain(TC, BoundArch), LinkingOutput);
   }
 }
@@ -1042,11 +1125,15 @@
                                        bool AtTopLevel) const {
   llvm::PrettyStackTraceString CrashInfo("Computing output path");
   // Output to a user requested destination?
-  if (AtTopLevel) {
+  if (AtTopLevel && !isa<DsymutilJobAction>(JA)) {
     if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
       return C.addResultFile(FinalOutput->getValue(C.getArgs()));
   }
 
+  // Default to writing to stdout?
+  if (AtTopLevel && isa<PreprocessJobAction>(JA))
+    return "-";
+
   // Output to a temporary file?
   if (!AtTopLevel && !C.getArgs().hasArg(options::OPT_save_temps)) {
     std::string TmpName =
@@ -1168,7 +1255,7 @@
 
   // TCE is an osless target
   if (Triple.getArchName() == "tce")
-    return createTCEHostInfo(*this, Triple); 
+    return createTCEHostInfo(*this, Triple);
 
   switch (Triple.getOS()) {
   case llvm::Triple::AuroraUX:
@@ -1181,8 +1268,15 @@
     return createOpenBSDHostInfo(*this, Triple);
   case llvm::Triple::FreeBSD:
     return createFreeBSDHostInfo(*this, Triple);
+  case llvm::Triple::Minix:
+    return createMinixHostInfo(*this, Triple);
   case llvm::Triple::Linux:
     return createLinuxHostInfo(*this, Triple);
+  case llvm::Triple::Win32:
+    return createWindowsHostInfo(*this, Triple);
+  case llvm::Triple::MinGW32:
+  case llvm::Triple::MinGW64:
+    return createMinGWHostInfo(*this, Triple);
   default:
     return createUnknownHostInfo(*this, Triple);
   }
@@ -1213,8 +1307,8 @@
 
   // 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)
+  if (isa<PrecompileJobAction>(JA) ||
+      types::isOnlyAcceptedByClang(JA.getType()))
     return true;
 
   // Finally, don't use clang if this isn't one of the user specified archs to
diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp
index d9e2e37..7c5e430 100644
--- a/lib/Driver/HostInfo.cpp
+++ b/lib/Driver/HostInfo.cpp
@@ -38,12 +38,6 @@
 
 /// 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;
 
@@ -53,37 +47,12 @@
 
   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() {
@@ -147,11 +116,10 @@
     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);
+      TC = new toolchains::DarwinClang(*this, TCTriple);
     } 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);
+      TC = new toolchains::DarwinGCC(*this, TCTriple);
     } else
       TC = new toolchains::Darwin_Generic_GCC(*this, TCTriple);
   }
@@ -170,15 +138,6 @@
 
   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;
 };
@@ -212,10 +171,6 @@
 
   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;
 };
@@ -279,10 +234,6 @@
 
   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;
 };
@@ -330,10 +281,6 @@
 
   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;
 };
@@ -379,10 +326,6 @@
 
   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;
 };
@@ -399,19 +342,22 @@
 
 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.
+  // Automatically handle some instances of -m32/-m64 we know about.
   std::string Arch = getArchName();
   ArchName = Arch.c_str();
-  if (Args.hasArg(options::OPT_m32) && getArchName() == "x86_64") {
-    ArchName = "i386";
-    Lib32 = true;
+  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];
@@ -419,7 +365,55 @@
     llvm::Triple TCTriple(getTriple());
     TCTriple.setArchName(ArchName);
 
-    TC = new toolchains::FreeBSD(*this, TCTriple, Lib32);
+    TC = new toolchains::FreeBSD(*this, TCTriple);
+  }
+
+  return TC;
+}
+
+// Minix Host Info
+
+/// MinixHostInfo -  Minix host information implementation.
+class MinixHostInfo : public HostInfo {
+  /// Cache of tool chains we have created.
+  mutable llvm::StringMap<ToolChain*> ToolChains;
+
+public:
+  MinixHostInfo(const Driver &D, const llvm::Triple& Triple)
+    : HostInfo(D, Triple) {}
+  ~MinixHostInfo();
+
+  virtual bool useDriverDriver() const;
+
+  virtual ToolChain *CreateToolChain(const ArgList &Args,
+                                     const char *ArchName) const;
+};
+
+MinixHostInfo::~MinixHostInfo() {
+  for (llvm::StringMap<ToolChain*>::iterator
+         it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it){
+    delete it->second;
+  }
+}
+
+bool MinixHostInfo::useDriverDriver() const {
+  return false;
+}
+
+ToolChain *MinixHostInfo::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::Minix(*this, TCTriple);
   }
 
   return TC;
@@ -439,10 +433,6 @@
 
   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;
 };
@@ -488,10 +478,6 @@
 
   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;
 };
@@ -539,8 +525,79 @@
   return TC;
 }
 
+// Windows Host Info
+
+/// WindowsHostInfo - Host information to use on Microsoft Windows.
+class WindowsHostInfo : public HostInfo {
+  /// Cache of tool chains we have created.
+  mutable llvm::StringMap<ToolChain*> ToolChains;
+
+public:
+  WindowsHostInfo(const Driver &D, const llvm::Triple& Triple);
+  ~WindowsHostInfo();
+
+  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;
+};
+
+WindowsHostInfo::WindowsHostInfo(const Driver &D, const llvm::Triple& Triple)
+  : HostInfo(D, Triple) {
 }
 
+WindowsHostInfo::~WindowsHostInfo() {
+  for (llvm::StringMap<ToolChain*>::iterator
+         it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
+    delete it->second;
+}
+
+bool WindowsHostInfo::useDriverDriver() const {
+  return false;
+}
+
+ToolChain *WindowsHostInfo::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";
+    }
+  }
+
+  ToolChain *&TC = ToolChains[ArchName];
+  if (!TC) {
+    llvm::Triple TCTriple(getTriple());
+    TCTriple.setArchName(ArchName);
+
+    TC = new toolchains::Windows(*this, TCTriple);
+  }
+
+  return TC;
+}
+
+// FIXME: This is a placeholder.
+class MinGWHostInfo : public UnknownHostInfo {
+public:
+  MinGWHostInfo(const Driver &D, const llvm::Triple& Triple);
+};
+
+MinGWHostInfo::MinGWHostInfo(const Driver &D, const llvm::Triple& Triple)
+  : UnknownHostInfo(D, Triple) {}
+
+} // end anon namespace
+
 const HostInfo *
 clang::driver::createAuroraUXHostInfo(const Driver &D,
                                       const llvm::Triple& Triple){
@@ -566,6 +623,12 @@
 }
 
 const HostInfo *
+clang::driver::createMinixHostInfo(const Driver &D,
+                                     const llvm::Triple& Triple) {
+  return new MinixHostInfo(D, Triple);
+}
+
+const HostInfo *
 clang::driver::createDragonFlyHostInfo(const Driver &D,
                                        const llvm::Triple& Triple) {
   return new DragonFlyHostInfo(D, Triple);
@@ -584,6 +647,18 @@
 }
 
 const HostInfo *
+clang::driver::createWindowsHostInfo(const Driver &D,
+                                     const llvm::Triple& Triple) {
+  return new WindowsHostInfo(D, Triple);
+}
+
+const HostInfo *
+clang::driver::createMinGWHostInfo(const Driver &D,
+                                   const llvm::Triple& Triple) {
+  return new MinGWHostInfo(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
index c657bef..2a2f4b9 100644
--- a/lib/Driver/InputInfo.h
+++ b/lib/Driver/InputInfo.h
@@ -17,7 +17,6 @@
 
 namespace clang {
 namespace driver {
-  class PipedJob;
 
 /// InputInfo - Wrapper for information about an input source.
 class InputInfo {
@@ -37,7 +36,6 @@
   union {
     const char *Filename;
     const Arg *InputArg;
-    PipedJob *Pipe;
   } Data;
   Class Kind;
   types::ID Type;
@@ -56,15 +54,10 @@
     : 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; }
 
@@ -76,17 +69,11 @@
     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())
+    if (isFilename())
       return std::string("\"") + getFilename() + '"';
     else if (isInputArg())
       return "(input arg)";
diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp
index bfeb41a..fa7d060 100644
--- a/lib/Driver/Job.cpp
+++ b/lib/Driver/Job.cpp
@@ -21,13 +21,6 @@
 {
 }
 
-PipedJob::PipedJob() : Job(PipedJobClass) {}
-
-PipedJob::~PipedJob() {
-  for (iterator it = begin(), ie = end(); it != ie; ++it)
-    delete *it;
-}
-
 JobList::JobList() : Job(JobListClass) {}
 
 JobList::~JobList() {
@@ -36,9 +29,6 @@
 }
 
 void Job::addCommand(Command *C) {
-  if (PipedJob *PJ = dyn_cast<PipedJob>(this))
-    PJ->addCommand(C);
-  else
-    cast<JobList>(this)->addJob(C);
+  cast<JobList>(this)->addJob(C);
 }
 
diff --git a/lib/Driver/Makefile b/lib/Driver/Makefile
index 371bda7..454ab86 100644
--- a/lib/Driver/Makefile
+++ b/lib/Driver/Makefile
@@ -7,10 +7,7 @@
 # 
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
+CLANG_LEVEL := ../..
 LIBRARYNAME := clangDriver
-BUILD_ARCHIVE = 1
 
-CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp
index de1e459..3c36314 100644
--- a/lib/Driver/OptTable.cpp
+++ b/lib/Driver/OptTable.cpp
@@ -164,17 +164,19 @@
     Opt->setLinkerInput(true);
   if (info.Flags & NoArgumentUnused)
     Opt->setNoArgumentUnused(true);
+  if (info.Flags & NoForward)
+    Opt->setNoForward(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);
+    Opt->setRenderStyle(Option::RenderJoinedStyle);
   }
   if (info.Flags & RenderSeparate) {
     assert((info.Kind == Option::JoinedOrSeparateClass ||
             info.Kind == Option::JoinedClass) && "Invalid option.");
-    Opt->setForceSeparateRender(true);
+    Opt->setRenderStyle(Option::RenderSeparateStyle);
   }
   if (info.Flags & Unsupported)
     Opt->setUnsupported(true);
@@ -182,13 +184,13 @@
   return Opt;
 }
 
-Arg *OptTable::ParseOneArg(const InputArgList &Args, unsigned &Index) const {
+Arg *OptTable::ParseOneArg(const ArgList &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++);
+    return new Arg(TheInputOption, Index++, Str);
 
   const Info *Start = OptionInfos + FirstSearchableIndex;
   const Info *End = OptionInfos + getNumOptions();
@@ -221,7 +223,7 @@
       return 0;
   }
 
-  return new PositionalArg(TheUnknownOption, Index++);
+  return new Arg(TheUnknownOption, Index++, Str);
 }
 
 InputArgList *OptTable::ParseArgs(const char **ArgBegin, const char **ArgEnd,
@@ -267,7 +269,7 @@
   case Option::GroupClass: case Option::InputClass: case Option::UnknownClass:
     assert(0 && "Invalid option with help text.");
 
-  case Option::MultiArgClass: case Option::JoinedAndSeparateClass:
+  case Option::MultiArgClass:
     assert(0 && "Cannot print metavar for this kind of option.");
 
   case Option::FlagClass:
@@ -277,6 +279,7 @@
     Name += ' ';
     // FALLTHROUGH
   case Option::JoinedClass: case Option::CommaJoinedClass:
+  case Option::JoinedAndSeparateClass:
     if (const char *MetaVarName = Opts.getOptionMetaVar(Id))
       Name += MetaVarName;
     else
diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp
index 17d00f5..5396250 100644
--- a/lib/Driver/Option.cpp
+++ b/lib/Driver/Option.cpp
@@ -20,14 +20,38 @@
                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) {
+    DriverOption(false), NoArgumentUnused(false), NoForward(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.");
+
+  // Initialize rendering options based on the class.
+  switch (Kind) {
+  case GroupClass:
+  case InputClass:
+  case UnknownClass:
+    RenderStyle = RenderValuesStyle;
+    break;
+
+  case JoinedClass:
+  case JoinedAndSeparateClass:
+    RenderStyle = RenderJoinedStyle;
+    break;
+
+  case CommaJoinedClass:
+    RenderStyle = RenderCommaJoinedStyle;
+    break;
+
+  case FlagClass:
+  case SeparateClass:
+  case MultiArgClass:
+  case JoinedOrSeparateClass:
+    RenderStyle = RenderSeparateStyle;
+    break;
+  }
 }
 
 Option::~Option() {
@@ -89,7 +113,7 @@
   : Option(Option::GroupClass, ID, Name, Group, 0) {
 }
 
-Arg *OptionGroup::accept(const InputArgList &Args, unsigned &Index) const {
+Arg *OptionGroup::accept(const ArgList &Args, unsigned &Index) const {
   assert(0 && "accept() should never be called on an OptionGroup");
   return 0;
 }
@@ -98,7 +122,7 @@
   : Option(Option::InputClass, ID, "<input>", 0, 0) {
 }
 
-Arg *InputOption::accept(const InputArgList &Args, unsigned &Index) const {
+Arg *InputOption::accept(const ArgList &Args, unsigned &Index) const {
   assert(0 && "accept() should never be called on an InputOption");
   return 0;
 }
@@ -107,7 +131,7 @@
   : Option(Option::UnknownClass, ID, "<unknown>", 0, 0) {
 }
 
-Arg *UnknownOption::accept(const InputArgList &Args, unsigned &Index) const {
+Arg *UnknownOption::accept(const ArgList &Args, unsigned &Index) const {
   assert(0 && "accept() should never be called on an UnknownOption");
   return 0;
 }
@@ -117,13 +141,13 @@
   : Option(Option::FlagClass, ID, Name, Group, Alias) {
 }
 
-Arg *FlagOption::accept(const InputArgList &Args, unsigned &Index) const {
+Arg *FlagOption::accept(const ArgList &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++);
+  return new Arg(getUnaliasedOption(), Index++);
 }
 
 JoinedOption::JoinedOption(OptSpecifier ID, const char *Name,
@@ -131,9 +155,10 @@
   : Option(Option::JoinedClass, ID, Name, Group, Alias) {
 }
 
-Arg *JoinedOption::accept(const InputArgList &Args, unsigned &Index) const {
+Arg *JoinedOption::accept(const ArgList &Args, unsigned &Index) const {
   // Always matches.
-  return new JoinedArg(this, Index++);
+  const char *Value = Args.getArgString(Index) + strlen(getName());
+  return new Arg(getUnaliasedOption(), Index++, Value);
 }
 
 CommaJoinedOption::CommaJoinedOption(OptSpecifier ID, const char *Name,
@@ -142,15 +167,34 @@
   : Option(Option::CommaJoinedClass, ID, Name, Group, Alias) {
 }
 
-Arg *CommaJoinedOption::accept(const InputArgList &Args,
+Arg *CommaJoinedOption::accept(const ArgList &Args,
                                unsigned &Index) const {
-  // Always matches. We count the commas now so we can answer
-  // getNumValues easily.
+  // Always matches.
+  const char *Str = Args.getArgString(Index) + strlen(getName());
+  Arg *A = new Arg(getUnaliasedOption(), Index++);
 
-  // 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);
+  // Parse out the comma separated values.
+  const char *Prev = Str;
+  for (;; ++Str) {
+    char c = *Str;
+
+    if (!c || c == ',') {
+      if (Prev != Str) {
+        char *Value = new char[Str - Prev + 1];
+        memcpy(Value, Prev, Str - Prev);
+        Value[Str - Prev] = '\0';
+        A->getValues().push_back(Value);
+      }
+
+      if (!c)
+        break;
+
+      Prev = Str + 1;
+    }
+  }
+  A->setOwnsValues(true);
+
+  return A;
 }
 
 SeparateOption::SeparateOption(OptSpecifier ID, const char *Name,
@@ -158,7 +202,7 @@
   : Option(Option::SeparateClass, ID, Name, Group, Alias) {
 }
 
-Arg *SeparateOption::accept(const InputArgList &Args, unsigned &Index) const {
+Arg *SeparateOption::accept(const ArgList &Args, unsigned &Index) const {
   // Matches iff this is an exact match.
   // FIXME: Avoid strlen.
   if (strlen(getName()) != strlen(Args.getArgString(Index)))
@@ -168,7 +212,7 @@
   if (Index > Args.getNumInputArgStrings())
     return 0;
 
-  return new SeparateArg(this, Index - 2, 1);
+  return new Arg(getUnaliasedOption(), Index - 2, Args.getArgString(Index - 1));
 }
 
 MultiArgOption::MultiArgOption(OptSpecifier ID, const char *Name,
@@ -178,7 +222,7 @@
   assert(NumArgs > 1  && "Invalid MultiArgOption!");
 }
 
-Arg *MultiArgOption::accept(const InputArgList &Args, unsigned &Index) const {
+Arg *MultiArgOption::accept(const ArgList &Args, unsigned &Index) const {
   // Matches iff this is an exact match.
   // FIXME: Avoid strlen.
   if (strlen(getName()) != strlen(Args.getArgString(Index)))
@@ -188,28 +232,35 @@
   if (Index > Args.getNumInputArgStrings())
     return 0;
 
-  return new SeparateArg(this, Index - 1 - NumArgs, NumArgs);
+  Arg *A = new Arg(getUnaliasedOption(), Index - 1 - NumArgs,
+                   Args.getArgString(Index - NumArgs));
+  for (unsigned i = 1; i != NumArgs; ++i)
+    A->getValues().push_back(Args.getArgString(Index - NumArgs + i));
+  return A;
 }
 
-JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
+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,
+Arg *JoinedOrSeparateOption::accept(const ArgList &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++);
+  if (strlen(getName()) != strlen(Args.getArgString(Index))) {
+    const char *Value = Args.getArgString(Index) + strlen(getName());
+    return new Arg(this, Index++, Value);
+  }
 
   // Otherwise it must be separate.
   Index += 2;
   if (Index > Args.getNumInputArgStrings())
     return 0;
 
-  return new SeparateArg(this, Index - 2, 1);
+  return new Arg(getUnaliasedOption(), Index - 2, Args.getArgString(Index - 1));
 }
 
 JoinedAndSeparateOption::JoinedAndSeparateOption(OptSpecifier ID,
@@ -219,7 +270,7 @@
   : Option(Option::JoinedAndSeparateClass, ID, Name, Group, Alias) {
 }
 
-Arg *JoinedAndSeparateOption::accept(const InputArgList &Args,
+Arg *JoinedAndSeparateOption::accept(const ArgList &Args,
                                      unsigned &Index) const {
   // Always matches.
 
@@ -227,6 +278,7 @@
   if (Index > Args.getNumInputArgStrings())
     return 0;
 
-  return new JoinedAndSeparateArg(this, Index - 2);
+  return new Arg(getUnaliasedOption(), Index - 2,
+                 Args.getArgString(Index-2)+strlen(getName()),
+                 Args.getArgString(Index-1));
 }
-
diff --git a/lib/Driver/Tool.cpp b/lib/Driver/Tool.cpp
index 781e0a7..fe01531 100644
--- a/lib/Driver/Tool.cpp
+++ b/lib/Driver/Tool.cpp
@@ -11,8 +11,10 @@
 
 using namespace clang::driver;
 
-Tool::Tool(const char *_Name, const ToolChain &TC) : Name(_Name),
-                                                     TheToolChain(TC) {
+Tool::Tool(const char *_Name, const char *_ShortName,
+           const ToolChain &TC) : Name(_Name), ShortName(_ShortName),
+                                  TheToolChain(TC)
+{
 }
 
 Tool::~Tool() {
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
index 9b6264a..94c1c6b 100644
--- a/lib/Driver/ToolChain.cpp
+++ b/lib/Driver/ToolChain.cpp
@@ -10,8 +10,12 @@
 #include "clang/Driver/ToolChain.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/HostInfo.h"
+#include "clang/Driver/Options.h"
 
 using namespace clang::driver;
 
@@ -26,14 +30,147 @@
  return Host.getDriver();
 }
 
-std::string ToolChain::GetFilePath(const Compilation &C,
-                                   const char *Name) const {
+std::string ToolChain::GetFilePath(const char *Name) const {
   return Host.getDriver().GetFilePath(Name, *this);
 
 }
 
-std::string ToolChain::GetProgramPath(const Compilation &C,
-                                      const char *Name,
-                                      bool WantFile) const {
+std::string ToolChain::GetProgramPath(const char *Name, bool WantFile) const {
   return Host.getDriver().GetProgramPath(Name, *this, WantFile);
 }
+
+types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
+  return types::lookupTypeForExtension(Ext);
+}
+
+/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting.
+//
+// FIXME: tblgen this.
+static const char *getARMTargetCPU(const ArgList &Args,
+                                   const llvm::Triple &Triple) {
+  // 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);
+
+  llvm::StringRef MArch;
+  if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
+    // Otherwise, if we have -march= choose the base CPU for that arch.
+    MArch = A->getValue(Args);
+  } else {
+    // Otherwise, use the Arch from the triple.
+    MArch = Triple.getArchName();
+  }
+
+  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";
+
+  // If all else failed, 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 "";
+}
+
+std::string ToolChain::ComputeLLVMTriple(const ArgList &Args) const {
+  switch (getTriple().getArch()) {
+  default:
+    return getTripleString();
+
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb: {
+    // FIXME: Factor into subclasses.
+    llvm::Triple Triple = 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, Triple));
+    bool ThumbDefault =
+      (Suffix == "v7" && 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();
+  }
+  }
+}
+
+std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args) const {
+  // 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))
+    getDriver().Diag(clang::diag::err_drv_clang_unsupported)
+      << A->getAsString(Args);
+
+  return ComputeLLVMTriple(Args);
+}
+
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 1cd8ee1..f5ed56b 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -11,6 +11,7 @@
 
 #include "clang/Driver/Arg.h"
 #include "clang/Driver/ArgList.h"
+#include "clang/Driver/Compilation.h"
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/HostInfo.h"
@@ -18,6 +19,7 @@
 #include "clang/Driver/Option.h"
 #include "clang/Driver/Options.h"
 
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
@@ -30,13 +32,30 @@
 
 /// Darwin - Darwin tool chain for i386 and x86_64.
 
-Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple,
-               const unsigned (&_DarwinVersion)[3])
+Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple)
   : ToolChain(Host, Triple), TargetInitialized(false)
 {
+  // Compute the initial Darwin version based on the host.
+  bool HadExtra;
+  std::string OSName = Triple.getOSName();
+  if (!Driver::GetReleaseVersion(&OSName[6],
+                                 DarwinVersion[0], DarwinVersion[1],
+                                 DarwinVersion[2], HadExtra))
+    getDriver().Diag(clang::diag::err_drv_invalid_darwin_version) << OSName;
+
   llvm::raw_string_ostream(MacosxVersionMin)
-    << "10." << std::max(0, (int)_DarwinVersion[0] - 4) << '.'
-    << _DarwinVersion[1];
+    << "10." << std::max(0, (int)DarwinVersion[0] - 4) << '.'
+    << DarwinVersion[1];
+}
+
+types::ID Darwin::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;
 }
 
 // FIXME: Can we tablegen this?
@@ -102,14 +121,13 @@
   }
 }
 
-DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple,
-                     const unsigned (&DarwinVersion)[3],
-                     const unsigned (&_GCCVersion)[3])
-  : Darwin(Host, Triple, DarwinVersion)
+DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple)
+  : Darwin(Host, Triple)
 {
-  GCCVersion[0] = _GCCVersion[0];
-  GCCVersion[1] = _GCCVersion[1];
-  GCCVersion[2] = _GCCVersion[2];
+  // We can only work with 4.2.1 currently.
+  GCCVersion[0] = 4;
+  GCCVersion[1] = 2;
+  GCCVersion[2] = 1;
 
   // Set up the tool chain paths to match gcc.
   ToolChainDir = "i686-apple-darwin";
@@ -173,7 +191,9 @@
   Path += ToolChainDir;
   getProgramPaths().push_back(Path);
 
-  getProgramPaths().push_back(getDriver().Dir);
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir)
+    getProgramPaths().push_back(getDriver().Dir);
 }
 
 Darwin::~Darwin() {
@@ -183,6 +203,38 @@
     delete it->second;
 }
 
+std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args) const {
+  llvm::Triple Triple(ComputeLLVMTriple(Args));
+
+  // If the target isn't initialized (e.g., an unknown Darwin platform, return
+  // the default triple).
+  if (!isTargetInitialized())
+    return Triple.getTriple();
+    
+  unsigned Version[3];
+  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 (!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();
+}
+
 Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const {
   Action::ActionClass Key;
   if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
@@ -190,6 +242,16 @@
   else
     Key = JA.getKind();
 
+  // FIXME: This doesn't belong here, but ideally we will support static soon
+  // anyway.
+  bool HasStatic = (C.getArgs().hasArg(options::OPT_mkernel) ||
+                    C.getArgs().hasArg(options::OPT_static) ||
+                    C.getArgs().hasArg(options::OPT_fapple_kext));
+  bool IsIADefault = IsIntegratedAssemblerDefault() && !HasStatic;
+  bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
+                                             options::OPT_no_integrated_as,
+                                             IsIADefault);
+
   Tool *&T = Tools[Key];
   if (!T) {
     switch (Key) {
@@ -203,12 +265,19 @@
     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::AssembleJobClass: {
+      if (UseIntegratedAs)
+        T = new tools::ClangAs(*this);
+      else
+        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;
+    case Action::DsymutilJobClass:
+      T = new tools::darwin::Dsymutil(*this); break;
     }
   }
 
@@ -227,7 +296,7 @@
     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;
@@ -296,17 +365,78 @@
   }
 }
 
-DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple,
-                         const unsigned (&DarwinVersion)[3])
-  : Darwin(Host, Triple, DarwinVersion)
+DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple)
+  : Darwin(Host, Triple)
 {
   // We expect 'as', 'ld', etc. to be adjacent to our install dir.
-  getProgramPaths().push_back(getDriver().Dir);
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir)
+    getProgramPaths().push_back(getDriver().Dir);
 }
 
 void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args,
                                        ArgStringList &CmdArgs) const {
   // The Clang toolchain uses explicit paths for internal libraries.
+
+  // Unfortunately, we still might depend on a few of the libraries that are
+  // only available in the gcc library directory (in particular
+  // libstdc++.dylib). For now, hardcode the path to the known install location.
+  llvm::sys::Path P(getDriver().Dir);
+  P.eraseComponent(); // .../usr/bin -> ../usr
+  P.appendComponent("lib");
+  P.appendComponent("gcc");
+  switch (getTriple().getArch()) {
+  default:
+    assert(0 && "Invalid Darwin arch!");
+  case llvm::Triple::x86:
+  case llvm::Triple::x86_64:
+    P.appendComponent("i686-apple-darwin10");
+    break;
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    P.appendComponent("arm-apple-darwin10");
+    break;
+  case llvm::Triple::ppc:
+  case llvm::Triple::ppc64:
+    P.appendComponent("powerpc-apple-darwin10");
+    break;
+  }
+  P.appendComponent("4.2.1");
+
+  // Determine the arch specific GCC subdirectory.
+  const char *ArchSpecificDir = 0;
+  switch (getTriple().getArch()) {
+  default:
+    break;
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb: {
+    std::string Triple = ComputeLLVMTriple(Args);
+    llvm::StringRef TripleStr = Triple;
+    if (TripleStr.startswith("armv5") || TripleStr.startswith("thumbv5"))
+      ArchSpecificDir = "v5";
+    else if (TripleStr.startswith("armv6") || TripleStr.startswith("thumbv6"))
+      ArchSpecificDir = "v6";
+    else if (TripleStr.startswith("armv7") || TripleStr.startswith("thumbv7"))
+      ArchSpecificDir = "v7";
+    break;
+  }
+  case llvm::Triple::ppc64:
+    ArchSpecificDir = "ppc64";
+    break;
+  case llvm::Triple::x86_64:
+    ArchSpecificDir = "x86_64";
+    break;
+  }
+
+  if (ArchSpecificDir) {
+    P.appendComponent(ArchSpecificDir);
+    if (P.exists())
+      CmdArgs.push_back(Args.MakeArgString("-L" + P.str()));
+    P.eraseComponent();
+  }
+
+  if (P.exists())
+    CmdArgs.push_back(Args.MakeArgString("-L" + P.str()));
 }
 
 void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
@@ -370,18 +500,9 @@
   }
 }
 
-DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
-                                      const char *BoundArch) const {
-  DerivedArgList *DAL = new DerivedArgList(Args, false);
+void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
   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) {
@@ -417,26 +538,17 @@
 
     if (OSXTarget) {
       const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
-      OSXVersion = DAL->MakeJoinedArg(0, O, OSXTarget);
-      DAL->append(OSXVersion);
+      OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget);
+      Args.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);
+      iPhoneVersion = Args.MakeJoinedArg(0, O, iPhoneOSTarget);
+      Args.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);
-      }
+      // Otherwise, assume we are targeting OS X.
+      const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
+      OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin);
+      Args.append(OSXVersion);
     }
   }
 
@@ -459,8 +571,22 @@
         << iPhoneVersion->getAsString(Args);
   }
   setTarget(iPhoneVersion, Major, Minor, Micro);
+}
 
-  for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) {
+DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
+                                      const char *BoundArch) const {
+  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
+  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.
+
+  for (ArgList::const_iterator it = Args.begin(),
+         ie = Args.end(); it != ie; ++it) {
     Arg *A = *it;
 
     if (A->getOption().matches(options::OPT_Xarch__)) {
@@ -468,9 +594,8 @@
       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;
+      unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(Args, 1));
+      unsigned Prev = Index;
       Arg *XarchArg = Opts.ParseOneArg(Args, Index);
 
       // If the argument parsing failed or more than one argument was
@@ -490,6 +615,8 @@
 
       XarchArg->setBaseArg(A);
       A = XarchArg;
+
+      DAL->AddSynthesizedArg(A);
     }
 
     // Sob. These is strictly gcc compatible for the time being. Apple
@@ -503,66 +630,61 @@
     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)));
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
+      DAL->AddFlagArg(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)));
+      DAL->AddSeparateArg(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)));
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
+      DAL->AddFlagArg(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)));
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
+      DAL->AddFlagArg(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)));
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_fapple_kext));
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
       break;
 
     case options::OPT_shared:
-      DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_dynamiclib)));
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
       break;
 
     case options::OPT_fconstant_cfstrings:
-      DAL->append(DAL->MakeFlagArg(A,
-                             Opts.getOption(options::OPT_mconstant_cfstrings)));
+      DAL->AddFlagArg(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)));
+      DAL->AddFlagArg(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)));
+      DAL->AddFlagArg(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)));
+      DAL->AddFlagArg(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)));
+      DAL->AddFlagArg(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)));
+      DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings));
       break;
     }
   }
@@ -570,8 +692,7 @@
   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"));
+      DAL->AddJoinedArg(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.
@@ -585,62 +706,67 @@
     if (Name == "ppc")
       ;
     else if (Name == "ppc601")
-      DAL->append(DAL->MakeJoinedArg(0, MCpu, "601"));
+      DAL->AddJoinedArg(0, MCpu, "601");
     else if (Name == "ppc603")
-      DAL->append(DAL->MakeJoinedArg(0, MCpu, "603"));
+      DAL->AddJoinedArg(0, MCpu, "603");
     else if (Name == "ppc604")
-      DAL->append(DAL->MakeJoinedArg(0, MCpu, "604"));
+      DAL->AddJoinedArg(0, MCpu, "604");
     else if (Name == "ppc604e")
-      DAL->append(DAL->MakeJoinedArg(0, MCpu, "604e"));
+      DAL->AddJoinedArg(0, MCpu, "604e");
     else if (Name == "ppc750")
-      DAL->append(DAL->MakeJoinedArg(0, MCpu, "750"));
+      DAL->AddJoinedArg(0, MCpu, "750");
     else if (Name == "ppc7400")
-      DAL->append(DAL->MakeJoinedArg(0, MCpu, "7400"));
+      DAL->AddJoinedArg(0, MCpu, "7400");
     else if (Name == "ppc7450")
-      DAL->append(DAL->MakeJoinedArg(0, MCpu, "7450"));
+      DAL->AddJoinedArg(0, MCpu, "7450");
     else if (Name == "ppc970")
-      DAL->append(DAL->MakeJoinedArg(0, MCpu, "970"));
+      DAL->AddJoinedArg(0, MCpu, "970");
 
     else if (Name == "ppc64")
-      DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
+      DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
 
     else if (Name == "i386")
       ;
     else if (Name == "i486")
-      DAL->append(DAL->MakeJoinedArg(0, MArch, "i486"));
+      DAL->AddJoinedArg(0, MArch, "i486");
     else if (Name == "i586")
-      DAL->append(DAL->MakeJoinedArg(0, MArch, "i586"));
+      DAL->AddJoinedArg(0, MArch, "i586");
     else if (Name == "i686")
-      DAL->append(DAL->MakeJoinedArg(0, MArch, "i686"));
+      DAL->AddJoinedArg(0, MArch, "i686");
     else if (Name == "pentium")
-      DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium"));
+      DAL->AddJoinedArg(0, MArch, "pentium");
     else if (Name == "pentium2")
-      DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium2"));
+      DAL->AddJoinedArg(0, MArch, "pentium2");
     else if (Name == "pentpro")
-      DAL->append(DAL->MakeJoinedArg(0, MArch, "pentiumpro"));
+      DAL->AddJoinedArg(0, MArch, "pentiumpro");
     else if (Name == "pentIIm3")
-      DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium2"));
+      DAL->AddJoinedArg(0, MArch, "pentium2");
 
     else if (Name == "x86_64")
-      DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
+      DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
 
     else if (Name == "arm")
-      DAL->append(DAL->MakeJoinedArg(0, MArch, "armv4t"));
+      DAL->AddJoinedArg(0, MArch, "armv4t");
     else if (Name == "armv4t")
-      DAL->append(DAL->MakeJoinedArg(0, MArch, "armv4t"));
+      DAL->AddJoinedArg(0, MArch, "armv4t");
     else if (Name == "armv5")
-      DAL->append(DAL->MakeJoinedArg(0, MArch, "armv5tej"));
+      DAL->AddJoinedArg(0, MArch, "armv5tej");
     else if (Name == "xscale")
-      DAL->append(DAL->MakeJoinedArg(0, MArch, "xscale"));
+      DAL->AddJoinedArg(0, MArch, "xscale");
     else if (Name == "armv6")
-      DAL->append(DAL->MakeJoinedArg(0, MArch, "armv6k"));
+      DAL->AddJoinedArg(0, MArch, "armv6k");
     else if (Name == "armv7")
-      DAL->append(DAL->MakeJoinedArg(0, MArch, "armv7a"));
+      DAL->AddJoinedArg(0, MArch, "armv7a");
 
     else
       llvm_unreachable("invalid Darwin arch");
   }
 
+  // Add an explicit version min argument for the deployment target. We do this
+  // after argument translation because -Xarch_ arguments may add a version min
+  // argument.
+  AddDeploymentTarget(*DAL);
+
   return DAL;
 }
 
@@ -677,13 +803,20 @@
   return !isTargetIPhoneOS();
 }
 
+std::string
+Darwin_Generic_GCC::ComputeEffectiveClangTriple(const ArgList &Args) const {
+  return ComputeLLVMTriple(Args);
+}
+
 /// 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);
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
+    getProgramPaths().push_back(getDriver().Dir);
 }
 
 Generic_GCC::~Generic_GCC() {
@@ -724,6 +857,8 @@
       // driver is Darwin.
     case Action::LipoJobClass:
       T = new tools::darwin::Lipo(*this); break;
+    case Action::DsymutilJobClass:
+      T = new tools::darwin::Dsymutil(*this); break;
     }
   }
 
@@ -744,12 +879,6 @@
   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.
@@ -804,11 +933,6 @@
   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)
@@ -841,8 +965,18 @@
 
 /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
 
-FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32)
+FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple)
   : Generic_GCC(Host, Triple) {
+
+  // Determine if we are compiling 32-bit code on an x86_64 platform.
+  bool Lib32 = false;
+  if (Triple.getArch() == llvm::Triple::x86 &&
+      llvm::Triple(getDriver().DefaultHostTriple).getArch() ==
+        llvm::Triple::x86_64)
+    Lib32 = true;
+    
+  getProgramPaths().push_back(getDriver().Dir + "/../libexec");
+  getProgramPaths().push_back("/usr/libexec");
   if (Lib32) {
     getFilePaths().push_back(getDriver().Dir + "/../lib32");
     getFilePaths().push_back("/usr/lib32");
@@ -874,12 +1008,46 @@
   return *T;
 }
 
+/// Minix - Minix tool chain which can call as(1) and ld(1) directly.
+
+Minix::Minix(const HostInfo &Host, const llvm::Triple& Triple)
+  : Generic_GCC(Host, Triple) {
+  getFilePaths().push_back(getDriver().Dir + "/../lib");
+  getFilePaths().push_back("/usr/lib");
+  getFilePaths().push_back("/usr/gnu/lib");
+  getFilePaths().push_back("/usr/gnu/lib/gcc/i686-pc-minix/4.4.3");
+}
+
+Tool &Minix::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::minix::Assemble(*this); break;
+    case Action::LinkJobClass:
+      T = new tools::minix::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);
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
+    getProgramPaths().push_back(getDriver().Dir);
 
   getFilePaths().push_back(getDriver().Dir + "/../lib");
   getFilePaths().push_back("/usr/lib");
@@ -937,13 +1105,35 @@
   // list), but that's messy at best.
 }
 
+Tool &Linux::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::linuxtools::Assemble(*this); break;
+    default:
+      T = &Generic_GCC::SelectTool(C, JA);
+    }
+  }
+
+  return *T;
+}
+
 /// 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);
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
+    getProgramPaths().push_back(getDriver().Dir);
 
   getFilePaths().push_back(getDriver().Dir + "/../lib");
   getFilePaths().push_back("/usr/lib");
@@ -971,3 +1161,57 @@
 
   return *T;
 }
+
+Windows::Windows(const HostInfo &Host, const llvm::Triple& Triple)
+  : ToolChain(Host, Triple) {
+}
+
+Tool &Windows::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:
+    case Action::LipoJobClass:
+    case Action::DsymutilJobClass:
+      assert(0 && "Invalid tool kind.");
+    case Action::PreprocessJobClass:
+    case Action::PrecompileJobClass:
+    case Action::AnalyzeJobClass:
+    case Action::CompileJobClass:
+      T = new tools::Clang(*this); break;
+    case Action::AssembleJobClass:
+      T = new tools::ClangAs(*this); break;
+    case Action::LinkJobClass:
+      T = new tools::visualstudio::Link(*this); break;
+    }
+  }
+
+  return *T;
+}
+
+bool Windows::IsIntegratedAssemblerDefault() const {
+  return true;
+}
+
+bool Windows::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 *Windows::GetDefaultRelocationModel() const {
+  return "static";
+}
+
+const char *Windows::GetForcedPicModel() const {
+  if (getArchName() == "x86_64")
+    return "pic";
+  return 0;
+}
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index 9acc950..d1f1556 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -25,7 +25,7 @@
 /// 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 {
+class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain {
 protected:
   mutable llvm::DenseMap<unsigned, Tool*> Tools;
 
@@ -33,9 +33,6 @@
   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;
@@ -44,7 +41,12 @@
 };
 
 /// Darwin - The base Darwin tool chain.
-class VISIBILITY_HIDDEN Darwin : public ToolChain {
+class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain {
+public:
+  /// The host version.
+  unsigned DarwinVersion[3];
+
+private:
   mutable llvm::DenseMap<unsigned, Tool*> Tools;
 
   /// Whether the information on the target has been initialized.
@@ -56,7 +58,7 @@
 
   /// Whether we are targetting iPhoneOS target.
   mutable bool TargetIsIPhoneOS;
-  
+
   /// The OS version we are targetting.
   mutable unsigned TargetVersion[3];
 
@@ -64,11 +66,15 @@
   /// initialized.
   std::string MacosxVersionMin;
 
+private:
+  void AddDeploymentTarget(DerivedArgList &Args) const;
+
 public:
-  Darwin(const HostInfo &Host, const llvm::Triple& Triple,
-         const unsigned (&DarwinVersion)[3]);
+  Darwin(const HostInfo &Host, const llvm::Triple& Triple);
   ~Darwin();
 
+  std::string ComputeEffectiveClangTriple(const ArgList &Args) const;
+
   /// @name Darwin Specific Toolchain API
   /// {
 
@@ -147,17 +153,26 @@
   /// @name ToolChain Implementation
   /// {
 
-  virtual DerivedArgList *TranslateArgs(InputArgList &Args,
+  virtual types::ID LookupTypeForExtension(const char *Ext) const;
+
+  virtual DerivedArgList *TranslateArgs(const DerivedArgList &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);
+    // Always allow blocks on Darwin; users interested in versioning are
+    // expected to use /usr/include/Blocks.h.
+    return true;
+  }
+  virtual bool IsIntegratedAssemblerDefault() const {
+#ifdef DISABLE_DEFAULT_INTEGRATED_ASSEMBLER
+    return false;
+#else
+    // Default integrated assembler to on for x86.
+    return (getTriple().getArch() == llvm::Triple::x86 ||
+            getTriple().getArch() == llvm::Triple::x86_64);
+#endif
   }
   virtual bool IsObjCNonFragileABIDefault() const {
     // Non-fragile ABI is default for everything but i386.
@@ -193,10 +208,9 @@
 };
 
 /// DarwinClang - The Darwin toolchain used by Clang.
-class VISIBILITY_HIDDEN DarwinClang : public Darwin {
+class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
 public:
-  DarwinClang(const HostInfo &Host, const llvm::Triple& Triple,
-              const unsigned (&DarwinVersion)[3]);
+  DarwinClang(const HostInfo &Host, const llvm::Triple& Triple);
 
   /// @name Darwin ToolChain Implementation
   /// {
@@ -211,7 +225,7 @@
 };
 
 /// DarwinGCC - The Darwin toolchain used by GCC.
-class VISIBILITY_HIDDEN DarwinGCC : public Darwin {
+class LLVM_LIBRARY_VISIBILITY DarwinGCC : public Darwin {
   /// GCC version to use.
   unsigned GCCVersion[3];
 
@@ -219,9 +233,7 @@
   std::string ToolChainDir;
 
 public:
-  DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple,
-            const unsigned (&DarwinVersion)[3],
-            const unsigned (&GCCVersion)[3]);
+  DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple);
 
   /// @name Darwin ToolChain Implementation
   /// {
@@ -236,57 +248,66 @@
 };
 
 /// Darwin_Generic_GCC - Generic Darwin tool chain using gcc.
-class VISIBILITY_HIDDEN Darwin_Generic_GCC : public Generic_GCC {
+class LLVM_LIBRARY_VISIBILITY Darwin_Generic_GCC : public Generic_GCC {
 public:
   Darwin_Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
     : Generic_GCC(Host, Triple) {}
 
+  std::string ComputeEffectiveClangTriple(const ArgList &Args) const;
+
   virtual const char *GetDefaultRelocationModel() const { return "pic"; }
 };
 
-class VISIBILITY_HIDDEN AuroraUX : public Generic_GCC {
+class LLVM_LIBRARY_VISIBILITY 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 {
+class LLVM_LIBRARY_VISIBILITY 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 {
+class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_GCC {
 public:
-  FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32);
+  FreeBSD(const HostInfo &Host, const llvm::Triple& Triple);
 
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
 };
 
-class VISIBILITY_HIDDEN DragonFly : public Generic_GCC {
+class LLVM_LIBRARY_VISIBILITY Minix : public Generic_GCC {
+public:
+  Minix(const HostInfo &Host, const llvm::Triple& Triple);
+
+  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+};
+
+class LLVM_LIBRARY_VISIBILITY 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 {
+class LLVM_LIBRARY_VISIBILITY Linux : public Generic_GCC {
 public:
   Linux(const HostInfo &Host, const llvm::Triple& Triple);
+
+  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
 };
 
 
 /// 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 {
+class LLVM_LIBRARY_VISIBILITY 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;
@@ -298,6 +319,20 @@
 
 };
 
+class LLVM_LIBRARY_VISIBILITY Windows : public ToolChain {
+  mutable llvm::DenseMap<unsigned, Tool*> Tools;
+
+public:
+  Windows(const HostInfo &Host, const llvm::Triple& Triple);
+
+  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+
+  virtual bool IsIntegratedAssemblerDefault() const;
+  virtual bool IsUnwindTablesDefault() const;
+  virtual const char *GetDefaultRelocationModel() const;
+  virtual const char *GetForcedPicModel() const;
+};
+
 } // end namespace toolchains
 } // end namespace driver
 } // end namespace clang
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 8ad04aa..9e7a061 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -105,10 +105,7 @@
     // Determine the output location.
     const char *DepFile;
     if (Output.getType() == types::TY_Dependencies) {
-      if (Output.isPipe())
-        DepFile = "-";
-      else
-        DepFile = Output.getFilename();
+      DepFile = Output.getFilename();
     } else if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
       DepFile = MF->getValue(Args);
     } else if (A->getOption().matches(options::OPT_M) ||
@@ -157,18 +154,18 @@
   for (arg_iterator it = Args.filtered_begin(options::OPT_MT,
                                              options::OPT_MQ),
          ie = Args.filtered_end(); it != ie; ++it) {
+    const Arg *A = *it;
+    A->claim();
 
-    it->claim();
-
-    if (it->getOption().matches(options::OPT_MQ)) {
+    if (A->getOption().matches(options::OPT_MQ)) {
       CmdArgs.push_back("-MT");
       llvm::SmallString<128> Quoted;
-      QuoteTarget(it->getValue(Args), Quoted);
+      QuoteTarget(A->getValue(Args), Quoted);
       CmdArgs.push_back(Args.MakeArgString(Quoted));
 
     // -MT flag - no change
     } else {
-      it->render(Args, CmdArgs);
+      A->render(Args, CmdArgs);
     }
   }
 
@@ -182,10 +179,8 @@
     const Arg *A = it;
 
     if (A->getOption().matches(options::OPT_include)) {
-      // Use PCH if the user requested it, except for C++ (for now).
+      // Use PCH if the user requested it.
       bool UsePCH = D.CCCUsePCH;
-      if (types::isCXX(Inputs[0].getType()))
-        UsePCH = false;
 
       bool FoundPTH = false;
       bool FoundPCH = false;
@@ -252,54 +247,59 @@
 /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting.
 //
 // FIXME: tblgen this.
-static const char *getARMTargetCPU(const ArgList &Args) {
+static const char *getARMTargetCPU(const ArgList &Args,
+                                   const llvm::Triple &Triple) {
   // 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.
+  llvm::StringRef MArch;
   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, if we have -march= choose the base CPU for that arch.
+    MArch = A->getValue(Args);
+  } else {
+    // Otherwise, use the Arch from the triple.
+    MArch = Triple.getArchName();
   }
 
-  // Otherwise return the most base CPU LLVM supports.
+  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";
+
+  // If all else failed, return the most base CPU LLVM supports.
   return "arm7tdmi";
 }
 
@@ -337,34 +337,6 @@
   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()) {
@@ -385,6 +357,7 @@
 void Clang::AddARMTargetArgs(const ArgList &Args,
                              ArgStringList &CmdArgs) const {
   const Driver &D = getToolChain().getDriver();
+  llvm::Triple Triple = getToolChain().getTriple();
 
   // Select the ABI to use.
   //
@@ -394,27 +367,20 @@
     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:
+    llvm::StringRef env = Triple.getEnvironmentName();
+    if (env == "gnueabi")
       ABIName = "aapcs-linux";
-      break;
-    }
+    else if (env == "eabi")
+      ABIName = "aapcs";
+    else
+      ABIName = "apcs-gnu";
   }
   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));
+  CmdArgs.push_back(getARMTargetCPU(Args, Triple));
 
   // Select the float ABI as determined by -msoft-float, -mhard-float, and
   // -mfloat-abi=.
@@ -438,14 +404,14 @@
 
   // 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()) {
+    const llvm::Triple &Triple = getToolChain().getTriple();
+    switch (Triple.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));
+      llvm::StringRef ArchName =
+        getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
       if (ArchName.startswith("v6") || ArchName.startswith("v7"))
         FloatABI = "softfp";
       else
@@ -453,6 +419,15 @@
       break;
     }
 
+    case llvm::Triple::Linux: {
+      llvm::StringRef Env = getToolChain().getTriple().getEnvironmentName();
+      if (Env == "gnueabi") {
+        FloatABI = "softfp";
+        break;
+      }
+    }
+    // fall through
+
     default:
       // Assume "soft", but warn the user we are guessing.
       FloatABI = "soft";
@@ -624,6 +599,11 @@
         CPUName = "x86-64";
       else if (getToolChain().getArchName() == "i386")
         CPUName = "i586";
+    } else if (getToolChain().getOS().startswith("openbsd"))  {
+      if (getToolChain().getArchName() == "x86_64")
+        CPUName = "x86-64";
+      else if (getToolChain().getArchName() == "i386")
+        CPUName = "i486";
     } else {
       if (getToolChain().getArchName() == "x86_64")
         CPUName = "x86-64";
@@ -639,8 +619,8 @@
 
   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();
+    llvm::StringRef Name = (*it)->getOption().getName();
+    (*it)->claim();
 
     // Skip over "-m".
     assert(Name.startswith("-m") && "Invalid feature name.");
@@ -685,57 +665,7 @@
   }
 }
 
-/// 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,
@@ -754,10 +684,11 @@
 
   // Add the "effective" target triple.
   CmdArgs.push_back("-triple");
-  std::string TripleStr = getEffectiveClangTriple(D, getToolChain(), Args);
+  std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
   CmdArgs.push_back(Args.MakeArgString(TripleStr));
 
   // Select the appropriate action.
+  bool IsRewriter = false;
   if (isa<AnalyzeJobAction>(JA)) {
     assert(JA.getType() == types::TY_Plist && "Invalid output type.");
     CmdArgs.push_back("-analyze");
@@ -768,11 +699,23 @@
       CmdArgs.push_back("-E");
   } else if (isa<AssembleJobAction>(JA)) {
     CmdArgs.push_back("-emit-obj");
+
+    // At -O0, we use -mrelax-all by default.
+    bool IsOpt = false;
+    if (Arg *A = Args.getLastArg(options::OPT_O_Group))
+      IsOpt = !A->getOption().matches(options::OPT_O0);
+    if (Args.hasFlag(options::OPT_mrelax_all,
+                      options::OPT_mno_relax_all,
+                      !IsOpt))
+      CmdArgs.push_back("-mrelax-all");
+
+    // When using an integrated assembler, we send -Wa, and -Xassembler options
+    // to -cc1.
+    Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+                         options::OPT_Xassembler);
   } else if (isa<PrecompileJobAction>(JA)) {
-    // Use PCH if the user requested it, except for C++ (for now).
+    // Use PCH if the user requested it.
     bool UsePCH = D.CCCUsePCH;
-    if (types::isCXX(Inputs[0].getType()))
-      UsePCH = false;
 
     if (UsePCH)
       CmdArgs.push_back("-emit-pch");
@@ -783,9 +726,11 @@
 
     if (JA.getType() == types::TY_Nothing) {
       CmdArgs.push_back("-fsyntax-only");
-    } else if (JA.getType() == types::TY_LLVMAsm) {
+    } else if (JA.getType() == types::TY_LLVM_IR ||
+               JA.getType() == types::TY_LTO_IR) {
       CmdArgs.push_back("-emit-llvm");
-    } else if (JA.getType() == types::TY_LLVMBC) {
+    } else if (JA.getType() == types::TY_LLVM_BC ||
+               JA.getType() == types::TY_LTO_BC) {
       CmdArgs.push_back("-emit-llvm-bc");
     } else if (JA.getType() == types::TY_PP_Asm) {
       CmdArgs.push_back("-S");
@@ -793,6 +738,7 @@
       CmdArgs.push_back("-emit-pch");
     } else if (JA.getType() == types::TY_RewrittenObjC) {
       CmdArgs.push_back("-rewrite-objc");
+      IsRewriter = true;
     } else {
       assert(JA.getType() == types::TY_PP_Asm &&
              "Unexpected output type!");
@@ -827,13 +773,16 @@
     // 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");
+      // Do not enable the security-syntatic check since it
+      // it needs to be refined (known issues).
+      // 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");
+      CmdArgs.push_back("-analyzer-check-idempotent-operations");
     }
 
     // Set the output format. The default is plist, for (lame) historical
@@ -908,8 +857,15 @@
   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))
+
+  // Decide whether to use verbose asm. Verbose assembly is the default on
+  // toolchains which have the integrated assembler on by default.
+  bool IsVerboseAsmDefault = getToolChain().IsIntegratedAssemblerDefault();
+  if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
+                   IsVerboseAsmDefault) || 
+      Args.hasArg(options::OPT_dA))
     CmdArgs.push_back("-masm-verbose");
+
   if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
     CmdArgs.push_back("-mdebug-pass");
     CmdArgs.push_back("Structure");
@@ -970,12 +926,26 @@
     break;
   }
 
+  // Pass the linker version in use.
+  if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
+    CmdArgs.push_back("-target-linker-version");
+    CmdArgs.push_back(A->getValue(Args));
+  }
+
+  // -mno-omit-leaf-frame-pointer is default.
+  if (Args.hasFlag(options::OPT_momit_leaf_frame_pointer,
+                   options::OPT_mno_omit_leaf_frame_pointer, false))
+    CmdArgs.push_back("-momit-leaf-frame-pointer");
+
   // -fno-math-errno is default.
   if (Args.hasFlag(options::OPT_fmath_errno,
                    options::OPT_fno_math_errno,
                    false))
     CmdArgs.push_back("-fmath-errno");
 
+  // Explicitly error on some things we know we don't support and can't just
+  // ignore.
+  types::ID InputType = Inputs[0].getType();
   Arg *Unsupported;
   if ((Unsupported = Args.getLastArg(options::OPT_MG)) ||
       (Unsupported = Args.getLastArg(options::OPT_iframework)) ||
@@ -983,16 +953,30 @@
     D.Diag(clang::diag::err_drv_clang_unsupported)
       << Unsupported->getOption().getName();
 
+  if (types::isCXX(InputType) &&
+      getToolChain().getTriple().getOS() == llvm::Triple::Darwin &&
+      getToolChain().getTriple().getArch() == llvm::Triple::x86) {
+    if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)))
+      D.Diag(clang::diag::err_drv_clang_unsupported_opt_cxx_darwin_i386)
+        << Unsupported->getOption().getName();
+  }
+
   Args.AddAllArgs(CmdArgs, options::OPT_v);
+  Args.AddLastArg(CmdArgs, options::OPT_H);
   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");
+  if (Arg *A = Args.getLastArg(options::OPT_g_Group))
+    if (!A->getOption().matches(options::OPT_g0))
+      CmdArgs.push_back("-g");
+
+  Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections);
+  Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections);
+
+  Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
 
   Args.AddLastArg(CmdArgs, options::OPT_nostdinc);
   Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
@@ -1006,7 +990,6 @@
   // preprocessor.
   //
   // FIXME: Support -fpreprocessed
-  types::ID InputType = Inputs[0].getType();
   if (types::getPreprocessedType(InputType) != types::TY_INVALID)
     AddPreprocessingOptions(D, Args, CmdArgs, Output, Inputs);
 
@@ -1015,7 +998,8 @@
   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')
+    else if (A->getOption().matches(options::OPT_O) &&
+             A->getValue(Args)[0] == '\0')
       CmdArgs.push_back("-O2");
     else
       A->render(Args, CmdArgs);
@@ -1040,8 +1024,9 @@
     else
       Std->render(Args, CmdArgs);
 
-    if (Arg *A = Args.getLastArg(options::OPT_trigraphs))
-      if (A->getIndex() > Std->getIndex())
+    if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,
+                                 options::OPT_trigraphs))
+      if (A != Std)
         A->render(Args, CmdArgs);
   } else {
     // Honor -std-default.
@@ -1056,6 +1041,14 @@
     Args.AddLastArg(CmdArgs, options::OPT_trigraphs);
   }
 
+  // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'.
+  if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) {
+    if (Asm->getOption().matches(options::OPT_fasm))
+      CmdArgs.push_back("-fgnu-keywords");
+    else
+      CmdArgs.push_back("-fno-gnu-keywords");
+  }
+
   if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_)) {
     CmdArgs.push_back("-ftemplate-depth");
     CmdArgs.push_back(A->getValue(Args));
@@ -1080,12 +1073,16 @@
   else
     CmdArgs.push_back("19");
 
-  CmdArgs.push_back("-ftemplate-backtrace-limit");
-  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ))
+  if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) {
+    CmdArgs.push_back("-fmacro-backtrace-limit");
     CmdArgs.push_back(A->getValue(Args));
-  else
-    CmdArgs.push_back("10");
-  
+  }
+
+  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) {
+    CmdArgs.push_back("-ftemplate-backtrace-limit");
+    CmdArgs.push_back(A->getValue(Args));
+  }
+
   // Pass -fmessage-length=.
   CmdArgs.push_back("-fmessage-length");
   if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
@@ -1102,6 +1099,8 @@
     CmdArgs.push_back(A->getValue(Args));
   }
 
+  Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
+                        
   // -fhosted is default.
   if (KernelOrKext || Args.hasFlag(options::OPT_ffreestanding,
                                    options::OPT_fhosted,
@@ -1133,13 +1132,15 @@
     }
   }
 
-  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_fdiagnostics_parseable_fixits);
   Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
   Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
+  Args.AddLastArg(CmdArgs, options::OPT_fwrapv);
   Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
+  Args.AddLastArg(CmdArgs, options::OPT_funroll_loops);
 
   Args.AddLastArg(CmdArgs, options::OPT_pthread);
 
@@ -1220,15 +1221,30 @@
                                options::OPT_fno_gnu_keywords))
     A->render(Args, CmdArgs);
 
-  // -fnext-runtime is default.
+  // -fnext-runtime defaults to on Darwin and when rewriting Objective-C, and is
+  // -the -cc1 default.
+  bool NeXTRuntimeIsDefault = 
+    IsRewriter || getToolChain().getTriple().getOS() == llvm::Triple::Darwin;
   if (!Args.hasFlag(options::OPT_fnext_runtime, options::OPT_fgnu_runtime,
-                    getToolChain().getTriple().getOS() == llvm::Triple::Darwin))
+                    NeXTRuntimeIsDefault))
     CmdArgs.push_back("-fgnu-runtime");
 
   // -fobjc-nonfragile-abi=0 is default.
   if (types::isObjC(InputType)) {
+    unsigned Version = 1;
     if (Args.hasArg(options::OPT_fobjc_nonfragile_abi) ||
-        getToolChain().IsObjCNonFragileABIDefault()) {
+        getToolChain().IsObjCNonFragileABIDefault())
+      Version = 2;
+    if (Arg *A = Args.getLastArg(options::OPT_fobjc_abi_version_EQ)) {
+      if (llvm::StringRef(A->getValue(Args)) == "1")
+        Version = 1;
+      else if (llvm::StringRef(A->getValue(Args)) == "2")
+        Version = 2;
+      else
+        D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+    }
+
+    if (Version == 2) {
       CmdArgs.push_back("-fobjc-nonfragile-abi");
 
       // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and
@@ -1242,18 +1258,29 @@
           CmdArgs.push_back("-fobjc-dispatch-method=non-legacy");
       }
     }
+
+    // FIXME: -fobjc-nonfragile-abi2 is a transient option meant to expose
+    // features in testing.  It will eventually be removed.
+    if (Args.hasArg(options::OPT_fobjc_nonfragile_abi2))
+      CmdArgs.push_back("-fobjc-nonfragile-abi2");
   }
 
   if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
                     options::OPT_fno_assume_sane_operator_new))
     CmdArgs.push_back("-fno-assume-sane-operator-new");
 
+  // -fconstant-cfstrings is default, and may be subject to argument translation
+  // on Darwin.
+  if (!Args.hasFlag(options::OPT_fconstant_cfstrings,
+                    options::OPT_fno_constant_cfstrings) ||
+      !Args.hasFlag(options::OPT_mconstant_cfstrings,
+                    options::OPT_mno_constant_cfstrings))
+    CmdArgs.push_back("-fno-constant-cfstrings");
+
   // -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");
-  }
+  if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar))
+    A->render(Args, CmdArgs);
 
   // -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.
@@ -1279,6 +1306,11 @@
     D.Diag(clang::diag::warn_drv_clang_unsupported)
       << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
 
+  // -fcaret-diagnostics is default.
+  if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
+                    options::OPT_fno_caret_diagnostics, true))
+    CmdArgs.push_back("-fno-caret-diagnostics");
+
   // -fdiagnostics-fixit-info is default, only pass non-default.
   if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
                     options::OPT_fno_diagnostics_fixit_info))
@@ -1291,6 +1323,12 @@
                    options::OPT_fno_diagnostics_show_option))
     CmdArgs.push_back("-fdiagnostics-show-option");
 
+  if (const Arg *A =
+        Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) {
+    CmdArgs.push_back("-fdiagnostics-show-category");
+    CmdArgs.push_back(A->getValue(Args));
+  }
+
   // Color diagnostics are the default, unless the terminal doesn't support
   // them.
   if (Args.hasFlag(options::OPT_fcolor_diagnostics,
@@ -1302,6 +1340,13 @@
                     options::OPT_fno_show_source_location))
     CmdArgs.push_back("-fno-show-source-location");
 
+  if (!Args.hasFlag(options::OPT_fspell_checking,
+                    options::OPT_fno_spell_checking))
+    CmdArgs.push_back("-fno-spell-checking");
+
+  if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
+    A->render(Args, CmdArgs);
+
   // -fdollars-in-identifiers default varies depending on platform and
   // language; only pass if specified.
   if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
@@ -1346,21 +1391,18 @@
   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();
+    (*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")
+    if (llvm::StringRef((*it)->getValue(Args, 0)) == "-disable-llvm-optzns")
       CmdArgs.push_back("-disable-llvm-optzns");
     else
-      it->render(Args, CmdArgs);
+      (*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());
@@ -1373,9 +1415,7 @@
     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())
+    if (II.isFilename())
       CmdArgs.push_back(II.getFilename());
     else
       II.getInputArg().renderAsInput(Args, CmdArgs);
@@ -1383,30 +1423,34 @@
 
   Args.AddAllArgs(CmdArgs, options::OPT_undef);
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath(C, "clang"));
+  const char *Exec = getToolChain().getDriver().getClangProgramPath();
 
   // Optionally embed the -cc1 level arguments into the debug info, for build
   // analysis.
   if (getToolChain().UseDwarfDebugFlags()) {
+    ArgStringList OriginalArgs;
+    for (ArgList::const_iterator it = Args.begin(),
+           ie = Args.end(); it != ie; ++it)
+      (*it)->render(Args, OriginalArgs);
+
     llvm::SmallString<256> Flags;
     Flags += Exec;
-    for (unsigned i = 0, e = CmdArgs.size(); i != e; ++i) {
+    for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) {
       Flags += " ";
-      Flags += CmdArgs[i];
+      Flags += OriginalArgs[i];
     }
     CmdArgs.push_back("-dwarf-debug-flags");
     CmdArgs.push_back(Args.MakeArgString(Flags.str()));
   }
 
-  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+  C.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);
+    (*it)->claim();
+    D.Diag(clang::diag::warn_drv_clang_unsupported) << (*it)->getAsString(Args);
   }
 
   // Claim some arguments which clang supports automatically.
@@ -1422,8 +1466,61 @@
   Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
 }
 
+void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
+                           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];
+
+  // Invoke ourselves in -cc1as mode.
+  //
+  // FIXME: Implement custom jobs for internal actions.
+  CmdArgs.push_back("-cc1as");
+
+  // Add the "effective" target triple.
+  CmdArgs.push_back("-triple");
+  std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
+  CmdArgs.push_back(Args.MakeArgString(TripleStr));
+
+  // Set the output mode, we currently only expect to be used as a real
+  // assembler.
+  CmdArgs.push_back("-filetype");
+  CmdArgs.push_back("obj");
+
+  // At -O0, we use -mrelax-all by default.
+  bool IsOpt = false;
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group))
+    IsOpt = !A->getOption().matches(options::OPT_O0);
+  if (Args.hasFlag(options::OPT_mrelax_all,
+                    options::OPT_mno_relax_all,
+                    !IsOpt))
+    CmdArgs.push_back("-relax-all");
+
+  // FIXME: Add -force_cpusubtype_ALL support, once we have it.
+
+  // FIXME: Add -g support, once we have it.
+
+  // FIXME: Add -static support, once we have it.
+
+  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());
+
+  assert(Input.isFilename() && "Invalid input.");
+  CmdArgs.push_back(Input.getFilename());
+
+  const char *Exec = getToolChain().getDriver().getClangProgramPath();
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
 void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
-                               Job &Dest,
                                const InputInfo &Output,
                                const InputInfoList &Inputs,
                                const ArgList &Args,
@@ -1435,6 +1532,11 @@
          it = Args.begin(), ie = Args.end(); it != ie; ++it) {
     Arg *A = *it;
     if (A->getOption().hasForwardToGCC()) {
+      // Don't forward any -g arguments to assembly steps.
+      if (isa<AssembleJobAction>(JA) &&
+          A->getOption().matches(options::OPT_g_Group))
+        continue;
+
       // 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
@@ -1470,10 +1572,7 @@
   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()) {
+  if (Output.isFilename()) {
     CmdArgs.push_back("-o");
     CmdArgs.push_back(Output.getFilename());
   } else {
@@ -1495,7 +1594,8 @@
     const InputInfo &II = *it;
 
     // Don't try to pass LLVM or AST inputs to a generic gcc.
-    if (II.getType() == types::TY_LLVMBC)
+    if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
+        II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
       D.Diag(clang::diag::err_drv_no_linker_llvm_support)
         << getToolChain().getTripleString();
     else if (II.getType() == types::TY_AST)
@@ -1507,9 +1607,7 @@
       CmdArgs.push_back(types::getTypeName(II.getType()));
     }
 
-    if (II.isPipe())
-      CmdArgs.push_back("-");
-    else if (II.isFilename())
+    if (II.isFilename())
       CmdArgs.push_back(II.getFilename());
     else
       // Don't render as input, we need gcc to do the translations.
@@ -1518,8 +1616,8 @@
 
   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));
+    Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
 void gcc::Preprocess::RenderExtraToolArgs(const JobAction &JA,
@@ -1537,7 +1635,8 @@
   const Driver &D = getToolChain().getDriver();
 
   // If -flto, etc. are present then make sure not to force assembly output.
-  if (JA.getType() == types::TY_LLVMBC)
+  if (JA.getType() == types::TY_LLVM_IR || JA.getType() == types::TY_LTO_IR ||
+      JA.getType() == types::TY_LLVM_BC || JA.getType() == types::TY_LTO_BC)
     CmdArgs.push_back("-c");
   else {
     if (JA.getType() != types::TY_PP_Asm)
@@ -1710,10 +1809,10 @@
     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);
+      if (!(*it)->getOption().matches(options::OPT_fbuiltin_strcat) &&
+          !(*it)->getOption().matches(options::OPT_fbuiltin_strcpy)) {
+        (*it)->claim();
+        (*it)->render(Args, CmdArgs);
       }
     }
   } else
@@ -1850,10 +1949,7 @@
          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());
+    CmdArgs.push_back(II.getFilename());
   }
 
   Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
@@ -1891,7 +1987,7 @@
 }
 
 void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA,
-                                      Job &Dest, const InputInfo &Output,
+                                      const InputInfo &Output,
                                       const InputInfoList &Inputs,
                                       const ArgList &Args,
                                       const char *LinkingOutput) const {
@@ -1906,12 +2002,9 @@
     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.");
-  }
+  assert(Output.isFilename() && "Unexpected CC1 output.");
+  OutputArgs.push_back("-o");
+  OutputArgs.push_back(Output.getFilename());
 
   if (Args.hasArg(options::OPT_E)) {
     AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
@@ -1924,12 +2017,12 @@
 
   const char *CC1Name = getCC1Name(Inputs[0].getType());
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name));
-  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+    Args.MakeArgString(getToolChain().GetProgramPath(CC1Name));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
 void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
-                                   Job &Dest, const InputInfo &Output,
+                                   const InputInfo &Output,
                                    const InputInfoList &Inputs,
                                    const ArgList &Args,
                                    const char *LinkingOutput) const {
@@ -1944,9 +2037,11 @@
     D.Diag(clang::diag::err_drv_argument_only_allowed_with)
       << A->getAsString(Args) << "-E";
 
-  if (Output.getType() == types::TY_LLVMAsm)
+  if (JA.getType() == types::TY_LLVM_IR ||
+      JA.getType() == types::TY_LTO_IR)
     CmdArgs.push_back("-emit-llvm");
-  else if (Output.getType() == types::TY_LLVMBC)
+  else if (JA.getType() == types::TY_LLVM_BC ||
+           JA.getType() == types::TY_LTO_BC)
     CmdArgs.push_back("-emit-llvm-bc");
   else if (Output.getType() == types::TY_AST)
     D.Diag(clang::diag::err_drv_no_ast_support)
@@ -1959,9 +2054,7 @@
   ArgStringList OutputArgs;
   if (Output.getType() != types::TY_PCH) {
     OutputArgs.push_back("-o");
-    if (Output.isPipe())
-      OutputArgs.push_back("-");
-    else if (Output.isNothing())
+    if (Output.isNothing())
       OutputArgs.push_back("/dev/null");
     else
       OutputArgs.push_back(Output.getFilename());
@@ -1994,10 +2087,7 @@
         return;
       }
 
-      if (II.isPipe())
-        CmdArgs.push_back("-");
-      else
-        CmdArgs.push_back(II.getFilename());
+      CmdArgs.push_back(II.getFilename());
     }
 
     if (OutputArgsEarly) {
@@ -2022,12 +2112,12 @@
 
   const char *CC1Name = getCC1Name(Inputs[0].getType());
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name));
-  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+    Args.MakeArgString(getToolChain().GetProgramPath(CC1Name));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
 void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
-                                    Job &Dest, const InputInfo &Output,
+                                    const InputInfo &Output,
                                     const InputInfoList &Inputs,
                                     const ArgList &Args,
                                     const char *LinkingOutput) const {
@@ -2050,7 +2140,9 @@
   // Derived from asm spec.
   AddDarwinArch(Args, CmdArgs);
 
-  if (!getDarwinToolChain().isTargetIPhoneOS() ||
+  // Use -force_cpusubtype_ALL on x86 by default.
+  if (getToolChain().getTriple().getArch() == llvm::Triple::x86 ||
+      getToolChain().getTriple().getArch() == llvm::Triple::x86_64 ||
       Args.hasArg(options::OPT_force__cpusubtype__ALL))
     CmdArgs.push_back("-force_cpusubtype_ALL");
 
@@ -2067,38 +2159,14 @@
   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());
-  }
+  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);
+    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
 void darwin::DarwinTool::AddDarwinArch(const ArgList &Args,
@@ -2118,6 +2186,22 @@
                                ArgStringList &CmdArgs) const {
   const Driver &D = getToolChain().getDriver();
 
+  unsigned Version[3] = { 0, 0, 0 };
+  if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
+    bool HadExtra;
+    if (!Driver::GetReleaseVersion(A->getValue(Args), Version[0],
+                                   Version[1], Version[2], HadExtra) ||
+        HadExtra)
+      D.Diag(clang::diag::err_drv_invalid_version_number)
+        << A->getAsString(Args);
+  }
+
+  // Newer linkers support -demangle, pass it if supported and not disabled by
+  // the user.
+  if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) {
+    CmdArgs.push_back("-demangle");
+  }
+
   // Derived from the "link" spec.
   Args.AddAllArgs(CmdArgs, options::OPT_static);
   if (!Args.hasArg(options::OPT_static))
@@ -2200,8 +2284,15 @@
   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");
+  if (const Arg *A = Args.getLastArg(options::OPT_fpie, options::OPT_fPIE,
+                                     options::OPT_fno_pie,
+                                     options::OPT_fno_PIE)) {
+    if (A->getOption().matches(options::OPT_fpie) ||
+        A->getOption().matches(options::OPT_fPIE))
+      CmdArgs.push_back("-pie");
+    else
+      CmdArgs.push_back("-no_pie");
+  }
 
   Args.AddLastArg(CmdArgs, options::OPT_prebind);
   Args.AddLastArg(CmdArgs, options::OPT_noprebind);
@@ -2252,7 +2343,7 @@
 }
 
 void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
-                                Job &Dest, const InputInfo &Output,
+                                const InputInfo &Output,
                                 const InputInfoList &Inputs,
                                 const ArgList &Args,
                                 const char *LinkingOutput) const {
@@ -2349,7 +2440,7 @@
         Args.hasArg(options::OPT_shared_libgcc) &&
         getDarwinToolChain().isMacosxVersionLT(10, 5)) {
       const char *Str =
-        Args.MakeArgString(getToolChain().GetFilePath(C, "crt3.o"));
+        Args.MakeArgString(getToolChain().GetFilePath("crt3.o"));
       CmdArgs.push_back(Str);
     }
   }
@@ -2409,44 +2500,12 @@
   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));
-    }
-  }
+    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
 void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
-                                Job &Dest, const InputInfo &Output,
+                                const InputInfo &Output,
                                 const InputInfoList &Inputs,
                                 const ArgList &Args,
                                 const char *LinkingOutput) const {
@@ -2465,12 +2524,32 @@
     CmdArgs.push_back(II.getFilename());
   }
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath(C, "lipo"));
-  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+    Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA,
+                                    const InputInfo &Output,
+                                    const InputInfoList &Inputs,
+                                    const ArgList &Args,
+                                    const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
+  const InputInfo &Input = Inputs[0];
+  assert(Input.isFilename() && "Unexpected dsymutil input.");
+  CmdArgs.push_back(Input.getFilename());
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
 void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
-                                      Job &Dest, const InputInfo &Output,
+                                      const InputInfo &Output,
                                       const InputInfoList &Inputs,
                                       const ArgList &Args,
                                       const char *LinkingOutput) const {
@@ -2480,27 +2559,21 @@
                        options::OPT_Xassembler);
 
   CmdArgs.push_back("-o");
-  if (Output.isPipe())
-    CmdArgs.push_back("-");
-  else
-    CmdArgs.push_back(Output.getFilename());
+  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());
+    CmdArgs.push_back(II.getFilename());
   }
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath(C, "gas"));
-  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+    Args.MakeArgString(getToolChain().GetProgramPath("gas"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
 void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA,
-                                  Job &Dest, const InputInfo &Output,
+                                  const InputInfo &Output,
                                   const InputInfoList &Inputs,
                                   const ArgList &Args,
                                   const char *LinkingOutput) const {
@@ -2527,10 +2600,7 @@
     }
   }
 
-  if (Output.isPipe()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back("-");
-  } else if (Output.isFilename()) {
+  if (Output.isFilename()) {
     CmdArgs.push_back("-o");
     CmdArgs.push_back(Output.getFilename());
   } else {
@@ -2540,13 +2610,18 @@
   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")));
+      CmdArgs.push_back(Args.MakeArgString(
+                                getToolChain().GetFilePath("crt1.o")));
+      CmdArgs.push_back(Args.MakeArgString(
+                                getToolChain().GetFilePath("crti.o")));
+      CmdArgs.push_back(Args.MakeArgString(
+                                getToolChain().GetFilePath("crtbegin.o")));
     } else {
-      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
+      CmdArgs.push_back(Args.MakeArgString(
+                                getToolChain().GetFilePath("crti.o")));
     }
-    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
+    CmdArgs.push_back(Args.MakeArgString(
+                                getToolChain().GetFilePath("crtn.o")));
   }
 
   CmdArgs.push_back(Args.MakeArgString("-L/opt/gcc4/lib/gcc/"
@@ -2562,13 +2637,12 @@
     const InputInfo &II = *it;
 
     // Don't try to pass LLVM inputs to a generic gcc.
-    if (II.getType() == types::TY_LLVMBC)
+    if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
+        II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
       D.Diag(clang::diag::err_drv_no_linker_llvm_support)
         << getToolChain().getTripleString();
 
-    if (II.isPipe())
-      CmdArgs.push_back("-");
-    else if (II.isFilename())
+    if (II.isFilename())
       CmdArgs.push_back(II.getFilename());
     else
       II.getInputArg().renderAsInput(Args, CmdArgs);
@@ -2590,18 +2664,17 @@
   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("crtend.o")));
   }
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
-  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
 void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
-                                     Job &Dest, const InputInfo &Output,
+                                     const InputInfo &Output,
                                      const InputInfoList &Inputs,
                                      const ArgList &Args,
                                      const char *LinkingOutput) const {
@@ -2611,27 +2684,21 @@
                        options::OPT_Xassembler);
 
   CmdArgs.push_back("-o");
-  if (Output.isPipe())
-    CmdArgs.push_back("-");
-  else
-    CmdArgs.push_back(Output.getFilename());
+  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());
+    CmdArgs.push_back(II.getFilename());
   }
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
-  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
 void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
-                                 Job &Dest, const InputInfo &Output,
+                                 const InputInfo &Output,
                                  const InputInfoList &Inputs,
                                  const ArgList &Args,
                                  const char *LinkingOutput) const {
@@ -2657,10 +2724,7 @@
     }
   }
 
-  if (Output.isPipe()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back("-");
-  } else if (Output.isFilename()) {
+  if (Output.isFilename()) {
     CmdArgs.push_back("-o");
     CmdArgs.push_back(Output.getFilename());
   } else {
@@ -2670,10 +2734,13 @@
   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")));
+      CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crt0.o")));
+      CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crtbegin.o")));
     } else {
-      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
+      CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crtbeginS.o")));
     }
   }
 
@@ -2681,7 +2748,7 @@
   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"));
+                                       "/4.2.1"));
 
   Args.AddAllArgs(CmdArgs, options::OPT_L);
   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
@@ -2692,13 +2759,12 @@
     const InputInfo &II = *it;
 
     // Don't try to pass LLVM inputs to a generic gcc.
-    if (II.getType() == types::TY_LLVMBC)
+    if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
+        II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
       D.Diag(clang::diag::err_drv_no_linker_llvm_support)
         << getToolChain().getTripleString();
 
-    if (II.isPipe())
-      CmdArgs.push_back("-");
-    else if (II.isFilename())
+    if (II.isFilename())
       CmdArgs.push_back(II.getFilename());
     else
       II.getInputArg().renderAsInput(Args, CmdArgs);
@@ -2706,6 +2772,11 @@
 
   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 before adding
     // the default system libraries. Just mimic this for now.
     CmdArgs.push_back("-lgcc");
@@ -2720,18 +2791,20 @@
   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")));
+      CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crtend.o")));
     else
-      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
+      CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crtendS.o")));
   }
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
-  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
 void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
-                                     Job &Dest, const InputInfo &Output,
+                                     const InputInfo &Output,
                                      const InputInfoList &Inputs,
                                      const ArgList &Args,
                                      const char *LinkingOutput) const {
@@ -2753,27 +2826,21 @@
                        options::OPT_Xassembler);
 
   CmdArgs.push_back("-o");
-  if (Output.isPipe())
-    CmdArgs.push_back("-");
-  else
-    CmdArgs.push_back(Output.getFilename());
+  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());
+    CmdArgs.push_back(II.getFilename());
   }
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
-  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
 void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
-                                 Job &Dest, const InputInfo &Output,
+                                 const InputInfo &Output,
                                  const InputInfoList &Inputs,
                                  const ArgList &Args,
                                  const char *LinkingOutput) const {
@@ -2799,10 +2866,7 @@
     CmdArgs.push_back("elf_i386_fbsd");
   }
 
-  if (Output.isPipe()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back("-");
-  } else if (Output.isFilename()) {
+  if (Output.isFilename()) {
     CmdArgs.push_back("-o");
     CmdArgs.push_back(Output.getFilename());
   } else {
@@ -2812,31 +2876,39 @@
   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")));
+      CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crt1.o")));
+      CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crti.o")));
+      CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crtbegin.o")));
     } else {
-      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
-      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
+      CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crti.o")));
+      CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crtbeginS.o")));
     }
   }
 
   Args.AddAllArgs(CmdArgs, options::OPT_L);
   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
   Args.AddAllArgs(CmdArgs, options::OPT_e);
+  Args.AddAllArgs(CmdArgs, options::OPT_s);
+  Args.AddAllArgs(CmdArgs, options::OPT_t);
+  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
+  Args.AddAllArgs(CmdArgs, options::OPT_r);
 
   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)
+    if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
+        II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
       D.Diag(clang::diag::err_drv_no_linker_llvm_support)
         << getToolChain().getTripleString();
 
-    if (II.isPipe())
-      CmdArgs.push_back("-");
-    else if (II.isFilename())
+    if (II.isFilename())
       CmdArgs.push_back(II.getFilename());
     else
       II.getInputArg().renderAsInput(Args, CmdArgs);
@@ -2876,15 +2948,147 @@
   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")));
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
+                                                                  "crtend.o")));
     else
-      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
-    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
+      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
+                                                                 "crtendS.o")));
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
+                                                                    "crtn.o")));
   }
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
-  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void linuxtools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
+                                        const InputInfo &Output,
+                                        const InputInfoList &Inputs,
+                                        const ArgList &Args,
+                                        const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  // Add --32/--64 to make sure we get the format we want.
+  // This is incomplete
+  if (getToolChain().getArch() == llvm::Triple::x86) {
+    CmdArgs.push_back("--32");
+  } else if (getToolChain().getArch() == llvm::Triple::x86_64) {
+    CmdArgs.push_back("--64");
+  } else if (getToolChain().getArch() == llvm::Triple::arm) {
+    llvm::StringRef MArch = getToolChain().getArchName();
+    if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
+      CmdArgs.push_back("-mfpu=neon");
+  }
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+                       options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+    CmdArgs.push_back(II.getFilename());
+  }
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+
+void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
+                                   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");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+    CmdArgs.push_back(II.getFilename());
+  }
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath("gas"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void minix::Link::ConstructJob(Compilation &C, const JobAction &JA,
+                               const InputInfo &Output,
+                               const InputInfoList &Inputs,
+                               const ArgList &Args,
+                               const char *LinkingOutput) const {
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  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))
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
+                                                      "/usr/gnu/lib/crtso.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_LLVM_IR || II.getType() == types::TY_LTO_IR ||
+        II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
+      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
+        << getToolChain().getTripleString();
+
+    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");
+    }
+
+    if (Args.hasArg(options::OPT_pthread))
+      CmdArgs.push_back("-lpthread");
+    CmdArgs.push_back("-lc");
+    CmdArgs.push_back("-lgcc");
+    CmdArgs.push_back("-L/usr/gnu/lib");
+    // FIXME: fill in the correct search path for the final
+    // support libraries.
+    CmdArgs.push_back("-L/usr/gnu/lib/gcc/i686-pc-minix/4.4.3");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
+                                              "/usr/gnu/lib/libend.a")));
+  }
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath("/usr/gnu/bin/gld"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
 /// DragonFly Tools
@@ -2892,7 +3096,7 @@
 // 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 InputInfo &Output,
                                        const InputInfoList &Inputs,
                                        const ArgList &Args,
                                        const char *LinkingOutput) const {
@@ -2907,30 +3111,24 @@
                        options::OPT_Xassembler);
 
   CmdArgs.push_back("-o");
-  if (Output.isPipe())
-    CmdArgs.push_back("-");
-  else
-    CmdArgs.push_back(Output.getFilename());
+  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());
+    CmdArgs.push_back(II.getFilename());
   }
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
-  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.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 InputInfo &Output,
+                                   const InputInfoList &Inputs,
+                                   const ArgList &Args,
+                                   const char *LinkingOutput) const {
   const Driver &D = getToolChain().getDriver();
   ArgStringList CmdArgs;
 
@@ -2952,10 +3150,7 @@
     CmdArgs.push_back("elf_i386");
   }
 
-  if (Output.isPipe()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back("-");
-  } else if (Output.isFilename()) {
+  if (Output.isFilename()) {
     CmdArgs.push_back("-o");
     CmdArgs.push_back(Output.getFilename());
   } else {
@@ -2965,12 +3160,17 @@
   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")));
+      CmdArgs.push_back(
+            Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
+      CmdArgs.push_back(
+            Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
+      CmdArgs.push_back(
+            Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
     } else {
-      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
-      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
+      CmdArgs.push_back(
+            Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
+      CmdArgs.push_back(
+            Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
     }
   }
 
@@ -2983,13 +3183,12 @@
     const InputInfo &II = *it;
 
     // Don't try to pass LLVM inputs to a generic gcc.
-    if (II.getType() == types::TY_LLVMBC)
+    if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
+        II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
       D.Diag(clang::diag::err_drv_no_linker_llvm_support)
         << getToolChain().getTripleString();
 
-    if (II.isPipe())
-      CmdArgs.push_back("-");
-    else if (II.isFilename())
+    if (II.isFilename())
       CmdArgs.push_back(II.getFilename());
     else
       II.getInputArg().renderAsInput(Args, CmdArgs);
@@ -3015,6 +3214,11 @@
       CmdArgs.push_back("/usr/lib");
     }
 
+    if (D.CCCIsCXX) {
+      CmdArgs.push_back("-lstdc++");
+      CmdArgs.push_back("-lm");
+    }
+
     if (Args.hasArg(options::OPT_shared)) {
       CmdArgs.push_back("-lgcc_pic");
     } else {
@@ -3039,13 +3243,57 @@
   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")));
+      CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crtend.o")));
     else
-      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
-    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
+      CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crtendS.o")));
+    CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crtn.o")));
   }
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
-  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
+    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA,
+                                      const InputInfo &Output,
+                                      const InputInfoList &Inputs,
+                                      const ArgList &Args,
+                                      const char *LinkingOutput) const {
+  const Driver &D = getToolChain().getDriver();
+  ArgStringList CmdArgs;
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back(Args.MakeArgString(std::string("-out:") + Output.getFilename()));
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+    !Args.hasArg(options::OPT_nostartfiles)) {
+    CmdArgs.push_back("-defaultlib:libcmt");
+  }
+
+  CmdArgs.push_back("-nologo");
+
+  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 visual studio linker.
+    if (II.getType() == types::TY_LLVM_BC)
+      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
+      << getToolChain().getTripleString();
+
+    if (II.isFilename())
+      CmdArgs.push_back(II.getFilename());
+    else
+      II.getInputArg().renderAsInput(Args, CmdArgs);
+  }
+
+  const char *Exec =
+  Args.MakeArgString(getToolChain().GetProgramPath("link.exe"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
index 091fec3..b5defa4 100644
--- a/lib/Driver/Tools.h
+++ b/lib/Driver/Tools.h
@@ -26,7 +26,8 @@
 
 namespace tools {
 
-  class VISIBILITY_HIDDEN Clang : public Tool {
+  /// \brief Clang compiler tool.
+  class LLVM_LIBRARY_VISIBILITY Clang : public Tool {
     void AddPreprocessingOptions(const Driver &D,
                                  const ArgList &Args,
                                  ArgStringList &CmdArgs,
@@ -38,16 +39,30 @@
     void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
 
   public:
-    Clang(const ToolChain &TC) : Tool("clang", TC) {}
+    Clang(const ToolChain &TC) : Tool("clang", "clang frontend", 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;
+  };
+
+  /// \brief Clang integrated assembler tool.
+  class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool {
+  public:
+    ClangAs(const ToolChain &TC) : Tool("clang::as",
+                                        "clang integrated assembler", TC) {}
+
+    virtual bool hasGoodDiagnostics() const { return true; }
+    virtual bool hasIntegratedAssembler() const { return false; }
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
                               const InputInfo &Output,
                               const InputInfoList &Inputs,
                               const ArgList &TCArgs,
@@ -56,12 +71,12 @@
 
   /// gcc - Generic GCC tool implementations.
 namespace gcc {
-  class VISIBILITY_HIDDEN Common : public Tool {
+  class LLVM_LIBRARY_VISIBILITY Common : public Tool {
   public:
-    Common(const char *Name, const ToolChain &TC) : Tool(Name, TC) {}
+    Common(const char *Name, const char *ShortName,
+           const ToolChain &TC) : Tool(Name, ShortName, TC) {}
 
     virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
                               const InputInfo &Output,
                               const InputInfoList &Inputs,
                               const ArgList &TCArgs,
@@ -74,12 +89,11 @@
   };
 
 
-  class VISIBILITY_HIDDEN Preprocess : public Common {
+  class LLVM_LIBRARY_VISIBILITY Preprocess : public Common {
   public:
-    Preprocess(const ToolChain &TC) : Common("gcc::Preprocess", TC) {}
+    Preprocess(const ToolChain &TC) : Common("gcc::Preprocess",
+                                             "gcc preprocessor", 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; }
 
@@ -87,12 +101,11 @@
                                      ArgStringList &CmdArgs) const;
   };
 
-  class VISIBILITY_HIDDEN Precompile : public Common  {
+  class LLVM_LIBRARY_VISIBILITY Precompile : public Common  {
   public:
-    Precompile(const ToolChain &TC) : Common("gcc::Precompile", TC) {}
+    Precompile(const ToolChain &TC) : Common("gcc::Precompile",
+                                             "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; }
 
@@ -100,12 +113,11 @@
                                      ArgStringList &CmdArgs) const;
   };
 
-  class VISIBILITY_HIDDEN Compile : public Common  {
+  class LLVM_LIBRARY_VISIBILITY Compile : public Common  {
   public:
-    Compile(const ToolChain &TC) : Common("gcc::Compile", TC) {}
+    Compile(const ToolChain &TC) : Common("gcc::Compile",
+                                          "gcc frontend", 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; }
 
@@ -113,24 +125,22 @@
                                      ArgStringList &CmdArgs) const;
   };
 
-  class VISIBILITY_HIDDEN Assemble : public Common  {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Common  {
   public:
-    Assemble(const ToolChain &TC) : Common("gcc::Assemble", TC) {}
+    Assemble(const ToolChain &TC) : Common("gcc::Assemble",
+                                           "assembler (via gcc)", 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  {
+  class LLVM_LIBRARY_VISIBILITY Link : public Common  {
   public:
-    Link(const ToolChain &TC) : Common("gcc::Link", TC) {}
+    Link(const ToolChain &TC) : Common("gcc::Link",
+                                       "linker (via gcc)", 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,
@@ -139,7 +149,7 @@
 } // end namespace gcc
 
 namespace darwin {
-  class VISIBILITY_HIDDEN DarwinTool : public Tool {
+  class LLVM_LIBRARY_VISIBILITY DarwinTool : public Tool {
   protected:
     void AddDarwinArch(const ArgList &Args, ArgStringList &CmdArgs) const;
 
@@ -148,10 +158,11 @@
     }
 
   public:
-    DarwinTool(const char *Name, const ToolChain &TC) : Tool(Name, TC) {}
+    DarwinTool(const char *Name, const char *ShortName,
+               const ToolChain &TC) : Tool(Name, ShortName, TC) {}
   };
 
-  class VISIBILITY_HIDDEN CC1 : public DarwinTool  {
+  class LLVM_LIBRARY_VISIBILITY CC1 : public DarwinTool  {
   public:
     static const char *getBaseInputName(const ArgList &Args,
                                  const InputInfoList &Input);
@@ -176,82 +187,86 @@
     void AddCPPArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
 
   public:
-    CC1(const char *Name, const ToolChain &TC) : DarwinTool(Name, TC) {}
+    CC1(const char *Name, const char *ShortName,
+        const ToolChain &TC) : DarwinTool(Name, ShortName, 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  {
+  class LLVM_LIBRARY_VISIBILITY Preprocess : public CC1  {
   public:
-    Preprocess(const ToolChain &TC) : CC1("darwin::Preprocess", TC) {}
+    Preprocess(const ToolChain &TC) : CC1("darwin::Preprocess",
+                                          "gcc preprocessor", 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  {
+  class LLVM_LIBRARY_VISIBILITY Compile : public CC1  {
   public:
-    Compile(const ToolChain &TC) : CC1("darwin::Compile", TC) {}
+    Compile(const ToolChain &TC) : CC1("darwin::Compile", "gcc frontend", 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  {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public DarwinTool  {
   public:
-    Assemble(const ToolChain &TC) : DarwinTool("darwin::Assemble", TC) {}
+    Assemble(const ToolChain &TC) : DarwinTool("darwin::Assemble",
+                                               "assembler", 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  {
+  class LLVM_LIBRARY_VISIBILITY Link : public DarwinTool  {
     void AddLinkArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
 
   public:
-    Link(const ToolChain &TC) : DarwinTool("darwin::Link", TC) {}
+    Link(const ToolChain &TC) : DarwinTool("darwin::Link", "linker", 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  {
+  class LLVM_LIBRARY_VISIBILITY Lipo : public DarwinTool  {
   public:
-    Lipo(const ToolChain &TC) : DarwinTool("darwin::Lipo", TC) {}
+    Lipo(const ToolChain &TC) : DarwinTool("darwin::Lipo", "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;
+  };
+
+  class LLVM_LIBRARY_VISIBILITY Dsymutil : public DarwinTool  {
+  public:
+    Dsymutil(const ToolChain &TC) : DarwinTool("darwin::Dsymutil",
+                                               "dsymutil", TC) {}
+
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
                               const InputInfo &Output,
                               const InputInfoList &Inputs,
                               const ArgList &TCArgs,
@@ -261,31 +276,26 @@
 
   /// openbsd -- Directly call GNU Binutils assembler and linker
 namespace openbsd {
-  class VISIBILITY_HIDDEN Assemble : public Tool  {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
   public:
-    Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", TC) {}
+    Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", "assembler",
+                                         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  {
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
   public:
-    Link(const ToolChain &TC) : Tool("openbsd::Link", TC) {}
+    Link(const ToolChain &TC) : Tool("openbsd::Link", "linker", 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,
@@ -295,31 +305,26 @@
 
   /// freebsd -- Directly call GNU Binutils assembler and linker
 namespace freebsd {
-  class VISIBILITY_HIDDEN Assemble : public Tool  {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
   public:
-    Assemble(const ToolChain &TC) : Tool("freebsd::Assemble", TC) {}
+    Assemble(const ToolChain &TC) : Tool("freebsd::Assemble", "assembler",
+                                         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  {
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
   public:
-    Link(const ToolChain &TC) : Tool("freebsd::Link", TC) {}
+    Link(const ToolChain &TC) : Tool("freebsd::Link", "linker", 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,
@@ -327,33 +332,73 @@
   };
 } // end namespace freebsd
 
-  /// auroraux -- Directly call GNU Binutils assembler and linker
-namespace auroraux {
-  class VISIBILITY_HIDDEN Assemble : public Tool  {
+  /// linux -- Directly call GNU Binutils assembler and linker
+namespace linuxtools {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
   public:
-    Assemble(const ToolChain &TC) : Tool("auroraux::Assemble", TC) {}
+    Assemble(const ToolChain &TC) : Tool("linux::Assemble", "assembler",
+                                         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  {
+}
+  /// minix -- Directly call GNU Binutils assembler and linker
+namespace minix {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
   public:
-    Link(const ToolChain &TC) : Tool("auroraux::Link", TC) {}
+    Assemble(const ToolChain &TC) : Tool("minix::Assemble", "assembler",
+                                         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 LLVM_LIBRARY_VISIBILITY Link : public Tool  {
+  public:
+    Link(const ToolChain &TC) : Tool("minix::Link", "linker", TC) {}
+
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+} // end namespace minix
+
+  /// auroraux -- Directly call GNU Binutils assembler and linker
+namespace auroraux {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
+  public:
+    Assemble(const ToolChain &TC) : Tool("auroraux::Assemble", "assembler",
+                                         TC) {}
+
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
+  public:
+    Link(const ToolChain &TC) : Tool("auroraux::Link", "linker", TC) {}
+
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
                               const InputInfo &Output,
                               const InputInfoList &Inputs,
                               const ArgList &TCArgs,
@@ -363,31 +408,26 @@
 
   /// dragonfly -- Directly call GNU Binutils assembler and linker
 namespace dragonfly {
-  class VISIBILITY_HIDDEN Assemble : public Tool  {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
   public:
-    Assemble(const ToolChain &TC) : Tool("dragonfly::Assemble", TC) {}
+    Assemble(const ToolChain &TC) : Tool("dragonfly::Assemble", "assembler",
+                                         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  {
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
   public:
-    Link(const ToolChain &TC) : Tool("dragonfly::Link", TC) {}
+    Link(const ToolChain &TC) : Tool("dragonfly::Link", "linker", 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,
@@ -395,6 +435,22 @@
   };
 } // end namespace dragonfly
 
+  /// Visual studio tools.
+namespace visualstudio {
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
+  public:
+    Link(const ToolChain &TC) : Tool("visualstudio::Link", "linker", TC) {}
+
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+} // end namespace visualstudio
+
 } // end namespace toolchains
 } // end namespace driver
 } // end namespace clang
diff --git a/lib/Driver/Types.cpp b/lib/Driver/Types.cpp
index 8857fb1..3c07cf2 100644
--- a/lib/Driver/Types.cpp
+++ b/lib/Driver/Types.cpp
@@ -86,6 +86,20 @@
   case TY_CXXHeader: case TY_PP_CXXHeader:
   case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
   case TY_AST:
+  case TY_LLVM_IR: case TY_LLVM_BC:
+    return true;
+  }
+}
+
+bool types::isOnlyAcceptedByClang(ID Id) {
+  switch (Id) {
+  default:
+    return false;
+
+  case TY_AST:
+  case TY_LLVM_IR:
+  case TY_LLVM_BC:
+  case TY_RewrittenObjC:
     return true;
   }
 }
@@ -132,15 +146,19 @@
            .Case("ii", TY_PP_CXX)
            .Case("mi", TY_PP_ObjC)
            .Case("mm", TY_ObjCXX)
+           .Case("bc", TY_LLVM_BC)
            .Case("cc", TY_CXX)
            .Case("CC", TY_CXX)
            .Case("cl", TY_CL)
            .Case("cp", TY_CXX)
            .Case("hh", TY_CXXHeader)
+           .Case("ll", TY_LLVM_IR)
            .Case("hpp", TY_CXXHeader)
            .Case("ads", TY_Ada)
            .Case("adb", TY_Ada)
            .Case("ast", TY_AST)
+           .Case("c++", TY_CXX)
+           .Case("C++", TY_CXX)
            .Case("cxx", TY_CXX)
            .Case("cpp", TY_CXX)
            .Case("CPP", TY_CXX)
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index 7b8ebf9..eb7f270 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -13,7 +13,6 @@
 
 #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"
@@ -22,7 +21,6 @@
 #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"
@@ -39,7 +37,7 @@
 
   public:
     ASTPrinter(llvm::raw_ostream* o = NULL, bool Dump = false)
-      : Out(o? *o : llvm::errs()), Dump(Dump) { }
+      : Out(o? *o : llvm::outs()), Dump(Dump) { }
 
     virtual void HandleTranslationUnit(ASTContext &Context) {
       PrintingPolicy Policy = Context.PrintingPolicy;
@@ -111,25 +109,14 @@
 }
 
 void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
-  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    FD->print(llvm::errs());
-
-    if (Stmt *Body = FD->getBody()) {
+  if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
+    D->print(llvm::errs());
+  
+    if (Stmt *Body = D->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';
-    }
   }
 }
 
diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp
index b0faf0a..b46212f 100644
--- a/lib/Frontend/ASTMerge.cpp
+++ b/lib/Frontend/ASTMerge.cpp
@@ -26,7 +26,8 @@
   // 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->setCurrentFile(getCurrentFile(), getCurrentFileKind(),
+                                takeCurrentASTUnit());
   AdaptedAction->setCompilerInstance(&CI);
   return AdaptedAction->BeginSourceFileAction(CI, Filename);
 }
@@ -39,10 +40,16 @@
                                        &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);
+    ASTUnit *Unit = ASTUnit::LoadFromASTFile(ASTFiles[I], Diags, false);
     if (!Unit)
       continue;
 
+    // Reset the argument -> string function so that it has the AST
+    // context we want, since the Sema object created by
+    // LoadFromASTFile will override it.
+    CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
+                                         &CI.getASTContext());
+
     ASTImporter Importer(CI.getDiagnostics(),
                          CI.getASTContext(), 
                          CI.getFileManager(),
@@ -95,8 +102,8 @@
   return AdaptedAction->hasPCHSupport();
 }
 
-bool ASTMergeAction::hasASTSupport() const {
-  return AdaptedAction->hasASTSupport();
+bool ASTMergeAction::hasASTFileSupport() const {
+  return AdaptedAction->hasASTFileSupport();
 }
 
 bool ASTMergeAction::hasCodeCompletionSupport() const {
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 0f7dca2..c76488b 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -12,10 +12,10 @@
 //===----------------------------------------------------------------------===//
 
 #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/TypeOrdering.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Driver/Compilation.h"
 #include "clang/Driver/Driver.h"
@@ -25,30 +25,294 @@
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/FrontendOptions.h"
+#include "clang/Serialization/ASTReader.h"
+#include "clang/Serialization/ASTWriter.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/ADT/StringSet.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/System/Host.h"
 #include "llvm/System/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Timer.h"
+#include <cstdlib>
+#include <cstdio>
+#include <sys/stat.h>
 using namespace clang;
 
+/// \brief After failing to build a precompiled preamble (due to
+/// errors in the source that occurs in the preamble), the number of
+/// reparses during which we'll skip even trying to precompile the
+/// preamble.
+const unsigned DefaultPreambleRebuildInterval = 5;
+
 ASTUnit::ASTUnit(bool _MainFileIsAST)
-  : MainFileIsAST(_MainFileIsAST), ConcurrencyCheckValue(CheckUnlocked) { }
+  : CaptureDiagnostics(false), MainFileIsAST(_MainFileIsAST), 
+    CompleteTranslationUnit(true), ConcurrencyCheckValue(CheckUnlocked), 
+    PreambleRebuildCounter(0), SavedMainFileBuffer(0), PreambleBuffer(0),
+    ShouldCacheCodeCompletionResults(false),
+    NumTopLevelDeclsAtLastCompletionCache(0),
+    CacheCodeCompletionCoolDown(0),
+    UnsafeToFree(false) { 
+}
 
 ASTUnit::~ASTUnit() {
   ConcurrencyCheckValue = CheckLocked;
+  CleanTemporaryFiles();
+  if (!PreambleFile.empty())
+    llvm::sys::Path(PreambleFile).eraseFromDisk();
+  
+  // Free the buffers associated with remapped files. We are required to
+  // perform this operation here because we explicitly request that the
+  // compiler instance *not* free these buffers for each invocation of the
+  // parser.
+  if (Invocation.get()) {
+    PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
+    for (PreprocessorOptions::remapped_file_buffer_iterator
+           FB = PPOpts.remapped_file_buffer_begin(),
+           FBEnd = PPOpts.remapped_file_buffer_end();
+         FB != FBEnd;
+         ++FB)
+      delete FB->second;
+  }
+  
+  delete SavedMainFileBuffer;
+  delete PreambleBuffer;
+
+  ClearCachedCompletionResults();
+  
+  for (unsigned I = 0, N = Timers.size(); I != N; ++I)
+    delete Timers[I];
+}
+
+void ASTUnit::CleanTemporaryFiles() {
   for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
     TemporaryFiles[I].eraseFromDisk();
+  TemporaryFiles.clear();
+}
+
+/// \brief Determine the set of code-completion contexts in which this 
+/// declaration should be shown.
+static unsigned getDeclShowContexts(NamedDecl *ND,
+                                    const LangOptions &LangOpts,
+                                    bool &IsNestedNameSpecifier) {
+  IsNestedNameSpecifier = false;
+  
+  if (isa<UsingShadowDecl>(ND))
+    ND = dyn_cast<NamedDecl>(ND->getUnderlyingDecl());
+  if (!ND)
+    return 0;
+  
+  unsigned Contexts = 0;
+  if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) || 
+      isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND)) {
+    // Types can appear in these contexts.
+    if (LangOpts.CPlusPlus || !isa<TagDecl>(ND))
+      Contexts |= (1 << (CodeCompletionContext::CCC_TopLevel - 1))
+                | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1))
+                | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1))
+                | (1 << (CodeCompletionContext::CCC_Statement - 1))
+                | (1 << (CodeCompletionContext::CCC_Type - 1));
+
+    // In C++, types can appear in expressions contexts (for functional casts).
+    if (LangOpts.CPlusPlus)
+      Contexts |= (1 << (CodeCompletionContext::CCC_Expression - 1));
+    
+    // In Objective-C, message sends can send interfaces. In Objective-C++,
+    // all types are available due to functional casts.
+    if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(ND))
+      Contexts |= (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1));
+
+    // Deal with tag names.
+    if (isa<EnumDecl>(ND)) {
+      Contexts |= (1 << (CodeCompletionContext::CCC_EnumTag - 1));
+      
+      // Part of the nested-name-specifier in C++0x.
+      if (LangOpts.CPlusPlus0x)
+        IsNestedNameSpecifier = true;
+    } else if (RecordDecl *Record = dyn_cast<RecordDecl>(ND)) {
+      if (Record->isUnion())
+        Contexts |= (1 << (CodeCompletionContext::CCC_UnionTag - 1));
+      else
+        Contexts |= (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1));
+      
+      if (LangOpts.CPlusPlus)
+        IsNestedNameSpecifier = true;
+    } else if (isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND))
+      IsNestedNameSpecifier = true;
+  } else if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) {
+    // Values can appear in these contexts.
+    Contexts = (1 << (CodeCompletionContext::CCC_Statement - 1))
+             | (1 << (CodeCompletionContext::CCC_Expression - 1))
+             | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1));
+  } else if (isa<ObjCProtocolDecl>(ND)) {
+    Contexts = (1 << (CodeCompletionContext::CCC_ObjCProtocolName - 1));
+  } else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) {
+    Contexts = (1 << (CodeCompletionContext::CCC_Namespace - 1));
+   
+    // Part of the nested-name-specifier.
+    IsNestedNameSpecifier = true;
+  }
+  
+  return Contexts;
+}
+
+void ASTUnit::CacheCodeCompletionResults() {
+  if (!TheSema)
+    return;
+  
+  llvm::Timer *CachingTimer = 0;
+  if (TimerGroup.get()) {
+    CachingTimer = new llvm::Timer("Cache global code completions", 
+                                   *TimerGroup);
+    CachingTimer->startTimer();
+    Timers.push_back(CachingTimer);
+  }
+
+  // Clear out the previous results.
+  ClearCachedCompletionResults();
+  
+  // Gather the set of global code completions.
+  typedef CodeCompletionResult Result;
+  llvm::SmallVector<Result, 8> Results;
+  TheSema->GatherGlobalCodeCompletions(Results);
+  
+  // Translate global code completions into cached completions.
+  llvm::DenseMap<CanQualType, unsigned> CompletionTypes;
+  
+  for (unsigned I = 0, N = Results.size(); I != N; ++I) {
+    switch (Results[I].Kind) {
+    case Result::RK_Declaration: {
+      bool IsNestedNameSpecifier = false;
+      CachedCodeCompletionResult CachedResult;
+      CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema);
+      CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration,
+                                                        Ctx->getLangOptions(),
+                                                        IsNestedNameSpecifier);
+      CachedResult.Priority = Results[I].Priority;
+      CachedResult.Kind = Results[I].CursorKind;
+      CachedResult.Availability = Results[I].Availability;
+
+      // Keep track of the type of this completion in an ASTContext-agnostic 
+      // way.
+      QualType UsageType = getDeclUsageType(*Ctx, Results[I].Declaration);
+      if (UsageType.isNull()) {
+        CachedResult.TypeClass = STC_Void;
+        CachedResult.Type = 0;
+      } else {
+        CanQualType CanUsageType
+          = Ctx->getCanonicalType(UsageType.getUnqualifiedType());
+        CachedResult.TypeClass = getSimplifiedTypeClass(CanUsageType);
+
+        // Determine whether we have already seen this type. If so, we save
+        // ourselves the work of formatting the type string by using the 
+        // temporary, CanQualType-based hash table to find the associated value.
+        unsigned &TypeValue = CompletionTypes[CanUsageType];
+        if (TypeValue == 0) {
+          TypeValue = CompletionTypes.size();
+          CachedCompletionTypes[QualType(CanUsageType).getAsString()]
+            = TypeValue;
+        }
+        
+        CachedResult.Type = TypeValue;
+      }
+      
+      CachedCompletionResults.push_back(CachedResult);
+      
+      /// Handle nested-name-specifiers in C++.
+      if (TheSema->Context.getLangOptions().CPlusPlus && 
+          IsNestedNameSpecifier && !Results[I].StartsNestedNameSpecifier) {
+        // The contexts in which a nested-name-specifier can appear in C++.
+        unsigned NNSContexts
+          = (1 << (CodeCompletionContext::CCC_TopLevel - 1))
+          | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1))
+          | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1))
+          | (1 << (CodeCompletionContext::CCC_Statement - 1))
+          | (1 << (CodeCompletionContext::CCC_Expression - 1))
+          | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1))
+          | (1 << (CodeCompletionContext::CCC_EnumTag - 1))
+          | (1 << (CodeCompletionContext::CCC_UnionTag - 1))
+          | (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1))
+          | (1 << (CodeCompletionContext::CCC_Type - 1))
+          | (1 << (CodeCompletionContext::CCC_PotentiallyQualifiedName - 1));
+
+        if (isa<NamespaceDecl>(Results[I].Declaration) ||
+            isa<NamespaceAliasDecl>(Results[I].Declaration))
+          NNSContexts |= (1 << (CodeCompletionContext::CCC_Namespace - 1));
+
+        if (unsigned RemainingContexts 
+                                = NNSContexts & ~CachedResult.ShowInContexts) {
+          // If there any contexts where this completion can be a 
+          // nested-name-specifier but isn't already an option, create a 
+          // nested-name-specifier completion.
+          Results[I].StartsNestedNameSpecifier = true;
+          CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema);
+          CachedResult.ShowInContexts = RemainingContexts;
+          CachedResult.Priority = CCP_NestedNameSpecifier;
+          CachedResult.TypeClass = STC_Void;
+          CachedResult.Type = 0;
+          CachedCompletionResults.push_back(CachedResult);
+        }
+      }
+      break;
+    }
+        
+    case Result::RK_Keyword:
+    case Result::RK_Pattern:
+      // Ignore keywords and patterns; we don't care, since they are so
+      // easily regenerated.
+      break;
+      
+    case Result::RK_Macro: {
+      CachedCodeCompletionResult CachedResult;
+      CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema);
+      CachedResult.ShowInContexts
+        = (1 << (CodeCompletionContext::CCC_TopLevel - 1))
+        | (1 << (CodeCompletionContext::CCC_ObjCInterface - 1))
+        | (1 << (CodeCompletionContext::CCC_ObjCImplementation - 1))
+        | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1))
+        | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1))
+        | (1 << (CodeCompletionContext::CCC_Statement - 1))
+        | (1 << (CodeCompletionContext::CCC_Expression - 1))
+        | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1))
+        | (1 << (CodeCompletionContext::CCC_MacroNameUse - 1))
+        | (1 << (CodeCompletionContext::CCC_PreprocessorExpression - 1));
+      
+      CachedResult.Priority = Results[I].Priority;
+      CachedResult.Kind = Results[I].CursorKind;
+      CachedResult.Availability = Results[I].Availability;
+      CachedResult.TypeClass = STC_Void;
+      CachedResult.Type = 0;
+      CachedCompletionResults.push_back(CachedResult);
+      break;
+    }
+    }
+    Results[I].Destroy();
+  }
+
+  if (CachingTimer)
+    CachingTimer->stopTimer();
+  
+  // Make a note of the state when we performed this caching.
+  NumTopLevelDeclsAtLastCompletionCache = top_level_size();
+  CacheCodeCompletionCoolDown = 15;
+}
+
+void ASTUnit::ClearCachedCompletionResults() {
+  for (unsigned I = 0, N = CachedCompletionResults.size(); I != N; ++I)
+    delete CachedCompletionResults[I].Completion;
+  CachedCompletionResults.clear();
+  CachedCompletionTypes.clear();
 }
 
 namespace {
 
-/// \brief Gathers information from PCHReader that will be used to initialize
+/// \brief Gathers information from ASTReader that will be used to initialize
 /// a Preprocessor.
-class PCHInfoCollector : public PCHReaderListener {
+class ASTInfoCollector : public ASTReaderListener {
   LangOptions &LangOpt;
   HeaderSearch &HSI;
   std::string &TargetTriple;
@@ -58,7 +322,7 @@
   unsigned NumHeaderInfos;
 
 public:
-  PCHInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI,
+  ASTInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI,
                    std::string &TargetTriple, std::string &Predefines,
                    unsigned &Counter)
     : LangOpt(LangOpt), HSI(HSI), TargetTriple(TargetTriple),
@@ -74,11 +338,13 @@
     return false;
   }
 
-  virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
-                                    FileID PCHBufferID,
+  virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
                                     llvm::StringRef OriginalFileName,
                                     std::string &SuggestedPredefines) {
-    Predefines = PCHPredef;
+    Predefines = Buffers[0].Data;
+    for (unsigned I = 1, N = Buffers.size(); I != N; ++I) {
+      Predefines += Buffers[I].Data;
+    }
     return false;
   }
 
@@ -113,14 +379,19 @@
 public:
   CaptureDroppedDiagnostics(bool RequestCapture, Diagnostic &Diags, 
                            llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags)
-    : Diags(Diags), Client(StoredDiags), PreviousClient(Diags.getClient()) 
+    : Diags(Diags), Client(StoredDiags), PreviousClient(0)
   {
-    if (RequestCapture || Diags.getClient() == 0)
+    if (RequestCapture || Diags.getClient() == 0) {
+      PreviousClient = Diags.takeClient();
       Diags.setClient(&Client);
+    }
   }
 
   ~CaptureDroppedDiagnostics() {
-    Diags.setClient(PreviousClient);
+    if (Diags.getClient() == &Client) {
+      Diags.takeClient();
+      Diags.setClient(PreviousClient);
+    }
   }
 };
 
@@ -135,12 +406,12 @@
   return OriginalSourceFile;
 }
 
-const std::string &ASTUnit::getPCHFileName() {
-  assert(isMainFileAST() && "Not an ASTUnit from a PCH file!");
-  return static_cast<PCHReader *>(Ctx->getExternalSource())->getFileName();
+const std::string &ASTUnit::getASTFileName() {
+  assert(isMainFileAST() && "Not an ASTUnit from an AST file!");
+  return static_cast<ASTReader *>(Ctx->getExternalSource())->getFileName();
 }
 
-ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
+ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,
                                   llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
                                   bool OnlyLocalDecls,
                                   RemappedFile *RemappedFiles,
@@ -154,13 +425,14 @@
     DiagnosticOptions DiagOpts;
     Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
   }
-  
+
+  AST->CaptureDiagnostics = CaptureDiagnostics;
   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);
@@ -192,33 +464,33 @@
   std::string Predefines;
   unsigned Counter;
 
-  llvm::OwningPtr<PCHReader> Reader;
-  llvm::OwningPtr<ExternalASTSource> Source;
+  llvm::OwningPtr<ASTReader> Reader;
 
-  Reader.reset(new PCHReader(AST->getSourceManager(), AST->getFileManager(),
+  Reader.reset(new ASTReader(AST->getSourceManager(), AST->getFileManager(),
                              AST->getDiagnostics()));
-  Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple,
+  Reader->setListener(new ASTInfoCollector(LangInfo, HeaderInfo, TargetTriple,
                                            Predefines, Counter));
 
-  switch (Reader->ReadPCH(Filename)) {
-  case PCHReader::Success:
+  switch (Reader->ReadAST(Filename)) {
+  case ASTReader::Success:
     break;
 
-  case PCHReader::Failure:
-  case PCHReader::IgnorePCH:
+  case ASTReader::Failure:
+  case ASTReader::IgnorePCH:
     AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
     return NULL;
   }
 
   AST->OriginalSourceFile = Reader->getOriginalSourceFile();
 
-  // PCH loaded successfully. Now create the preprocessor.
+  // AST file 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.
+  // FIXME: This is broken, we should store the TargetOptions in the AST file.
   TargetOptions TargetOpts;
   TargetOpts.ABI = "";
+  TargetOpts.CXXABI = "";
   TargetOpts.CPU = "";
   TargetOpts.Features.clear();
   TargetOpts.Triple = TargetTriple;
@@ -241,18 +513,26 @@
                                 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
+  // Attach the AST 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());
+  // AST file as needed.
+  ASTReader *ReaderPtr = Reader.get();
+  llvm::OwningPtr<ExternalASTSource> Source(Reader.take());
   Context.setExternalSource(Source);
 
+  // Create an AST consumer, even though it isn't used.
+  AST->Consumer.reset(new ASTConsumer);
+  
+  // Create a semantic analysis object and tell the AST reader about it.
+  AST->TheSema.reset(new Sema(PP, Context, *AST->Consumer));
+  AST->TheSema->Initialize();
+  ReaderPtr->InitializeSema(*AST->TheSema);
+
   return AST.take();
 }
 
@@ -265,9 +545,20 @@
   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);
+    for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) {
+      Decl *D = *it;
+      // FIXME: Currently ObjC method declarations are incorrectly being
+      // reported as top-level declarations, even though their DeclContext
+      // is the containing ObjC @interface/@implementation.  This is a
+      // fundamental problem in the parser right now.
+      if (isa<ObjCMethodDecl>(D))
+        continue;
+      Unit.addTopLevelDecl(D);
+    }
   }
+
+  // We're not interested in "interesting" decls.
+  void HandleInterestingDecl(DeclGroupRef) {}
 };
 
 class TopLevelDeclTrackerAction : public ASTFrontendAction {
@@ -283,37 +574,108 @@
   TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
 
   virtual bool hasCodeCompletionSupport() const { return false; }
+  virtual bool usesCompleteTranslationUnit()  { 
+    return Unit.isCompleteTranslationUnit(); 
+  }
+};
+
+class PrecompilePreambleConsumer : public PCHGenerator {
+  ASTUnit &Unit;
+  std::vector<Decl *> TopLevelDecls;
+
+public:
+  PrecompilePreambleConsumer(ASTUnit &Unit,
+                             const Preprocessor &PP, bool Chaining,
+                             const char *isysroot, llvm::raw_ostream *Out)
+    : PCHGenerator(PP, Chaining, isysroot, Out), Unit(Unit) { }
+
+  virtual void HandleTopLevelDecl(DeclGroupRef D) {
+    for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) {
+      Decl *D = *it;
+      // FIXME: Currently ObjC method declarations are incorrectly being
+      // reported as top-level declarations, even though their DeclContext
+      // is the containing ObjC @interface/@implementation.  This is a
+      // fundamental problem in the parser right now.
+      if (isa<ObjCMethodDecl>(D))
+        continue;
+      TopLevelDecls.push_back(D);
+    }
+  }
+
+  virtual void HandleTranslationUnit(ASTContext &Ctx) {
+    PCHGenerator::HandleTranslationUnit(Ctx);
+    if (!Unit.getDiagnostics().hasErrorOccurred()) {
+      // Translate the top-level declarations we captured during
+      // parsing into declaration IDs in the precompiled
+      // preamble. This will allow us to deserialize those top-level
+      // declarations when requested.
+      for (unsigned I = 0, N = TopLevelDecls.size(); I != N; ++I)
+        Unit.addTopLevelDeclFromPreamble(
+                                      getWriter().getDeclID(TopLevelDecls[I]));
+    }
+  }
+};
+
+class PrecompilePreambleAction : public ASTFrontendAction {
+  ASTUnit &Unit;
+
+public:
+  explicit PrecompilePreambleAction(ASTUnit &Unit) : Unit(Unit) {}
+
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile) {
+    std::string Sysroot;
+    llvm::raw_ostream *OS = 0;
+    bool Chaining;
+    if (GeneratePCHAction::ComputeASTConsumerArguments(CI, InFile, Sysroot, 
+                                                       OS, Chaining))
+      return 0;
+    
+    const char *isysroot = CI.getFrontendOpts().RelocatablePCH ?
+                             Sysroot.c_str() : 0;  
+    return new PrecompilePreambleConsumer(Unit, CI.getPreprocessor(), Chaining,
+                                          isysroot, OS);
+  }
+
+  virtual bool hasCodeCompletionSupport() const { return false; }
+  virtual bool hasASTFileSupport() const { return false; }
+  virtual bool usesCompleteTranslationUnit() { 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);
+/// Parse the source file into a translation unit using the given compiler
+/// invocation, replacing the current translation unit.
+///
+/// \returns True if a failure occurred that causes the ASTUnit not to
+/// contain any translation-unit information, false otherwise.
+bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
+  delete SavedMainFileBuffer;
+  SavedMainFileBuffer = 0;
+  
+  if (!Invocation.get()) {
+    delete OverrideMainBuffer;
+    return true;
   }
   
-  Clang.setInvocation(CI);
-
-  Clang.setDiagnostics(Diags.getPtr());
-  Clang.setDiagnosticClient(Diags->getClient());
-
+  // Create the compiler instance to use for building the AST.
+  CompilerInstance Clang;
+  Clang.setInvocation(Invocation.take());
+  OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second;
+    
+  // Set up diagnostics, capturing any diagnostics that would
+  // otherwise be dropped.
+  Clang.setDiagnostics(&getDiagnostics());
+  CaptureDroppedDiagnostics Capture(CaptureDiagnostics, 
+                                    getDiagnostics(),
+                                    StoredDiagnostics);
+  
   // Create the target instance.
   Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
                                                Clang.getTargetOpts()));
   if (!Clang.hasTarget()) {
-    Clang.takeDiagnosticClient();
-    return 0;
+    delete OverrideMainBuffer;
+    return true;
   }
 
   // Inform the target of the language options.
@@ -321,62 +683,657 @@
   // 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 &&
+  assert(Clang.getFrontendOpts().Inputs[0].first != IK_AST &&
          "FIXME: AST inputs not yet supported here!");
+  assert(Clang.getFrontendOpts().Inputs[0].first != IK_LLVM_IR &&
+         "IR inputs not support 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;
+  // Configure the various subsystems.
+  // FIXME: Should we retain the previous file manager?
+  FileMgr.reset(new FileManager);
+  SourceMgr.reset(new SourceManager(getDiagnostics()));
+  TheSema.reset();
+  Ctx.reset();
+  PP.reset();
+  
+  // Clear out old caches and data.
+  TopLevelDecls.clear();
+  CleanTemporaryFiles();
+  PreprocessedEntitiesByFile.clear();
 
-  // Capture any diagnostics that would otherwise be dropped.
-  CaptureDroppedDiagnostics Capture(CaptureDiagnostics, 
-                                    Clang.getDiagnostics(),
-                                    AST->StoredDiagnostics);
+  if (!OverrideMainBuffer) {
+    StoredDiagnostics.clear();
+    TopLevelDeclsInPreamble.clear();
+  }
 
   // Create a file manager object to provide access to and cache the filesystem.
-  Clang.setFileManager(&AST->getFileManager());
-
+  Clang.setFileManager(&getFileManager());
+  
   // Create the source manager.
-  Clang.setSourceManager(&AST->getSourceManager());
+  Clang.setSourceManager(&getSourceManager());
+  
+  // If the main file has been overridden due to the use of a preamble,
+  // make that override happen and introduce the preamble.
+  PreprocessorOptions &PreprocessorOpts = Clang.getPreprocessorOpts();
+  std::string PriorImplicitPCHInclude;
+  if (OverrideMainBuffer) {
+    PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer);
+    PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size();
+    PreprocessorOpts.PrecompiledPreambleBytes.second
+                                                    = PreambleEndsAtStartOfLine;
+    PriorImplicitPCHInclude = PreprocessorOpts.ImplicitPCHInclude;
+    PreprocessorOpts.ImplicitPCHInclude = PreambleFile;
+    PreprocessorOpts.DisablePCHValidation = true;
+    
+    // Keep track of the override buffer;
+    SavedMainFileBuffer = OverrideMainBuffer;
 
-  // Create the preprocessor.
-  Clang.createPreprocessor();
-
-  Act.reset(new TopLevelDeclTrackerAction(*AST));
+    // The stored diagnostic has the old source manager in it; update
+    // the locations to refer into the new source manager. Since we've
+    // been careful to make sure that the source manager's state
+    // before and after are identical, so that we can reuse the source
+    // location itself.
+    for (unsigned I = 0, N = StoredDiagnostics.size(); I != N; ++I) {
+      FullSourceLoc Loc(StoredDiagnostics[I].getLocation(),
+                        getSourceManager());
+      StoredDiagnostics[I].setLocation(Loc);
+    }
+  } else {
+    PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
+    PreprocessorOpts.PrecompiledPreambleBytes.second = false;
+  }
+  
+  llvm::OwningPtr<TopLevelDeclTrackerAction> Act;
+  Act.reset(new TopLevelDeclTrackerAction(*this));
   if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second,
-                           /*IsAST=*/false))
+                            Clang.getFrontendOpts().Inputs[0].first))
     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());
+  TheSema.reset(Clang.takeSema());
+  Consumer.reset(Clang.takeASTConsumer());
+  Ctx.reset(Clang.takeASTContext());
+  PP.reset(Clang.takePreprocessor());
   Clang.takeSourceManager();
   Clang.takeFileManager();
-  AST->Target.reset(Clang.takeTarget());
-
+  Target.reset(Clang.takeTarget());
+  
   Act->EndSourceFile();
 
-  Clang.takeDiagnosticClient();
-  Clang.takeInvocation();
+  // Remove the overridden buffer we used for the preamble.
+  if (OverrideMainBuffer) {
+    PreprocessorOpts.eraseRemappedFile(
+                               PreprocessorOpts.remapped_file_buffer_end() - 1);
+    PreprocessorOpts.ImplicitPCHInclude = PriorImplicitPCHInclude;
+  }
 
-  AST->Invocation.reset(Clang.takeInvocation());
-  return AST.take();
-
+  Invocation.reset(Clang.takeInvocation());
+  
+  // If we were asked to cache code-completion results and don't have any
+  // results yet, do so now.
+  if (ShouldCacheCodeCompletionResults && CachedCompletionResults.empty())
+    CacheCodeCompletionResults();
+  
+  return false;
+  
 error:
+  // Remove the overridden buffer we used for the preamble.
+  if (OverrideMainBuffer) {
+    PreprocessorOpts.eraseRemappedFile(
+                               PreprocessorOpts.remapped_file_buffer_end() - 1);
+    PreprocessorOpts.DisablePCHValidation = true;
+    PreprocessorOpts.ImplicitPCHInclude = PriorImplicitPCHInclude;
+    delete OverrideMainBuffer;
+  }
+  
   Clang.takeSourceManager();
   Clang.takeFileManager();
-  Clang.takeDiagnosticClient();
-  return 0;
+  Invocation.reset(Clang.takeInvocation());
+  return true;
+}
+
+/// \brief Simple function to retrieve a path for a preamble precompiled header.
+static std::string GetPreamblePCHPath() {
+  // FIXME: This is lame; sys::Path should provide this function (in particular,
+  // it should know how to find the temporary files dir).
+  // FIXME: This is really lame. I copied this code from the Driver!
+  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("preamble");
+  P.appendSuffix("pch");
+  if (P.createTemporaryFileOnDisk())
+    return std::string();
+  
+  return P.str();
+}
+
+/// \brief Compute the preamble for the main file, providing the source buffer
+/// that corresponds to the main file along with a pair (bytes, start-of-line)
+/// that describes the preamble.
+std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > 
+ASTUnit::ComputePreamble(CompilerInvocation &Invocation, 
+                         unsigned MaxLines, bool &CreatedBuffer) {
+  FrontendOptions &FrontendOpts = Invocation.getFrontendOpts();
+  PreprocessorOptions &PreprocessorOpts
+    = Invocation.getPreprocessorOpts();
+  CreatedBuffer = false;
+  
+  // Try to determine if the main file has been remapped, either from the 
+  // command line (to another file) or directly through the compiler invocation
+  // (to a memory buffer).
+  llvm::MemoryBuffer *Buffer = 0;
+  llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second);
+  if (const llvm::sys::FileStatus *MainFileStatus = MainFilePath.getFileStatus()) {
+    // Check whether there is a file-file remapping of the main file
+    for (PreprocessorOptions::remapped_file_iterator
+          M = PreprocessorOpts.remapped_file_begin(),
+          E = PreprocessorOpts.remapped_file_end();
+         M != E;
+         ++M) {
+      llvm::sys::PathWithStatus MPath(M->first);    
+      if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) {
+        if (MainFileStatus->uniqueID == MStatus->uniqueID) {
+          // We found a remapping. Try to load the resulting, remapped source.
+          if (CreatedBuffer) {
+            delete Buffer;
+            CreatedBuffer = false;
+          }
+          
+          Buffer = llvm::MemoryBuffer::getFile(M->second);
+          if (!Buffer)
+            return std::make_pair((llvm::MemoryBuffer*)0, 
+                                  std::make_pair(0, true));
+          CreatedBuffer = true;
+          
+          // Remove this remapping. We've captured the buffer already.
+          M = PreprocessorOpts.eraseRemappedFile(M);
+          E = PreprocessorOpts.remapped_file_end();
+          if (M == E)
+            break;
+        }
+      }
+    }
+    
+    // Check whether there is a file-buffer remapping. It supercedes the
+    // file-file remapping.
+    for (PreprocessorOptions::remapped_file_buffer_iterator
+           M = PreprocessorOpts.remapped_file_buffer_begin(),
+           E = PreprocessorOpts.remapped_file_buffer_end();
+         M != E;
+         ++M) {
+      llvm::sys::PathWithStatus MPath(M->first);    
+      if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) {
+        if (MainFileStatus->uniqueID == MStatus->uniqueID) {
+          // We found a remapping. 
+          if (CreatedBuffer) {
+            delete Buffer;
+            CreatedBuffer = false;
+          }
+          
+          Buffer = const_cast<llvm::MemoryBuffer *>(M->second);
+
+          // Remove this remapping. We've captured the buffer already.
+          M = PreprocessorOpts.eraseRemappedFile(M);
+          E = PreprocessorOpts.remapped_file_buffer_end();
+          if (M == E)
+            break;
+        }
+      }
+    }
+  }
+  
+  // If the main source file was not remapped, load it now.
+  if (!Buffer) {
+    Buffer = llvm::MemoryBuffer::getFile(FrontendOpts.Inputs[0].second);
+    if (!Buffer)
+      return std::make_pair((llvm::MemoryBuffer*)0, std::make_pair(0, true));    
+    
+    CreatedBuffer = true;
+  }
+  
+  return std::make_pair(Buffer, Lexer::ComputePreamble(Buffer, MaxLines));
+}
+
+static llvm::MemoryBuffer *CreatePaddedMainFileBuffer(llvm::MemoryBuffer *Old,
+                                                      bool DeleteOld,
+                                                      unsigned NewSize,
+                                                      llvm::StringRef NewName) {
+  llvm::MemoryBuffer *Result
+    = llvm::MemoryBuffer::getNewUninitMemBuffer(NewSize, NewName);
+  memcpy(const_cast<char*>(Result->getBufferStart()), 
+         Old->getBufferStart(), Old->getBufferSize());
+  memset(const_cast<char*>(Result->getBufferStart()) + Old->getBufferSize(), 
+         ' ', NewSize - Old->getBufferSize() - 1);
+  const_cast<char*>(Result->getBufferEnd())[-1] = '\n';  
+  
+  if (DeleteOld)
+    delete Old;
+  
+  return Result;
+}
+
+/// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing
+/// the source file.
+///
+/// This routine will compute the preamble of the main source file. If a
+/// non-trivial preamble is found, it will precompile that preamble into a 
+/// precompiled header so that the precompiled preamble can be used to reduce
+/// reparsing time. If a precompiled preamble has already been constructed,
+/// this routine will determine if it is still valid and, if so, avoid 
+/// rebuilding the precompiled preamble.
+///
+/// \param AllowRebuild When true (the default), this routine is
+/// allowed to rebuild the precompiled preamble if it is found to be
+/// out-of-date.
+///
+/// \param MaxLines When non-zero, the maximum number of lines that
+/// can occur within the preamble.
+///
+/// \returns If the precompiled preamble can be used, returns a newly-allocated
+/// buffer that should be used in place of the main file when doing so.
+/// Otherwise, returns a NULL pointer.
+llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
+                                          CompilerInvocation PreambleInvocation,
+                                                           bool AllowRebuild,
+                                                           unsigned MaxLines) {
+  FrontendOptions &FrontendOpts = PreambleInvocation.getFrontendOpts();
+  PreprocessorOptions &PreprocessorOpts
+    = PreambleInvocation.getPreprocessorOpts();
+
+  bool CreatedPreambleBuffer = false;
+  std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > NewPreamble 
+    = ComputePreamble(PreambleInvocation, MaxLines, CreatedPreambleBuffer);
+
+  if (!NewPreamble.second.first) {
+    // We couldn't find a preamble in the main source. Clear out the current
+    // preamble, if we have one. It's obviously no good any more.
+    Preamble.clear();
+    if (!PreambleFile.empty()) {
+      llvm::sys::Path(PreambleFile).eraseFromDisk();
+      PreambleFile.clear();
+    }
+    if (CreatedPreambleBuffer)
+      delete NewPreamble.first;
+
+    // The next time we actually see a preamble, precompile it.
+    PreambleRebuildCounter = 1;
+    return 0;
+  }
+  
+  if (!Preamble.empty()) {
+    // We've previously computed a preamble. Check whether we have the same
+    // preamble now that we did before, and that there's enough space in
+    // the main-file buffer within the precompiled preamble to fit the
+    // new main file.
+    if (Preamble.size() == NewPreamble.second.first &&
+        PreambleEndsAtStartOfLine == NewPreamble.second.second &&
+        NewPreamble.first->getBufferSize() < PreambleReservedSize-2 &&
+        memcmp(&Preamble[0], NewPreamble.first->getBufferStart(),
+               NewPreamble.second.first) == 0) {
+      // The preamble has not changed. We may be able to re-use the precompiled
+      // preamble.
+
+      // Check that none of the files used by the preamble have changed.
+      bool AnyFileChanged = false;
+          
+      // First, make a record of those files that have been overridden via
+      // remapping or unsaved_files.
+      llvm::StringMap<std::pair<off_t, time_t> > OverriddenFiles;
+      for (PreprocessorOptions::remapped_file_iterator
+                R = PreprocessorOpts.remapped_file_begin(),
+             REnd = PreprocessorOpts.remapped_file_end();
+           !AnyFileChanged && R != REnd;
+           ++R) {
+        struct stat StatBuf;
+        if (stat(R->second.c_str(), &StatBuf)) {
+          // If we can't stat the file we're remapping to, assume that something
+          // horrible happened.
+          AnyFileChanged = true;
+          break;
+        }
+        
+        OverriddenFiles[R->first] = std::make_pair(StatBuf.st_size, 
+                                                   StatBuf.st_mtime);
+      }
+      for (PreprocessorOptions::remapped_file_buffer_iterator
+                R = PreprocessorOpts.remapped_file_buffer_begin(),
+             REnd = PreprocessorOpts.remapped_file_buffer_end();
+           !AnyFileChanged && R != REnd;
+           ++R) {
+        // FIXME: Should we actually compare the contents of file->buffer
+        // remappings?
+        OverriddenFiles[R->first] = std::make_pair(R->second->getBufferSize(), 
+                                                   0);
+      }
+       
+      // Check whether anything has changed.
+      for (llvm::StringMap<std::pair<off_t, time_t> >::iterator 
+             F = FilesInPreamble.begin(), FEnd = FilesInPreamble.end();
+           !AnyFileChanged && F != FEnd; 
+           ++F) {
+        llvm::StringMap<std::pair<off_t, time_t> >::iterator Overridden
+          = OverriddenFiles.find(F->first());
+        if (Overridden != OverriddenFiles.end()) {
+          // This file was remapped; check whether the newly-mapped file 
+          // matches up with the previous mapping.
+          if (Overridden->second != F->second)
+            AnyFileChanged = true;
+          continue;
+        }
+        
+        // The file was not remapped; check whether it has changed on disk.
+        struct stat StatBuf;
+        if (stat(F->first(), &StatBuf)) {
+          // If we can't stat the file, assume that something horrible happened.
+          AnyFileChanged = true;
+        } else if (StatBuf.st_size != F->second.first || 
+                   StatBuf.st_mtime != F->second.second)
+          AnyFileChanged = true;
+      }
+          
+      if (!AnyFileChanged) {
+        // Okay! We can re-use the precompiled preamble.
+
+        // Set the state of the diagnostic object to mimic its state
+        // after parsing the preamble.
+        getDiagnostics().Reset();
+        getDiagnostics().setNumWarnings(NumWarningsInPreamble);
+        if (StoredDiagnostics.size() > NumStoredDiagnosticsInPreamble)
+          StoredDiagnostics.erase(
+            StoredDiagnostics.begin() + NumStoredDiagnosticsInPreamble,
+                                  StoredDiagnostics.end());
+
+        // Create a version of the main file buffer that is padded to
+        // buffer size we reserved when creating the preamble.
+        return CreatePaddedMainFileBuffer(NewPreamble.first, 
+                                          CreatedPreambleBuffer,
+                                          PreambleReservedSize,
+                                          FrontendOpts.Inputs[0].second);
+      }
+    }
+
+    // If we aren't allowed to rebuild the precompiled preamble, just
+    // return now.
+    if (!AllowRebuild)
+      return 0;
+    
+    // We can't reuse the previously-computed preamble. Build a new one.
+    Preamble.clear();
+    llvm::sys::Path(PreambleFile).eraseFromDisk();
+    PreambleRebuildCounter = 1;
+  } else if (!AllowRebuild) {
+    // We aren't allowed to rebuild the precompiled preamble; just
+    // return now.
+    return 0;
+  }
+
+  // If the preamble rebuild counter > 1, it's because we previously
+  // failed to build a preamble and we're not yet ready to try
+  // again. Decrement the counter and return a failure.
+  if (PreambleRebuildCounter > 1) {
+    --PreambleRebuildCounter;
+    return 0;
+  }
+
+  // We did not previously compute a preamble, or it can't be reused anyway.
+  llvm::Timer *PreambleTimer = 0;
+  if (TimerGroup.get()) {
+    PreambleTimer = new llvm::Timer("Precompiling preamble", *TimerGroup);
+    PreambleTimer->startTimer();
+    Timers.push_back(PreambleTimer);
+  }
+  
+  // Create a new buffer that stores the preamble. The buffer also contains
+  // extra space for the original contents of the file (which will be present
+  // when we actually parse the file) along with more room in case the file
+  // grows.  
+  PreambleReservedSize = NewPreamble.first->getBufferSize();
+  if (PreambleReservedSize < 4096)
+    PreambleReservedSize = 8191;
+  else
+    PreambleReservedSize *= 2;
+
+  // Save the preamble text for later; we'll need to compare against it for
+  // subsequent reparses.
+  Preamble.assign(NewPreamble.first->getBufferStart(), 
+                  NewPreamble.first->getBufferStart() 
+                                                  + NewPreamble.second.first);
+  PreambleEndsAtStartOfLine = NewPreamble.second.second;
+
+  delete PreambleBuffer;
+  PreambleBuffer
+    = llvm::MemoryBuffer::getNewUninitMemBuffer(PreambleReservedSize,
+                                                FrontendOpts.Inputs[0].second);
+  memcpy(const_cast<char*>(PreambleBuffer->getBufferStart()), 
+         NewPreamble.first->getBufferStart(), Preamble.size());
+  memset(const_cast<char*>(PreambleBuffer->getBufferStart()) + Preamble.size(), 
+         ' ', PreambleReservedSize - Preamble.size() - 1);
+  const_cast<char*>(PreambleBuffer->getBufferEnd())[-1] = '\n';  
+  
+  // Remap the main source file to the preamble buffer.
+  llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second);
+  PreprocessorOpts.addRemappedFile(MainFilePath.str(), PreambleBuffer);
+  
+  // Tell the compiler invocation to generate a temporary precompiled header.
+  FrontendOpts.ProgramAction = frontend::GeneratePCH;
+  // FIXME: Set ChainedPCH unconditionally, once it is ready.
+  if (::getenv("LIBCLANG_CHAINING"))
+    FrontendOpts.ChainedPCH = true;
+  // FIXME: Generate the precompiled header into memory?
+  FrontendOpts.OutputFile = GetPreamblePCHPath();
+  
+  // Create the compiler instance to use for building the precompiled preamble.
+  CompilerInstance Clang;
+  Clang.setInvocation(&PreambleInvocation);
+  OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second;
+  
+  // Set up diagnostics, capturing all of the diagnostics produced.
+  Clang.setDiagnostics(&getDiagnostics());
+  CaptureDroppedDiagnostics Capture(CaptureDiagnostics, 
+                                    getDiagnostics(),
+                                    StoredDiagnostics);
+  
+  // Create the target instance.
+  Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
+                                               Clang.getTargetOpts()));
+  if (!Clang.hasTarget()) {
+    llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk();
+    Preamble.clear();
+    if (CreatedPreambleBuffer)
+      delete NewPreamble.first;
+    if (PreambleTimer)
+      PreambleTimer->stopTimer();
+    PreambleRebuildCounter = DefaultPreambleRebuildInterval;
+    PreprocessorOpts.eraseRemappedFile(
+                               PreprocessorOpts.remapped_file_buffer_end() - 1);
+    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 != IK_AST &&
+         "FIXME: AST inputs not yet supported here!");
+  assert(Clang.getFrontendOpts().Inputs[0].first != IK_LLVM_IR &&
+         "IR inputs not support here!");
+  
+  // Clear out old caches and data.
+  StoredDiagnostics.clear();
+  TopLevelDecls.clear();
+  TopLevelDeclsInPreamble.clear();
+  
+  // Create a file manager object to provide access to and cache the filesystem.
+  Clang.setFileManager(new FileManager);
+  
+  // Create the source manager.
+  Clang.setSourceManager(new SourceManager(getDiagnostics()));
+  
+  llvm::OwningPtr<PrecompilePreambleAction> Act;
+  Act.reset(new PrecompilePreambleAction(*this));
+  if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second,
+                            Clang.getFrontendOpts().Inputs[0].first)) {
+    Clang.takeInvocation();
+    llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk();
+    Preamble.clear();
+    if (CreatedPreambleBuffer)
+      delete NewPreamble.first;
+    if (PreambleTimer)
+      PreambleTimer->stopTimer();
+    PreambleRebuildCounter = DefaultPreambleRebuildInterval;
+    PreprocessorOpts.eraseRemappedFile(
+                               PreprocessorOpts.remapped_file_buffer_end() - 1);
+    return 0;
+  }
+  
+  Act->Execute();
+  Act->EndSourceFile();
+  Clang.takeInvocation();
+  
+  if (Diagnostics->hasErrorOccurred()) {
+    // There were errors parsing the preamble, so no precompiled header was
+    // generated. Forget that we even tried.
+    // FIXME: Should we leave a note for ourselves to try again?
+    llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk();
+    Preamble.clear();
+    if (CreatedPreambleBuffer)
+      delete NewPreamble.first;
+    if (PreambleTimer)
+      PreambleTimer->stopTimer();
+    TopLevelDeclsInPreamble.clear();
+    PreambleRebuildCounter = DefaultPreambleRebuildInterval;
+    PreprocessorOpts.eraseRemappedFile(
+                               PreprocessorOpts.remapped_file_buffer_end() - 1);
+    return 0;
+  }
+  
+  // Keep track of the preamble we precompiled.
+  PreambleFile = FrontendOpts.OutputFile;
+  NumStoredDiagnosticsInPreamble = StoredDiagnostics.size();
+  NumWarningsInPreamble = getDiagnostics().getNumWarnings();
+  
+  // Keep track of all of the files that the source manager knows about,
+  // so we can verify whether they have changed or not.
+  FilesInPreamble.clear();
+  SourceManager &SourceMgr = Clang.getSourceManager();
+  const llvm::MemoryBuffer *MainFileBuffer
+    = SourceMgr.getBuffer(SourceMgr.getMainFileID());
+  for (SourceManager::fileinfo_iterator F = SourceMgr.fileinfo_begin(),
+                                     FEnd = SourceMgr.fileinfo_end();
+       F != FEnd;
+       ++F) {
+    const FileEntry *File = F->second->Entry;
+    if (!File || F->second->getRawBuffer() == MainFileBuffer)
+      continue;
+    
+    FilesInPreamble[File->getName()]
+      = std::make_pair(F->second->getSize(), File->getModificationTime());
+  }
+  
+  if (PreambleTimer)
+    PreambleTimer->stopTimer();
+  
+  PreambleRebuildCounter = 1;
+  PreprocessorOpts.eraseRemappedFile(
+                               PreprocessorOpts.remapped_file_buffer_end() - 1);
+  return CreatePaddedMainFileBuffer(NewPreamble.first, 
+                                    CreatedPreambleBuffer,
+                                    PreambleReservedSize,
+                                    FrontendOpts.Inputs[0].second);
+}
+
+void ASTUnit::RealizeTopLevelDeclsFromPreamble() {
+  std::vector<Decl *> Resolved;
+  Resolved.reserve(TopLevelDeclsInPreamble.size());
+  ExternalASTSource &Source = *getASTContext().getExternalSource();
+  for (unsigned I = 0, N = TopLevelDeclsInPreamble.size(); I != N; ++I) {
+    // Resolve the declaration ID to an actual declaration, possibly
+    // deserializing the declaration in the process.
+    Decl *D = Source.GetExternalDecl(TopLevelDeclsInPreamble[I]);
+    if (D)
+      Resolved.push_back(D);
+  }
+  TopLevelDeclsInPreamble.clear();
+  TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end());
+}
+
+unsigned ASTUnit::getMaxPCHLevel() const {
+  if (!getOnlyLocalDecls())
+    return Decl::MaxPCHLevel;
+
+  unsigned Result = 0;
+  if (isMainFileAST() || SavedMainFileBuffer)
+    ++Result;
+  return Result;
+}
+
+ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
+                                   llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
+                                             bool OnlyLocalDecls,
+                                             bool CaptureDiagnostics,
+                                             bool PrecompilePreamble,
+                                             bool CompleteTranslationUnit,
+                                             bool CacheCodeCompletionResults) {
+  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);
+  }
+  
+  // Create the AST unit.
+  llvm::OwningPtr<ASTUnit> AST;
+  AST.reset(new ASTUnit(false));
+  AST->Diagnostics = Diags;
+  AST->CaptureDiagnostics = CaptureDiagnostics;
+  AST->OnlyLocalDecls = OnlyLocalDecls;
+  AST->CompleteTranslationUnit = CompleteTranslationUnit;
+  AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
+  AST->Invocation.reset(CI);
+  CI->getPreprocessorOpts().RetainRemappedFileBuffers = true;
+  
+  if (getenv("LIBCLANG_TIMING"))
+    AST->TimerGroup.reset(
+                  new llvm::TimerGroup(CI->getFrontendOpts().Inputs[0].second));
+  
+  
+  llvm::MemoryBuffer *OverrideMainBuffer = 0;
+  // FIXME: When C++ PCH is ready, allow use of it for a precompiled preamble.
+  if (PrecompilePreamble && !CI->getLangOpts().CPlusPlus) {
+    AST->PreambleRebuildCounter = 1;
+    OverrideMainBuffer
+      = AST->getMainBufferWithPrecompiledPreamble(*AST->Invocation);
+  }
+  
+  llvm::Timer *ParsingTimer = 0;
+  if (AST->TimerGroup.get()) {
+    ParsingTimer = new llvm::Timer("Initial parse", *AST->TimerGroup);
+    ParsingTimer->startTimer();
+    AST->Timers.push_back(ParsingTimer);
+  }
+  
+  bool Failed = AST->Parse(OverrideMainBuffer);
+  if (ParsingTimer)
+    ParsingTimer->stopTimer();
+  
+  return Failed? 0 : AST.take();
 }
 
 ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
@@ -386,12 +1343,18 @@
                                       bool OnlyLocalDecls,
                                       RemappedFile *RemappedFiles,
                                       unsigned NumRemappedFiles,
-                                      bool CaptureDiagnostics) {
+                                      bool CaptureDiagnostics,
+                                      bool PrecompilePreamble,
+                                      bool CompleteTranslationUnit,
+                                      bool CacheCodeCompletionResults) {
+  bool CreatedDiagnosticsObject = false;
+  
   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);
+    CreatedDiagnosticsObject = true;
   }
   
   llvm::SmallVector<const char *, 16> Args;
@@ -403,7 +1366,7 @@
   Args.push_back("-fsyntax-only");
 
   // FIXME: We shouldn't have to pass in the path info.
-  driver::Driver TheDriver("clang", "/", llvm::sys::getHostTriple(),
+  driver::Driver TheDriver("clang", llvm::sys::getHostTriple(),
                            "a.out", false, false, *Diags);
 
   // Don't check that inputs exist, they have been remapped.
@@ -434,7 +1397,7 @@
   CompilerInvocation::CreateFromArgs(*CI,
                                      const_cast<const char **>(CCArgs.data()),
                                      const_cast<const char **>(CCArgs.data()) +
-                                       CCArgs.size(),
+                                     CCArgs.size(),
                                      *Diags);
 
   // Override any files that need remapping
@@ -445,7 +1408,468 @@
   // Override the resources path.
   CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
 
-  CI->getFrontendOpts().DisableFree = true;
+  CI->getFrontendOpts().DisableFree = false;
   return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls,
-                                    CaptureDiagnostics);
+                                    CaptureDiagnostics, PrecompilePreamble,
+                                    CompleteTranslationUnit,
+                                    CacheCodeCompletionResults);
+}
+
+bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) {
+  if (!Invocation.get())
+    return true;
+  
+  llvm::Timer *ReparsingTimer = 0;
+  if (TimerGroup.get()) {
+    ReparsingTimer = new llvm::Timer("Reparse", *TimerGroup);
+    ReparsingTimer->startTimer();
+    Timers.push_back(ReparsingTimer);
+  }
+  
+  // Remap files.
+  PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
+  for (PreprocessorOptions::remapped_file_buffer_iterator 
+         R = PPOpts.remapped_file_buffer_begin(),
+         REnd = PPOpts.remapped_file_buffer_end();
+       R != REnd; 
+       ++R) {
+    delete R->second;
+  }
+  Invocation->getPreprocessorOpts().clearRemappedFiles();
+  for (unsigned I = 0; I != NumRemappedFiles; ++I)
+    Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
+                                                      RemappedFiles[I].second);
+  
+  // If we have a preamble file lying around, or if we might try to
+  // build a precompiled preamble, do so now.
+  llvm::MemoryBuffer *OverrideMainBuffer = 0;
+  if (!PreambleFile.empty() || PreambleRebuildCounter > 0)
+    OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation);
+    
+  // Clear out the diagnostics state.
+  if (!OverrideMainBuffer)
+    getDiagnostics().Reset();
+  
+  // Parse the sources
+  bool Result = Parse(OverrideMainBuffer);  
+  if (ReparsingTimer)
+    ReparsingTimer->stopTimer();
+  
+  if (ShouldCacheCodeCompletionResults) {
+    if (CacheCodeCompletionCoolDown > 0)
+      --CacheCodeCompletionCoolDown;
+    else if (top_level_size() != NumTopLevelDeclsAtLastCompletionCache)
+      CacheCodeCompletionResults();
+  }
+  
+  return Result;
+}
+
+//----------------------------------------------------------------------------//
+// Code completion
+//----------------------------------------------------------------------------//
+
+namespace {
+  /// \brief Code completion consumer that combines the cached code-completion
+  /// results from an ASTUnit with the code-completion results provided to it,
+  /// then passes the result on to 
+  class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer {
+    unsigned NormalContexts;
+    ASTUnit &AST;
+    CodeCompleteConsumer &Next;
+    
+  public:
+    AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,
+                                  bool IncludeMacros, bool IncludeCodePatterns,
+                                  bool IncludeGlobals)
+      : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals,
+                             Next.isOutputBinary()), AST(AST), Next(Next) 
+    { 
+      // Compute the set of contexts in which we will look when we don't have
+      // any information about the specific context.
+      NormalContexts 
+        = (1 << (CodeCompletionContext::CCC_TopLevel - 1))
+        | (1 << (CodeCompletionContext::CCC_ObjCInterface - 1))
+        | (1 << (CodeCompletionContext::CCC_ObjCImplementation - 1))
+        | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1))
+        | (1 << (CodeCompletionContext::CCC_Statement - 1))
+        | (1 << (CodeCompletionContext::CCC_Expression - 1))
+        | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1))
+        | (1 << (CodeCompletionContext::CCC_MemberAccess - 1))
+        | (1 << (CodeCompletionContext::CCC_ObjCProtocolName - 1));
+      
+      if (AST.getASTContext().getLangOptions().CPlusPlus)
+        NormalContexts |= (1 << (CodeCompletionContext::CCC_EnumTag - 1))
+                    | (1 << (CodeCompletionContext::CCC_UnionTag - 1))
+                    | (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1));
+    }
+    
+    virtual void ProcessCodeCompleteResults(Sema &S, 
+                                            CodeCompletionContext Context,
+                                            CodeCompletionResult *Results,
+                                            unsigned NumResults);
+    
+    virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+                                           OverloadCandidate *Candidates,
+                                           unsigned NumCandidates) { 
+      Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates);
+    }
+  };
+}
+
+/// \brief Helper function that computes which global names are hidden by the
+/// local code-completion results.
+void CalculateHiddenNames(const CodeCompletionContext &Context,
+                          CodeCompletionResult *Results,
+                          unsigned NumResults,
+                          ASTContext &Ctx,
+                          llvm::StringSet<> &HiddenNames) {
+  bool OnlyTagNames = false;
+  switch (Context.getKind()) {
+  case CodeCompletionContext::CCC_Other:
+  case CodeCompletionContext::CCC_TopLevel:
+  case CodeCompletionContext::CCC_ObjCInterface:
+  case CodeCompletionContext::CCC_ObjCImplementation:
+  case CodeCompletionContext::CCC_ObjCIvarList:
+  case CodeCompletionContext::CCC_ClassStructUnion:
+  case CodeCompletionContext::CCC_Statement:
+  case CodeCompletionContext::CCC_Expression:
+  case CodeCompletionContext::CCC_ObjCMessageReceiver:
+  case CodeCompletionContext::CCC_MemberAccess:
+  case CodeCompletionContext::CCC_Namespace:
+  case CodeCompletionContext::CCC_Type:
+  case CodeCompletionContext::CCC_Name:
+  case CodeCompletionContext::CCC_PotentiallyQualifiedName:
+    break;
+    
+  case CodeCompletionContext::CCC_EnumTag:
+  case CodeCompletionContext::CCC_UnionTag:
+  case CodeCompletionContext::CCC_ClassOrStructTag:
+    OnlyTagNames = true;
+    break;
+    
+  case CodeCompletionContext::CCC_ObjCProtocolName:
+  case CodeCompletionContext::CCC_MacroName:
+  case CodeCompletionContext::CCC_MacroNameUse:
+  case CodeCompletionContext::CCC_PreprocessorExpression:
+  case CodeCompletionContext::CCC_PreprocessorDirective:
+  case CodeCompletionContext::CCC_NaturalLanguage:
+  case CodeCompletionContext::CCC_SelectorName:
+  case CodeCompletionContext::CCC_TypeQualifiers:
+    // We're looking for nothing, or we're looking for names that cannot
+    // be hidden.
+    return;
+  }
+  
+  typedef CodeCompletionResult Result;
+  for (unsigned I = 0; I != NumResults; ++I) {
+    if (Results[I].Kind != Result::RK_Declaration)
+      continue;
+    
+    unsigned IDNS
+      = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace();
+
+    bool Hiding = false;
+    if (OnlyTagNames)
+      Hiding = (IDNS & Decl::IDNS_Tag);
+    else {
+      unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member | 
+                             Decl::IDNS_Namespace | Decl::IDNS_Ordinary |
+                             Decl::IDNS_NonMemberOperator);
+      if (Ctx.getLangOptions().CPlusPlus)
+        HiddenIDNS |= Decl::IDNS_Tag;
+      Hiding = (IDNS & HiddenIDNS);
+    }
+  
+    if (!Hiding)
+      continue;
+    
+    DeclarationName Name = Results[I].Declaration->getDeclName();
+    if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo())
+      HiddenNames.insert(Identifier->getName());
+    else
+      HiddenNames.insert(Name.getAsString());
+  }
+}
+
+
+void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
+                                            CodeCompletionContext Context,
+                                            CodeCompletionResult *Results,
+                                            unsigned NumResults) { 
+  // Merge the results we were given with the results we cached.
+  bool AddedResult = false;
+  unsigned InContexts  
+    = (Context.getKind() == CodeCompletionContext::CCC_Other? NormalContexts
+                                            : (1 << (Context.getKind() - 1)));
+
+  // Contains the set of names that are hidden by "local" completion results.
+  llvm::StringSet<> HiddenNames;
+  llvm::SmallVector<CodeCompletionString *, 4> StringsToDestroy;
+  typedef CodeCompletionResult Result;
+  llvm::SmallVector<Result, 8> AllResults;
+  for (ASTUnit::cached_completion_iterator 
+            C = AST.cached_completion_begin(),
+         CEnd = AST.cached_completion_end();
+       C != CEnd; ++C) {
+    // If the context we are in matches any of the contexts we are 
+    // interested in, we'll add this result.
+    if ((C->ShowInContexts & InContexts) == 0)
+      continue;
+    
+    // If we haven't added any results previously, do so now.
+    if (!AddedResult) {
+      CalculateHiddenNames(Context, Results, NumResults, S.Context, 
+                           HiddenNames);
+      AllResults.insert(AllResults.end(), Results, Results + NumResults);
+      AddedResult = true;
+    }
+    
+    // Determine whether this global completion result is hidden by a local
+    // completion result. If so, skip it.
+    if (C->Kind != CXCursor_MacroDefinition &&
+        HiddenNames.count(C->Completion->getTypedText()))
+      continue;
+    
+    // Adjust priority based on similar type classes.
+    unsigned Priority = C->Priority;
+    CXCursorKind CursorKind = C->Kind;
+    CodeCompletionString *Completion = C->Completion;
+    if (!Context.getPreferredType().isNull()) {
+      if (C->Kind == CXCursor_MacroDefinition) {
+        Priority = getMacroUsagePriority(C->Completion->getTypedText(),
+                               Context.getPreferredType()->isAnyPointerType());        
+      } else if (C->Type) {
+        CanQualType Expected
+          = S.Context.getCanonicalType(
+                               Context.getPreferredType().getUnqualifiedType());
+        SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(Expected);
+        if (ExpectedSTC == C->TypeClass) {
+          // We know this type is similar; check for an exact match.
+          llvm::StringMap<unsigned> &CachedCompletionTypes
+            = AST.getCachedCompletionTypes();
+          llvm::StringMap<unsigned>::iterator Pos
+            = CachedCompletionTypes.find(QualType(Expected).getAsString());
+          if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type)
+            Priority /= CCF_ExactTypeMatch;
+          else
+            Priority /= CCF_SimilarTypeMatch;
+        }
+      }
+    }
+    
+    // Adjust the completion string, if required.
+    if (C->Kind == CXCursor_MacroDefinition &&
+        Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
+      // Create a new code-completion string that just contains the
+      // macro name, without its arguments.
+      Completion = new CodeCompletionString;
+      Completion->AddTypedTextChunk(C->Completion->getTypedText());
+      StringsToDestroy.push_back(Completion);
+      CursorKind = CXCursor_NotImplemented;
+      Priority = CCP_CodePattern;
+    }
+    
+    AllResults.push_back(Result(Completion, Priority, CursorKind, 
+                                C->Availability));
+  }
+  
+  // If we did not add any cached completion results, just forward the
+  // results we were given to the next consumer.
+  if (!AddedResult) {
+    Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
+    return;
+  }
+  
+  Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),
+                                  AllResults.size());
+  
+  for (unsigned I = 0, N = StringsToDestroy.size(); I != N; ++I)
+    delete StringsToDestroy[I];
+}
+
+
+
+void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
+                           RemappedFile *RemappedFiles, 
+                           unsigned NumRemappedFiles,
+                           bool IncludeMacros, 
+                           bool IncludeCodePatterns,
+                           CodeCompleteConsumer &Consumer,
+                           Diagnostic &Diag, LangOptions &LangOpts,
+                           SourceManager &SourceMgr, FileManager &FileMgr,
+                   llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
+             llvm::SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) {
+  if (!Invocation.get())
+    return;
+
+  llvm::Timer *CompletionTimer = 0;
+  if (TimerGroup.get()) {
+    llvm::SmallString<128> TimerName;
+    llvm::raw_svector_ostream TimerNameOut(TimerName);
+    TimerNameOut << "Code completion @ " << File << ":" << Line << ":" 
+                 << Column;
+    CompletionTimer = new llvm::Timer(TimerNameOut.str(), *TimerGroup);
+    CompletionTimer->startTimer();
+    Timers.push_back(CompletionTimer);
+  }
+
+  CompilerInvocation CCInvocation(*Invocation);
+  FrontendOptions &FrontendOpts = CCInvocation.getFrontendOpts();
+  PreprocessorOptions &PreprocessorOpts = CCInvocation.getPreprocessorOpts();
+
+  FrontendOpts.ShowMacrosInCodeCompletion
+    = IncludeMacros && CachedCompletionResults.empty();
+  FrontendOpts.ShowCodePatternsInCodeCompletion = IncludeCodePatterns;
+  FrontendOpts.ShowGlobalSymbolsInCodeCompletion
+    = CachedCompletionResults.empty();
+  FrontendOpts.CodeCompletionAt.FileName = File;
+  FrontendOpts.CodeCompletionAt.Line = Line;
+  FrontendOpts.CodeCompletionAt.Column = Column;
+
+  // Turn on spell-checking when performing code completion. It leads
+  // to better results.
+  unsigned SpellChecking = CCInvocation.getLangOpts().SpellChecking;
+  CCInvocation.getLangOpts().SpellChecking = 1;
+
+  // Set the language options appropriately.
+  LangOpts = CCInvocation.getLangOpts();
+
+  CompilerInstance Clang;
+  Clang.setInvocation(&CCInvocation);
+  OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second;
+    
+  // Set up diagnostics, capturing any diagnostics produced.
+  Clang.setDiagnostics(&Diag);
+  CaptureDroppedDiagnostics Capture(true, 
+                                    Clang.getDiagnostics(),
+                                    StoredDiagnostics);
+  
+  // Create the target instance.
+  Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
+                                               Clang.getTargetOpts()));
+  if (!Clang.hasTarget()) {
+    Clang.takeInvocation();
+    CCInvocation.getLangOpts().SpellChecking = SpellChecking;
+    return;
+  }
+  
+  // 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 != IK_AST &&
+         "FIXME: AST inputs not yet supported here!");
+  assert(Clang.getFrontendOpts().Inputs[0].first != IK_LLVM_IR &&
+         "IR inputs not support here!");
+
+  
+  // Use the source and file managers that we were given.
+  Clang.setFileManager(&FileMgr);
+  Clang.setSourceManager(&SourceMgr);
+
+  // Remap files.
+  PreprocessorOpts.clearRemappedFiles();
+  PreprocessorOpts.RetainRemappedFileBuffers = true;
+  for (unsigned I = 0; I != NumRemappedFiles; ++I) {
+    PreprocessorOpts.addRemappedFile(RemappedFiles[I].first,
+                                     RemappedFiles[I].second);
+    OwnedBuffers.push_back(RemappedFiles[I].second);
+  }
+  
+  // Use the code completion consumer we were given, but adding any cached
+  // code-completion results.
+  AugmentedCodeCompleteConsumer 
+  AugmentedConsumer(*this, Consumer, FrontendOpts.ShowMacrosInCodeCompletion,
+                    FrontendOpts.ShowCodePatternsInCodeCompletion,
+                    FrontendOpts.ShowGlobalSymbolsInCodeCompletion);
+  Clang.setCodeCompletionConsumer(&AugmentedConsumer);
+
+  // If we have a precompiled preamble, try to use it. We only allow
+  // the use of the precompiled preamble if we're if the completion
+  // point is within the main file, after the end of the precompiled
+  // preamble.
+  llvm::MemoryBuffer *OverrideMainBuffer = 0;
+  if (!PreambleFile.empty()) {
+    using llvm::sys::FileStatus;
+    llvm::sys::PathWithStatus CompleteFilePath(File);
+    llvm::sys::PathWithStatus MainPath(OriginalSourceFile);
+    if (const FileStatus *CompleteFileStatus = CompleteFilePath.getFileStatus())
+      if (const FileStatus *MainStatus = MainPath.getFileStatus())
+        if (CompleteFileStatus->getUniqueID() == MainStatus->getUniqueID())
+          OverrideMainBuffer
+            = getMainBufferWithPrecompiledPreamble(CCInvocation, false, 
+                                                   Line - 1);
+  }
+
+  // If the main file has been overridden due to the use of a preamble,
+  // make that override happen and introduce the preamble.
+  if (OverrideMainBuffer) {
+    PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer);
+    PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size();
+    PreprocessorOpts.PrecompiledPreambleBytes.second
+                                                    = PreambleEndsAtStartOfLine;
+    PreprocessorOpts.ImplicitPCHInclude = PreambleFile;
+    PreprocessorOpts.DisablePCHValidation = true;
+    
+    // The stored diagnostics have the old source manager. Copy them
+    // to our output set of stored diagnostics, updating the source
+    // manager to the one we were given.
+    for (unsigned I = 0, N = this->StoredDiagnostics.size(); I != N; ++I) {
+      StoredDiagnostics.push_back(this->StoredDiagnostics[I]);
+      FullSourceLoc Loc(StoredDiagnostics[I].getLocation(), SourceMgr);
+      StoredDiagnostics[I].setLocation(Loc);
+    }
+    
+    OwnedBuffers.push_back(OverrideMainBuffer);
+  } else {
+    PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
+    PreprocessorOpts.PrecompiledPreambleBytes.second = false;
+  }
+
+  llvm::OwningPtr<SyntaxOnlyAction> Act;
+  Act.reset(new SyntaxOnlyAction);
+  if (Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second,
+                           Clang.getFrontendOpts().Inputs[0].first)) {
+    Act->Execute();
+    Act->EndSourceFile();
+  }
+
+  if (CompletionTimer)
+    CompletionTimer->stopTimer();
+  
+  // Steal back our resources. 
+  Clang.takeFileManager();
+  Clang.takeSourceManager();
+  Clang.takeInvocation();
+  Clang.takeCodeCompletionConsumer();
+  CCInvocation.getLangOpts().SpellChecking = SpellChecking;
+}
+
+bool ASTUnit::Save(llvm::StringRef File) {
+  if (getDiagnostics().hasErrorOccurred())
+    return true;
+  
+  // FIXME: Can we somehow regenerate the stat cache here, or do we need to 
+  // unconditionally create a stat cache when we parse the file?
+  std::string ErrorInfo;
+  llvm::raw_fd_ostream Out(File.str().c_str(), ErrorInfo,
+                           llvm::raw_fd_ostream::F_Binary);
+  if (!ErrorInfo.empty() || Out.has_error())
+    return true;
+  
+  std::vector<unsigned char> Buffer;
+  llvm::BitstreamWriter Stream(Buffer);
+  ASTWriter Writer(Stream);
+  Writer.WriteAST(getSema(), 0, 0);
+  
+  // Write the generated bitstream to "Out".
+  if (!Buffer.empty())
+    Out.write((char *)&Buffer.front(), Buffer.size());  
+  Out.close();
+  return Out.has_error();
 }
diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp
deleted file mode 100644
index d55fbc1..0000000
--- a/lib/Frontend/AnalysisConsumer.cpp
+++ /dev/null
@@ -1,661 +0,0 @@
-//===--- 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/BoostConAction.cpp b/lib/Frontend/BoostConAction.cpp
new file mode 100644
index 0000000..4a12ff2
--- /dev/null
+++ b/lib/Frontend/BoostConAction.cpp
@@ -0,0 +1,39 @@
+//===-- BoostConAction.cpp - BoostCon Workshop 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/FrontendActions.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include <cstdio>
+#include <iostream>
+using namespace clang;
+
+namespace {
+  class BoostConASTConsumer : public ASTConsumer,
+                              public RecursiveASTVisitor<BoostConASTConsumer> {
+  public:
+    /// HandleTranslationUnit - This method is called when the ASTs for entire
+    /// translation unit have been parsed.
+    virtual void HandleTranslationUnit(ASTContext &Ctx);
+
+    bool VisitCXXRecordDecl(CXXRecordDecl *D) {
+      std::cout << D->getNameAsString() << std::endl;
+      return true;
+    }
+  };
+}
+
+ASTConsumer *BoostConAction::CreateASTConsumer(CompilerInstance &CI,
+                                               llvm::StringRef InFile) {
+  return new BoostConASTConsumer();
+}
+
+void BoostConASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
+  fprintf(stderr, "Welcome to BoostCon!\n");
+  TraverseDecl(Ctx.getTranslationUnitDecl());
+}
diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt
index b69ad97..5a31495 100644
--- a/lib/Frontend/CMakeLists.txt
+++ b/lib/Frontend/CMakeLists.txt
@@ -4,37 +4,21 @@
   ASTConsumers.cpp
   ASTMerge.cpp
   ASTUnit.cpp
-  AnalysisConsumer.cpp
+  BoostConAction.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
@@ -52,6 +36,10 @@
 ENDIF(MSVC)
 
 add_dependencies(clangFrontend 
+  ClangAttrClasses
+  ClangAttrList
   ClangDiagnosticFrontend 
   ClangDiagnosticLex
-  ClangDiagnosticSema)
+  ClangDiagnosticSema
+  ClangDeclNodes
+  ClangStmtNodes)
diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp
index a5fcebe..53f7362 100644
--- a/lib/Frontend/CacheTokens.cpp
+++ b/lib/Frontend/CacheTokens.cpp
@@ -311,14 +311,19 @@
       // the next token.
       assert(!ParsingPreprocessorDirective);
       Offset HashOff = (Offset) Out.tell();
-      EmitToken(Tok);
 
       // Get the next token.
-      L.LexFromRawLexer(Tok);
+      Token NextTok;
+      L.LexFromRawLexer(NextTok);
 
-      // If we see the start of line, then we had a null directive "#".
-      if (Tok.isAtStartOfLine())
+      // If we see the start of line, then we had a null directive "#".  In
+      // this case, discard both tokens.
+      if (NextTok.isAtStartOfLine())
         goto NextToken;
+      
+      // The token is the start of a directive.  Emit it.
+      EmitToken(Tok);
+      Tok = NextTok;
 
       // Did we see 'include'/'import'/'include_next'?
       if (Tok.isNot(tok::identifier)) {
diff --git a/lib/Frontend/CodeGenAction.cpp b/lib/Frontend/CodeGenAction.cpp
deleted file mode 100644
index 80b0038..0000000
--- a/lib/Frontend/CodeGenAction.cpp
+++ /dev/null
@@ -1,590 +0,0 @@
-//===--- 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
index 5ed9c40..ce0b072 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Frontend/CompilerInstance.h"
+#include "clang/Sema/Sema.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/Basic/Diagnostic.h"
@@ -20,11 +21,11 @@
 #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/Serialization/ASTReader.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "llvm/LLVMContext.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -55,10 +56,6 @@
   Diagnostics = Value;
 }
 
-void CompilerInstance::setDiagnosticClient(DiagnosticClient *Value) {
-  DiagClient.reset(Value);
-}
-
 void CompilerInstance::setTarget(TargetInfo *Value) {
   Target.reset(Value);
 }
@@ -79,6 +76,10 @@
   Context.reset(Value);
 }
 
+void CompilerInstance::setSema(Sema *S) {
+  TheSema.reset(S);
+}
+
 void CompilerInstance::setASTConsumer(ASTConsumer *Value) {
   Consumer.reset(Value);
 }
@@ -126,14 +127,11 @@
   // 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));
+  Diags.setClient(new ChainedDiagnosticClient(Diags.takeClient(), Logger));
 }
 
 void CompilerInstance::createDiagnostics(int Argc, char **Argv) {
   Diagnostics = createDiagnostics(getDiagnosticOpts(), Argc, Argv);
-
-  if (Diagnostics)
-    DiagClient.reset(Diagnostics->getClient());
 }
 
 llvm::IntrusiveRefCntPtr<Diagnostic> 
@@ -150,22 +148,20 @@
       // 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->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts));
       Diags->Report(diag::err_fe_stderr_binary);
       return Diags;
     } else {
-      DiagClient.reset(new BinaryDiagnosticSerializer(llvm::errs()));
+      Diags->setClient(new BinaryDiagnosticSerializer(llvm::errs()));
     }
   } else {
-    DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(), Opts));
+    Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts));
   }
 
   // Chain in -verify checker, if requested.
   if (Opts.VerifyDiagnostics)
-    DiagClient.reset(new VerifyDiagnosticsClient(*Diags, DiagClient.take()));
+    Diags->setClient(new VerifyDiagnosticsClient(*Diags, Diags->takeClient()));
 
-  Diags->setClient(DiagClient.take());
   if (!Opts.DumpBuildInformation.empty())
     SetUpBuildDumpLog(Opts, Argc, Argv, *Diags);
 
@@ -245,40 +241,48 @@
   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) {
+void CompilerInstance::createPCHExternalASTSource(llvm::StringRef Path,
+                                                  bool DisablePCHValidation,
+                                                 void *DeserializationListener){
   llvm::OwningPtr<ExternalASTSource> Source;
   Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot,
-                                          getPreprocessor(), getASTContext()));
+                                          DisablePCHValidation,
+                                          getPreprocessor(), getASTContext(),
+                                          DeserializationListener));
   getASTContext().setExternalSource(Source);
 }
 
 ExternalASTSource *
 CompilerInstance::createPCHExternalASTSource(llvm::StringRef Path,
                                              const std::string &Sysroot,
+                                             bool DisablePCHValidation,
                                              Preprocessor &PP,
-                                             ASTContext &Context) {
-  llvm::OwningPtr<PCHReader> Reader;
-  Reader.reset(new PCHReader(PP, &Context,
-                             Sysroot.empty() ? 0 : Sysroot.c_str()));
+                                             ASTContext &Context,
+                                             void *DeserializationListener) {
+  llvm::OwningPtr<ASTReader> Reader;
+  Reader.reset(new ASTReader(PP, &Context,
+                             Sysroot.empty() ? 0 : Sysroot.c_str(),
+                             DisablePCHValidation));
 
-  switch (Reader->ReadPCH(Path)) {
-  case PCHReader::Success:
+  Reader->setDeserializationListener(
+            static_cast<ASTDeserializationListener *>(DeserializationListener));
+  switch (Reader->ReadAST(Path)) {
+  case ASTReader::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:
+  case ASTReader::Failure:
     // Unrecoverable failure: don't even try to process the input file.
     break;
 
-  case PCHReader::IgnorePCH:
+  case ASTReader::IgnorePCH:
     // No suitable PCH file could be found. Return an error.
     break;
   }
@@ -288,16 +292,42 @@
 
 // Code Completion
 
+static bool EnableCodeCompletion(Preprocessor &PP, 
+                                 const std::string &Filename,
+                                 unsigned Line,
+                                 unsigned Column) {
+  // 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 true;
+  }
+
+  // Truncate the named file at the given line/column.
+  PP.SetCodeCompletionPoint(Entry, Line, Column);
+  return false;
+}
+
 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)
+  if (!CompletionConsumer) {
+    CompletionConsumer.reset(
+      createCodeCompletionConsumer(getPreprocessor(),
+                                   Loc.FileName, Loc.Line, Loc.Column,
+                                   getFrontendOpts().DebugCodeCompletionPrinter,
+                                   getFrontendOpts().ShowMacrosInCodeCompletion,
+                             getFrontendOpts().ShowCodePatternsInCodeCompletion,
+                           getFrontendOpts().ShowGlobalSymbolsInCodeCompletion,
+                                   llvm::outs()));
+    if (!CompletionConsumer)
+      return;
+  } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName,
+                                  Loc.Line, Loc.Column)) {
+    CompletionConsumer.reset();
     return;
+  }
 
   if (CompletionConsumer->isOutputBinary() &&
       llvm::sys::Program::ChangeStdoutToBinary()) {
@@ -317,24 +347,25 @@
                                                unsigned Column,
                                                bool UseDebugPrinter,
                                                bool ShowMacros,
+                                               bool ShowCodePatterns,
+                                               bool ShowGlobals,
                                                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;
+  if (EnableCodeCompletion(PP, Filename, Line, Column))
     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);
+    return new PrintingCodeCompleteConsumer(ShowMacros, ShowCodePatterns, 
+                                            ShowGlobals, OS);
   else
-    return new CIndexCodeCompleteConsumer(ShowMacros, OS);
+    return new CIndexCodeCompleteConsumer(ShowMacros, ShowCodePatterns, 
+                                          ShowGlobals, OS);
+}
+
+void CompilerInstance::createSema(bool CompleteTranslationUnit,
+                                  CodeCompleteConsumer *CompletionConsumer) {
+  TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(),
+                         CompleteTranslationUnit, CompletionConsumer));
 }
 
 // Output Files
@@ -433,14 +464,14 @@
   // 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 (File) SourceMgr.createMainFileID(File);
     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 (SB) SourceMgr.createMainFileIDForMemBuffer(SB);
     if (SourceMgr.getMainFileID().isInvalid()) {
       Diags.Report(diag::err_fe_error_reading_stdin);
       return false;
@@ -487,27 +518,11 @@
   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();
+    // Reset the ID tables if we are reusing the SourceManager.
+    if (hasSourceManager())
+      getSourceManager().clearIDTables();
 
-        // 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)) {
+    if (Act.BeginSourceFile(*this, InFile, getFrontendOpts().Inputs[i].first)) {
       Act.Execute();
       Act.EndSourceFile();
     }
@@ -528,7 +543,7 @@
       OS << " generated.\n";
   }
 
-  if (getFrontendOpts().ShowStats) {
+  if (getFrontendOpts().ShowStats && hasFileManager()) {
     getFileManager().PrintStats();
     OS << "\n";
   }
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 68842a4..68e2d84 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -18,7 +18,7 @@
 #include "clang/Driver/Option.h"
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Frontend/LangStandard.h"
-#include "clang/Frontend/PCHReader.h"
+#include "clang/Serialization/ASTReader.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
@@ -112,6 +112,8 @@
     Res.push_back("-analyzer-experimental-checks");
   if (Opts.EnableExperimentalInternalChecks)
     Res.push_back("-analyzer-experimental-internal-checks");
+  if (Opts.IdempotentOps)
+      Res.push_back("-analyzer-check-idempotent-operations");
 }
 
 static void CodeGenOptsToArgs(const CodeGenOptions &Opts,
@@ -132,6 +134,8 @@
     Res.push_back("-fno-common");
   if (Opts.NoImplicitFloat)
     Res.push_back("-no-implicit-float");
+  if (Opts.OmitLeafFramePointer)
+    Res.push_back("-momit-leaf-frame-pointer");
   if (Opts.OptimizeSize) {
     assert(Opts.OptimizationLevel == 2 && "Invalid options!");
     Res.push_back("-Os");
@@ -144,10 +148,12 @@
   // SimplifyLibCalls is only derived.
   // TimePasses is only derived.
   // UnitAtATime is unused.
-  // UnrollLoops is only derived.
-  // VerifyModule is only derived.
   // Inlining is only derived.
-
+  
+  // UnrollLoops is derived, but also accepts an option, no
+  // harm in pushing it back here.
+  if (Opts.UnrollLoops)
+    Res.push_back("-funroll-loops");
   if (Opts.DataSections)
     Res.push_back("-fdata-sections");
   if (Opts.FunctionSections)
@@ -188,6 +194,8 @@
     Res.push_back("-fobjc-dispatch-method=non-legacy");
     break;
   }
+  if (Opts.RelaxAll)
+    Res.push_back("-mrelax-all");
   if (Opts.SoftFloat)
     Res.push_back("-msoft-float");
   if (Opts.UnwindTables)
@@ -236,6 +244,8 @@
     Res.push_back("-fno-diagnostics-fixit-info");
   if (Opts.ShowSourceRanges)
     Res.push_back("-fdiagnostics-print-source-range-info");
+  if (Opts.ShowParseableFixits)
+    Res.push_back("-fdiagnostics-parseable-fixits");
   if (Opts.ShowColors)
     Res.push_back("-fcolor-diagnostics");
   if (Opts.VerifyDiagnostics)
@@ -244,11 +254,21 @@
     Res.push_back("-fdiagnostics-binary");
   if (Opts.ShowOptionNames)
     Res.push_back("-fdiagnostics-show-option");
+  if (Opts.ShowCategories == 1)
+    Res.push_back("-fdiagnostics-show-category=id");
+  else if (Opts.ShowCategories == 2)
+    Res.push_back("-fdiagnostics-show-category=name");
   if (Opts.ErrorLimit) {
     Res.push_back("-ferror-limit");
     Res.push_back(llvm::utostr(Opts.ErrorLimit));
   }
-  if (Opts.TemplateBacktraceLimit != 10) {
+  if (Opts.MacroBacktraceLimit
+                        != DiagnosticOptions::DefaultMacroBacktraceLimit) {
+    Res.push_back("-fmacro-backtrace-limit");
+    Res.push_back(llvm::utostr(Opts.MacroBacktraceLimit));
+  }
+  if (Opts.TemplateBacktraceLimit
+                        != DiagnosticOptions::DefaultTemplateBacktraceLimit) {
     Res.push_back("-ftemplate-backtrace-limit");
     Res.push_back(llvm::utostr(Opts.TemplateBacktraceLimit));
   }
@@ -269,20 +289,21 @@
     Res.push_back("-W" + Opts.Warnings[i]);
 }
 
-static const char *getInputKindName(FrontendOptions::InputKind Kind) {
+static const char *getInputKindName(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";
+  case IK_None:              break;
+  case IK_AST:               return "ast";
+  case IK_Asm:               return "assembler-with-cpp";
+  case IK_C:                 return "c";
+  case IK_CXX:               return "c++";
+  case IK_LLVM_IR:           return "ir";
+  case IK_ObjC:              return "objective-c";
+  case IK_ObjCXX:            return "objective-c++";
+  case IK_OpenCL:            return "cl";
+  case IK_PreprocessedC:     return "cpp-output";
+  case IK_PreprocessedCXX:   return "c++-cpp-output";
+  case IK_PreprocessedObjC:  return "objective-c-cpp-output";
+  case IK_PreprocessedObjCXX:return "objective-c++-cpp-output";
   }
 
   llvm_unreachable("Unexpected language kind!");
@@ -299,6 +320,8 @@
   case frontend::ASTPrint:               return "-ast-print";
   case frontend::ASTPrintXML:            return "-ast-print-xml";
   case frontend::ASTView:                return "-ast-view";
+  case frontend::BoostCon:               return "-boostcon";
+  case frontend::CreateModule:           return "-create-module";
   case frontend::DumpRawTokens:          return "-dump-raw-tokens";
   case frontend::DumpTokens:             return "-dump-tokens";
   case frontend::EmitAssembly:           return "-S";
@@ -306,15 +329,15 @@
   case frontend::EmitHTML:               return "-emit-html";
   case frontend::EmitLLVM:               return "-emit-llvm";
   case frontend::EmitLLVMOnly:           return "-emit-llvm-only";
+  case frontend::EmitCodeGenOnly:        return "-emit-codegen-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::PrintPreamble:          return "-print-preamble";
   case frontend::PrintPreprocessedInput: return "-E";
   case frontend::RewriteMacros:          return "-rewrite-macros";
   case frontend::RewriteObjC:            return "-rewrite-objc";
@@ -335,16 +358,24 @@
     Res.push_back("-disable-free");
   if (Opts.RelocatablePCH)
     Res.push_back("-relocatable-pch");
+  if (Opts.ChainedPCH)
+    Res.push_back("-chained-pch");
   if (Opts.ShowHelp)
     Res.push_back("-help");
   if (Opts.ShowMacrosInCodeCompletion)
     Res.push_back("-code-completion-macros");
+  if (Opts.ShowCodePatternsInCodeCompletion)
+    Res.push_back("-code-completion-patterns");
+  if (!Opts.ShowGlobalSymbolsInCodeCompletion)
+    Res.push_back("-no-code-completion-globals");
   if (Opts.ShowStats)
     Res.push_back("-print-stats");
   if (Opts.ShowTimers)
     Res.push_back("-ftime-report");
   if (Opts.ShowVersion)
     Res.push_back("-version");
+  if (Opts.FixWhatYouCan)
+    Res.push_back("-fix-what-you-can");
 
   bool NeedLang = false;
   for (unsigned i = 0, e = Opts.Inputs.size(); i != e; ++i)
@@ -381,6 +412,10 @@
   if (!Opts.ActionName.empty()) {
     Res.push_back("-plugin");
     Res.push_back(Opts.ActionName);
+    for(unsigned i = 0, e = Opts.PluginArgs.size(); i != e; ++i) {
+      Res.push_back("-plugin-arg-" + Opts.ActionName);
+      Res.push_back(Opts.PluginArgs[i]);
+    }
   }
   for (unsigned i = 0, e = Opts.Plugins.size(); i != e; ++i) {
     Res.push_back("-load");
@@ -390,6 +425,10 @@
     Res.push_back("-ast-merge");
     Res.push_back(Opts.ASTMergeFiles[i]);
   }
+  for (unsigned i = 0, e = Opts.Modules.size(); i != e; ++i) {
+    Res.push_back("-import-module");
+    Res.push_back(Opts.Modules[i]);
+  }
   for (unsigned i = 0, e = Opts.LLVMArgs.size(); i != e; ++i) {
     Res.push_back("-mllvm");
     Res.push_back(Opts.LLVMArgs[i]);
@@ -529,8 +568,11 @@
     Res.push_back("-femit-all-decls");
   if (Opts.MathErrno)
     Res.push_back("-fmath-errno");
-  if (Opts.OverflowChecking)
-    Res.push_back("-ftrapv");
+  switch (Opts.getSignedOverflowBehavior()) {
+  case LangOptions::SOB_Undefined: break;
+  case LangOptions::SOB_Defined:   Res.push_back("-fwrapv"); break;
+  case LangOptions::SOB_Trapping:  Res.push_back("-ftrapv"); break;
+  }
   if (Opts.HeinousExtensions)
     Res.push_back("-fheinous-gnu-extensions");
   // Optimize is implicit.
@@ -579,6 +621,9 @@
       Res.push_back("protected");
     }
   }
+  if (Opts.InlineVisibilityHidden)
+    Res.push_back("-fvisibility-inlines-hidden");
+  
   if (Opts.getStackProtectorMode() != 0) {
     Res.push_back("-stack-protector");
     Res.push_back(llvm::utostr(Opts.getStackProtectorMode()));
@@ -644,6 +689,8 @@
   else if (!Opts.ShowCPP && Opts.ShowMacros)
     Res.push_back("-dM");
 
+  if (Opts.ShowHeaderIncludes)
+    Res.push_back("-H");
   if (!Opts.ShowLineMarkers)
     Res.push_back("-P");
   if (Opts.ShowComments)
@@ -664,6 +711,14 @@
     Res.push_back("-target-abi");
     Res.push_back(Opts.ABI);
   }
+  if (!Opts.LinkerVersion.empty()) {
+    Res.push_back("-target-linker-version");
+    Res.push_back(Opts.LinkerVersion);
+  }
+  if (!Opts.CXXABI.empty()) {
+    Res.push_back("-cxx-abi");
+    Res.push_back(Opts.CXXABI);
+  }
   for (unsigned i = 0, e = Opts.Features.size(); i != e; ++i) {
     Res.push_back("-target-feature");
     Res.push_back(Opts.Features[i]);
@@ -690,34 +745,6 @@
 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,
@@ -739,7 +766,7 @@
     // FIXME: Error handling.
     if (Value == NumStores)
       Diags.Report(diag::err_drv_invalid_value)
-        << Args.getLastArg(OPT_O)->getAsString(Args) << Name;
+        << A->getAsString(Args) << Name;
     else
       Opts.AnalysisStoreOpt = Value;
   }
@@ -754,7 +781,7 @@
     // FIXME: Error handling.
     if (Value == NumConstraints)
       Diags.Report(diag::err_drv_invalid_value)
-        << Args.getLastArg(OPT_O)->getAsString(Args) << Name;
+        << A->getAsString(Args) << Name;
     else
       Opts.AnalysisConstraintsOpt = Value;
   }
@@ -769,7 +796,7 @@
     // FIXME: Error handling.
     if (Value == NUM_ANALYSIS_DIAG_CLIENTS)
       Diags.Report(diag::err_drv_invalid_value)
-        << Args.getLastArg(OPT_O)->getAsString(Args) << Name;
+        << A->getAsString(Args) << Name;
     else
       Opts.AnalysisDiagOpt = Value;
   }
@@ -782,12 +809,16 @@
     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.AnalyzeSpecificFunction = Args.getLastArgValue(OPT_analyze_function);
+  Opts.UnoptimizedCFG = Args.hasArg(OPT_analysis_UnoptimizedCFG);
   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);
+  Opts.MaxNodes = Args.getLastArgIntValue(OPT_analyzer_max_nodes, 150000,Diags);
+  Opts.MaxLoop = Args.getLastArgIntValue(OPT_analyzer_max_loop, 3, Diags);
+  Opts.InlineCall = Args.hasArg(OPT_analyzer_inline_call);
+  Opts.IdempotentOps = Args.hasArg(OPT_analysis_WarnIdempotentOps);
 }
 
 static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
@@ -797,7 +828,7 @@
   if (Args.hasArg(OPT_Os))
     Opts.OptimizationLevel = 2;
   else {
-    Opts.OptimizationLevel = getLastArgIntValue(Args, OPT_O, 0, Diags);
+    Opts.OptimizationLevel = Args.getLastArgIntValue(OPT_O, 0, Diags);
     if (Opts.OptimizationLevel > 3) {
       Diags.Report(diag::err_drv_invalid_value)
         << Args.getLastArg(OPT_O)->getAsString(Args) << Opts.OptimizationLevel;
@@ -812,32 +843,40 @@
   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.DwarfDebugFlags = Args.getLastArgValue(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.SimplifyLibCalls = !(Args.hasArg(OPT_fno_builtin) ||
+                            Args.hasArg(OPT_ffreestanding));
+  Opts.UnrollLoops = Args.hasArg(OPT_funroll_loops) || 
+                     (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.CodeModel = Args.getLastArgValue(OPT_mcode_model);
+  Opts.DebugPass = Args.getLastArgValue(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.FloatABI = Args.getLastArgValue(OPT_mfloat_abi);
+  Opts.HiddenWeakVTables = Args.hasArg(OPT_fhidden_weak_vtables);
+  Opts.LimitFloatPrecision = Args.getLastArgValue(OPT_mlimit_float_precision);
   Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss);
+  Opts.RelaxAll = Args.hasArg(OPT_mrelax_all);
+  Opts.OmitLeafFramePointer = Args.hasArg(OPT_momit_leaf_frame_pointer);
   Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
   Opts.UnwindTables = Args.hasArg(OPT_munwind_tables);
-  Opts.RelocationModel = getLastArgValue(Args, OPT_mrelocation_model, "pic");
+  Opts.RelocationModel = Args.getLastArgValue(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.MainFileName = Args.getLastArgValue(OPT_main_file_name);
   Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier);
 
+  Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions);
+
   if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) {
     llvm::StringRef Name = A->getValue(Args);
     unsigned Method = llvm::StringSwitch<unsigned>(Name)
@@ -855,8 +894,8 @@
 static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
                                       ArgList &Args) {
   using namespace cc1options;
-  Opts.OutputFile = getLastArgValue(Args, OPT_dependency_file);
-  Opts.Targets = getAllArgValues(Args, OPT_MT);
+  Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file);
+  Opts.Targets = Args.getAllArgValues(OPT_MT);
   Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps);
   Opts.UsePhonyTargets = Args.hasArg(OPT_MP);
 }
@@ -874,26 +913,57 @@
   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);
+
+  llvm::StringRef ShowOverloads =
+    Args.getLastArgValue(OPT_fshow_overloads_EQ, "all");
+  if (ShowOverloads == "best")
+    Opts.ShowOverloads = Diagnostic::Ovl_Best;
+  else if (ShowOverloads == "all")
+    Opts.ShowOverloads = Diagnostic::Ovl_All;
+  else
+    Diags.Report(diag::err_drv_invalid_value)
+      << Args.getLastArg(OPT_fshow_overloads_EQ)->getAsString(Args)
+      << ShowOverloads;
+
+  llvm::StringRef ShowCategory =
+    Args.getLastArgValue(OPT_fdiagnostics_show_category, "none");
+  if (ShowCategory == "none")
+    Opts.ShowCategories = 0;
+  else if (ShowCategory == "id")
+    Opts.ShowCategories = 1;
+  else if (ShowCategory == "name")
+    Opts.ShowCategories = 2;
+  else
+    Diags.Report(diag::err_drv_invalid_value)
+      << Args.getLastArg(OPT_fdiagnostics_show_category)->getAsString(Args)
+      << ShowCategory;
+  
   Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info);
+  Opts.ShowParseableFixits = Args.hasArg(OPT_fdiagnostics_parseable_fixits);
   Opts.VerifyDiagnostics = Args.hasArg(OPT_verify);
   Opts.BinaryOutput = Args.hasArg(OPT_fdiagnostics_binary);
-  Opts.ErrorLimit = getLastArgIntValue(Args, OPT_ferror_limit, 0, Diags);
+  Opts.ErrorLimit = Args.getLastArgIntValue(OPT_ferror_limit, 0, Diags);
+  Opts.MacroBacktraceLimit
+    = Args.getLastArgIntValue(OPT_fmacro_backtrace_limit, 
+                         DiagnosticOptions::DefaultMacroBacktraceLimit, Diags);
   Opts.TemplateBacktraceLimit
-    = getLastArgIntValue(Args, OPT_ftemplate_backtrace_limit, 0, Diags);
-  Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop,
+    = Args.getLastArgIntValue(OPT_ftemplate_backtrace_limit, 
+                         DiagnosticOptions::DefaultTemplateBacktraceLimit, 
+                         Diags);
+  Opts.TabStop = Args.getLastArgIntValue(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);
+  Opts.MessageLength = Args.getLastArgIntValue(OPT_fmessage_length, 0, Diags);
+  Opts.DumpBuildInformation = Args.getLastArgValue(OPT_dump_build_information);
+  Opts.Warnings = Args.getAllArgValues(OPT_W);
 }
 
-static FrontendOptions::InputKind
-ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Diagnostic &Diags) {
+static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
+                                   Diagnostic &Diags) {
   using namespace cc1options;
   Opts.ProgramAction = frontend::ParseSyntaxOnly;
   if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {
@@ -908,6 +978,8 @@
       Opts.ProgramAction = frontend::ASTPrintXML; break;
     case OPT_ast_view:
       Opts.ProgramAction = frontend::ASTView; break;
+    case OPT_boostcon:
+      Opts.ProgramAction = frontend::BoostCon; break;
     case OPT_dump_raw_tokens:
       Opts.ProgramAction = frontend::DumpRawTokens; break;
     case OPT_dump_tokens:
@@ -922,6 +994,8 @@
       Opts.ProgramAction = frontend::EmitLLVM; break;
     case OPT_emit_llvm_only:
       Opts.ProgramAction = frontend::EmitLLVMOnly; break;
+    case OPT_emit_codegen_only:
+      Opts.ProgramAction = frontend::EmitCodeGenOnly; break;
     case OPT_emit_obj:
       Opts.ProgramAction = frontend::EmitObj; break;
     case OPT_fixit_EQ:
@@ -935,14 +1009,12 @@
       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_print_preamble:
+      Opts.ProgramAction = frontend::PrintPreamble; break;
     case OPT_E:
       Opts.ProgramAction = frontend::PrintPreprocessedInput; break;
     case OPT_rewrite_macros:
@@ -955,11 +1027,21 @@
       Opts.ProgramAction = frontend::RunAnalysis; break;
     case OPT_Eonly:
       Opts.ProgramAction = frontend::RunPreprocessorOnly; break;
+    case OPT_create_module:
+      Opts.ProgramAction = frontend::CreateModule; break;
     }
   }
-  if (const Arg *A = Args.getLastArg(OPT_plugin)) {
+
+  if (const Arg* A = Args.getLastArg(OPT_plugin)) {
+    Opts.Plugins.push_back(A->getValue(Args,0));
     Opts.ProgramAction = frontend::PluginAction;
     Opts.ActionName = A->getValue(Args);
+
+    for (arg_iterator it = Args.filtered_begin(OPT_plugin_arg),
+           end = Args.filtered_end(); it != end; ++it) {
+      if ((*it)->getValue(Args, 0) == Opts.ActionName)
+        Opts.PluginArgs.push_back((*it)->getValue(Args, 1));
+    }
   }
 
   if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
@@ -973,52 +1055,60 @@
     !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.OutputFile = Args.getLastArgValue(OPT_o);
+  Opts.Plugins = Args.getAllArgValues(OPT_load);
   Opts.RelocatablePCH = Args.hasArg(OPT_relocatable_pch);
+  Opts.ChainedPCH = Args.hasArg(OPT_chained_pch);
   Opts.ShowHelp = Args.hasArg(OPT_help);
   Opts.ShowMacrosInCodeCompletion = Args.hasArg(OPT_code_completion_macros);
+  Opts.ShowCodePatternsInCodeCompletion
+    = Args.hasArg(OPT_code_completion_patterns);
+  Opts.ShowGlobalSymbolsInCodeCompletion
+    = !Args.hasArg(OPT_no_code_completion_globals);
   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);
+  Opts.ViewClassInheritance = Args.getLastArgValue(OPT_cxx_inheritance_view);
+  Opts.ASTMergeFiles = Args.getAllArgValues(OPT_ast_merge);
+  Opts.LLVMArgs = Args.getAllArgValues(OPT_mllvm);
+  Opts.FixWhatYouCan = Args.hasArg(OPT_fix_what_you_can);
+  Opts.Modules = Args.getAllArgValues(OPT_import_module);
 
-  FrontendOptions::InputKind DashX = FrontendOptions::IK_None;
+  InputKind DashX = 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)
+    DashX = llvm::StringSwitch<InputKind>(A->getValue(Args))
+      .Case("c", IK_C)
+      .Case("cl", IK_OpenCL)
+      .Case("c", IK_C)
+      .Case("cl", IK_OpenCL)
+      .Case("c++", IK_CXX)
+      .Case("objective-c", IK_ObjC)
+      .Case("objective-c++", IK_ObjCXX)
+      .Case("cpp-output", IK_PreprocessedC)
+      .Case("assembler-with-cpp", IK_Asm)
+      .Case("c++-cpp-output", IK_PreprocessedCXX)
+      .Case("objective-c-cpp-output", IK_PreprocessedObjC)
+      .Case("objective-c++-cpp-output", IK_PreprocessedObjCXX)
+      .Case("c-header", IK_C)
+      .Case("objective-c-header", IK_ObjC)
+      .Case("c++-header", IK_CXX)
+      .Case("objective-c++-header", IK_ObjCXX)
+      .Case("ast", IK_AST)
+      .Case("ir", IK_LLVM_IR)
+      .Default(IK_None);
+    if (DashX == 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);
+  std::vector<std::string> Inputs = Args.getAllArgValues(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) {
+    InputKind IK = DashX;
+    if (IK == IK_None) {
       IK = FrontendOptions::getInputKindForExtension(
         llvm::StringRef(Inputs[i]).rsplit('.').second);
       // FIXME: Remove this hack.
@@ -1050,61 +1140,62 @@
 
 static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) {
   using namespace cc1options;
-  Opts.Sysroot = getLastArgValue(Args, OPT_isysroot, "/");
+  Opts.Sysroot = Args.getLastArgValue(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);
+  Opts.ResourceDir = Args.getLastArgValue(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));
+    Opts.AddPath((*it)->getValue(Args), frontend::Angled, true,
+                 /*IsFramework=*/ (*it)->getOption().matches(OPT_F), true);
 
   // 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);
+    const Arg *A = *it;
+    if (A->getOption().matches(OPT_iprefix))
+      Prefix = A->getValue(Args);
+    else if (A->getOption().matches(OPT_iwithprefix))
+      Opts.AddPath(Prefix.str() + A->getValue(Args),
+                   frontend::System, false, false, true);
     else
-      Opts.AddPath(Prefix.str() + it->getValue(Args),
-                   frontend::Angled, false, false);
+      Opts.AddPath(Prefix.str() + A->getValue(Args),
+                   frontend::Angled, false, false, true);
   }
 
   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);
+    Opts.AddPath((*it)->getValue(Args), frontend::After, true, false, true);
   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),
+    Opts.AddPath((*it)->getValue(Args), frontend::Quoted, true, false, true);
+  for (arg_iterator it = Args.filtered_begin(OPT_isystem, OPT_iwithsysroot),
          ie = Args.filtered_end(); it != ie; ++it)
-    Opts.AddPath(it->getValue(Args), frontend::System, true, false);
+    Opts.AddPath((*it)->getValue(Args), frontend::System, true, false,
+                 (*it)->getOption().matches(OPT_iwithsysroot));
 
   // FIXME: Need options for the various environment variables!
 }
 
-static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
-                          FrontendOptions::InputKind IK,
+static void ParseLangArgs(LangOptions &Opts, ArgList &Args, 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) {
+  if (IK == IK_Asm) {
     Opts.AsmPreprocessor = 1;
-  } else if (IK == FrontendOptions::IK_ObjC ||
-             IK == FrontendOptions::IK_ObjCXX ||
-             IK == FrontendOptions::IK_PreprocessedObjC ||
-             IK == FrontendOptions::IK_PreprocessedObjCXX) {
+  } else if (IK == IK_ObjC ||
+             IK == IK_ObjCXX ||
+             IK == IK_PreprocessedObjC ||
+             IK == IK_PreprocessedObjCXX) {
     Opts.ObjC1 = Opts.ObjC2 = 1;
   }
 
@@ -1123,23 +1214,24 @@
   if (LangStd == LangStandard::lang_unspecified) {
     // Based on the base language, pick one.
     switch (IK) {
-    case FrontendOptions::IK_None:
-    case FrontendOptions::IK_AST:
+    case IK_None:
+    case IK_AST:
+    case IK_LLVM_IR:
       assert(0 && "Invalid input kind!");
-    case FrontendOptions::IK_OpenCL:
+    case 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:
+    case IK_Asm:
+    case IK_C:
+    case IK_PreprocessedC:
+    case IK_ObjC:
+    case IK_PreprocessedObjC:
       LangStd = LangStandard::lang_gnu99;
       break;
-    case FrontendOptions::IK_CXX:
-    case FrontendOptions::IK_PreprocessedCXX:
-    case FrontendOptions::IK_ObjCXX:
-    case FrontendOptions::IK_PreprocessedObjCXX:
+    case IK_CXX:
+    case IK_PreprocessedCXX:
+    case IK_ObjCXX:
+    case IK_PreprocessedObjCXX:
       LangStd = LangStandard::lang_gnucxx98;
       break;
     }
@@ -1194,8 +1286,7 @@
   if (Args.hasArg(OPT_pthread))
     Opts.POSIXThreads = 1;
 
-  llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
-                                        "default");
+  llvm::StringRef Vis = Args.getLastArgValue(OPT_fvisibility, "default");
   if (Vis == "default")
     Opts.setVisibilityMode(LangOptions::Default);
   else if (Vis == "hidden")
@@ -1206,7 +1297,13 @@
     Diags.Report(diag::err_drv_invalid_value)
       << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
 
-  Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
+  if (Args.hasArg(OPT_fvisibility_inlines_hidden))
+    Opts.InlineVisibilityHidden = 1;
+  
+  if (Args.hasArg(OPT_ftrapv))
+    Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping); 
+  else if (Args.hasArg(OPT_fwrapv))
+    Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined); 
 
   // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
   // is specified, or -std is set to a conforming mode.
@@ -1237,28 +1334,29 @@
   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,
+  Opts.InstantiationDepth = Args.getLastArgIntValue(OPT_ftemplate_depth, 1024,
                                                Diags);
   Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
-  Opts.ObjCConstantStringClass = getLastArgValue(Args,
-                                                 OPT_fconstant_string_class);
+  Opts.ObjCConstantStringClass =
+    Args.getLastArgValue(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.PICLevel = Args.getLastArgIntValue(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.SpellChecking = !Args.hasArg(OPT_fno_spell_checking);
   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);
+    Args.hasArg(OPT_Os) ? 2 : Args.getLastArgIntValue(OPT_O, 0, Diags);
   Opts.Optimize = Opt != 0;
 
   // This is the __NO_INLINE__ define, which just depends on things like the
@@ -1268,7 +1366,7 @@
   // FIXME: This is affected by other options (-fno-inline).
   Opts.NoInline = !Opt;
 
-  unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
+  unsigned SSP = Args.getLastArgIntValue(OPT_stack_protector, 0, Diags);
   switch (SSP) {
   default:
     Diags.Report(diag::err_drv_invalid_value)
@@ -1283,39 +1381,58 @@
 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);
+  Opts.ImplicitPCHInclude = Args.getLastArgValue(OPT_include_pch);
+  Opts.ImplicitPTHInclude = Args.getLastArgValue(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);
+  Opts.DisablePCHValidation = Args.hasArg(OPT_fno_validate_pch);
+
+  if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
+    llvm::StringRef Value(A->getValue(Args));
+    size_t Comma = Value.find(',');
+    unsigned Bytes = 0;
+    unsigned EndOfLine = 0;
+    
+    if (Comma == llvm::StringRef::npos ||
+        Value.substr(0, Comma).getAsInteger(10, Bytes) ||
+        Value.substr(Comma + 1).getAsInteger(10, EndOfLine))
+      Diags.Report(diag::err_drv_preamble_format);
+    else {
+      Opts.PrecompiledPreambleBytes.first = Bytes;
+      Opts.PrecompiledPreambleBytes.second = (EndOfLine != 0);
+    }
+  }
+    
   // 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));
+    if ((*it)->getOption().matches(OPT_D))
+      Opts.addMacroDef((*it)->getValue(Args));
     else
-      Opts.addMacroUndef(it->getValue(Args));
+      Opts.addMacroUndef((*it)->getValue(Args));
   }
 
-  Opts.MacroIncludes = getAllArgValues(Args, OPT_imacros);
+  Opts.MacroIncludes = Args.getAllArgValues(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) {
+    const Arg *A = *it;
     // PCH is handled specially, we need to extra the original include path.
-    if (it->getOption().matches(OPT_include_pch)) {
+    if (A->getOption().matches(OPT_include_pch)) {
       std::string OriginalFile =
-        PCHReader::getOriginalSourceFile(it->getValue(Args), Diags);
+        ASTReader::getOriginalSourceFile(A->getValue(Args), Diags);
       if (OriginalFile.empty())
         continue;
 
       Opts.Includes.push_back(OriginalFile);
     } else
-      Opts.Includes.push_back(it->getValue(Args));
+      Opts.Includes.push_back(A->getValue(Args));
   }
 
   // Include 'altivec.h' if -faltivec option present
@@ -1324,11 +1441,12 @@
 
   for (arg_iterator it = Args.filtered_begin(OPT_remap_file),
          ie = Args.filtered_end(); it != ie; ++it) {
+    const Arg *A = *it;
     std::pair<llvm::StringRef,llvm::StringRef> Split =
-      llvm::StringRef(it->getValue(Args)).split(';');
+      llvm::StringRef(A->getValue(Args)).split(';');
 
     if (Split.second.empty()) {
-      Diags.Report(diag::err_drv_invalid_remap_file) << it->getAsString(Args);
+      Diags.Report(diag::err_drv_invalid_remap_file) << A->getAsString(Args);
       continue;
     }
 
@@ -1340,18 +1458,21 @@
                                         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.ShowHeaderIncludes = Args.hasArg(OPT_H);
+  Opts.ShowLineMarkers = !Args.hasArg(OPT_P);
   Opts.ShowMacroComments = Args.hasArg(OPT_CC);
+  Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
 }
 
 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);
+  Opts.ABI = Args.getLastArgValue(OPT_target_abi);
+  Opts.CXXABI = Args.getLastArgValue(OPT_cxx_abi);
+  Opts.CPU = Args.getLastArgValue(OPT_target_cpu);
+  Opts.Features = Args.getAllArgValues(OPT_target_feature);
+  Opts.LinkerVersion = Args.getLastArgValue(OPT_target_linker_version);
+  Opts.Triple = Args.getLastArgValue(OPT_triple);
 
   // Use the host triple if unspecified.
   if (Opts.Triple.empty())
@@ -1378,16 +1499,15 @@
   // 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);
+    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);
+  InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), *Args, Diags);
   ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *Args);
-  if (DashX != FrontendOptions::IK_AST)
+  if (DashX != IK_AST && DashX != IK_LLVM_IR)
     ParseLangArgs(Res.getLangOpts(), *Args, DashX, Diags);
   ParsePreprocessorArgs(Res.getPreprocessorOpts(), *Args, Diags);
   ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), *Args);
diff --git a/lib/Frontend/DeclXML.cpp b/lib/Frontend/DeclXML.cpp
index 8750b1e..97a7f55 100644
--- a/lib/Frontend/DeclXML.cpp
+++ b/lib/Frontend/DeclXML.cpp
@@ -47,11 +47,39 @@
 
   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();
+
+    if (RD->isDefinition()) {
+      // FIXME: This breaks XML generation
+      //Doc.addAttribute("num_bases", RD->getNumBases());
+
+      for (CXXRecordDecl::base_class_iterator 
+             base = RD->bases_begin(),
+             bend = RD->bases_end();
+           base != bend;
+           ++base) {
+        Doc.addSubNode("Base");
+        Doc.addAttribute("id", base->getType());
+        AccessSpecifier as = base->getAccessSpecifierAsWritten();
+        const char* as_name = "";
+        switch(as) {
+        case AS_none:      as_name = ""; break;
+        case AS_public:    as_name = "public"; break;
+        case AS_protected: as_name = "protected"; break;
+        case AS_private:   as_name = "private"; break;
+        }
+        Doc.addAttributeOptional("access", as_name);
+        Doc.addAttribute("is_virtual", base->isVirtual());
+        Doc.toParent();
+      }
+
+      for (CXXRecordDecl::method_iterator i = RD->method_begin(),
+             e = RD->method_end(); i != e; ++i) {
+        Visit(*i);
+        Doc.toParent();
+      }
+
     }
+
   }
 
   void addSubNodes(EnumDecl* ED) {
@@ -82,6 +110,18 @@
       Doc.PrintStmt(argDecl->getDefaultArg());
   }
 
+  void addSubNodes(NamespaceDecl* ns) {
+
+    for (DeclContext::decl_iterator 
+           d    = ns->decls_begin(), 
+           dend = ns->decls_end();
+         d != dend;
+         ++d) {
+      Visit(*d);
+      Doc.toParent();
+    }
+  }
+
   void addSpecialAttribute(const char* pName, EnumDecl* ED) {
     const QualType& enumType = ED->getIntegerType();
     if (!enumType.isNull())
diff --git a/lib/Frontend/DependencyFile.cpp b/lib/Frontend/DependencyFile.cpp
index 14aee35..cdff807 100644
--- a/lib/Frontend/DependencyFile.cpp
+++ b/lib/Frontend/DependencyFile.cpp
@@ -53,7 +53,6 @@
 
   virtual void EndOfMainFile() {
     OutputDependencyFile();
-    OS->flush();
     delete OS;
     OS = 0;
   }
diff --git a/lib/Frontend/DiagChecker.cpp b/lib/Frontend/DiagChecker.cpp
index a50cc99..66d7ed7 100644
--- a/lib/Frontend/DiagChecker.cpp
+++ b/lib/Frontend/DiagChecker.cpp
@@ -13,7 +13,7 @@
 
 #include "clang/Frontend/Utils.h"
 #include "clang/Frontend/TextDiagnosticBuffer.h"
-#include "clang/Sema/ParseAST.h"
+#include "clang/Parse/ParseAST.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Preprocessor.h"
diff --git a/lib/Frontend/DocumentXML.cpp b/lib/Frontend/DocumentXML.cpp
index 0263c30..894f230 100644
--- a/lib/Frontend/DocumentXML.cpp
+++ b/lib/Frontend/DocumentXML.cpp
@@ -199,6 +199,35 @@
 }
 
 //---------------------------------------------------------
+void DocumentXML::addPtrAttribute(const char* pAttributeName,
+                                  const NestedNameSpecifier* pNNS) {
+  switch (pNNS->getKind()) {
+  case NestedNameSpecifier::Identifier: {
+    IdentifierInfo *ii = pNNS->getAsIdentifier();
+    // FIXME how should we handle those ?
+    addPtrAttribute(pAttributeName, ii->getName().data());
+    break;
+  }
+  case NestedNameSpecifier::Namespace: {
+    addPtrAttribute(pAttributeName, pNNS->getAsNamespace());
+    break;
+  }
+  case NestedNameSpecifier::TypeSpec: {
+    addPtrAttribute(pAttributeName, pNNS->getAsType());
+    break;
+  }
+  case NestedNameSpecifier::TypeSpecWithTemplate: {
+    addPtrAttribute(pAttributeName, pNNS->getAsType());
+    break;
+  }
+  case NestedNameSpecifier::Global: {
+    addPtrAttribute(pAttributeName, "::");
+    break;
+  }
+  }
+}
+
+//---------------------------------------------------------
 void DocumentXML::addTypeRecursively(const QualType& pType)
 {
   if (addToMap(Types, pType))
diff --git a/lib/Frontend/FixItRewriter.cpp b/lib/Frontend/FixItRewriter.cpp
deleted file mode 100644
index 7c9a566..0000000
--- a/lib/Frontend/FixItRewriter.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-//===--- 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
index 87fc122..b244c5c 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -8,13 +8,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Frontend/FrontendAction.h"
+#include "clang/AST/ASTConsumer.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 "clang/Parse/ParseAST.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -25,33 +26,36 @@
 
 FrontendAction::~FrontendAction() {}
 
-void FrontendAction::setCurrentFile(llvm::StringRef Value, ASTUnit *AST) {
+void FrontendAction::setCurrentFile(llvm::StringRef Value, InputKind Kind,
+                                    ASTUnit *AST) {
   CurrentFile = Value;
+  CurrentFileKind = Kind;
   CurrentASTUnit.reset(AST);
 }
 
 bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
                                      llvm::StringRef Filename,
-                                     bool IsAST) {
+                                     InputKind InputKind) {
   assert(!Instance && "Already processing a source file!");
   assert(!Filename.empty() && "Unexpected empty filename!");
-  setCurrentFile(Filename);
+  setCurrentFile(Filename, InputKind);
   setCompilerInstance(&CI);
 
   // AST files follow a very different path, since they share objects via the
   // AST unit.
-  if (IsAST) {
+  if (InputKind == IK_AST) {
     assert(!usesPreprocessorOnly() &&
            "Attempt to pass AST file to preprocessor only action!");
-    assert(hasASTSupport() && "This action does not have AST support!");
+    assert(hasASTFileSupport() &&
+           "This action does not have AST file support!");
 
     llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics());
     std::string Error;
-    ASTUnit *AST = ASTUnit::LoadFromPCHFile(Filename, Diags);
+    ASTUnit *AST = ASTUnit::LoadFromASTFile(Filename, Diags);
     if (!AST)
       goto failure;
 
-    setCurrentFile(Filename, AST);
+    setCurrentFile(Filename, InputKind, AST);
 
     // Set the shared objects, these are reset when we finish processing the
     // file, otherwise the CompilerInstance will happily destroy them.
@@ -72,6 +76,30 @@
     return true;
   }
 
+  // Set up the file and source managers, if needed.
+  if (!CI.hasFileManager())
+    CI.createFileManager();
+  if (!CI.hasSourceManager())
+    CI.createSourceManager();
+
+  // IR files bypass the rest of initialization.
+  if (InputKind == IK_LLVM_IR) {
+    assert(hasIRSupport() &&
+           "This action does not have IR file support!");
+
+    // Inform the diagnostic client we are processing a source file.
+    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0);
+
+    // Initialize the action.
+    if (!BeginSourceFileAction(CI, Filename))
+      goto failure;
+
+    return true;
+  }
+
+  // Set up the preprocessor.
+  CI.createPreprocessor();
+
   // Inform the diagnostic client we are processing a source file.
   CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
                                            &CI.getPreprocessor());
@@ -84,18 +112,24 @@
   /// action.
   if (!usesPreprocessorOnly()) {
     CI.createASTContext();
-    CI.setASTConsumer(CreateASTConsumer(CI, Filename));
-    if (!CI.hasASTConsumer())
-      goto failure;
+
+    llvm::OwningPtr<ASTConsumer> Consumer(CreateASTConsumer(CI, Filename));
 
     /// Use PCH?
     if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
       assert(hasPCHSupport() && "This action does not have PCH support!");
       CI.createPCHExternalASTSource(
-        CI.getPreprocessorOpts().ImplicitPCHInclude);
+                                CI.getPreprocessorOpts().ImplicitPCHInclude,
+                                CI.getPreprocessorOpts().DisablePCHValidation,
+                                CI.getInvocation().getFrontendOpts().ChainedPCH?
+                                 Consumer->GetASTDeserializationListener() : 0);
       if (!CI.getASTContext().getExternalSource())
         goto failure;
     }
+
+    CI.setASTConsumer(Consumer.take());
+    if (!CI.hasASTConsumer())
+      goto failure;
   }
 
   // Initialize builtin info as long as we aren't using an external AST
@@ -119,7 +153,7 @@
   }
 
   CI.getDiagnosticClient().EndSourceFile();
-  setCurrentFile("");
+  setCurrentFile("", IK_None);
   setCompilerInstance(0);
   return false;
 }
@@ -162,12 +196,16 @@
   // FIXME: There is more per-file stuff we could just drop here?
   if (CI.getFrontendOpts().DisableFree) {
     CI.takeASTConsumer();
-    if (!isCurrentFileAST())
+    if (!isCurrentFileAST()) {
+      CI.takeSema();
       CI.takeASTContext();
+    }
   } else {
-    CI.setASTConsumer(0);
-    if (!isCurrentFileAST())
+    if (!isCurrentFileAST()) {
+      CI.setSema(0);
       CI.setASTContext(0);
+    }
+    CI.setASTConsumer(0);
   }
 
   // Inform the preprocessor we are done.
@@ -191,6 +229,7 @@
   CI.getDiagnosticClient().EndSourceFile();
 
   if (isCurrentFileAST()) {
+    CI.takeSema();
     CI.takeASTContext();
     CI.takePreprocessor();
     CI.takeSourceManager();
@@ -198,7 +237,7 @@
   }
 
   setCompilerInstance(0);
-  setCurrentFile("");
+  setCurrentFile("", IK_None);
 }
 
 //===----------------------------------------------------------------------===//
@@ -219,9 +258,10 @@
   if (CI.hasCodeCompletionConsumer())
     CompletionConsumer = &CI.getCodeCompletionConsumer();
 
-  ParseAST(CI.getPreprocessor(), &CI.getASTConsumer(), CI.getASTContext(),
-           CI.getFrontendOpts().ShowStats,
-           usesCompleteTranslationUnit(), CompletionConsumer);
+  if (!CI.hasSema())
+    CI.createSema(usesCompleteTranslationUnit(), CompletionConsumer);
+
+  ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats);
 }
 
 ASTConsumer *
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index 6cd960b..5bc6506 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -9,17 +9,18 @@
 
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/AST/ASTConsumer.h"
+#include "clang/Lex/Pragma.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 "clang/Serialization/ASTWriter.h"
 #include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
 
@@ -39,13 +40,6 @@
 // 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))
@@ -77,28 +71,35 @@
 
 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)
+  std::string Sysroot;
+  llvm::raw_ostream *OS = 0;
+  bool Chaining;
+  if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OS, Chaining))
     return 0;
 
-  if (CI.getFrontendOpts().RelocatablePCH)
-    return CreatePCHGenerator(CI.getPreprocessor(), OS, Sysroot.c_str());
-
-  return CreatePCHGenerator(CI.getPreprocessor(), OS);
+  const char *isysroot = CI.getFrontendOpts().RelocatablePCH ?
+                             Sysroot.c_str() : 0;  
+  return new PCHGenerator(CI.getPreprocessor(), Chaining, isysroot, 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;
+bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
+                                                    llvm::StringRef InFile,
+                                                    std::string &Sysroot,
+                                                    llvm::raw_ostream *&OS,
+                                                    bool &Chaining) {
+  Sysroot = CI.getHeaderSearchOpts().Sysroot;
+  if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
+    CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot);
+    return true;
+  }
+
+  OS = CI.createDefaultOutputFile(true, InFile);
+  if (!OS)
+    return true;
+
+  Chaining = CI.getInvocation().getFrontendOpts().ChainedPCH &&
+             !CI.getPreprocessorOpts().ImplicitPCHInclude.empty();
+  return false;
 }
 
 ASTConsumer *InheritanceViewAction::CreateASTConsumer(CompilerInstance &CI,
@@ -106,57 +107,6 @@
   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();
@@ -211,18 +161,12 @@
   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();
 
+  // Ignore unknown pragmas.
+  PP.AddPragmaHandler(new EmptyPragmaHandler());
+
   Token Tok;
   // Start parsing the specified input file.
   PP.EnterMainSourceFile();
@@ -231,19 +175,6 @@
   } 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
@@ -255,18 +186,31 @@
                            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);
+void PrintPreambleAction::ExecuteAction() {
+  switch (getCurrentFileKind()) {
+  case IK_C:
+  case IK_CXX:
+  case IK_ObjC:
+  case IK_ObjCXX:
+  case IK_OpenCL:
+    break;
+      
+  case IK_None:
+  case IK_Asm:
+  case IK_PreprocessedC:
+  case IK_PreprocessedCXX:
+  case IK_PreprocessedObjC:
+  case IK_PreprocessedObjCXX:
+  case IK_AST:
+  case IK_LLVM_IR:
+    // We can't do anything with these.
+    return;
+  }
+  
+  llvm::MemoryBuffer *Buffer = llvm::MemoryBuffer::getFile(getCurrentFile());
+  if (Buffer) {
+    unsigned Preamble = Lexer::ComputePreamble(Buffer).first;
+    llvm::outs().write(Buffer->getBufferStart(), Preamble);
+    delete Buffer;
+  }
 }
diff --git a/lib/Frontend/FrontendOptions.cpp b/lib/Frontend/FrontendOptions.cpp
index bd91638..9dfee24 100644
--- a/lib/Frontend/FrontendOptions.cpp
+++ b/lib/Frontend/FrontendOptions.cpp
@@ -11,8 +11,7 @@
 #include "llvm/ADT/StringSwitch.h"
 using namespace clang;
 
-FrontendOptions::InputKind
-FrontendOptions::getInputKindForExtension(llvm::StringRef Extension) {
+InputKind FrontendOptions::getInputKindForExtension(llvm::StringRef Extension) {
   return llvm::StringSwitch<InputKind>(Extension)
     .Case("ast", IK_AST)
     .Case("c", IK_C)
@@ -27,5 +26,6 @@
     .Cases("C", "cc", "cp", IK_CXX)
     .Cases("cpp", "CPP", "c++", "cxx", "hpp", IK_CXX)
     .Case("cl", IK_OpenCL)
+    .Cases("ll", "bc", IK_LLVM_IR)
     .Default(IK_C);
 }
diff --git a/lib/Frontend/GeneratePCH.cpp b/lib/Frontend/GeneratePCH.cpp
deleted file mode 100644
index 6251bac..0000000
--- a/lib/Frontend/GeneratePCH.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-//===--- 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
deleted file mode 100644
index 022a34d..0000000
--- a/lib/Frontend/HTMLDiagnostics.cpp
+++ /dev/null
@@ -1,577 +0,0 @@
-//===--- 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
deleted file mode 100644
index 9ea8cb3..0000000
--- a/lib/Frontend/HTMLPrint.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-//===--- 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
index 12a4d4d..1b6712f 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -1,4 +1,4 @@
-//===--- InitHeaderSearch.cpp - Initialize header search paths ----------*-===//
+//===--- InitHeaderSearch.cpp - Initialize header search paths ------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -54,7 +54,7 @@
                bool isCXXAware, bool isUserSupplied,
                bool isFramework, bool IgnoreSysRoot = false);
 
-  /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to suport a gnu
+  /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to support a gnu
   ///  libstdc++.
   void AddGnuCPlusPlusIncludePaths(llvm::StringRef Base,
                                    llvm::StringRef ArchDir,
@@ -73,7 +73,8 @@
   void AddDelimitedPaths(llvm::StringRef String);
 
   // AddDefaultCIncludePaths - Add paths that should always be searched.
-  void AddDefaultCIncludePaths(const llvm::Triple &triple);
+  void AddDefaultCIncludePaths(const llvm::Triple &triple,
+                               const HeaderSearchOptions &HSOpts);
 
   // AddDefaultCPlusPlusIncludePaths -  Add paths that should be searched when
   //  compiling c++.
@@ -83,7 +84,7 @@
   ///  that e.g. stdio.h is found.
   void AddDefaultSystemIncludePaths(const LangOptions &Lang,
                                     const llvm::Triple &triple,
-                                    bool UseStandardCXXIncludes);
+                                    const HeaderSearchOptions &HSOpts);
 
   /// Realize - Merges all search path lists into one list and send it to
   /// HeaderSearch.
@@ -322,11 +323,25 @@
 
   // Get Visual Studio installation directory.
 static bool getVisualStudioDir(std::string &path) {
+  // First check the environment variables that vsvars32.bat sets.
+  const char* vcinstalldir = getenv("VCINSTALLDIR");
+  if(vcinstalldir) {
+    char *p = const_cast<char *>(strstr(vcinstalldir, "\\VC"));
+    if (p)
+      *p = '\0';
+    path = vcinstalldir;
+    return(true);
+  }
+
   char vsIDEInstallDir[256];
-  // Try the Windows registry first.
+  char vsExpressIDEInstallDir[256];
+  // Then try the windows registry.
   bool hasVCDir = getSystemRegistryString(
     "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
     "InstallDir", vsIDEInstallDir, sizeof(vsIDEInstallDir) - 1);
+  bool hasVCExpressDir = getSystemRegistryString(
+    "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
+    "InstallDir", vsExpressIDEInstallDir, sizeof(vsExpressIDEInstallDir) - 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");
@@ -335,25 +350,43 @@
     path = vsIDEInstallDir;
     return(true);
   }
+  else if (hasVCExpressDir && vsExpressIDEInstallDir[0]) {
+    char *p = (char*)strstr(vsExpressIDEInstallDir, "\\Common7\\IDE");
+    if (p)
+      *p = '\0';
+    path = vsExpressIDEInstallDir;
+    return(true);
+  }
   else {
     // Try the environment.
+    const char* vs100comntools = getenv("VS100COMNTOOLS");
     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
+
+    // Try to find the version that we were compiled with 
+    if(false) {}
+    #if (_MSC_VER >= 1600)  // VC100
+    else if(vs100comntools) {
+      vscomntools = vs100comntools;
     }
+    #elif (_MSC_VER == 1500) // VC80
+    else if(vs90comntools) {
+      vscomntools = vs90comntools;
+    }
+    #elif (_MSC_VER == 1400) // VC80
+    else if(vs80comntools) {
+      vscomntools = vs80comntools;
+    }
+    #endif
+    // Otherwise find any version we can
+    else if (vs100comntools)
+      vscomntools = vs100comntools;
     else if (vs90comntools)
       vscomntools = vs90comntools;
     else if (vs80comntools)
       vscomntools = vs80comntools;
+
     if (vscomntools && *vscomntools) {
       char *p = const_cast<char *>(strstr(vscomntools, "\\Common7\\Tools"));
       if (p)
@@ -382,8 +415,22 @@
   return(false);
 }
 
-void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple) {
+void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
+                                            const HeaderSearchOptions &HSOpts) {
   // FIXME: temporary hack: hard-coded paths.
+  AddPath("/usr/local/include", System, true, false, false);
+
+  // Builtin includes use #include_next directives and should be positioned
+  // just prior C include dirs.
+  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");
+    AddPath(P.str(), System, false, false, false, /*IgnoreSysRoot=*/ true);
+  }
+
+  // Add dirs specified via 'configure --with-c-include-dirs'.
   llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS);
   if (CIncludeDirs != "") {
     llvm::SmallVector<llvm::StringRef, 5> dirs;
@@ -403,13 +450,15 @@
       if (getVisualStudioDir(VSDir)) {
         AddPath(VSDir + "\\VC\\include", System, false, false, false);
         if (getWindowsSDKDir(WindowsSDKDir))
-          AddPath(WindowsSDKDir, System, false, false, false);
+          AddPath(WindowsSDKDir + "\\include", 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 10.0/VC/include",
+          System, false, false, false);
         AddPath("C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
           System, false, false, false);
         AddPath(
@@ -471,7 +520,7 @@
     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;
+    break;
   case llvm::Triple::MinGW64:
   case llvm::Triple::MinGW32:
     AddPath("c:/mingw/include", System, true, false, false);
@@ -480,21 +529,23 @@
     break;
   }
 
-  AddPath("/usr/local/include", System, true, false, false);
   AddPath("/usr/include", System, false, false, false);
 }
 
-void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple) {
+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);
+                                  CXX_INCLUDE_32BIT_DIR, CXX_INCLUDE_64BIT_DIR,
+                                  triple);
     else
       AddGnuCPlusPlusIncludePaths(CxxIncludeRoot, CXX_INCLUDE_ARCH,
-                                  CXX_INCLUDE_32BIT_DIR, CXX_INCLUDE_64BIT_DIR, triple);
+                                  CXX_INCLUDE_32BIT_DIR, CXX_INCLUDE_64BIT_DIR,
+                                  triple);
     return;
   }
   // FIXME: temporary hack: hard-coded paths.
@@ -504,6 +555,8 @@
         System, true, false, false);
     AddPath("/lib/gcc/i686-pc-cygwin/3.4.4/include/c++",
         System, true, false, false);
+    AddPath("/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/i686-pc-cygwin",
+        System, true, false, false);
     break;
   case llvm::Triple::MinGW64:
     // Try gcc 4.4.0
@@ -518,71 +571,118 @@
     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);
+    switch (triple.getArch()) {
+    default: break;
+
+    case llvm::Triple::ppc: 
+    case llvm::Triple::ppc64:
+      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
+                                  "powerpc-apple-darwin10", "", "ppc64", 
+                                  triple);
+      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
+                                  "powerpc-apple-darwin10", "", "ppc64", 
+                                  triple);
+      break;
+
+    case llvm::Triple::x86:
+    case llvm::Triple::x86_64:
+      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::arm:
+    case llvm::Triple::thumb:
+      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
+                                  "arm-apple-darwin10", "v7", "", triple);
+      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
+                                  "arm-apple-darwin10", "v6", "", triple);
+      break;
+    }
     break;
   case llvm::Triple::DragonFly:
     AddPath("/usr/include/c++/4.1", System, true, false, false);
     break;
   case llvm::Triple::Linux:
+    //===------------------------------------------------------------------===//
+    // Debian based distros.
+    // Note: these distros symlink /usr/include/c++/X.Y.Z -> X.Y
+    //===------------------------------------------------------------------===//
+    // Ubuntu 10.04 LTS "Lucid Lynx" -- gcc-4.4.3
+    // Ubuntu 9.10 "Karmic Koala"    -- gcc-4.4.1
+    // Debian 6.0 "squeeze"          -- gcc-4.4.2
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
+                                "x86_64-linux-gnu", "32", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
+                                "i486-linux-gnu", "", "64", triple);
+    // Ubuntu 9.04 "Jaunty Jackalope" -- gcc-4.3.3
+    // Ubuntu 8.10 "Intrepid Ibex"    -- gcc-4.3.2
+    // Debian 5.0 "lenny"             -- gcc-4.3.2
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
+                                "x86_64-linux-gnu", "32", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
+                                "i486-linux-gnu", "", "64", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
+                                "arm-linux-gnueabi", "", "", triple);
+    // Ubuntu 8.04.4 LTS "Hardy Heron"     -- gcc-4.2.4
+    // Ubuntu 8.04.[0-3] LTS "Hardy Heron" -- gcc-4.2.3
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2",
+                                "x86_64-linux-gnu", "32", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2",
+                                "i486-linux-gnu", "", "64", triple);
+    // Ubuntu 7.10 "Gutsy Gibbon" -- gcc-4.1.3
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1",
+                                "x86_64-linux-gnu", "32", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1",
+                                "i486-linux-gnu", "", "64", triple);
+
+    //===------------------------------------------------------------------===//
+    // Redhat based distros.
+    //===------------------------------------------------------------------===//
+    // Fedora 13
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.4",
+                                "x86_64-redhat-linux", "32", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.4",
+                                "i686-redhat-linux","", "", triple);
+    // Fedora 12
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
+                                "x86_64-redhat-linux", "32", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
+                                "i686-redhat-linux","", "", triple);
+    // Fedora 12 (pre-FEB-2010)
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
+                                "x86_64-redhat-linux", "32", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
+                                "i686-redhat-linux","", "", triple);
+    // Fedora 11
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
+                                "x86_64-redhat-linux", "32", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
+                                "i586-redhat-linux","", "", triple);
+    // Fedora 10
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2",
+                                "x86_64-redhat-linux", "32", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2",
+                                "i386-redhat-linux","", "", triple);
+    // Fedora 9
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.0",
+                                "x86_64-redhat-linux", "32", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.0",
+                                "i386-redhat-linux", "", "", triple);
+    // Fedora 8
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.2",
+                                "x86_64-redhat-linux", "", "", triple);
+    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.2",
+                                "i386-redhat-linux", "", "", triple);
+
+    //===------------------------------------------------------------------===//
+
     // 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",
@@ -612,12 +712,6 @@
     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",
@@ -632,11 +726,30 @@
     AddGnuCPlusPlusIncludePaths(
         "/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/include/g++-v4",
         "x86_64-pc-linux-gnu", "32", "", triple);
+
+    // Gentoo amd64 llvm-gcc trunk
+    AddGnuCPlusPlusIncludePaths(
+        "/usr/lib/llvm-gcc-4.2-9999/include/c++/4.2.1",
+        "x86_64-pc-linux-gnu", "", "", triple);
     
     break;
   case llvm::Triple::FreeBSD:
+    // FreeBSD 8.0
+    // FreeBSD 7.3
     AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "", "", "", triple);
     break;
+  case llvm::Triple::OpenBSD: {
+    std::string t = triple.getTriple();
+    if (t.substr(0, 6) == "x86_64")
+      t.replace(0, 6, "amd64");
+    AddGnuCPlusPlusIncludePaths("/usr/include/g++",
+                                t, "", "", triple);
+    break;
+  }
+  case llvm::Triple::Minix:
+    AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3",
+                                "", "", "", triple);
+    break;
   case llvm::Triple::Solaris:
     // Solaris - Fall though..
   case llvm::Triple::AuroraUX:
@@ -651,11 +764,11 @@
 
 void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang,
                                                     const llvm::Triple &triple,
-                                                  bool UseStandardCXXIncludes) {
-  if (Lang.CPlusPlus && UseStandardCXXIncludes)
+                                            const HeaderSearchOptions &HSOpts) {
+  if (Lang.CPlusPlus && HSOpts.UseStandardCXXIncludes)
     AddDefaultCPlusPlusIncludePaths(triple);
 
-  AddDefaultCIncludePaths(triple);
+  AddDefaultCIncludePaths(triple, HSOpts);
 
   // Add the default framework include paths on Darwin.
   if (triple.getOS() == llvm::Triple::Darwin) {
@@ -799,7 +912,7 @@
   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);
+                 !E.IsSysRootRelative);
   }
 
   // Add entries from CPATH and friends.
@@ -813,17 +926,8 @@
   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.AddDefaultSystemIncludePaths(Lang, Triple, HSOpts);
 
   Init.Realize();
 }
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index e035afd..29a8bec 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/Basic/Version.h"
 #include "clang/Frontend/Utils.h"
 #include "clang/Basic/MacroBuilder.h"
 #include "clang/Basic/TargetInfo.h"
@@ -82,8 +83,8 @@
 static void AddImplicitIncludePTH(MacroBuilder &Builder, Preprocessor &PP,
                                   llvm::StringRef ImplicitIncludePTH) {
   PTHManager *P = PP.getPTHManager();
-  assert(P && "No PTHManager.");
-  const char *OriginalFile = P->getOriginalSourceFile();
+  // Null check 'P' in the corner case where it couldn't be created.
+  const char *OriginalFile = P ? P->getOriginalSourceFile() : 0;
 
   if (!OriginalFile) {
     PP.getDiagnostics().Report(diag::err_fe_pth_file_has_no_source_header)
@@ -168,10 +169,11 @@
                            llvm::StringRef ValSuffix, bool isSigned,
                            MacroBuilder& Builder) {
   long long MaxVal;
-  if (isSigned)
-    MaxVal = (1LL << (TypeWidth - 1)) - 1;
-  else
-    MaxVal = ~0LL >> (64-TypeWidth);
+  if (isSigned) {
+    assert(TypeWidth != 1);
+    MaxVal = ~0ULL >> (65-TypeWidth);
+  } else
+    MaxVal = ~0ULL >> (64-TypeWidth);
 
   Builder.defineMacro(MacroName, llvm::Twine(MaxVal) + ValSuffix);
 }
@@ -194,9 +196,21 @@
   Builder.defineMacro(MacroName, llvm::Twine(TI.getTypeWidth(Ty)));
 }
 
+static void DefineTypeSizeof(llvm::StringRef MacroName, unsigned BitWidth,
+                             const TargetInfo &TI, MacroBuilder &Builder) {
+  Builder.defineMacro(MacroName,
+                      llvm::Twine(BitWidth / TI.getCharWidth()));
+}
+
 static void DefineExactWidthIntType(TargetInfo::IntType Ty, 
                                const TargetInfo &TI, MacroBuilder &Builder) {
   int TypeWidth = TI.getTypeWidth(Ty);
+
+  // Use the target specified int64 type, when appropriate, so that [u]int64_t
+  // ends up being defined in terms of the correct type.
+  if (TypeWidth == 64)
+    Ty = TI.getInt64Type();
+
   DefineType("__INT" + llvm::Twine(TypeWidth) + "_TYPE__", Ty, Builder);
 
   llvm::StringRef ConstSuffix(TargetInfo::getTypeConstantSuffix(Ty));
@@ -212,7 +226,20 @@
   // Compiler version introspection macros.
   Builder.defineMacro("__llvm__");  // LLVM Backend
   Builder.defineMacro("__clang__"); // Clang Frontend
-
+#define TOSTR2(X) #X
+#define TOSTR(X) TOSTR2(X)
+  Builder.defineMacro("__clang_major__", TOSTR(CLANG_VERSION_MAJOR));
+  Builder.defineMacro("__clang_minor__", TOSTR(CLANG_VERSION_MINOR));
+#ifdef CLANG_VERSION_PATCHLEVEL
+  Builder.defineMacro("__clang_patchlevel__", TOSTR(CLANG_VERSION_PATCHLEVEL));
+#else
+  Builder.defineMacro("__clang_patchlevel__", "0");
+#endif
+  Builder.defineMacro("__clang_version__", 
+                      "\"" CLANG_VERSION_STRING " ("
+                      + getClangFullRepositoryVersion() + ")\"");
+#undef TOSTR
+#undef TOSTR2
   // Currently claim to be compatible with GCC 4.2.1-5621.
   Builder.defineMacro("__GNUC_MINOR__", "2");
   Builder.defineMacro("__GNUC_PATCHLEVEL__", "1");
@@ -279,6 +306,8 @@
 
   if (LangOpts.Exceptions)
     Builder.defineMacro("__EXCEPTIONS");
+  if (LangOpts.RTTI)
+    Builder.defineMacro("__GXX_RTTI");
   if (LangOpts.SjLjExceptions)
     Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__");
 
@@ -290,7 +319,7 @@
       Builder.defineMacro("__cplusplus");
     else
       // C++ [cpp.predefined]p1:
-      //   The name_ _cplusplusis defined to the value199711Lwhen compiling a
+      //   The name_ _cplusplusis defined to the value 199711L when compiling a
       //   C++ translation unit.
       Builder.defineMacro("__cplusplus", "199711L");
     Builder.defineMacro("__private_extern__", "extern");
@@ -336,6 +365,23 @@
   DefineTypeSize("__WCHAR_MAX__", TI.getWCharType(), TI, Builder);
   DefineTypeSize("__INTMAX_MAX__", TI.getIntMaxType(), TI, Builder);
 
+  DefineTypeSizeof("__SIZEOF_DOUBLE__", TI.getDoubleWidth(), TI, Builder);
+  DefineTypeSizeof("__SIZEOF_FLOAT__", TI.getFloatWidth(), TI, Builder);
+  DefineTypeSizeof("__SIZEOF_INT__", TI.getIntWidth(), TI, Builder);
+  DefineTypeSizeof("__SIZEOF_LONG__", TI.getLongWidth(), TI, Builder);
+  DefineTypeSizeof("__SIZEOF_LONG_DOUBLE__",TI.getLongDoubleWidth(),TI,Builder);
+  DefineTypeSizeof("__SIZEOF_LONG_LONG__", TI.getLongLongWidth(), TI, Builder);
+  DefineTypeSizeof("__SIZEOF_POINTER__", TI.getPointerWidth(0), TI, Builder);
+  DefineTypeSizeof("__SIZEOF_SHORT__", TI.getShortWidth(), TI, Builder);
+  DefineTypeSizeof("__SIZEOF_PTRDIFF_T__",
+                   TI.getTypeWidth(TI.getPtrDiffType(0)), TI, Builder);
+  DefineTypeSizeof("__SIZEOF_SIZE_T__",
+                   TI.getTypeWidth(TI.getSizeType()), TI, Builder);
+  DefineTypeSizeof("__SIZEOF_WCHAR_T__",
+                   TI.getTypeWidth(TI.getWCharType()), TI, Builder);
+  DefineTypeSizeof("__SIZEOF_WINT_T__",
+                   TI.getTypeWidth(TI.getWIntType()), TI, Builder);
+
   DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Builder);
   DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Builder);
   DefineTypeWidth("__INTMAX_WIDTH__",  TI.getIntMaxType(), TI, Builder);
@@ -350,6 +396,8 @@
   DefineType("__WINT_TYPE__", TI.getWIntType(), Builder);
   DefineTypeWidth("__WINT_WIDTH__", TI.getWIntType(), TI, Builder);
   DefineTypeWidth("__SIG_ATOMIC_WIDTH__", TI.getSigAtomicType(), TI, Builder);
+  DefineType("__CHAR16_TYPE__", TI.getChar16Type(), Builder);
+  DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder);
 
   DefineFloatMacros(Builder, "FLT", &TI.getFloatFormat());
   DefineFloatMacros(Builder, "DBL", &TI.getDoubleFormat());
@@ -414,6 +462,11 @@
 
   if (FEOpts.ProgramAction == frontend::RewriteObjC)
     Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
+
+  // Define a macro that exists only when using the static analyzer.
+  if (FEOpts.ProgramAction == frontend::RunAnalysis)
+    Builder.defineMacro("__clang_analyzer__");
+
   // Get other target #defines.
   TI.getTargetDefines(LangOpts, Builder);
 }
@@ -425,7 +478,7 @@
                                     FileManager &FileMgr,
                                     const PreprocessorOptions &InitOpts) {
   // Remap files in the source manager (with buffers).
-  for (PreprocessorOptions::remapped_file_buffer_iterator
+  for (PreprocessorOptions::const_remapped_file_buffer_iterator
          Remap = InitOpts.remapped_file_buffer_begin(),
          RemapEnd = InitOpts.remapped_file_buffer_end();
        Remap != RemapEnd;
@@ -437,19 +490,21 @@
     if (!FromFile) {
       Diags.Report(diag::err_fe_remap_missing_from_file)
         << Remap->first;
-      delete Remap->second;
+      if (!InitOpts.RetainRemappedFileBuffers)
+        delete Remap->second;
       continue;
     }
 
     // Override the contents of the "from" file with the contents of
     // the "to" file.
-    SourceMgr.overrideFileContents(FromFile, Remap->second);
+    SourceMgr.overrideFileContents(FromFile, Remap->second,
+                                   InitOpts.RetainRemappedFileBuffers);
   }
 
   // Remap files in the source manager (with other files).
-  for (PreprocessorOptions::remapped_file_iterator
-       Remap = InitOpts.remapped_file_begin(),
-       RemapEnd = InitOpts.remapped_file_end();
+  for (PreprocessorOptions::const_remapped_file_iterator
+         Remap = InitOpts.remapped_file_begin(),
+         RemapEnd = InitOpts.remapped_file_end();
        Remap != RemapEnd;
        ++Remap) {
     // Find the file that we're mapping to.
@@ -544,6 +599,10 @@
   if (!PP.getLangOptions().AsmPreprocessor)
     Builder.append("# 1 \"<built-in>\" 2");
 
+  // Instruct the preprocessor to skip the preamble.
+  PP.setSkipMainFilePreamble(InitOpts.PrecompiledPreambleBytes.first,
+                             InitOpts.PrecompiledPreambleBytes.second);
+                          
   // Copy PredefinedBuffer into the Preprocessor.
   PP.setPredefines(Predefines.str());
 
diff --git a/lib/Frontend/Makefile b/lib/Frontend/Makefile
index 9e1a864..3c13ad6 100644
--- a/lib/Frontend/Makefile
+++ b/lib/Frontend/Makefile
@@ -7,11 +7,8 @@
 # 
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
+CLANG_LEVEL := ../..
 LIBRARYNAME := clangFrontend
-BUILD_ARCHIVE = 1
 
-CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
 
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
deleted file mode 100644
index ae57ce5..0000000
--- a/lib/Frontend/PCHReader.cpp
+++ /dev/null
@@ -1,3045 +0,0 @@
-//===--- 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
deleted file mode 100644
index 53647ba..0000000
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ /dev/null
@@ -1,808 +0,0 @@
-//===--- 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
deleted file mode 100644
index 5e08be1..0000000
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ /dev/null
@@ -1,1311 +0,0 @@
-//===--- 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
deleted file mode 100644
index e56dd31..0000000
--- a/lib/Frontend/PCHWriter.cpp
+++ /dev/null
@@ -1,2409 +0,0 @@
-//===--- 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
deleted file mode 100644
index 6b4ba67..0000000
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ /dev/null
@@ -1,632 +0,0 @@
-//===--- 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
deleted file mode 100644
index a0ea5c9..0000000
--- a/lib/Frontend/PCHWriterStmt.cpp
+++ /dev/null
@@ -1,952 +0,0 @@
-//===--- 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
deleted file mode 100644
index 5706a07..0000000
--- a/lib/Frontend/PlistDiagnostics.cpp
+++ /dev/null
@@ -1,471 +0,0 @@
-//===--- 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
deleted file mode 100644
index 4df5c52..0000000
--- a/lib/Frontend/PrintParserCallbacks.cpp
+++ /dev/null
@@ -1,849 +0,0 @@
-//===--- 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
index b6c18b7..cfaf8a2 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -23,6 +23,7 @@
 #include "clang/Lex/TokenConcatenation.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Config/config.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdio>
@@ -84,6 +85,10 @@
   llvm::raw_ostream &OS;
 private:
   unsigned CurLine;
+
+  /// The current include nesting level, used by header include dumping (-H).
+  unsigned CurrentIncludeDepth;
+
   bool EmittedTokensOnThisLine;
   bool EmittedMacroOnThisLine;
   SrcMgr::CharacteristicKind FileType;
@@ -91,19 +96,22 @@
   bool Initialized;
   bool DisableLineMarkers;
   bool DumpDefines;
+  bool DumpHeaderIncludes;
   bool UseLineDirective;
+  bool HasProcessedPredefines;
 public:
   PrintPPOutputPPCallbacks(Preprocessor &pp, llvm::raw_ostream &os,
-                           bool lineMarkers, bool defines)
+                           bool lineMarkers, bool defines, bool headers)
      : PP(pp), SM(PP.getSourceManager()),
        ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers),
-       DumpDefines(defines) {
-    CurLine = 0;
+       DumpDefines(defines), DumpHeaderIncludes(headers) {
+    CurLine = CurrentIncludeDepth = 0;
     CurFilename += "<uninit>";
     EmittedTokensOnThisLine = false;
     EmittedMacroOnThisLine = false;
     FileType = SrcMgr::C_User;
     Initialized = false;
+    HasProcessedPredefines = false;
 
     // If we're in microsoft mode, use normal #line instead of line markers.
     UseLineDirective = PP.getLangOptions().Microsoft;
@@ -117,7 +125,7 @@
   virtual void Ident(SourceLocation Loc, const std::string &str);
   virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
                              const std::string &Str);
-
+  virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str);
 
   bool HandleFirstTokOnLine(Token &Tok);
   bool MoveToLine(SourceLocation Loc) {
@@ -136,6 +144,9 @@
   /// MacroDefined - This hook is called whenever a macro definition is seen.
   void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI);
 
+  /// MacroUndefined - This hook is called whenever a macro #undef is seen.
+  void MacroUndefined(SourceLocation Loc, const IdentifierInfo *II,
+                      const MacroInfo *MI);
 };
 }  // end anonymous namespace
 
@@ -174,20 +185,6 @@
 /// #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) {
@@ -199,8 +196,17 @@
       const char *NewLines = "\n\n\n\n\n\n\n\n";
       OS.write(NewLines, LineNo-CurLine);
     }
-  } else {
+  } else if (!DisableLineMarkers) {
+    // Emit a #line or line marker.
     WriteLineInfo(LineNo, 0, 0);
+  } else {
+    // Okay, we're in -P mode, which turns off line markers.  However, we still
+    // need to emit a newline between tokens on different lines.
+    if (EmittedTokensOnThisLine || EmittedMacroOnThisLine) {
+      OS << '\n';
+      EmittedTokensOnThisLine = false;
+      EmittedMacroOnThisLine = false;
+    }
   }
 
   CurLine = LineNo;
@@ -220,7 +226,7 @@
   
   PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc);
   unsigned NewLine = UserLoc.getLine();
-  
+
   if (Reason == PPCallbacks::EnterFile) {
     SourceLocation IncludeLoc = SourceMgr.getPresumedLoc(Loc).getIncludeLoc();
     if (IncludeLoc.isValid())
@@ -232,16 +238,41 @@
     // directive and emits a bunch of spaces that aren't needed.  Emulate this
     // strange behavior.
   }
+
+  // Adjust the current include depth.
+  if (Reason == PPCallbacks::EnterFile) {
+    ++CurrentIncludeDepth;
+  } else {
+    if (CurrentIncludeDepth)
+      --CurrentIncludeDepth;
+
+    // We track when we are done with the predefines by watching for the first
+    // place where we drop back to a nesting depth of 0.
+    if (CurrentIncludeDepth == 0 && !HasProcessedPredefines)
+      HasProcessedPredefines = true;
+  }
   
   CurLine = NewLine;
 
-  if (DisableLineMarkers) return;
-
   CurFilename.clear();
   CurFilename += UserLoc.getFilename();
   Lexer::Stringify(CurFilename);
   FileType = NewFileType;
 
+  // Dump the header include information, if enabled and we are past the
+  // predefines buffer.
+  if (DumpHeaderIncludes && HasProcessedPredefines &&
+      Reason == PPCallbacks::EnterFile) {
+    llvm::SmallString<256> Msg;
+    llvm::raw_svector_ostream OS(Msg);
+    for (unsigned i = 0; i != CurrentIncludeDepth; ++i)
+      OS << '.';
+    OS << ' ' << CurFilename << '\n';
+    llvm::errs() << OS.str();
+  }
+
+  if (DisableLineMarkers) return;
+  
   if (!Initialized) {
     WriteLineInfo(CurLine);
     Initialized = true;
@@ -284,6 +315,16 @@
   EmittedMacroOnThisLine = true;
 }
 
+void PrintPPOutputPPCallbacks::MacroUndefined(SourceLocation Loc,
+                                              const IdentifierInfo *II,
+                                              const MacroInfo *MI) {
+  // Only print out macro definitions in -dD mode.
+  if (!DumpDefines) return;
+
+  MoveToLine(Loc);
+  OS << "#undef " << II->getName();
+  EmittedMacroOnThisLine = true;
+}
 
 void PrintPPOutputPPCallbacks::PragmaComment(SourceLocation Loc,
                                              const IdentifierInfo *Kind,
@@ -311,6 +352,29 @@
   EmittedTokensOnThisLine = true;
 }
 
+void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
+                                             llvm::StringRef Str) {
+  MoveToLine(Loc);
+  OS << "#pragma message(";
+
+  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
@@ -372,7 +436,7 @@
   PrintPPOutputPPCallbacks *Callbacks;
 
   UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks)
-    : PragmaHandler(0), Prefix(prefix), Callbacks(callbacks) {}
+    : 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.
@@ -397,8 +461,9 @@
                                     PrintPPOutputPPCallbacks *Callbacks,
                                     llvm::raw_ostream &OS) {
   char Buffer[256];
-  Token PrevPrevTok;
-  Token PrevTok;
+  Token PrevPrevTok, PrevTok;
+  PrevPrevTok.startToken();
+  PrevTok.startToken();
   while (1) {
 
     // If this token is at the start of a line, emit newlines if needed.
@@ -454,6 +519,9 @@
 }
 
 static void DoPrintMacros(Preprocessor &PP, llvm::raw_ostream *OS) {
+  // Ignore unknown pragmas.
+  PP.AddPragmaHandler(new EmptyPragmaHandler());
+
   // -dM mode just scans and ignores all tokens in the files, then dumps out
   // the macro table at the end.
   PP.EnterMainSourceFile();
@@ -493,8 +561,8 @@
 
   PrintPPOutputPPCallbacks *Callbacks =
       new PrintPPOutputPPCallbacks(PP, *OS, !Opts.ShowLineMarkers,
-                                   Opts.ShowMacros);
-  PP.AddPragmaHandler(0, new UnknownPragmaHandler("#pragma", Callbacks));
+                                   Opts.ShowMacros, Opts.ShowHeaderIncludes);
+  PP.AddPragmaHandler(new UnknownPragmaHandler("#pragma", Callbacks));
   PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC",
                                                       Callbacks));
 
diff --git a/lib/Frontend/RewriteMacros.cpp b/lib/Frontend/RewriteMacros.cpp
deleted file mode 100644
index 954e8e2..0000000
--- a/lib/Frontend/RewriteMacros.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-//===--- 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
deleted file mode 100644
index 1169832..0000000
--- a/lib/Frontend/RewriteObjC.cpp
+++ /dev/null
@@ -1,5727 +0,0 @@
-//===--- 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
deleted file mode 100644
index 0414678..0000000
--- a/lib/Frontend/RewriteTest.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-//===--- 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
index ce474d3..b660734 100644
--- a/lib/Frontend/StmtXML.cpp
+++ b/lib/Frontend/StmtXML.cpp
@@ -32,7 +32,8 @@
 
 
   void addSpecialAttribute(const char* pName, StringLiteral* Str) {
-    Doc.addAttribute(pName, Doc.escapeString(Str->getStrData(), Str->getByteLength()));
+    Doc.addAttribute(pName, Doc.escapeString(Str->getString().data(),
+                                             Str->getString().size()));
   }
 
   void addSpecialAttribute(const char* pName, SizeOfAlignOfExpr* S) {
@@ -125,6 +126,7 @@
     void VisitFloatingLiteral(FloatingLiteral *Node);
     void VisitStringLiteral(StringLiteral *Str);
     void VisitUnaryOperator(UnaryOperator *Node);
+    void VisitOffsetOfExpr(OffsetOfExpr *Node);
     void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node);
     void VisitMemberExpr(MemberExpr *Node);
     void VisitExtVectorElementExpr(ExtVectorElementExpr *Node);
@@ -260,7 +262,6 @@
   case UnaryOperator::Real:    return "__real";
   case UnaryOperator::Imag:    return "__imag";
   case UnaryOperator::Extension: return "__extension__";
-  case UnaryOperator::OffsetOf: return "__builtin_offsetof";
   }
 }
 
@@ -308,6 +309,10 @@
   Doc.addAttribute("op_code", getOpcodeStr(Node->getOpcode()));
 }
 
+void StmtXML::OffsetOfExpr(OffsetOfExpr *Node) {
+  DumpExpr(Node);
+}
+
 void StmtXML::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
   DumpExpr(Node);
   Doc.addAttribute("is_sizeof", Node->isSizeOf() ? "sizeof" : "alignof");
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index 28bb17a..1e453a0 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -18,6 +18,7 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
 #include <algorithm>
 using namespace clang;
 
@@ -69,7 +70,7 @@
 
 /// 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,
+void TextDiagnosticPrinter::HighlightRange(const CharSourceRange &R,
                                            const SourceManager &SM,
                                            unsigned LineNo, FileID FID,
                                            std::string &CaretLine,
@@ -111,8 +112,10 @@
     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);
+      // Add in the length of the token, so that we cover multi-char tokens if
+      // this is a token range.
+      if (R.isTokenRange())
+        EndColNo += Lexer::MeasureTokenLength(End, SM, *LangOpts);
     } else {
       EndColNo = CaretLine.size();
     }
@@ -120,21 +123,24 @@
 
   assert(StartColNo <= EndColNo && "Invalid range!");
 
-  // Pick the first non-whitespace column.
-  while (StartColNo < SourceLine.size() &&
-         (SourceLine[StartColNo] == ' ' || SourceLine[StartColNo] == '\t'))
-    ++StartColNo;
+  // Check that a token range does not highlight only whitespace.
+  if (R.isTokenRange()) {
+    // 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;
+    // 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??");
+    // 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)
@@ -280,12 +286,15 @@
 }
 
 void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc,
-                                                SourceRange *Ranges,
+                                                CharSourceRange *Ranges,
                                                 unsigned NumRanges,
                                                 const SourceManager &SM,
                                                 const FixItHint *Hints,
                                                 unsigned NumHints,
-                                                unsigned Columns) {
+                                                unsigned Columns,  
+                                                unsigned OnMacroInst,
+                                                unsigned MacroSkipStart,
+                                                unsigned MacroSkipEnd) {
   assert(LangOpts && "Unexpected diagnostic outside source file processing");
   assert(!Loc.isInvalid() && "must have a valid source location here");
 
@@ -293,41 +302,61 @@
   // instantiated (recursively) then emit information about where the token was
   // spelled from.
   if (!Loc.isFileID()) {
+    // Whether to suppress printing this macro instantiation.
+    bool Suppressed 
+      = OnMacroInst >= MacroSkipStart && OnMacroInst < MacroSkipEnd;
+    
+
     SourceLocation OneLevelUp = SM.getImmediateInstantiationRange(Loc).first;
     // FIXME: Map ranges?
-    EmitCaretDiagnostic(OneLevelUp, Ranges, NumRanges, SM, 0, 0, Columns);
-
+    EmitCaretDiagnostic(OneLevelUp, Ranges, NumRanges, SM, 0, 0, Columns,
+                        OnMacroInst + 1, MacroSkipStart, MacroSkipEnd);
+    
     // 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);
+      CharSourceRange &R = Ranges[i];
+      SourceLocation S = R.getBegin(), E = R.getEnd();
+      if (S.isMacroID())
+        R.setBegin(SM.getImmediateSpellingLoc(S));
+      if (E.isMacroID())
+        R.setEnd(SM.getImmediateSpellingLoc(E));
     }
 
-    // Get the pretty name, according to #line directives etc.
-    PresumedLoc PLoc = SM.getPresumedLoc(Loc);
+    if (!Suppressed) {
+      // 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 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,
+                          OnMacroInst + 1, MacroSkipStart, MacroSkipEnd);
+      return;
     }
-
-    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 << ' ';
+    
+    if (OnMacroInst == MacroSkipStart) {
+      // Tell the user that we've skipped contexts.
+      OS << "note: (skipping " << (MacroSkipEnd - MacroSkipStart) 
+      << " contexts in backtrace; use -fmacro-backtrace-limit=0 to see "
+      "all)\n";
     }
-    OS << "note: instantiated from:\n";
-
-    EmitCaretDiagnostic(Loc, Ranges, NumRanges, SM, Hints, NumHints, Columns);
+    
     return;
   }
 
@@ -418,11 +447,11 @@
   if (NumHints && DiagOpts->ShowFixits) {
     for (const FixItHint *Hint = Hints, *LastHint = Hints + NumHints;
          Hint != LastHint; ++Hint) {
-      if (Hint->InsertionLoc.isValid()) {
+      if (!Hint->CodeToInsert.empty()) {
         // 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);
+          = SM.getDecomposedInstantiationLoc(Hint->RemoveRange.getBegin());
         if (SM.getLineNumber(HintLocInfo.first, HintLocInfo.second) ==
               SM.getLineNumber(FID, FileOffset)) {
           // Insert the new code into the line just below the code
@@ -508,6 +537,48 @@
     if (DiagOpts->ShowColors)
       OS.resetColor();
   }
+
+  if (DiagOpts->ShowParseableFixits) {
+
+    // We follow FixItRewriter's example in not (yet) handling
+    // fix-its in macros.
+    bool BadApples = false;
+    for (const FixItHint *Hint = Hints; Hint != Hints + NumHints; ++Hint) {
+      if (Hint->RemoveRange.isInvalid() ||
+          Hint->RemoveRange.getBegin().isMacroID() ||
+          Hint->RemoveRange.getEnd().isMacroID()) {
+        BadApples = true;
+        break;
+      }
+    }
+
+    if (!BadApples) {
+      for (const FixItHint *Hint = Hints; Hint != Hints + NumHints; ++Hint) {
+
+        SourceLocation B = Hint->RemoveRange.getBegin();
+        SourceLocation E = Hint->RemoveRange.getEnd();
+
+        std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(B);
+        std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(E);
+
+        // Adjust for token ranges.
+        if (Hint->RemoveRange.isTokenRange())
+          EInfo.second += Lexer::MeasureTokenLength(E, SM, *LangOpts);
+
+        // We specifically do not do word-wrapping or tab-expansion here,
+        // because this is supposed to be easy to parse.
+        OS << "fix-it:\"";
+        OS.write_escaped(SM.getPresumedLoc(B).getFilename());
+        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)
+          << "}:\"";
+        OS.write_escaped(Hint->CodeToInsert);
+        OS << "\"\n";
+      }
+    }
+  }
 }
 
 /// \brief Skip over whitespace in the string, starting at the given
@@ -755,7 +826,9 @@
             continue;
 
           // Add in the length of the token, so that we cover multi-char tokens.
-          unsigned TokSize = Lexer::MeasureTokenLength(E, SM, *LangOpts);
+          unsigned TokSize = 0;
+          if (Info.getRange(i).isTokenRange())
+            TokSize = Lexer::MeasureTokenLength(E, SM, *LangOpts);
 
           OS << '{' << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
              << SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
@@ -798,21 +871,52 @@
   llvm::SmallString<100> OutStr;
   Info.FormatDiagnostic(OutStr);
 
+  std::string OptionName;
   if (DiagOpts->ShowOptionNames) {
     if (const char *Opt = Diagnostic::getWarningOptionForDiag(Info.getID())) {
-      OutStr += " [-W";
-      OutStr += Opt;
-      OutStr += ']';
+      OptionName = "-W";
+      OptionName += Opt;
+    } else if (Info.getID() == diag::fatal_too_many_errors) {
+      OptionName = "-ferror-limit=";
     } 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]";
+        OptionName = "-pedantic";
     }
   }
+  
+  // If the user wants to see category information, include it too.
+  unsigned DiagCategory = 0;
+  if (DiagOpts->ShowCategories)
+    DiagCategory = Diagnostic::getCategoryNumberForDiag(Info.getID());
 
+  // If there is any categorization information, include it.
+  if (!OptionName.empty() || DiagCategory != 0) {
+    bool NeedsComma = false;
+    OutStr += " [";
+    
+    if (!OptionName.empty()) {
+      OutStr += OptionName;
+      NeedsComma = true;
+    }
+    
+    if (DiagCategory) {
+      if (NeedsComma) OutStr += ',';
+      if (DiagOpts->ShowCategories == 1)
+        OutStr += llvm::utostr(DiagCategory);
+      else {
+        assert(DiagOpts->ShowCategories == 2 && "Invalid ShowCategories value");
+        OutStr += Diagnostic::getCategoryNameFromID(DiagCategory);
+      }
+    }
+    
+    OutStr += "]";
+  }
+
+  
   if (DiagOpts->ShowColors) {
     // Print warnings, errors and fatal errors in bold, no color
     switch (Level) {
@@ -851,25 +955,44 @@
     LastCaretDiagnosticWasNote = (Level == Diagnostic::Note);
 
     // Get the ranges into a local array we can hack on.
-    SourceRange Ranges[20];
+    CharSourceRange 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);
+    for (unsigned i = 0; i != NumHints; ++i) {
+      const FixItHint &Hint = Info.getFixItHint(i);
       if (Hint.RemoveRange.isValid()) {
         assert(NumRanges < 20 && "Out of space");
         Ranges[NumRanges++] = Hint.RemoveRange;
       }
     }
 
+    unsigned MacroInstSkipStart = 0, MacroInstSkipEnd = 0;
+    if (DiagOpts && DiagOpts->MacroBacktraceLimit && !LastLoc.isFileID()) {
+      // Compute the length of the macro-instantiation backtrace, so that we
+      // can establish which steps in the macro backtrace we'll skip.
+      SourceLocation Loc = LastLoc;
+      unsigned Depth = 0;
+      do {
+        ++Depth;
+        Loc = LastLoc.getManager().getImmediateInstantiationRange(Loc).first;
+      } while (!Loc.isFileID());
+      
+      if (Depth > DiagOpts->MacroBacktraceLimit) {
+        MacroInstSkipStart = DiagOpts->MacroBacktraceLimit / 2 + 
+                             DiagOpts->MacroBacktraceLimit % 2;
+        MacroInstSkipEnd = Depth - DiagOpts->MacroBacktraceLimit / 2;
+      }
+    }        
+    
     EmitCaretDiagnostic(LastLoc, Ranges, NumRanges, LastLoc.getManager(),
                         Info.getFixItHints(),
                         Info.getNumFixItHints(),
-                        DiagOpts->MessageLength);
+                        DiagOpts->MessageLength, 
+                        0, MacroInstSkipStart, MacroInstSkipEnd);
   }
 
   OS.flush();
diff --git a/lib/Frontend/VerifyDiagnosticsClient.cpp b/lib/Frontend/VerifyDiagnosticsClient.cpp
index 99ec910..c7c84c1 100644
--- a/lib/Frontend/VerifyDiagnosticsClient.cpp
+++ b/lib/Frontend/VerifyDiagnosticsClient.cpp
@@ -16,6 +16,7 @@
 #include "clang/Frontend/TextDiagnosticBuffer.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Regex.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
 
@@ -71,97 +72,267 @@
 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.
+namespace {
+
+/// Directive - Abstract class representing a parsed verify directive.
 ///
-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);
+class Directive {
+public:
+  static Directive* Create(bool RegexKind, const SourceLocation &Location,
+                           const std::string &Text, unsigned Count);
+public:
+  SourceLocation Location;
+  const std::string Text;
+  unsigned Count;
 
-  // 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;
+  virtual ~Directive() { }
 
-    // If this isn't expected-foo, ignore it.
-    if (memcmp(CommentStart, ExpectedStr, ExpectedStrLen)) {
-      ++CommentStart;
+  // Returns true if directive text is valid.
+  // Otherwise returns false and populates E.
+  virtual bool isValid(std::string &Error) = 0;
+
+  // Returns true on match.
+  virtual bool Match(const std::string &S) = 0;
+
+protected:
+  Directive(const SourceLocation &Location, const std::string &Text,
+            unsigned Count)
+    : Location(Location), Text(Text), Count(Count) { }
+
+private:
+  Directive(const Directive&); // DO NOT IMPLEMENT
+  void operator=(const Directive&); // DO NOT IMPLEMENT
+};
+
+/// StandardDirective - Directive with string matching.
+///
+class StandardDirective : public Directive {
+public:
+  StandardDirective(const SourceLocation &Location, const std::string &Text,
+                    unsigned Count)
+    : Directive(Location, Text, Count) { }
+
+  virtual bool isValid(std::string &Error) {
+    // all strings are considered valid; even empty ones
+    return true;
+  }
+
+  virtual bool Match(const std::string &S) {
+    return S.find(Text) != std::string::npos ||
+           Text.find(S) != std::string::npos;
+  }
+};
+
+/// RegexDirective - Directive with regular-expression matching.
+///
+class RegexDirective : public Directive {
+public:
+  RegexDirective(const SourceLocation &Location, const std::string &Text,
+                 unsigned Count)
+    : Directive(Location, Text, Count), Regex(Text) { }
+
+  virtual bool isValid(std::string &Error) {
+    if (Regex.isValid(Error))
+      return true;
+    return false;
+  }
+
+  virtual bool Match(const std::string &S) {
+    return Regex.match(S);
+  }
+
+private:
+  llvm::Regex Regex;
+};
+
+typedef std::vector<Directive*> DirectiveList;
+
+/// ExpectedData - owns directive objects and deletes on destructor.
+///
+struct ExpectedData {
+  DirectiveList Errors;
+  DirectiveList Warnings;
+  DirectiveList Notes;
+
+  ~ExpectedData() {
+    DirectiveList* Lists[] = { &Errors, &Warnings, &Notes, 0 };
+    for (DirectiveList **PL = Lists; *PL; ++PL) {
+      DirectiveList * const L = *PL;
+      for (DirectiveList::iterator I = L->begin(), E = L->end(); I != E; ++I)
+        delete *I;
+    }
+  }
+};  
+
+class ParseHelper
+{
+public:
+  ParseHelper(const char *Begin, const char *End)
+    : Begin(Begin), End(End), C(Begin), P(Begin), PEnd(NULL) { }
+
+  // Return true if string literal is next.
+  bool Next(const std::string &S) {
+    std::string::size_type LEN = S.length();
+    P = C;
+    PEnd = C + LEN;
+    if (PEnd > End)
+      return false;
+    return !memcmp(P, S.c_str(), LEN);
+  }
+
+  // Return true if number is next.
+  // Output N only if number is next.
+  bool Next(unsigned &N) {
+    unsigned TMP = 0;
+    P = C;
+    for (; P < End && P[0] >= '0' && P[0] <= '9'; ++P) {
+      TMP *= 10;
+      TMP += P[0] - '0';
+    }
+    if (P == C)
+      return false;
+    PEnd = P;
+    N = TMP;
+    return true;
+  }
+
+  // Return true if string literal is found.
+  // When true, P marks begin-position of S in content.
+  bool Search(const std::string &S) {
+    P = std::search(C, End, S.begin(), S.end());
+    PEnd = P + S.length();
+    return P != End;
+  }
+
+  // Advance 1-past previous next/search.
+  // Behavior is undefined if previous next/search failed.
+  bool Advance() {
+    C = PEnd;
+    return C < End;
+  }
+
+  // Skip zero or more whitespace.
+  void SkipWhitespace() {
+    for (; C < End && isspace(*C); ++C)
+      ;
+  }
+
+  // Return true if EOF reached.
+  bool Done() {
+    return !(C < End);
+  }
+
+  const char * const Begin; // beginning of expected content
+  const char * const End;   // end of expected content (1-past)
+  const char *C;            // position of next char in content
+  const char *P;
+
+private:
+  const char *PEnd; // previous next/search subject end (1-past)
+};
+
+} // namespace anonymous
+
+/// ParseDirective - Go through the comment and see if it indicates expected
+/// diagnostics. If so, then put them in the appropriate directive list.
+///
+static void ParseDirective(const char *CommentStart, unsigned CommentLen,
+                           ExpectedData &ED, Preprocessor &PP,
+                           SourceLocation Pos) {
+  // A single comment may contain multiple directives.
+  for (ParseHelper PH(CommentStart, CommentStart+CommentLen); !PH.Done();) {
+    // search for token: expected
+    if (!PH.Search("expected"))
+      break;
+    PH.Advance();
+
+    // next token: -
+    if (!PH.Next("-"))
+      continue;
+    PH.Advance();
+
+    // next token: { error | warning | note }
+    DirectiveList* DL = NULL;
+    if (PH.Next("error"))
+      DL = &ED.Errors;
+    else if (PH.Next("warning"))
+      DL = &ED.Warnings;
+    else if (PH.Next("note"))
+      DL = &ED.Notes;
+    else
+      continue;
+    PH.Advance();
+
+    // default directive kind
+    bool RegexKind = false;
+    const char* KindStr = "string";
+
+    // next optional token: -
+    if (PH.Next("-re")) {
+      PH.Advance();
+      RegexKind = true;
+      KindStr = "regex";
+    }
+
+    // skip optional whitespace
+    PH.SkipWhitespace();
+
+    // next optional token: positive integer
+    unsigned Count = 1;
+    if (PH.Next(Count))
+      PH.Advance();
+
+    // skip optional whitespace
+    PH.SkipWhitespace();
+
+    // next token: {{
+    if (!PH.Next("{{")) {
+      PP.Diag(Pos.getFileLocWithOffset(PH.C-PH.Begin),
+              diag::err_verify_missing_start) << KindStr;
       continue;
     }
+    PH.Advance();
+    const char* const ContentBegin = PH.C; // mark content begin
 
-    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;
+    // search for token: }}
+    if (!PH.Search("}}")) {
+      PP.Diag(Pos.getFileLocWithOffset(PH.C-PH.Begin),
+              diag::err_verify_missing_end) << KindStr;
+      continue;
     }
-    if (Temp > 0)
-      Times = Temp;
+    const char* const ContentEnd = PH.P; // mark content end
+    PH.Advance();
 
-    // 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;
+    // build directive text; convert \n to newlines
+    std::string Text;
+    llvm::StringRef NewlineStr = "\\n";
+    llvm::StringRef Content(ContentBegin, ContentEnd-ContentBegin);
+    size_t CPos = 0;
+    size_t FPos;
+    while ((FPos = Content.find(NewlineStr, CPos)) != llvm::StringRef::npos) {
+      Text += Content.substr(CPos, FPos-CPos);
+      Text += '\n';
+      CPos = FPos + NewlineStr.size();
     }
-    CommentStart += 2;
+    if (Text.empty())
+      Text.assign(ContentBegin, ContentEnd);
 
-    // 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
+    // construct new directive
+    Directive *D = Directive::Create(RegexKind, Pos, Text, Count);
+    std::string Error;
+    if (D->isValid(Error))
+      DL->push_back(D);
+    else {
+      PP.Diag(Pos.getFileLocWithOffset(ContentBegin-PH.Begin),
+              diag::err_verify_invalid_content)
+        << KindStr << Error;
     }
-
-    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) {
+static void FindExpectedDiags(Preprocessor &PP, ExpectedData &ED) {
   // 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();
@@ -185,17 +356,8 @@
     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");
+    // Find all expected errors/warnings/notes.
+    ParseDirective(&Comment[0], Comment.size(), ED, PP, Tok.getLocation());
   };
 }
 
@@ -225,49 +387,68 @@
   return std::distance(diag_begin, diag_end);
 }
 
-/// CompareDiagLists - Compare two diagnostic lists and return the difference
-/// between them.
+static unsigned PrintProblem(Diagnostic &Diags, SourceManager *SourceMgr,
+                             DirectiveList &DL, const char *Kind,
+                             bool Expected) {
+  if (DL.empty())
+    return 0;
+
+  llvm::SmallString<256> Fmt;
+  llvm::raw_svector_ostream OS(Fmt);
+  for (DirectiveList::iterator I = DL.begin(), E = DL.end(); I != E; ++I) {
+    Directive& D = **I;
+    if (D.Location.isInvalid() || !SourceMgr)
+      OS << "\n  (frontend)";
+    else
+      OS << "\n  Line " << SourceMgr->getInstantiationLineNumber(D.Location);
+    OS << ": " << D.Text;
+  }
+
+  Diags.Report(diag::err_verify_inconsistent_diags)
+    << Kind << !Expected << OS.str();
+  return DL.size();
+}
+
+/// CheckLists - Compare expected to seen diagnostic lists and return the
+/// 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);
+static unsigned CheckLists(Diagnostic &Diags, SourceManager &SourceMgr,
+                           const char *Label,
+                           DirectiveList &Left,
+                           const_diag_iterator d2_begin,
+                           const_diag_iterator d2_end) {
+  DirectiveList LeftOnly;
   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;
+  for (DirectiveList::iterator I = Left.begin(), E = Left.end(); I != E; ++I) {
+    Directive& D = **I;
+    unsigned LineNo1 = SourceMgr.getInstantiationLineNumber(D.Location);
 
-    DiagList::iterator II, IE;
-    for (II = Right.begin(), IE = Right.end(); II != IE; ++II) {
-      unsigned LineNo2 = SourceMgr.getInstantiationLineNumber(II->first);
-      if (LineNo1 != LineNo2) continue;
+    for (unsigned i = 0; i < D.Count; ++i) {
+      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;
+        const std::string &RightText = II->second;
+        if (D.Match(RightText))
+          break;
       }
-    }
-    if (II == IE) {
-      // Not found.
-      LeftOnly.push_back(*I);
-    } else {
-      // Found. The same cannot be found twice.
-      Right.erase(II);
+      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));
+  return (PrintProblem(Diags, &SourceMgr, LeftOnly, Label, true) +
+          PrintProblem(Diags, &SourceMgr, Right.begin(), Right.end(),
+                       Label, false));
 }
 
 /// CheckResults - This compares the expected results to those that
@@ -276,9 +457,7 @@
 ///
 static unsigned CheckResults(Diagnostic &Diags, SourceManager &SourceMgr,
                              const TextDiagnosticBuffer &Buffer,
-                             const DiagList &ExpectedErrors,
-                             const DiagList &ExpectedWarnings,
-                             const DiagList &ExpectedNotes) {
+                             ExpectedData &ED) {
   // We want to capture the delta between what was expected and what was
   // seen.
   //
@@ -287,46 +466,35 @@
   unsigned NumProblems = 0;
 
   // See if there are error mismatches.
-  NumProblems += CompareDiagLists(Diags, SourceMgr,
-                                  ExpectedErrors.begin(), ExpectedErrors.end(),
-                                  Buffer.err_begin(), Buffer.err_end(),
-                                  "error");
+  NumProblems += CheckLists(Diags, SourceMgr, "error", ED.Errors,
+                            Buffer.err_begin(), Buffer.err_end());
 
   // See if there are warning mismatches.
-  NumProblems += CompareDiagLists(Diags, SourceMgr,
-                                  ExpectedWarnings.begin(),
-                                  ExpectedWarnings.end(),
-                                  Buffer.warn_begin(), Buffer.warn_end(),
-                                  "warning");
+  NumProblems += CheckLists(Diags, SourceMgr, "warning", ED.Warnings,
+                            Buffer.warn_begin(), Buffer.warn_end());
 
   // See if there are note mismatches.
-  NumProblems += CompareDiagLists(Diags, SourceMgr,
-                                  ExpectedNotes.begin(),
-                                  ExpectedNotes.end(),
-                                  Buffer.note_begin(), Buffer.note_end(),
-                                  "note");
+  NumProblems += CheckLists(Diags, SourceMgr, "note", ED.Notes,
+                            Buffer.note_begin(), Buffer.note_end());
 
   return NumProblems;
 }
 
-
 void VerifyDiagnosticsClient::CheckDiagnostics() {
-  DiagList ExpectedErrors, ExpectedWarnings, ExpectedNotes;
+  ExpectedData ED;
 
   // Ensure any diagnostics go to the primary client.
-  DiagnosticClient *CurClient = Diags.getClient();
+  DiagnosticClient *CurClient = Diags.takeClient();
   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);
+    FindExpectedDiags(*CurrentPreprocessor, ED);
 
     // Check that the expected diagnostics occurred.
     NumErrors += CheckResults(Diags, CurrentPreprocessor->getSourceManager(),
-                              *Buffer,
-                              ExpectedErrors, ExpectedWarnings, ExpectedNotes);
+                              *Buffer, ED);
   } else {
     NumErrors += (PrintProblem(Diags, 0,
                                Buffer->err_begin(), Buffer->err_end(),
@@ -339,8 +507,16 @@
                                "note", false));
   }
 
+  Diags.takeClient();
   Diags.setClient(CurClient);
 
   // Reset the buffer, we have processed all the diagnostics in it.
   Buffer.reset(new TextDiagnosticBuffer());
 }
+
+Directive* Directive::Create(bool RegexKind, const SourceLocation &Location,
+                             const std::string &Text, unsigned Count) {
+  if (RegexKind)
+    return new RegexDirective(Location, Text, Count);
+  return new StandardDirective(Location, Text, Count);
+}
diff --git a/lib/Frontend/Warnings.cpp b/lib/Frontend/Warnings.cpp
index 84c4f5d..8cc5616 100644
--- a/lib/Frontend/Warnings.cpp
+++ b/lib/Frontend/Warnings.cpp
@@ -35,6 +35,8 @@
                                   const DiagnosticOptions &Opts) {
   Diags.setSuppressSystemWarnings(true);  // Default to -Wno-system-headers
   Diags.setIgnoreAllWarnings(Opts.IgnoreWarnings);
+  Diags.setShowOverloads(
+    static_cast<Diagnostic::OverloadsShown>(Opts.ShowOverloads));
   
   // Handle -ferror-limit
   if (Opts.ErrorLimit)
diff --git a/lib/FrontendTool/CMakeLists.txt b/lib/FrontendTool/CMakeLists.txt
new file mode 100644
index 0000000..26c9fc7
--- /dev/null
+++ b/lib/FrontendTool/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_clang_library(clangFrontendTool
+  ExecuteCompilerInvocation.cpp
+  )
diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
new file mode 100644
index 0000000..63c6287
--- /dev/null
+++ b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -0,0 +1,155 @@
+//===--- ExecuteCompilerInvocation.cpp ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file holds ExecuteCompilerInvocation(). It is split into its own file to
+// minimize the impact of pulling in essentially everything else in Clang.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/FrontendTool/Utils.h"
+#include "clang/Checker/FrontendActions.h"
+#include "clang/CodeGen/CodeGenAction.h"
+#include "clang/Driver/CC1Options.h"
+#include "clang/Driver/OptTable.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/FrontendPluginRegistry.h"
+#include "clang/Rewrite/FrontendActions.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/System/DynamicLibrary.h"
+using namespace clang;
+
+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 BoostCon:               return new BoostConAction();
+  case CreateModule:           return 0;
+  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 EmitCodeGenOnly:        return new EmitCodeGenOnlyAction();
+  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 ParseSyntaxOnly:        return new SyntaxOnlyAction();
+
+  case PluginAction: {
+    for (FrontendPluginRegistry::iterator it =
+           FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end();
+         it != ie; ++it) {
+      if (it->getName() == CI.getFrontendOpts().ActionName) {
+        llvm::OwningPtr<PluginASTAction> P(it->instantiate());
+        if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs))
+          return 0;
+        return P.take();
+      }
+    }
+
+    CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
+      << CI.getFrontendOpts().ActionName;
+    return 0;
+  }
+
+  case PrintDeclContext:       return new DeclContextPrintAction();
+  case PrintPreamble:          return new PrintPreambleAction();
+  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;
+}
+
+bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) {
+  // 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));
+  }
+
+  // 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))
+      Clang->getDiagnostics().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();
+    }
+  }
+
+  return Success;
+}
diff --git a/lib/FrontendTool/Makefile b/lib/FrontendTool/Makefile
new file mode 100644
index 0000000..c43213f
--- /dev/null
+++ b/lib/FrontendTool/Makefile
@@ -0,0 +1,13 @@
+##===- clang/lib/FrontendTool/Makefile ---------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+CLANG_LEVEL := ../..
+LIBRARYNAME := clangFrontendTool
+
+include $(CLANG_LEVEL)/Makefile
diff --git a/lib/Headers/CMakeLists.txt b/lib/Headers/CMakeLists.txt
index 4416302..a1b5f50 100644
--- a/lib/Headers/CMakeLists.txt
+++ b/lib/Headers/CMakeLists.txt
@@ -1,12 +1,15 @@
 set(files
   altivec.h
+  avxintrin.h
   emmintrin.h	
   float.h		
+  immintrin.h
   iso646.h	
   limits.h	
   mm_malloc.h	
   mmintrin.h	
   pmmintrin.h	
+  smmintrin.h
   stdarg.h	
   stdbool.h	
   stddef.h	
@@ -21,6 +24,14 @@
   set(output_dir ${LLVM_BINARY_DIR}/lib/clang/${CLANG_VERSION}/include)
 endif ()
 
+# Generate arm_neon.h
+set(LLVM_TARGET_DEFINITIONS ${CLANG_SOURCE_DIR}/include/clang/Basic/arm_neon.td)
+tablegen(arm_neon.h.inc -gen-arm-neon)
+
+add_custom_command(OUTPUT ${output_dir}/arm_neon.h 
+  DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h.inc
+  COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h.inc ${output_dir}/arm_neon.h
+  COMMENT "Copying clang's arm_neon.h...")
 
 foreach( f ${files} )
   set( src ${CMAKE_CURRENT_SOURCE_DIR}/${f} )
@@ -32,8 +43,8 @@
 endforeach( f )
 
 add_custom_target(clang-headers ALL
-  DEPENDS ${files})
+  DEPENDS ${files} ${output_dir}/arm_neon.h)
 
-install(FILES ${files}
+install(FILES ${files} ${output_dir}/arm_neon.h
   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
index cb36e84..d75b1a2 100644
--- a/lib/Headers/Makefile
+++ b/lib/Headers/Makefile
@@ -7,10 +7,15 @@
 # 
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
-include $(LEVEL)/Makefile.common
+CLANG_LEVEL := ../..
 
-CLANG_VERSION := $(shell cat $(PROJ_SRC_DIR)/../../VER)
+BUILT_SOURCES = arm_neon.h.inc
+TABLEGEN_INC_FILES_COMMON = 1
+
+include $(CLANG_LEVEL)/Makefile
+
+CLANG_VERSION := $(word 3,$(shell grep "CLANG_VERSION " \
+	$(PROJ_OBJ_DIR)/$(CLANG_LEVEL)/include/clang/Basic/Version.inc))
 
 HeaderDir := $(PROJ_OBJ_ROOT)/$(BuildMode)/lib/clang/$(CLANG_VERSION)/include
 
@@ -19,7 +24,11 @@
 OBJHEADERS := $(addprefix $(HeaderDir)/, $(HEADERS))
 
 
-$(OBJHEADERS): $(HeaderDir)/%.h: $(PROJ_SRC_DIR)/%.h $(HeaderDir)/.dir
+$(OBJHEADERS): $(HeaderDir)/%.h: $(PROJ_SRC_DIR)/%.h $(HeaderDir)/.dir $(HeaderDir)/arm_neon.h
+	$(Verb) cp $< $@
+	$(Echo) Copying $(notdir $<) to build dir
+
+$(HeaderDir)/arm_neon.h: $(BUILT_SOURCES) $(HeaderDir)/.dir
 	$(Verb) cp $< $@
 	$(Echo) Copying $(notdir $<) to build dir
 
@@ -29,6 +38,7 @@
 PROJ_headers := $(DESTDIR)$(PROJ_prefix)/lib/clang/$(CLANG_VERSION)/include
 
 INSTHEADERS := $(addprefix $(PROJ_headers)/, $(HEADERS))
+INSTHEADERS += $(PROJ_headers)/arm_neon.h
 
 $(PROJ_headers):
 	$(Verb) $(MKDIR) $@
@@ -38,3 +48,7 @@
 	$(Echo) Installing compiler include file: $(notdir $<)
 
 install-local:: $(INSTHEADERS)
+
+$(ObjDir)/arm_neon.h.inc.tmp : $(CLANG_LEVEL)/include/clang/Basic/arm_neon.td $(TBLGEN) $(ObjDir)/.dir
+	$(Echo) "Building Clang arm_neon.h.inc with tblgen"
+	$(Verb) $(TableGen) -gen-arm-neon -o $(call SYSPATH, $@) $<
diff --git a/lib/Headers/altivec.h b/lib/Headers/altivec.h
index 1cd0db8..89bd259 100644
--- a/lib/Headers/altivec.h
+++ b/lib/Headers/altivec.h
@@ -20,6 +20,9 @@
  *
 \*===----------------------------------------------------------------------===*/
 
+// TODO: add functions for 'vector bool ..' and 'vector pixel' argument types according to 
+// the 'AltiVec Technology Programming Interface Manual'
+
 #ifndef __ALTIVEC_H
 #define __ALTIVEC_H
 
@@ -34,849 +37,8485 @@
 #define __CR6_LT     2
 #define __CR6_LT_REV 3
 
-#define _ATTRS_o_ai __attribute__((__overloadable__, __always_inline__))
+#define __ATTRS_o_ai __attribute__((__overloadable__, __always_inline__))
+
+static vector signed char __ATTRS_o_ai
+vec_perm(vector signed char a, vector signed char b, vector unsigned char c);
+
+static vector unsigned char __ATTRS_o_ai
+vec_perm(vector unsigned char a, vector unsigned char b, vector unsigned char c);
+
+static vector bool char __ATTRS_o_ai
+vec_perm(vector bool char a, vector bool char b, vector unsigned char c);
+
+static vector short __ATTRS_o_ai
+vec_perm(vector short a, vector short b, vector unsigned char c);
+
+static vector unsigned short __ATTRS_o_ai
+vec_perm(vector unsigned short a, vector unsigned short b, vector unsigned char c);
+
+static vector bool short __ATTRS_o_ai
+vec_perm(vector bool short a, vector bool short b, vector unsigned char c);
+
+static vector pixel __ATTRS_o_ai
+vec_perm(vector pixel a, vector pixel b, vector unsigned char c);
+
+static vector int __ATTRS_o_ai
+vec_perm(vector int a, vector int b, vector unsigned char c);
+
+static vector unsigned int __ATTRS_o_ai
+vec_perm(vector unsigned int a, vector unsigned int b, vector unsigned char c);
+
+static vector bool int __ATTRS_o_ai
+vec_perm(vector bool int a, vector bool int b, vector unsigned char c);
+
+static vector float __ATTRS_o_ai
+vec_perm(vector float a, vector float b, vector unsigned char c);
 
 /* 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
+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
+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
+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
+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);
+  vector unsigned int res = (vector unsigned int)a & (vector unsigned int)(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
+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));
+  return __builtin_altivec_vmaxsb(a, __builtin_altivec_vsubsbs((vector signed char)(0), a));
 }
 
-static vector signed short _ATTRS_o_ai
+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));
+  return __builtin_altivec_vmaxsh(a, __builtin_altivec_vsubshs((vector signed short)(0), a));
 }
 
-static vector signed int _ATTRS_o_ai
+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));
+  return __builtin_altivec_vmaxsw(a, __builtin_altivec_vsubsws((vector signed int)(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
+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
+static vector signed char __ATTRS_o_ai
+vec_add(vector bool char a, vector signed char b)
+{
+  return (vector signed char)a + b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_add(vector signed char a, vector bool char b)
+{
+  return a + (vector signed char)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
+static vector unsigned char __ATTRS_o_ai
+vec_add(vector bool char a, vector unsigned char b)
+{
+  return (vector unsigned char)a + b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_add(vector unsigned char a, vector bool char b)
+{
+  return a + (vector unsigned char)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
+static vector short __ATTRS_o_ai
+vec_add(vector bool short a, vector short b)
+{
+  return (vector short)a + b;
+}
+
+static vector short __ATTRS_o_ai
+vec_add(vector short a, vector bool short b)
+{
+  return a + (vector short)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
+static vector unsigned short __ATTRS_o_ai
+vec_add(vector bool short a, vector unsigned short b)
+{
+  return (vector unsigned short)a + b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_add(vector unsigned short a, vector bool short b)
+{
+  return a + (vector unsigned short)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
+static vector int __ATTRS_o_ai
+vec_add(vector bool int a, vector int b)
+{
+  return (vector int)a + b;
+}
+
+static vector int __ATTRS_o_ai
+vec_add(vector int a, vector bool int b)
+{
+  return a + (vector int)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
+static vector unsigned int __ATTRS_o_ai
+vec_add(vector bool int a, vector unsigned int b)
+{
+  return (vector unsigned int)a + b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_add(vector unsigned int a, vector bool int b)
+{
+  return a + (vector unsigned int)b;
+}
+
+static vector float __ATTRS_o_ai
 vec_add(vector float a, vector float b)
 {
   return a + b;
 }
 
+/* vec_vaddubm */
+
+#define __builtin_altivec_vaddubm vec_vaddubm
+
+static vector signed char __ATTRS_o_ai
+vec_vaddubm(vector signed char a, vector signed char b)
+{
+  return a + b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vaddubm(vector bool char a, vector signed char b)
+{
+  return (vector signed char)a + b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vaddubm(vector signed char a, vector bool char b)
+{
+  return a + (vector signed char)b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vaddubm(vector unsigned char a, vector unsigned char b)
+{
+  return a + b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vaddubm(vector bool char a, vector unsigned char b)
+{
+  return (vector unsigned char)a + b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vaddubm(vector unsigned char a, vector bool char b)
+{
+  return a + (vector unsigned char)b;
+}
+
+/* vec_vadduhm */
+
+#define __builtin_altivec_vadduhm vec_vadduhm
+
+static vector short __ATTRS_o_ai
+vec_vadduhm(vector short a, vector short b)
+{
+  return a + b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vadduhm(vector bool short a, vector short b)
+{
+  return (vector short)a + b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vadduhm(vector short a, vector bool short b)
+{
+  return a + (vector short)b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vadduhm(vector unsigned short a, vector unsigned short b)
+{
+  return a + b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vadduhm(vector bool short a, vector unsigned short b)
+{
+  return (vector unsigned short)a + b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vadduhm(vector unsigned short a, vector bool short b)
+{
+  return a + (vector unsigned short)b;
+}
+
+/* vec_vadduwm */
+
+#define __builtin_altivec_vadduwm vec_vadduwm
+
+static vector int __ATTRS_o_ai
+vec_vadduwm(vector int a, vector int b)
+{
+  return a + b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vadduwm(vector bool int a, vector int b)
+{
+  return (vector int)a + b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vadduwm(vector int a, vector bool int b)
+{
+  return a + (vector int)b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vadduwm(vector unsigned int a, vector unsigned int b)
+{
+  return a + b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vadduwm(vector bool int a, vector unsigned int b)
+{
+  return (vector unsigned int)a + b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vadduwm(vector unsigned int a, vector bool int b)
+{
+  return a + (vector unsigned int)b;
+}
+
+/* vec_vaddfp */
+
+#define __builtin_altivec_vaddfp  vec_vaddfp
+
+static vector float __attribute__((__always_inline__))
+vec_vaddfp(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
+static vector unsigned int __attribute__((__always_inline__))
+vec_addc(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vaddcuw(a, b);
+}
+
+/* vec_vaddcuw */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vaddcuw(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vaddcuw(a, b);
+}
 
 /* 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
+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
+static vector signed char __ATTRS_o_ai
+vec_adds(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vaddsbs((vector signed char)a, b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_adds(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vaddsbs(a, (vector signed char)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
+static vector unsigned char __ATTRS_o_ai
+vec_adds(vector bool char a, vector unsigned char b)
+{
+  return __builtin_altivec_vaddubs((vector unsigned char)a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_adds(vector unsigned char a, vector bool char b)
+{
+  return __builtin_altivec_vaddubs(a, (vector unsigned char)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
+static vector short __ATTRS_o_ai
+vec_adds(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vaddshs((vector short)a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_adds(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vaddshs(a, (vector short)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
+static vector unsigned short __ATTRS_o_ai
+vec_adds(vector bool short a, vector unsigned short b)
+{
+  return __builtin_altivec_vadduhs((vector unsigned short)a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_adds(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vadduhs(a, (vector unsigned short)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
+static vector int __ATTRS_o_ai
+vec_adds(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vaddsws((vector int)a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_adds(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vaddsws(a, (vector int)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)
+static vector unsigned int __ATTRS_o_ai
+vec_adds(vector bool int a, vector unsigned int b)
 {
-  return a - b;
+  return __builtin_altivec_vadduws((vector unsigned int)a, b);
 }
 
-static vector unsigned char _ATTRS_o_ai
-vec_sub(vector unsigned char a, vector unsigned char b)
+static vector unsigned int __ATTRS_o_ai
+vec_adds(vector unsigned int a, vector bool int b)
 {
-  return a - b;
+  return __builtin_altivec_vadduws(a, (vector unsigned int)b);
 }
 
-static vector short _ATTRS_o_ai
-vec_sub(vector short a, vector short b)
+/* vec_vaddsbs */
+
+static vector signed char __ATTRS_o_ai
+vec_vaddsbs(vector signed char a, vector signed char b)
 {
-  return a - b;
+  return __builtin_altivec_vaddsbs(a, b);
 }
 
-static vector unsigned short _ATTRS_o_ai
-vec_sub(vector unsigned short a, vector unsigned short b)
+static vector signed char __ATTRS_o_ai
+vec_vaddsbs(vector bool char a, vector signed char b)
 {
-  return a - b;
+  return __builtin_altivec_vaddsbs((vector signed char)a, b);
 }
 
-static vector int _ATTRS_o_ai
-vec_sub(vector int a, vector int b)
+static vector signed char __ATTRS_o_ai
+vec_vaddsbs(vector signed char a, vector bool char b)
 {
-  return a - b;
+  return __builtin_altivec_vaddsbs(a, (vector signed char)b);
 }
 
-static vector unsigned int _ATTRS_o_ai
-vec_sub(vector unsigned int a, vector unsigned int b)
+/* vec_vaddubs */
+
+static vector unsigned char __ATTRS_o_ai
+vec_vaddubs(vector unsigned char a, vector unsigned char b)
 {
-  return a - b;
+  return __builtin_altivec_vaddubs(a, b);
 }
 
-static vector float _ATTRS_o_ai
-vec_sub(vector float a, vector float b)
+static vector unsigned char __ATTRS_o_ai
+vec_vaddubs(vector bool char a, vector unsigned char b)
 {
-  return a - b;
+  return __builtin_altivec_vaddubs((vector unsigned char)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)
+static vector unsigned char __ATTRS_o_ai
+vec_vaddubs(vector unsigned char a, vector bool char b)
 {
-  return __builtin_altivec_vsubsbs(a, b);
+  return __builtin_altivec_vaddubs(a, (vector unsigned char)b);
 }
 
-static vector unsigned char _ATTRS_o_ai
-vec_subs(vector unsigned char a, vector unsigned char b)
+/* vec_vaddshs */
+
+static vector short __ATTRS_o_ai
+vec_vaddshs(vector short a, vector short b)
 {
-  return __builtin_altivec_vsububs(a, b);
+  return __builtin_altivec_vaddshs(a, b);
 }
 
-static vector short _ATTRS_o_ai
-vec_subs(vector short a, vector short b)
+static vector short __ATTRS_o_ai
+vec_vaddshs(vector bool short a, vector short b)
 {
-  return __builtin_altivec_vsubshs(a, b);
+  return __builtin_altivec_vaddshs((vector short)a, b);
 }
 
-static vector unsigned short _ATTRS_o_ai
-vec_subs(vector unsigned short a, vector unsigned short b)
+static vector short __ATTRS_o_ai
+vec_vaddshs(vector short a, vector bool short b)
 {
-  return __builtin_altivec_vsubuhs(a, b);
+  return __builtin_altivec_vaddshs(a, (vector short)b);
 }
 
-static vector int _ATTRS_o_ai
-vec_subs(vector int a, vector int b)
+/* vec_vadduhs */
+
+static vector unsigned short __ATTRS_o_ai
+vec_vadduhs(vector unsigned short a, vector unsigned short b)
 {
-  return __builtin_altivec_vsubsws(a, b);
+  return __builtin_altivec_vadduhs(a, b);
 }
 
-static vector unsigned int _ATTRS_o_ai
-vec_subs(vector unsigned int a, vector unsigned int b)
+static vector unsigned short __ATTRS_o_ai
+vec_vadduhs(vector bool short a, vector unsigned short b)
 {
-  return __builtin_altivec_vsubuws(a, b);
+  return __builtin_altivec_vadduhs((vector unsigned short)a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vadduhs(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vadduhs(a, (vector unsigned short)b);
+}
+
+/* vec_vaddsws */
+
+static vector int __ATTRS_o_ai
+vec_vaddsws(vector int a, vector int b)
+{
+  return __builtin_altivec_vaddsws(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vaddsws(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vaddsws((vector int)a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vaddsws(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vaddsws(a, (vector int)b);
+}
+
+/* vec_vadduws */
+
+static vector unsigned int __ATTRS_o_ai
+vec_vadduws(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vadduws(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vadduws(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vadduws((vector unsigned int)a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vadduws(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vadduws(a, (vector unsigned int)b);
+}
+
+/* vec_and */
+
+#define __builtin_altivec_vand vec_and
+
+static vector signed char __ATTRS_o_ai
+vec_and(vector signed char a, vector signed char b)
+{
+  return a & b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_and(vector bool char a, vector signed char b)
+{
+  return (vector signed char)a & b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_and(vector signed char a, vector bool char b)
+{
+  return a & (vector signed char)b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_and(vector unsigned char a, vector unsigned char b)
+{
+  return a & b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_and(vector bool char a, vector unsigned char b)
+{
+  return (vector unsigned char)a & b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_and(vector unsigned char a, vector bool char b)
+{
+  return a & (vector unsigned char)b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_and(vector bool char a, vector bool char b)
+{
+  return a & b;
+}
+
+static vector short __ATTRS_o_ai
+vec_and(vector short a, vector short b)
+{
+  return a & b;
+}
+
+static vector short __ATTRS_o_ai
+vec_and(vector bool short a, vector short b)
+{
+  return (vector short)a & b;
+}
+
+static vector short __ATTRS_o_ai
+vec_and(vector short a, vector bool short b)
+{
+  return a & (vector short)b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_and(vector unsigned short a, vector unsigned short b)
+{
+  return a & b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_and(vector bool short a, vector unsigned short b)
+{
+  return (vector unsigned short)a & b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_and(vector unsigned short a, vector bool short b)
+{
+  return a & (vector unsigned short)b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_and(vector bool short a, vector bool short b)
+{
+  return a & b;
+}
+
+static vector int __ATTRS_o_ai
+vec_and(vector int a, vector int b)
+{
+  return a & b;
+}
+
+static vector int __ATTRS_o_ai
+vec_and(vector bool int a, vector int b)
+{
+  return (vector int)a & b;
+}
+
+static vector int __ATTRS_o_ai
+vec_and(vector int a, vector bool int b)
+{
+  return a & (vector int)b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_and(vector unsigned int a, vector unsigned int b)
+{
+  return a & b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_and(vector bool int a, vector unsigned int b)
+{
+  return (vector unsigned int)a & b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_and(vector unsigned int a, vector bool int b)
+{
+  return a & (vector unsigned int)b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_and(vector bool int a, vector bool int b)
+{
+  return a & b;
+}
+
+static vector float __ATTRS_o_ai
+vec_and(vector float a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a & (vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_and(vector bool int a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a & (vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_and(vector float a, vector bool int b)
+{
+  vector unsigned int res = (vector unsigned int)a & (vector unsigned int)b;
+  return (vector float)res;
+}
+
+/* vec_vand */
+
+static vector signed char __ATTRS_o_ai
+vec_vand(vector signed char a, vector signed char b)
+{
+  return a & b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vand(vector bool char a, vector signed char b)
+{
+  return (vector signed char)a & b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vand(vector signed char a, vector bool char b)
+{
+  return a & (vector signed char)b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vand(vector unsigned char a, vector unsigned char b)
+{
+  return a & b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vand(vector bool char a, vector unsigned char b)
+{
+  return (vector unsigned char)a & b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vand(vector unsigned char a, vector bool char b)
+{
+  return a & (vector unsigned char)b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vand(vector bool char a, vector bool char b)
+{
+  return a & b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vand(vector short a, vector short b)
+{
+  return a & b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vand(vector bool short a, vector short b)
+{
+  return (vector short)a & b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vand(vector short a, vector bool short b)
+{
+  return a & (vector short)b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vand(vector unsigned short a, vector unsigned short b)
+{
+  return a & b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vand(vector bool short a, vector unsigned short b)
+{
+  return (vector unsigned short)a & b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vand(vector unsigned short a, vector bool short b)
+{
+  return a & (vector unsigned short)b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vand(vector bool short a, vector bool short b)
+{
+  return a & b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vand(vector int a, vector int b)
+{
+  return a & b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vand(vector bool int a, vector int b)
+{
+  return (vector int)a & b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vand(vector int a, vector bool int b)
+{
+  return a & (vector int)b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vand(vector unsigned int a, vector unsigned int b)
+{
+  return a & b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vand(vector bool int a, vector unsigned int b)
+{
+  return (vector unsigned int)a & b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vand(vector unsigned int a, vector bool int b)
+{
+  return a & (vector unsigned int)b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vand(vector bool int a, vector bool int b)
+{
+  return a & b;
+}
+
+static vector float __ATTRS_o_ai
+vec_vand(vector float a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a & (vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vand(vector bool int a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a & (vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vand(vector float a, vector bool int b)
+{
+  vector unsigned int res = (vector unsigned int)a & (vector unsigned int)b;
+  return (vector float)res;
+}
+
+/* vec_andc */
+
+#define __builtin_altivec_vandc vec_andc
+
+static vector signed char __ATTRS_o_ai
+vec_andc(vector signed char a, vector signed char b)
+{
+  return a & ~b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_andc(vector bool char a, vector signed char b)
+{
+  return (vector signed char)a & ~b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_andc(vector signed char a, vector bool char b)
+{
+  return a & ~(vector signed char)b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_andc(vector unsigned char a, vector unsigned char b)
+{
+  return a & ~b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_andc(vector bool char a, vector unsigned char b)
+{
+  return (vector unsigned char)a & ~b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_andc(vector unsigned char a, vector bool char b)
+{
+  return a & ~(vector unsigned char)b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_andc(vector bool char a, vector bool char b)
+{
+  return a & ~b;
+}
+
+static vector short __ATTRS_o_ai
+vec_andc(vector short a, vector short b)
+{
+  return a & ~b;
+}
+
+static vector short __ATTRS_o_ai
+vec_andc(vector bool short a, vector short b)
+{
+  return (vector short)a & ~b;
+}
+
+static vector short __ATTRS_o_ai
+vec_andc(vector short a, vector bool short b)
+{
+  return a & ~(vector short)b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_andc(vector unsigned short a, vector unsigned short b)
+{
+  return a & ~b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_andc(vector bool short a, vector unsigned short b)
+{
+  return (vector unsigned short)a & ~b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_andc(vector unsigned short a, vector bool short b)
+{
+  return a & ~(vector unsigned short)b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_andc(vector bool short a, vector bool short b)
+{
+  return a & ~b;
+}
+
+static vector int __ATTRS_o_ai
+vec_andc(vector int a, vector int b)
+{
+  return a & ~b;
+}
+
+static vector int __ATTRS_o_ai
+vec_andc(vector bool int a, vector int b)
+{
+  return (vector int)a & ~b;
+}
+
+static vector int __ATTRS_o_ai
+vec_andc(vector int a, vector bool int b)
+{
+  return a & ~(vector int)b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_andc(vector unsigned int a, vector unsigned int b)
+{
+  return a & ~b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_andc(vector bool int a, vector unsigned int b)
+{
+  return (vector unsigned int)a & ~b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_andc(vector unsigned int a, vector bool int b)
+{
+  return a & ~(vector unsigned int)b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_andc(vector bool int a, vector bool int b)
+{
+  return a & ~b;
+}
+
+static vector float __ATTRS_o_ai
+vec_andc(vector float a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a & ~(vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_andc(vector bool int a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a & ~(vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_andc(vector float a, vector bool int b)
+{
+  vector unsigned int res = (vector unsigned int)a & ~(vector unsigned int)b;
+  return (vector float)res;
+}
+
+/* vec_vandc */
+
+static vector signed char __ATTRS_o_ai
+vec_vandc(vector signed char a, vector signed char b)
+{
+  return a & ~b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vandc(vector bool char a, vector signed char b)
+{
+  return (vector signed char)a & ~b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vandc(vector signed char a, vector bool char b)
+{
+  return a & ~(vector signed char)b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vandc(vector unsigned char a, vector unsigned char b)
+{
+  return a & ~b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vandc(vector bool char a, vector unsigned char b)
+{
+  return (vector unsigned char)a & ~b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vandc(vector unsigned char a, vector bool char b)
+{
+  return a & ~(vector unsigned char)b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vandc(vector bool char a, vector bool char b)
+{
+  return a & ~b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vandc(vector short a, vector short b)
+{
+  return a & ~b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vandc(vector bool short a, vector short b)
+{
+  return (vector short)a & ~b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vandc(vector short a, vector bool short b)
+{
+  return a & ~(vector short)b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vandc(vector unsigned short a, vector unsigned short b)
+{
+  return a & ~b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vandc(vector bool short a, vector unsigned short b)
+{
+  return (vector unsigned short)a & ~b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vandc(vector unsigned short a, vector bool short b)
+{
+  return a & ~(vector unsigned short)b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vandc(vector bool short a, vector bool short b)
+{
+  return a & ~b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vandc(vector int a, vector int b)
+{
+  return a & ~b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vandc(vector bool int a, vector int b)
+{
+  return (vector int)a & ~b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vandc(vector int a, vector bool int b)
+{
+  return a & ~(vector int)b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vandc(vector unsigned int a, vector unsigned int b)
+{
+  return a & ~b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vandc(vector bool int a, vector unsigned int b)
+{
+  return (vector unsigned int)a & ~b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vandc(vector unsigned int a, vector bool int b)
+{
+  return a & ~(vector unsigned int)b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vandc(vector bool int a, vector bool int b)
+{
+  return a & ~b;
+}
+
+static vector float __ATTRS_o_ai
+vec_vandc(vector float a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a & ~(vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vandc(vector bool int a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a & ~(vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vandc(vector float a, vector bool int b)
+{
+  vector unsigned int res = (vector unsigned int)a & ~(vector unsigned int)b;
+  return (vector float)res;
 }
 
 /* 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
+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
+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
+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
+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
+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
+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 */
+/* vec_vavgsb */
 
-#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)
+static vector signed char __attribute__((__always_inline__))
+vec_vavgsb(vector signed char a, vector signed char b)
 {
-  __builtin_altivec_stvx((vector int)a, b, (void *)c);
+  return __builtin_altivec_vavgsb(a, b);
 }
 
-static void _ATTRS_o_ai
-vec_st(vector unsigned char a, int b, vector unsigned char *c)
+/* vec_vavgub */
+
+static vector unsigned char __attribute__((__always_inline__))
+vec_vavgub(vector unsigned char a, vector unsigned char b)
 {
-  __builtin_altivec_stvx((vector int)a, b, (void *)c);
+  return __builtin_altivec_vavgub(a, b);
 }
 
-static void _ATTRS_o_ai
-vec_st(vector short a, int b, vector short *c)
+/* vec_vavgsh */
+
+static vector short __attribute__((__always_inline__))
+vec_vavgsh(vector short a, vector short b)
 {
-  __builtin_altivec_stvx((vector int)a, b, (void *)c);
+  return __builtin_altivec_vavgsh(a, b);
 }
 
-static void _ATTRS_o_ai
-vec_st(vector unsigned short a, int b, vector unsigned short *c)
+/* vec_vavguh */
+
+static vector unsigned short __attribute__((__always_inline__))
+vec_vavguh(vector unsigned short a, vector unsigned short b)
 {
-  __builtin_altivec_stvx((vector int)a, b, (void *)c);
+  return __builtin_altivec_vavguh(a, b);
 }
 
-static void _ATTRS_o_ai
-vec_st(vector int a, int b, vector int *c)
+/* vec_vavgsw */
+
+static vector int __attribute__((__always_inline__))
+vec_vavgsw(vector int a, vector int b)
 {
-  __builtin_altivec_stvx(a, b, (void *)c);
+  return __builtin_altivec_vavgsw(a, b);
 }
 
-static void _ATTRS_o_ai
-vec_st(vector unsigned int a, int b, vector unsigned int *c)
+/* vec_vavguw */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vavguw(vector unsigned int a, vector unsigned int b)
 {
-  __builtin_altivec_stvx((vector int)a, b, (void *)c);
+  return __builtin_altivec_vavguw(a, b);
 }
 
-static void _ATTRS_o_ai
-vec_st(vector float a, int b, vector float *c)
+/* vec_ceil */
+
+static vector float __attribute__((__always_inline__))
+vec_ceil(vector float a)
 {
-  __builtin_altivec_stvx((vector int)a, b, (void *)c);
+  return __builtin_altivec_vrfip(a);
 }
 
-/* vec_stl */
+/* vec_vrfip */
 
-#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)
+static vector float __attribute__((__always_inline__))
+vec_vrfip(vector float a)
 {
-  __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);
+  return __builtin_altivec_vrfip(a);
 }
 
 /* vec_cmpb */
 
-#define vec_cmpb           __builtin_altivec_vcmpbfp
-#define vec_vcmpbfp        __builtin_altivec_vcmpbfp
-#define __builtin_vec_cmpb __builtin_altivec_vcmpbfp
+static vector int __attribute__((__always_inline__))
+vec_cmpb(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpbfp(a, b);
+}
+
+/* vec_vcmpbfp */
+
+static vector int __attribute__((__always_inline__))
+vec_vcmpbfp(vector float a, vector float b)
+{
+  return __builtin_altivec_vcmpbfp(a, b);
+}
 
 /* vec_cmpeq */
 
-#define __builtin_vec_cmpeq vec_cmpeq
-
-static vector /*bool*/ char _ATTRS_o_ai
+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);
+  return (vector bool char)
+    __builtin_altivec_vcmpequb((vector char)a, (vector char)b);
 }
 
-static vector /*bool*/ char _ATTRS_o_ai
+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);
+  return (vector bool char)
+    __builtin_altivec_vcmpequb((vector char)a, (vector char)b);
 }
 
-static vector /*bool*/ short _ATTRS_o_ai
+static vector bool short __ATTRS_o_ai
 vec_cmpeq(vector short a, vector short b)
 {
-  return __builtin_altivec_vcmpequh(a, b);
+  return (vector bool short)__builtin_altivec_vcmpequh(a, b);
 }
 
-static vector /*bool*/ short _ATTRS_o_ai
+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);
+  return (vector bool short)
+    __builtin_altivec_vcmpequh((vector short)a, (vector short)b);
 }
 
-static vector /*bool*/ int _ATTRS_o_ai
+static vector bool int __ATTRS_o_ai
 vec_cmpeq(vector int a, vector int b)
 {
-  return __builtin_altivec_vcmpequw(a, b);
+  return (vector bool int)__builtin_altivec_vcmpequw(a, b);
 }
 
-static vector /*bool*/ int _ATTRS_o_ai
+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);
+  return (vector bool int)
+    __builtin_altivec_vcmpequw((vector int)a, (vector int)b);
 }
 
-static vector /*bool*/ int _ATTRS_o_ai
+static vector bool int __ATTRS_o_ai
 vec_cmpeq(vector float a, vector float b)
 {
-  return __builtin_altivec_vcmpeqfp(a, b);
+  return (vector bool int)__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
+static vector bool int __attribute__((__always_inline__))
+vec_cmpge(vector float a, vector float b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgefp(a, b);
+}
+
+/* vec_vcmpgefp */
+
+static vector bool int __attribute__((__always_inline__))
+vec_vcmpgefp(vector float a, vector float b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgefp(a, b);
+}
 
 /* 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
+static vector bool char __ATTRS_o_ai
 vec_cmpgt(vector signed char a, vector signed char b)
 {
-  return __builtin_altivec_vcmpgtsb(a, b);
+  return (vector bool char)__builtin_altivec_vcmpgtsb(a, b);
 }
 
-static vector /*bool*/ char _ATTRS_o_ai
+static vector bool char __ATTRS_o_ai
 vec_cmpgt(vector unsigned char a, vector unsigned char b)
 {
-  return __builtin_altivec_vcmpgtub(a, b);
+  return (vector bool char)__builtin_altivec_vcmpgtub(a, b);
 }
 
-static vector /*bool*/ short _ATTRS_o_ai
+static vector bool short __ATTRS_o_ai
 vec_cmpgt(vector short a, vector short b)
 {
-  return __builtin_altivec_vcmpgtsh(a, b);
+  return (vector bool short)__builtin_altivec_vcmpgtsh(a, b);
 }
 
-static vector /*bool*/ short _ATTRS_o_ai
+static vector bool short __ATTRS_o_ai
 vec_cmpgt(vector unsigned short a, vector unsigned short b)
 {
-  return __builtin_altivec_vcmpgtuh(a, b);
+  return (vector bool short)__builtin_altivec_vcmpgtuh(a, b);
 }
 
-static vector /*bool*/ int _ATTRS_o_ai
+static vector bool int __ATTRS_o_ai
 vec_cmpgt(vector int a, vector int b)
 {
-  return __builtin_altivec_vcmpgtsw(a, b);
+  return (vector bool int)__builtin_altivec_vcmpgtsw(a, b);
 }
 
-static vector /*bool*/ int _ATTRS_o_ai
+static vector bool int __ATTRS_o_ai
 vec_cmpgt(vector unsigned int a, vector unsigned int b)
 {
-  return __builtin_altivec_vcmpgtuw(a, b);
+  return (vector bool int)__builtin_altivec_vcmpgtuw(a, b);
 }
 
-static vector /*bool*/ int _ATTRS_o_ai
+static vector bool int __ATTRS_o_ai
 vec_cmpgt(vector float a, vector float b)
 {
-  return __builtin_altivec_vcmpgtfp(a, b);
+  return (vector bool int)__builtin_altivec_vcmpgtfp(a, b);
+}
+
+/* vec_vcmpgtsb */
+
+static vector bool char __attribute__((__always_inline__))
+vec_vcmpgtsb(vector signed char a, vector signed char b)
+{
+  return (vector bool char)__builtin_altivec_vcmpgtsb(a, b);
+}
+
+/* vec_vcmpgtub */
+
+static vector bool char __attribute__((__always_inline__))
+vec_vcmpgtub(vector unsigned char a, vector unsigned char b)
+{
+  return (vector bool char)__builtin_altivec_vcmpgtub(a, b);
+}
+
+/* vec_vcmpgtsh */
+
+static vector bool short __attribute__((__always_inline__))
+vec_vcmpgtsh(vector short a, vector short b)
+{
+  return (vector bool short)__builtin_altivec_vcmpgtsh(a, b);
+}
+
+/* vec_vcmpgtuh */
+
+static vector bool short __attribute__((__always_inline__))
+vec_vcmpgtuh(vector unsigned short a, vector unsigned short b)
+{
+  return (vector bool short)__builtin_altivec_vcmpgtuh(a, b);
+}
+
+/* vec_vcmpgtsw */
+
+static vector bool int __attribute__((__always_inline__))
+vec_vcmpgtsw(vector int a, vector int b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgtsw(a, b);
+}
+
+/* vec_vcmpgtuw */
+
+static vector bool int __attribute__((__always_inline__))
+vec_vcmpgtuw(vector unsigned int a, vector unsigned int b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgtuw(a, b);
+}
+
+/* vec_vcmpgtfp */
+
+static vector bool int __attribute__((__always_inline__))
+vec_vcmpgtfp(vector float a, vector float b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgtfp(a, b);
 }
 
 /* vec_cmple */
 
-#define __builtin_vec_cmple vec_cmple
-
-static vector /*bool*/ int __attribute__((__always_inline__))
+static vector bool int __attribute__((__always_inline__))
 vec_cmple(vector float a, vector float b)
 {
-  return __builtin_altivec_vcmpgefp(b, a);
+  return (vector bool int)__builtin_altivec_vcmpgefp(b, a);
 }
 
 /* vec_cmplt */
 
-#define __builtin_vec_cmplt vec_cmplt
-
-static vector /*bool*/ char _ATTRS_o_ai
+static vector bool char __ATTRS_o_ai
 vec_cmplt(vector signed char a, vector signed char b)
 {
-  return __builtin_altivec_vcmpgtsb(b, a);
+  return (vector bool char)__builtin_altivec_vcmpgtsb(b, a);
 }
 
-static vector /*bool*/ char _ATTRS_o_ai
+static vector bool char __ATTRS_o_ai
 vec_cmplt(vector unsigned char a, vector unsigned char b)
 {
-  return __builtin_altivec_vcmpgtub(b, a);
+  return (vector bool char)__builtin_altivec_vcmpgtub(b, a);
 }
 
-static vector /*bool*/ short _ATTRS_o_ai
+static vector bool short __ATTRS_o_ai
 vec_cmplt(vector short a, vector short b)
 {
-  return __builtin_altivec_vcmpgtsh(b, a);
+  return (vector bool short)__builtin_altivec_vcmpgtsh(b, a);
 }
 
-static vector /*bool*/ short _ATTRS_o_ai
+static vector bool short __ATTRS_o_ai
 vec_cmplt(vector unsigned short a, vector unsigned short b)
 {
-  return __builtin_altivec_vcmpgtuh(b, a);
+  return (vector bool short)__builtin_altivec_vcmpgtuh(b, a);
 }
 
-static vector /*bool*/ int _ATTRS_o_ai
+static vector bool int __ATTRS_o_ai
 vec_cmplt(vector int a, vector int b)
 {
-  return __builtin_altivec_vcmpgtsw(b, a);
+  return (vector bool int)__builtin_altivec_vcmpgtsw(b, a);
 }
 
-static vector /*bool*/ int _ATTRS_o_ai
+static vector bool int __ATTRS_o_ai
 vec_cmplt(vector unsigned int a, vector unsigned int b)
 {
-  return __builtin_altivec_vcmpgtuw(b, a);
+  return (vector bool int)__builtin_altivec_vcmpgtuw(b, a);
 }
 
-static vector /*bool*/ int _ATTRS_o_ai
+static vector bool int __ATTRS_o_ai
 vec_cmplt(vector float a, vector float b)
 {
-  return __builtin_altivec_vcmpgtfp(b, a);
+  return (vector bool int)__builtin_altivec_vcmpgtfp(b, a);
+}
+
+/* vec_ctf */
+
+static vector float __ATTRS_o_ai
+vec_ctf(vector int a, int b)
+{
+  return __builtin_altivec_vcfsx(a, b);
+}
+
+static vector float __ATTRS_o_ai
+vec_ctf(vector unsigned int a, int b)
+{
+  return __builtin_altivec_vcfux((vector int)a, b);
+}
+
+/* vec_vcfsx */
+
+static vector float __attribute__((__always_inline__))
+vec_vcfsx(vector int a, int b)
+{
+  return __builtin_altivec_vcfsx(a, b);
+}
+
+/* vec_vcfux */
+
+static vector float __attribute__((__always_inline__))
+vec_vcfux(vector unsigned int a, int b)
+{
+  return __builtin_altivec_vcfux((vector int)a, b);
+}
+
+/* vec_cts */
+
+static vector int __attribute__((__always_inline__))
+vec_cts(vector float a, int b)
+{
+  return __builtin_altivec_vctsxs(a, b);
+}
+
+/* vec_vctsxs */
+
+static vector int __attribute__((__always_inline__))
+vec_vctsxs(vector float a, int b)
+{
+  return __builtin_altivec_vctsxs(a, b);
+}
+
+/* vec_ctu */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_ctu(vector float a, int b)
+{
+  return __builtin_altivec_vctuxs(a, b);
+}
+
+/* vec_vctuxs */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vctuxs(vector float a, int b)
+{
+  return __builtin_altivec_vctuxs(a, b);
+}
+
+/* vec_dss */
+
+static void __attribute__((__always_inline__))
+vec_dss(int a)
+{
+  __builtin_altivec_dss(a);
+}
+
+/* vec_dssall */
+
+static void __attribute__((__always_inline__))
+vec_dssall(void)
+{
+  __builtin_altivec_dssall();
+}
+
+/* vec_dst */
+
+static void __attribute__((__always_inline__))
+vec_dst(void *a, int b, int c)
+{
+  __builtin_altivec_dst(a, b, c);
+}
+
+/* vec_dstst */
+
+static void __attribute__((__always_inline__))
+vec_dstst(void *a, int b, int c)
+{
+  __builtin_altivec_dstst(a, b, c);
+}
+
+/* vec_dststt */
+
+static void __attribute__((__always_inline__))
+vec_dststt(void *a, int b, int c)
+{
+  __builtin_altivec_dststt(a, b, c);
+}
+
+/* vec_dstt */
+
+static void __attribute__((__always_inline__))
+vec_dstt(void *a, int b, int c)
+{
+  __builtin_altivec_dstt(a, b, c);
+}
+
+/* vec_expte */
+
+static vector float __attribute__((__always_inline__))
+vec_expte(vector float a)
+{
+  return __builtin_altivec_vexptefp(a);
+}
+
+/* vec_vexptefp */
+
+static vector float __attribute__((__always_inline__))
+vec_vexptefp(vector float a)
+{
+  return __builtin_altivec_vexptefp(a);
+}
+
+/* vec_floor */
+
+static vector float __attribute__((__always_inline__))
+vec_floor(vector float a)
+{
+  return __builtin_altivec_vrfim(a);
+}
+
+/* vec_vrfim */
+
+static vector float __attribute__((__always_inline__))
+vec_vrfim(vector float a)
+{
+  return __builtin_altivec_vrfim(a);
+}
+
+/* vec_ld */
+
+static vector signed char __ATTRS_o_ai
+vec_ld(int a, vector signed char *b)
+{
+  return (vector signed char)__builtin_altivec_lvx(a, b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_ld(int a, signed char *b)
+{
+  return (vector signed char)__builtin_altivec_lvx(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_ld(int a, vector unsigned char *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvx(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_ld(int a, unsigned char *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvx(a, b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_ld(int a, vector bool char *b)
+{
+  return (vector bool char)__builtin_altivec_lvx(a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_ld(int a, vector short *b)
+{
+  return (vector short)__builtin_altivec_lvx(a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_ld(int a, short *b)
+{
+  return (vector short)__builtin_altivec_lvx(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_ld(int a, vector unsigned short *b)
+{
+  return (vector unsigned short)__builtin_altivec_lvx(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_ld(int a, unsigned short *b)
+{
+  return (vector unsigned short)__builtin_altivec_lvx(a, b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_ld(int a, vector bool short *b)
+{
+  return (vector bool short)__builtin_altivec_lvx(a, b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_ld(int a, vector pixel *b)
+{
+  return (vector pixel)__builtin_altivec_lvx(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_ld(int a, vector int *b)
+{
+  return (vector int)__builtin_altivec_lvx(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_ld(int a, int *b)
+{
+  return (vector int)__builtin_altivec_lvx(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_ld(int a, vector unsigned int *b)
+{
+  return (vector unsigned int)__builtin_altivec_lvx(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_ld(int a, unsigned int *b)
+{
+  return (vector unsigned int)__builtin_altivec_lvx(a, b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_ld(int a, vector bool int *b)
+{
+  return (vector bool int)__builtin_altivec_lvx(a, b);
+}
+
+static vector float __ATTRS_o_ai
+vec_ld(int a, vector float *b)
+{
+  return (vector float)__builtin_altivec_lvx(a, b);
+}
+
+static vector float __ATTRS_o_ai
+vec_ld(int a, float *b)
+{
+  return (vector float)__builtin_altivec_lvx(a, b);
+}
+
+/* vec_lvx */
+
+static vector signed char __ATTRS_o_ai
+vec_lvx(int a, vector signed char *b)
+{
+  return (vector signed char)__builtin_altivec_lvx(a, b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_lvx(int a, signed char *b)
+{
+  return (vector signed char)__builtin_altivec_lvx(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvx(int a, vector unsigned char *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvx(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvx(int a, unsigned char *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvx(a, b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_lvx(int a, vector bool char *b)
+{
+  return (vector bool char)__builtin_altivec_lvx(a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_lvx(int a, vector short *b)
+{
+  return (vector short)__builtin_altivec_lvx(a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_lvx(int a, short *b)
+{
+  return (vector short)__builtin_altivec_lvx(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvx(int a, vector unsigned short *b)
+{
+  return (vector unsigned short)__builtin_altivec_lvx(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvx(int a, unsigned short *b)
+{
+  return (vector unsigned short)__builtin_altivec_lvx(a, b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_lvx(int a, vector bool short *b)
+{
+  return (vector bool short)__builtin_altivec_lvx(a, b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_lvx(int a, vector pixel *b)
+{
+  return (vector pixel)__builtin_altivec_lvx(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_lvx(int a, vector int *b)
+{
+  return (vector int)__builtin_altivec_lvx(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_lvx(int a, int *b)
+{
+  return (vector int)__builtin_altivec_lvx(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvx(int a, vector unsigned int *b)
+{
+  return (vector unsigned int)__builtin_altivec_lvx(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvx(int a, unsigned int *b)
+{
+  return (vector unsigned int)__builtin_altivec_lvx(a, b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_lvx(int a, vector bool int *b)
+{
+  return (vector bool int)__builtin_altivec_lvx(a, b);
+}
+
+static vector float __ATTRS_o_ai
+vec_lvx(int a, vector float *b)
+{
+  return (vector float)__builtin_altivec_lvx(a, b);
+}
+
+static vector float __ATTRS_o_ai
+vec_lvx(int a, float *b)
+{
+  return (vector float)__builtin_altivec_lvx(a, b);
+}
+
+/* vec_lde */
+
+static vector signed char __ATTRS_o_ai
+vec_lde(int a, vector signed char *b)
+{
+  return (vector signed char)__builtin_altivec_lvebx(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lde(int a, vector unsigned char *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvebx(a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_lde(int a, vector short *b)
+{
+  return (vector short)__builtin_altivec_lvehx(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lde(int a, vector unsigned short *b)
+{
+  return (vector unsigned short)__builtin_altivec_lvehx(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_lde(int a, vector int *b)
+{
+  return (vector int)__builtin_altivec_lvewx(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lde(int a, vector unsigned int *b)
+{
+  return (vector unsigned int)__builtin_altivec_lvewx(a, b);
+}
+
+static vector float __ATTRS_o_ai
+vec_lde(int a, vector float *b)
+{
+  return (vector float)__builtin_altivec_lvewx(a, b);
+}
+
+/* vec_lvebx */
+
+static vector signed char __ATTRS_o_ai
+vec_lvebx(int a, vector signed char *b)
+{
+  return (vector signed char)__builtin_altivec_lvebx(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvebx(int a, vector unsigned char *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvebx(a, b);
+}
+
+/* vec_lvehx */
+
+static vector short __ATTRS_o_ai
+vec_lvehx(int a, vector short *b)
+{
+  return (vector short)__builtin_altivec_lvehx(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvehx(int a, vector unsigned short *b)
+{
+  return (vector unsigned short)__builtin_altivec_lvehx(a, b);
+}
+
+/* vec_lvewx */
+
+static vector int __ATTRS_o_ai
+vec_lvewx(int a, vector int *b)
+{
+  return (vector int)__builtin_altivec_lvewx(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvewx(int a, vector unsigned int *b)
+{
+  return (vector unsigned int)__builtin_altivec_lvewx(a, b);
+}
+
+static vector float __ATTRS_o_ai
+vec_lvewx(int a, vector float *b)
+{
+  return (vector float)__builtin_altivec_lvewx(a, b);
+}
+
+/* vec_ldl */
+
+static vector signed char __ATTRS_o_ai
+vec_ldl(int a, vector signed char *b)
+{
+  return (vector signed char)__builtin_altivec_lvxl(a, b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_ldl(int a, signed char *b)
+{
+  return (vector signed char)__builtin_altivec_lvxl(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_ldl(int a, vector unsigned char *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvxl(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_ldl(int a, unsigned char *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvxl(a, b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_ldl(int a, vector bool char *b)
+{
+  return (vector bool char)__builtin_altivec_lvxl(a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_ldl(int a, vector short *b)
+{
+  return (vector short)__builtin_altivec_lvxl(a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_ldl(int a, short *b)
+{
+  return (vector short)__builtin_altivec_lvxl(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_ldl(int a, vector unsigned short *b)
+{
+  return (vector unsigned short)__builtin_altivec_lvxl(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_ldl(int a, unsigned short *b)
+{
+  return (vector unsigned short)__builtin_altivec_lvxl(a, b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_ldl(int a, vector bool short *b)
+{
+  return (vector bool short)__builtin_altivec_lvxl(a, b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_ldl(int a, vector pixel *b)
+{
+  return (vector pixel short)__builtin_altivec_lvxl(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_ldl(int a, vector int *b)
+{
+  return (vector int)__builtin_altivec_lvxl(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_ldl(int a, int *b)
+{
+  return (vector int)__builtin_altivec_lvxl(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_ldl(int a, vector unsigned int *b)
+{
+  return (vector unsigned int)__builtin_altivec_lvxl(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_ldl(int a, unsigned int *b)
+{
+  return (vector unsigned int)__builtin_altivec_lvxl(a, b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_ldl(int a, vector bool int *b)
+{
+  return (vector bool int)__builtin_altivec_lvxl(a, b);
+}
+
+static vector float __ATTRS_o_ai
+vec_ldl(int a, vector float *b)
+{
+  return (vector float)__builtin_altivec_lvxl(a, b);
+}
+
+static vector float __ATTRS_o_ai
+vec_ldl(int a, float *b)
+{
+  return (vector float)__builtin_altivec_lvxl(a, b);
+}
+
+/* vec_lvxl */
+
+static vector signed char __ATTRS_o_ai
+vec_lvxl(int a, vector signed char *b)
+{
+  return (vector signed char)__builtin_altivec_lvxl(a, b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_lvxl(int a, signed char *b)
+{
+  return (vector signed char)__builtin_altivec_lvxl(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvxl(int a, vector unsigned char *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvxl(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvxl(int a, unsigned char *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvxl(a, b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_lvxl(int a, vector bool char *b)
+{
+  return (vector bool char)__builtin_altivec_lvxl(a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_lvxl(int a, vector short *b)
+{
+  return (vector short)__builtin_altivec_lvxl(a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_lvxl(int a, short *b)
+{
+  return (vector short)__builtin_altivec_lvxl(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvxl(int a, vector unsigned short *b)
+{
+  return (vector unsigned short)__builtin_altivec_lvxl(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvxl(int a, unsigned short *b)
+{
+  return (vector unsigned short)__builtin_altivec_lvxl(a, b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_lvxl(int a, vector bool short *b)
+{
+  return (vector bool short)__builtin_altivec_lvxl(a, b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_lvxl(int a, vector pixel *b)
+{
+  return (vector pixel)__builtin_altivec_lvxl(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_lvxl(int a, vector int *b)
+{
+  return (vector int)__builtin_altivec_lvxl(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_lvxl(int a, int *b)
+{
+  return (vector int)__builtin_altivec_lvxl(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvxl(int a, vector unsigned int *b)
+{
+  return (vector unsigned int)__builtin_altivec_lvxl(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvxl(int a, unsigned int *b)
+{
+  return (vector unsigned int)__builtin_altivec_lvxl(a, b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_lvxl(int a, vector bool int *b)
+{
+  return (vector bool int)__builtin_altivec_lvxl(a, b);
+}
+
+static vector float __ATTRS_o_ai
+vec_lvxl(int a, vector float *b)
+{
+  return (vector float)__builtin_altivec_lvxl(a, b);
+}
+
+static vector float __ATTRS_o_ai
+vec_lvxl(int a, float *b)
+{
+  return (vector float)__builtin_altivec_lvxl(a, b);
+}
+
+/* vec_loge */
+
+static vector float __attribute__((__always_inline__))
+vec_loge(vector float a)
+{
+  return __builtin_altivec_vlogefp(a);
+}
+
+/* vec_vlogefp */
+
+static vector float __attribute__((__always_inline__))
+vec_vlogefp(vector float a)
+{
+  return __builtin_altivec_vlogefp(a);
+}
+
+/* vec_lvsl */
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsl(int a, signed char *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsl(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsl(int a, unsigned char *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsl(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsl(int a, short *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsl(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsl(int a, unsigned short *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsl(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsl(int a, int *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsl(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsl(int a, unsigned int *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsl(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsl(int a, float *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsl(a, b);
+}
+
+/* vec_lvsr */
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsr(int a, signed char *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsr(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsr(int a, unsigned char *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsr(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsr(int a, short *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsr(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsr(int a, unsigned short *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsr(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsr(int a, int *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsr(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsr(int a, unsigned int *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsr(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsr(int a, float *b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsr(a, b);
+}
+
+/* vec_madd */
+
+static vector float __attribute__((__always_inline__))
+vec_madd(vector float a, vector float b, vector float c)
+{
+  return __builtin_altivec_vmaddfp(a, b, c);
+}
+
+/* vec_vmaddfp */
+
+static vector float __attribute__((__always_inline__))
+vec_vmaddfp(vector float a, vector float b, vector float c)
+{
+  return __builtin_altivec_vmaddfp(a, b, c);
+}
+
+/* vec_madds */
+
+static vector signed short __attribute__((__always_inline__))
+vec_madds(vector signed short a, vector signed short b, vector signed short c)
+{
+  return __builtin_altivec_vmhaddshs(a, b, c);
+}
+
+/* vec_vmhaddshs */
+static vector signed short __attribute__((__always_inline__))
+vec_vmhaddshs(vector signed short a, vector signed short b, vector signed short c)
+{
+  return __builtin_altivec_vmhaddshs(a, b, c);
 }
 
 /* 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)
+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)
+static vector signed char __ATTRS_o_ai
+vec_max(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vmaxsb((vector signed char)a, b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_max(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vmaxsb(a, (vector signed char)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
+static vector unsigned char __ATTRS_o_ai
+vec_max(vector bool char a, vector unsigned char b)
+{
+  return __builtin_altivec_vmaxub((vector unsigned char)a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_max(vector unsigned char a, vector bool char b)
+{
+  return __builtin_altivec_vmaxub(a, (vector unsigned char)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
+static vector short __ATTRS_o_ai
+vec_max(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vmaxsh((vector short)a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_max(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vmaxsh(a, (vector short)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
+static vector unsigned short __ATTRS_o_ai
+vec_max(vector bool short a, vector unsigned short b)
+{
+  return __builtin_altivec_vmaxuh((vector unsigned short)a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_max(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vmaxuh(a, (vector unsigned short)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
+static vector int __ATTRS_o_ai
+vec_max(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vmaxsw((vector int)a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_max(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vmaxsw(a, (vector int)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
+static vector unsigned int __ATTRS_o_ai
+vec_max(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vmaxuw((vector unsigned int)a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_max(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vmaxuw(a, (vector unsigned int)b);
+}
+
+static vector float __ATTRS_o_ai
 vec_max(vector float a, vector float b)
 {
   return __builtin_altivec_vmaxfp(a, b);
 }
 
+/* vec_vmaxsb */
+
+static vector signed char __ATTRS_o_ai
+vec_vmaxsb(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vmaxsb(a, b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vmaxsb(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vmaxsb((vector signed char)a, b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vmaxsb(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vmaxsb(a, (vector signed char)b);
+}
+
+/* vec_vmaxub */
+
+static vector unsigned char __ATTRS_o_ai
+vec_vmaxub(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vmaxub(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vmaxub(vector bool char a, vector unsigned char b)
+{
+  return __builtin_altivec_vmaxub((vector unsigned char)a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vmaxub(vector unsigned char a, vector bool char b)
+{
+  return __builtin_altivec_vmaxub(a, (vector unsigned char)b);
+}
+
+/* vec_vmaxsh */
+
+static vector short __ATTRS_o_ai
+vec_vmaxsh(vector short a, vector short b)
+{
+  return __builtin_altivec_vmaxsh(a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vmaxsh(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vmaxsh((vector short)a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vmaxsh(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vmaxsh(a, (vector short)b);
+}
+
+/* vec_vmaxuh */
+
+static vector unsigned short __ATTRS_o_ai
+vec_vmaxuh(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vmaxuh(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vmaxuh(vector bool short a, vector unsigned short b)
+{
+  return __builtin_altivec_vmaxuh((vector unsigned short)a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vmaxuh(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vmaxuh(a, (vector unsigned short)b);
+}
+
+/* vec_vmaxsw */
+
+static vector int __ATTRS_o_ai
+vec_vmaxsw(vector int a, vector int b)
+{
+  return __builtin_altivec_vmaxsw(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vmaxsw(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vmaxsw((vector int)a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vmaxsw(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vmaxsw(a, (vector int)b);
+}
+
+/* vec_vmaxuw */
+
+static vector unsigned int __ATTRS_o_ai
+vec_vmaxuw(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vmaxuw(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vmaxuw(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vmaxuw((vector unsigned int)a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vmaxuw(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vmaxuw(a, (vector unsigned int)b);
+}
+
+/* vec_vmaxfp */
+
+static vector float __attribute__((__always_inline__))
+vec_vmaxfp(vector float a, vector float b)
+{
+  return __builtin_altivec_vmaxfp(a, b);
+}
+
+/* vec_mergeh */
+
+static vector signed char __ATTRS_o_ai
+vec_mergeh(vector signed char a, vector signed char b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 
+     0x04, 0x14, 0x05, 0x15, 0x06, 0x16, 0x07, 0x17));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_mergeh(vector unsigned char a, vector unsigned char b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 
+     0x04, 0x14, 0x05, 0x15, 0x06, 0x16, 0x07, 0x17));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_mergeh(vector bool char a, vector bool char b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 
+     0x04, 0x14, 0x05, 0x15, 0x06, 0x16, 0x07, 0x17));
+}
+
+static vector short __ATTRS_o_ai
+vec_mergeh(vector short a, vector short b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_mergeh(vector unsigned short a, vector unsigned short b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_mergeh(vector bool short a, vector bool short b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_mergeh(vector pixel a, vector pixel b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+static vector int __ATTRS_o_ai
+vec_mergeh(vector int a, vector int b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_mergeh(vector unsigned int a, vector unsigned int b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_mergeh(vector bool int a, vector bool int b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+static vector float __ATTRS_o_ai
+vec_mergeh(vector float a, vector float b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+/* vec_vmrghb */
+
+#define __builtin_altivec_vmrghb vec_vmrghb
+
+static vector signed char __ATTRS_o_ai
+vec_vmrghb(vector signed char a, vector signed char b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 
+     0x04, 0x14, 0x05, 0x15, 0x06, 0x16, 0x07, 0x17));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vmrghb(vector unsigned char a, vector unsigned char b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 
+     0x04, 0x14, 0x05, 0x15, 0x06, 0x16, 0x07, 0x17));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vmrghb(vector bool char a, vector bool char b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 
+     0x04, 0x14, 0x05, 0x15, 0x06, 0x16, 0x07, 0x17));
+}
+
+/* vec_vmrghh */
+
+#define __builtin_altivec_vmrghh vec_vmrghh
+
+static vector short __ATTRS_o_ai
+vec_vmrghh(vector short a, vector short b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vmrghh(vector unsigned short a, vector unsigned short b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vmrghh(vector bool short a, vector bool short b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vmrghh(vector pixel a, vector pixel b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+/* vec_vmrghw */
+
+#define __builtin_altivec_vmrghw vec_vmrghw
+
+static vector int __ATTRS_o_ai
+vec_vmrghw(vector int a, vector int b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vmrghw(vector unsigned int a, vector unsigned int b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vmrghw(vector bool int a, vector bool int b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+static vector float __ATTRS_o_ai
+vec_vmrghw(vector float a, vector float b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+/* vec_mergel */
+
+static vector signed char __ATTRS_o_ai
+vec_mergel(vector signed char a, vector signed char b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, 0x0B, 0x1B, 
+     0x0C, 0x1C, 0x0D, 0x1D, 0x0E, 0x1E, 0x0F, 0x1F));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_mergel(vector unsigned char a, vector unsigned char b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, 0x0B, 0x1B, 
+     0x0C, 0x1C, 0x0D, 0x1D, 0x0E, 0x1E, 0x0F, 0x1F));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_mergel(vector bool char a, vector bool char b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, 0x0B, 0x1B, 
+     0x0C, 0x1C, 0x0D, 0x1D, 0x0E, 0x1E, 0x0F, 0x1F));
+}
+
+static vector short __ATTRS_o_ai
+vec_mergel(vector short a, vector short b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_mergel(vector unsigned short a, vector unsigned short b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_mergel(vector bool short a, vector bool short b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_mergel(vector pixel a, vector pixel b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+static vector int __ATTRS_o_ai
+vec_mergel(vector int a, vector int b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_mergel(vector unsigned int a, vector unsigned int b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_mergel(vector bool int a, vector bool int b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+static vector float __ATTRS_o_ai
+vec_mergel(vector float a, vector float b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+/* vec_vmrglb */
+
+#define __builtin_altivec_vmrglb vec_vmrglb
+
+static vector signed char __ATTRS_o_ai
+vec_vmrglb(vector signed char a, vector signed char b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, 0x0B, 0x1B, 
+     0x0C, 0x1C, 0x0D, 0x1D, 0x0E, 0x1E, 0x0F, 0x1F));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vmrglb(vector unsigned char a, vector unsigned char b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, 0x0B, 0x1B, 
+     0x0C, 0x1C, 0x0D, 0x1D, 0x0E, 0x1E, 0x0F, 0x1F));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vmrglb(vector bool char a, vector bool char b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, 0x0B, 0x1B, 
+     0x0C, 0x1C, 0x0D, 0x1D, 0x0E, 0x1E, 0x0F, 0x1F));
+}
+
+/* vec_vmrglh */
+
+#define __builtin_altivec_vmrglh vec_vmrglh
+
+static vector short __ATTRS_o_ai
+vec_vmrglh(vector short a, vector short b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vmrglh(vector unsigned short a, vector unsigned short b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vmrglh(vector bool short a, vector bool short b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vmrglh(vector pixel a, vector pixel b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+/* vec_vmrglw */
+
+#define __builtin_altivec_vmrglw vec_vmrglw
+
+static vector int __ATTRS_o_ai
+vec_vmrglw(vector int a, vector int b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vmrglw(vector unsigned int a, vector unsigned int b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vmrglw(vector bool int a, vector bool int b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+static vector float __ATTRS_o_ai
+vec_vmrglw(vector float a, vector float b)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
 /* vec_mfvscr */
 
-#define __builtin_vec_mfvscr __builtin_altivec_mfvscr
-#define vec_mfvscr           __builtin_altivec_mfvscr
+static vector unsigned short __attribute__((__always_inline__))
+vec_mfvscr(void)
+{
+  return __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)
+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)
+static vector signed char __ATTRS_o_ai
+vec_min(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vminsb((vector signed char)a, b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_min(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vminsb(a, (vector signed char)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
+static vector unsigned char __ATTRS_o_ai
+vec_min(vector bool char a, vector unsigned char b)
+{
+  return __builtin_altivec_vminub((vector unsigned char)a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_min(vector unsigned char a, vector bool char b)
+{
+  return __builtin_altivec_vminub(a, (vector unsigned char)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
+static vector short __ATTRS_o_ai
+vec_min(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vminsh((vector short)a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_min(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vminsh(a, (vector short)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
+static vector unsigned short __ATTRS_o_ai
+vec_min(vector bool short a, vector unsigned short b)
+{
+  return __builtin_altivec_vminuh((vector unsigned short)a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_min(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vminuh(a, (vector unsigned short)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
+static vector int __ATTRS_o_ai
+vec_min(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vminsw((vector int)a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_min(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vminsw(a, (vector int)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
+static vector unsigned int __ATTRS_o_ai
+vec_min(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vminuw((vector unsigned int)a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_min(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vminuw(a, (vector unsigned int)b);
+}
+
+static vector float __ATTRS_o_ai
 vec_min(vector float a, vector float b)
 {
   return __builtin_altivec_vminfp(a, b);
 }
 
+/* vec_vminsb */
+
+static vector signed char __ATTRS_o_ai
+vec_vminsb(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vminsb(a, b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vminsb(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vminsb((vector signed char)a, b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vminsb(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vminsb(a, (vector signed char)b);
+}
+
+/* vec_vminub */
+
+static vector unsigned char __ATTRS_o_ai
+vec_vminub(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vminub(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vminub(vector bool char a, vector unsigned char b)
+{
+  return __builtin_altivec_vminub((vector unsigned char)a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vminub(vector unsigned char a, vector bool char b)
+{
+  return __builtin_altivec_vminub(a, (vector unsigned char)b);
+}
+
+/* vec_vminsh */
+
+static vector short __ATTRS_o_ai
+vec_vminsh(vector short a, vector short b)
+{
+  return __builtin_altivec_vminsh(a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vminsh(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vminsh((vector short)a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vminsh(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vminsh(a, (vector short)b);
+}
+
+/* vec_vminuh */
+
+static vector unsigned short __ATTRS_o_ai
+vec_vminuh(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vminuh(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vminuh(vector bool short a, vector unsigned short b)
+{
+  return __builtin_altivec_vminuh((vector unsigned short)a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vminuh(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vminuh(a, (vector unsigned short)b);
+}
+
+/* vec_vminsw */
+
+static vector int __ATTRS_o_ai
+vec_vminsw(vector int a, vector int b)
+{
+  return __builtin_altivec_vminsw(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vminsw(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vminsw((vector int)a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vminsw(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vminsw(a, (vector int)b);
+}
+
+/* vec_vminuw */
+
+static vector unsigned int __ATTRS_o_ai
+vec_vminuw(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vminuw(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vminuw(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vminuw((vector unsigned int)a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vminuw(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vminuw(a, (vector unsigned int)b);
+}
+
+/* vec_vminfp */
+
+static vector float __attribute__((__always_inline__))
+vec_vminfp(vector float a, vector float b)
+{
+  return __builtin_altivec_vminfp(a, b);
+}
+
+/* vec_mladd */
+
+#define __builtin_altivec_vmladduhm vec_mladd
+
+static vector short __ATTRS_o_ai
+vec_mladd(vector short a, vector short b, vector short c)
+{
+  return a * b + c;
+}
+
+static vector short __ATTRS_o_ai
+vec_mladd(vector short a, vector unsigned short b, vector unsigned short c)
+{
+  return a * (vector short)b + (vector short)c;
+}
+
+static vector short __ATTRS_o_ai
+vec_mladd(vector unsigned short a, vector short b, vector short c)
+{
+  return (vector short)a * b + c;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_mladd(vector unsigned short a, vector unsigned short b, vector unsigned short c)
+{
+  return a * b + c;
+}
+
+/* vec_vmladduhm */
+
+static vector short __ATTRS_o_ai
+vec_vmladduhm(vector short a, vector short b, vector short c)
+{
+  return a * b + c;
+}
+
+static vector short __ATTRS_o_ai
+vec_vmladduhm(vector short a, vector unsigned short b, vector unsigned short c)
+{
+  return a * (vector short)b + (vector short)c;
+}
+
+static vector short __ATTRS_o_ai
+vec_vmladduhm(vector unsigned short a, vector short b, vector short c)
+{
+  return (vector short)a * b + c;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vmladduhm(vector unsigned short a, vector unsigned short b, vector unsigned short c)
+{
+  return a * b + c;
+}
+
+/* vec_mradds */
+
+static vector short __attribute__((__always_inline__))
+vec_mradds(vector short a, vector short b, vector short c)
+{
+  return __builtin_altivec_vmhraddshs(a, b, c);
+}
+
+/* vec_vmhraddshs */
+
+static vector short __attribute__((__always_inline__))
+vec_vmhraddshs(vector short a, vector short b, vector short c)
+{
+  return __builtin_altivec_vmhraddshs(a, b, c);
+}
+
+/* vec_msum */
+
+static vector int __ATTRS_o_ai
+vec_msum(vector signed char a, vector unsigned char b, vector int c)
+{
+  return __builtin_altivec_vmsummbm(a, b, c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_msum(vector unsigned char a, vector unsigned char b, vector unsigned int c)
+{
+  return __builtin_altivec_vmsumubm(a, b, c);
+}
+
+static vector int __ATTRS_o_ai
+vec_msum(vector short a, vector short b, vector int c)
+{
+  return __builtin_altivec_vmsumshm(a, b, c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_msum(vector unsigned short a, vector unsigned short b, vector unsigned int c)
+{
+  return __builtin_altivec_vmsumuhm(a, b, c);
+}
+
+/* vec_vmsummbm */
+
+static vector int __attribute__((__always_inline__))
+vec_vmsummbm(vector signed char a, vector unsigned char b, vector int c)
+{
+  return __builtin_altivec_vmsummbm(a, b, c);
+}
+
+/* vec_vmsumubm */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vmsumubm(vector unsigned char a, vector unsigned char b, vector unsigned int c)
+{
+  return __builtin_altivec_vmsumubm(a, b, c);
+}
+
+/* vec_vmsumshm */
+
+static vector int __attribute__((__always_inline__))
+vec_vmsumshm(vector short a, vector short b, vector int c)
+{
+  return __builtin_altivec_vmsumshm(a, b, c);
+}
+
+/* vec_vmsumuhm */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vmsumuhm(vector unsigned short a, vector unsigned short b, vector unsigned int c)
+{
+  return __builtin_altivec_vmsumuhm(a, b, c);
+}
+
+/* vec_msums */
+
+static vector int __ATTRS_o_ai
+vec_msums(vector short a, vector short b, vector int c)
+{
+  return __builtin_altivec_vmsumshs(a, b, c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_msums(vector unsigned short a, vector unsigned short b, vector unsigned int c)
+{
+  return __builtin_altivec_vmsumuhs(a, b, c);
+}
+
+/* vec_vmsumshs */
+
+static vector int __attribute__((__always_inline__))
+vec_vmsumshs(vector short a, vector short b, vector int c)
+{
+  return __builtin_altivec_vmsumshs(a, b, c);
+}
+
+/* vec_vmsumuhs */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vmsumuhs(vector unsigned short a, vector unsigned short b, vector unsigned int c)
+{
+  return __builtin_altivec_vmsumuhs(a, b, c);
+}
+
 /* vec_mtvscr */
 
-#define __builtin_vec_mtvscr __builtin_altivec_mtvscr
-#define vec_mtvscr           __builtin_altivec_mtvscr
+static void __ATTRS_o_ai
+vec_mtvscr(vector signed char a)
+{
+  __builtin_altivec_mtvscr((vector int)a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector unsigned char a)
+{
+  __builtin_altivec_mtvscr((vector int)a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector bool char a)
+{
+  __builtin_altivec_mtvscr((vector int)a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector short a)
+{
+  __builtin_altivec_mtvscr((vector int)a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector unsigned short a)
+{
+  __builtin_altivec_mtvscr((vector int)a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector bool short a)
+{
+  __builtin_altivec_mtvscr((vector int)a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector pixel a)
+{
+  __builtin_altivec_mtvscr((vector int)a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector int a)
+{
+  __builtin_altivec_mtvscr((vector int)a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector unsigned int a)
+{
+  __builtin_altivec_mtvscr((vector int)a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector bool int a)
+{
+  __builtin_altivec_mtvscr((vector int)a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector float a)
+{
+  __builtin_altivec_mtvscr((vector int)a);
+}
+
+/* vec_mule */
+
+static vector short __ATTRS_o_ai
+vec_mule(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vmulesb(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_mule(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vmuleub(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_mule(vector short a, vector short b)
+{
+  return __builtin_altivec_vmulesh(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_mule(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vmuleuh(a, b);
+}
+
+/* vec_vmulesb */
+
+static vector short __attribute__((__always_inline__))
+vec_vmulesb(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vmulesb(a, b);
+}
+
+/* vec_vmuleub */
+
+static vector unsigned short __attribute__((__always_inline__))
+vec_vmuleub(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vmuleub(a, b);
+}
+
+/* vec_vmulesh */
+
+static vector int __attribute__((__always_inline__))
+vec_vmulesh(vector short a, vector short b)
+{
+  return __builtin_altivec_vmulesh(a, b);
+}
+
+/* vec_vmuleuh */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vmuleuh(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vmuleuh(a, b);
+}
+
+/* vec_mulo */
+
+static vector short __ATTRS_o_ai
+vec_mulo(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vmulosb(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_mulo(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vmuloub(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_mulo(vector short a, vector short b)
+{
+  return __builtin_altivec_vmulosh(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_mulo(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vmulouh(a, b);
+}
+
+/* vec_vmulosb */
+
+static vector short __attribute__((__always_inline__))
+vec_vmulosb(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vmulosb(a, b);
+}
+
+/* vec_vmuloub */
+
+static vector unsigned short __attribute__((__always_inline__))
+vec_vmuloub(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vmuloub(a, b);
+}
+
+/* vec_vmulosh */
+
+static vector int __attribute__((__always_inline__))
+vec_vmulosh(vector short a, vector short b)
+{
+  return __builtin_altivec_vmulosh(a, b);
+}
+
+/* vec_vmulouh */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vmulouh(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vmulouh(a, b);
+}
+
+/* vec_nmsub */
+
+static vector float __attribute__((__always_inline__))
+vec_nmsub(vector float a, vector float b, vector float c)
+{
+  return __builtin_altivec_vnmsubfp(a, b, c);
+}
+
+/* vec_vnmsubfp */
+
+static vector float __attribute__((__always_inline__))
+vec_vnmsubfp(vector float a, vector float b, vector float c)
+{
+  return __builtin_altivec_vnmsubfp(a, b, c);
+}
+
+/* vec_nor */
+
+#define __builtin_altivec_vnor vec_nor
+
+static vector signed char __ATTRS_o_ai
+vec_nor(vector signed char a, vector signed char b)
+{
+  return ~(a | b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_nor(vector unsigned char a, vector unsigned char b)
+{
+  return ~(a | b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_nor(vector bool char a, vector bool char b)
+{
+  return ~(a | b);
+}
+
+static vector short __ATTRS_o_ai
+vec_nor(vector short a, vector short b)
+{
+  return ~(a | b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_nor(vector unsigned short a, vector unsigned short b)
+{
+  return ~(a | b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_nor(vector bool short a, vector bool short b)
+{
+  return ~(a | b);
+}
+
+static vector int __ATTRS_o_ai
+vec_nor(vector int a, vector int b)
+{
+  return ~(a | b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_nor(vector unsigned int a, vector unsigned int b)
+{
+  return ~(a | b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_nor(vector bool int a, vector bool int b)
+{
+  return ~(a | b);
+}
+
+static vector float __ATTRS_o_ai
+vec_nor(vector float a, vector float b)
+{
+  vector unsigned int res = ~((vector unsigned int)a | (vector unsigned int)b);
+  return (vector float)res;
+}
+
+/* vec_vnor */
+
+static vector signed char __ATTRS_o_ai
+vec_vnor(vector signed char a, vector signed char b)
+{
+  return ~(a | b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vnor(vector unsigned char a, vector unsigned char b)
+{
+  return ~(a | b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vnor(vector bool char a, vector bool char b)
+{
+  return ~(a | b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vnor(vector short a, vector short b)
+{
+  return ~(a | b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vnor(vector unsigned short a, vector unsigned short b)
+{
+  return ~(a | b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vnor(vector bool short a, vector bool short b)
+{
+  return ~(a | b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vnor(vector int a, vector int b)
+{
+  return ~(a | b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vnor(vector unsigned int a, vector unsigned int b)
+{
+  return ~(a | b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vnor(vector bool int a, vector bool int b)
+{
+  return ~(a | b);
+}
+
+static vector float __ATTRS_o_ai
+vec_vnor(vector float a, vector float b)
+{
+  vector unsigned int res = ~((vector unsigned int)a | (vector unsigned int)b);
+  return (vector float)res;
+}
+
+/* vec_or */
+
+#define __builtin_altivec_vor vec_or
+
+static vector signed char __ATTRS_o_ai
+vec_or(vector signed char a, vector signed char b)
+{
+  return a | b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_or(vector bool char a, vector signed char b)
+{
+  return (vector signed char)a | b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_or(vector signed char a, vector bool char b)
+{
+  return a | (vector signed char)b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_or(vector unsigned char a, vector unsigned char b)
+{
+  return a | b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_or(vector bool char a, vector unsigned char b)
+{
+  return (vector unsigned char)a | b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_or(vector unsigned char a, vector bool char b)
+{
+  return a | (vector unsigned char)b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_or(vector bool char a, vector bool char b)
+{
+  return a | b;
+}
+
+static vector short __ATTRS_o_ai
+vec_or(vector short a, vector short b)
+{
+  return a | b;
+}
+
+static vector short __ATTRS_o_ai
+vec_or(vector bool short a, vector short b)
+{
+  return (vector short)a | b;
+}
+
+static vector short __ATTRS_o_ai
+vec_or(vector short a, vector bool short b)
+{
+  return a | (vector short)b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_or(vector unsigned short a, vector unsigned short b)
+{
+  return a | b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_or(vector bool short a, vector unsigned short b)
+{
+  return (vector unsigned short)a | b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_or(vector unsigned short a, vector bool short b)
+{
+  return a | (vector unsigned short)b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_or(vector bool short a, vector bool short b)
+{
+  return a | b;
+}
+
+static vector int __ATTRS_o_ai
+vec_or(vector int a, vector int b)
+{
+  return a | b;
+}
+
+static vector int __ATTRS_o_ai
+vec_or(vector bool int a, vector int b)
+{
+  return (vector int)a | b;
+}
+
+static vector int __ATTRS_o_ai
+vec_or(vector int a, vector bool int b)
+{
+  return a | (vector int)b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_or(vector unsigned int a, vector unsigned int b)
+{
+  return a | b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_or(vector bool int a, vector unsigned int b)
+{
+  return (vector unsigned int)a | b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_or(vector unsigned int a, vector bool int b)
+{
+  return a | (vector unsigned int)b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_or(vector bool int a, vector bool int b)
+{
+  return a | b;
+}
+
+static vector float __ATTRS_o_ai
+vec_or(vector float a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a | (vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_or(vector bool int a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a | (vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_or(vector float a, vector bool int b)
+{
+  vector unsigned int res = (vector unsigned int)a | (vector unsigned int)b;
+  return (vector float)res;
+}
+
+/* vec_vor */
+
+static vector signed char __ATTRS_o_ai
+vec_vor(vector signed char a, vector signed char b)
+{
+  return a | b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vor(vector bool char a, vector signed char b)
+{
+  return (vector signed char)a | b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vor(vector signed char a, vector bool char b)
+{
+  return a | (vector signed char)b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vor(vector unsigned char a, vector unsigned char b)
+{
+  return a | b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vor(vector bool char a, vector unsigned char b)
+{
+  return (vector unsigned char)a | b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vor(vector unsigned char a, vector bool char b)
+{
+  return a | (vector unsigned char)b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vor(vector bool char a, vector bool char b)
+{
+  return a | b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vor(vector short a, vector short b)
+{
+  return a | b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vor(vector bool short a, vector short b)
+{
+  return (vector short)a | b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vor(vector short a, vector bool short b)
+{
+  return a | (vector short)b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vor(vector unsigned short a, vector unsigned short b)
+{
+  return a | b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vor(vector bool short a, vector unsigned short b)
+{
+  return (vector unsigned short)a | b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vor(vector unsigned short a, vector bool short b)
+{
+  return a | (vector unsigned short)b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vor(vector bool short a, vector bool short b)
+{
+  return a | b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vor(vector int a, vector int b)
+{
+  return a | b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vor(vector bool int a, vector int b)
+{
+  return (vector int)a | b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vor(vector int a, vector bool int b)
+{
+  return a | (vector int)b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vor(vector unsigned int a, vector unsigned int b)
+{
+  return a | b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vor(vector bool int a, vector unsigned int b)
+{
+  return (vector unsigned int)a | b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vor(vector unsigned int a, vector bool int b)
+{
+  return a | (vector unsigned int)b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vor(vector bool int a, vector bool int b)
+{
+  return a | b;
+}
+
+static vector float __ATTRS_o_ai
+vec_vor(vector float a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a | (vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vor(vector bool int a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a | (vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vor(vector float a, vector bool int b)
+{
+  vector unsigned int res = (vector unsigned int)a | (vector unsigned int)b;
+  return (vector float)res;
+}
+
+/* vec_pack */
+
+static vector signed char __ATTRS_o_ai
+vec_pack(vector signed short a, vector signed short b)
+{
+  return (vector signed char)vec_perm(a, b, (vector unsigned char)
+    (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
+     0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_pack(vector unsigned short a, vector unsigned short b)
+{
+  return (vector unsigned char)vec_perm(a, b, (vector unsigned char)
+    (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
+     0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_pack(vector bool short a, vector bool short b)
+{
+  return (vector bool char)vec_perm(a, b, (vector unsigned char)
+    (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
+     0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+}
+
+static vector short __ATTRS_o_ai
+vec_pack(vector int a, vector int b)
+{
+  return (vector short)vec_perm(a, b, (vector unsigned char)
+    (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
+     0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_pack(vector unsigned int a, vector unsigned int b)
+{
+  return (vector unsigned short)vec_perm(a, b, (vector unsigned char)
+    (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
+     0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_pack(vector bool int a, vector bool int b)
+{
+  return (vector bool short)vec_perm(a, b, (vector unsigned char)
+    (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
+     0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+}
+
+/* vec_vpkuhum */
+
+#define __builtin_altivec_vpkuhum vec_vpkuhum
+
+static vector signed char __ATTRS_o_ai
+vec_vpkuhum(vector signed short a, vector signed short b)
+{
+  return (vector signed char)vec_perm(a, b, (vector unsigned char)
+    (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
+     0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vpkuhum(vector unsigned short a, vector unsigned short b)
+{
+  return (vector unsigned char)vec_perm(a, b, (vector unsigned char)
+    (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
+     0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vpkuhum(vector bool short a, vector bool short b)
+{
+  return (vector bool char)vec_perm(a, b, (vector unsigned char)
+    (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
+     0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+}
+
+/* vec_vpkuwum */
+
+#define __builtin_altivec_vpkuwum vec_vpkuwum
+
+static vector short __ATTRS_o_ai
+vec_vpkuwum(vector int a, vector int b)
+{
+  return (vector short)vec_perm(a, b, (vector unsigned char)
+    (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
+     0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vpkuwum(vector unsigned int a, vector unsigned int b)
+{
+  return (vector unsigned short)vec_perm(a, b, (vector unsigned char)
+    (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
+     0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vpkuwum(vector bool int a, vector bool int b)
+{
+  return (vector bool short)vec_perm(a, b, (vector unsigned char)
+    (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
+     0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+}
+
+/* vec_packpx */
+
+static vector pixel __attribute__((__always_inline__))
+vec_packpx(vector unsigned int a, vector unsigned int b)
+{
+  return (vector pixel)__builtin_altivec_vpkpx(a, b);
+}
+
+/* vec_vpkpx */
+
+static vector pixel __attribute__((__always_inline__))
+vec_vpkpx(vector unsigned int a, vector unsigned int b)
+{
+  return (vector pixel)__builtin_altivec_vpkpx(a, b);
+}
+
+/* vec_packs */
+
+static vector signed char __ATTRS_o_ai
+vec_packs(vector short a, vector short b)
+{
+  return __builtin_altivec_vpkshss(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_packs(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vpkuhus(a, b);
+}
+
+static vector signed short __ATTRS_o_ai
+vec_packs(vector int a, vector int b)
+{
+  return __builtin_altivec_vpkswss(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_packs(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vpkuwus(a, b);
+}
+
+/* vec_vpkshss */
+
+static vector signed char __attribute__((__always_inline__))
+vec_vpkshss(vector short a, vector short b)
+{
+  return __builtin_altivec_vpkshss(a, b);
+}
+
+/* vec_vpkuhus */
+
+static vector unsigned char __attribute__((__always_inline__))
+vec_vpkuhus(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vpkuhus(a, b);
+}
+
+/* vec_vpkswss */
+
+static vector signed short __attribute__((__always_inline__))
+vec_vpkswss(vector int a, vector int b)
+{
+  return __builtin_altivec_vpkswss(a, b);
+}
+
+/* vec_vpkuwus */
+
+static vector unsigned short __attribute__((__always_inline__))
+vec_vpkuwus(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vpkuwus(a, b);
+}
+
+/* vec_packsu */
+
+static vector unsigned char __ATTRS_o_ai
+vec_packsu(vector short a, vector short b)
+{
+  return __builtin_altivec_vpkshus(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_packsu(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vpkuhus(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_packsu(vector int a, vector int b)
+{
+  return __builtin_altivec_vpkswus(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_packsu(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vpkuwus(a, b);
+}
+
+/* vec_vpkshus */
+
+static vector unsigned char __ATTRS_o_ai
+vec_vpkshus(vector short a, vector short b)
+{
+  return __builtin_altivec_vpkshus(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vpkshus(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vpkuhus(a, b);
+}
+
+/* vec_vpkswus */
+
+static vector unsigned short __ATTRS_o_ai
+vec_vpkswus(vector int a, vector int b)
+{
+  return __builtin_altivec_vpkswus(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vpkswus(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vpkuwus(a, b);
+}
+
+/* vec_perm */
+
+vector signed char __ATTRS_o_ai
+vec_perm(vector signed char a, vector signed char b, vector unsigned char c)
+{
+  return (vector signed char)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector unsigned char __ATTRS_o_ai
+vec_perm(vector unsigned char a, vector unsigned char b, vector unsigned char c)
+{
+  return (vector unsigned char)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector bool char __ATTRS_o_ai
+vec_perm(vector bool char a, vector bool char b, vector unsigned char c)
+{
+  return (vector bool char)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector short __ATTRS_o_ai
+vec_perm(vector short a, vector short b, vector unsigned char c)
+{
+  return (vector short)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector unsigned short __ATTRS_o_ai
+vec_perm(vector unsigned short a, vector unsigned short b, vector unsigned char c)
+{
+  return (vector unsigned short)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector bool short __ATTRS_o_ai
+vec_perm(vector bool short a, vector bool short b, vector unsigned char c)
+{
+  return (vector bool short)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector pixel __ATTRS_o_ai
+vec_perm(vector pixel a, vector pixel b, vector unsigned char c)
+{
+  return (vector pixel)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector int __ATTRS_o_ai
+vec_perm(vector int a, vector int b, vector unsigned char c)
+{
+  return (vector int)__builtin_altivec_vperm_4si(a, b, c);
+}
+
+vector unsigned int __ATTRS_o_ai
+vec_perm(vector unsigned int a, vector unsigned int b, vector unsigned char c)
+{
+  return (vector unsigned int)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector bool int __ATTRS_o_ai
+vec_perm(vector bool int a, vector bool int b, vector unsigned char c)
+{
+  return (vector bool int)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector float __ATTRS_o_ai
+vec_perm(vector float a, vector float b, vector unsigned char c)
+{
+  return (vector float)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+/* vec_vperm */
+
+vector signed char __ATTRS_o_ai
+vec_vperm(vector signed char a, vector signed char b, vector unsigned char c)
+{
+  return (vector signed char)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector unsigned char __ATTRS_o_ai
+vec_vperm(vector unsigned char a, vector unsigned char b, vector unsigned char c)
+{
+  return (vector unsigned char)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector bool char __ATTRS_o_ai
+vec_vperm(vector bool char a, vector bool char b, vector unsigned char c)
+{
+  return (vector bool char)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector short __ATTRS_o_ai
+vec_vperm(vector short a, vector short b, vector unsigned char c)
+{
+  return (vector short)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector unsigned short __ATTRS_o_ai
+vec_vperm(vector unsigned short a, vector unsigned short b, vector unsigned char c)
+{
+  return (vector unsigned short)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector bool short __ATTRS_o_ai
+vec_vperm(vector bool short a, vector bool short b, vector unsigned char c)
+{
+  return (vector bool short)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector pixel __ATTRS_o_ai
+vec_vperm(vector pixel a, vector pixel b, vector unsigned char c)
+{
+  return (vector pixel)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector int __ATTRS_o_ai
+vec_vperm(vector int a, vector int b, vector unsigned char c)
+{
+  return (vector int)__builtin_altivec_vperm_4si(a, b, c);
+}
+
+vector unsigned int __ATTRS_o_ai
+vec_vperm(vector unsigned int a, vector unsigned int b, vector unsigned char c)
+{
+  return (vector unsigned int)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector bool int __ATTRS_o_ai
+vec_vperm(vector bool int a, vector bool int b, vector unsigned char c)
+{
+  return (vector bool int)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+vector float __ATTRS_o_ai
+vec_vperm(vector float a, vector float b, vector unsigned char c)
+{
+  return (vector float)__builtin_altivec_vperm_4si((vector int)a, (vector int)b, c);
+}
+
+/* vec_re */
+
+vector float __attribute__((__always_inline__))
+vec_re(vector float a)
+{
+  return __builtin_altivec_vrefp(a);
+}
+
+/* vec_vrefp */
+
+vector float __attribute__((__always_inline__))
+vec_vrefp(vector float a)
+{
+  return __builtin_altivec_vrefp(a);
+}
+
+/* vec_rl */
+
+static vector signed char __ATTRS_o_ai
+vec_rl(vector signed char a, vector unsigned char b)
+{
+  return (vector signed char)__builtin_altivec_vrlb((vector char)a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_rl(vector unsigned char a, vector unsigned char b)
+{
+  return (vector unsigned char)__builtin_altivec_vrlb((vector char)a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_rl(vector short a, vector unsigned short b)
+{
+  return __builtin_altivec_vrlh(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_rl(vector unsigned short a, vector unsigned short b)
+{
+  return (vector unsigned short)__builtin_altivec_vrlh((vector short)a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_rl(vector int a, vector unsigned int b)
+{
+  return __builtin_altivec_vrlw(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_rl(vector unsigned int a, vector unsigned int b)
+{
+  return (vector unsigned int)__builtin_altivec_vrlw((vector int)a, b);
+}
+
+/* vec_vrlb */
+
+static vector signed char __ATTRS_o_ai
+vec_vrlb(vector signed char a, vector unsigned char b)
+{
+  return (vector signed char)__builtin_altivec_vrlb((vector char)a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vrlb(vector unsigned char a, vector unsigned char b)
+{
+  return (vector unsigned char)__builtin_altivec_vrlb((vector char)a, b);
+}
+
+/* vec_vrlh */
+
+static vector short __ATTRS_o_ai
+vec_vrlh(vector short a, vector unsigned short b)
+{
+  return __builtin_altivec_vrlh(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vrlh(vector unsigned short a, vector unsigned short b)
+{
+  return (vector unsigned short)__builtin_altivec_vrlh((vector short)a, b);
+}
+
+/* vec_vrlw */
+
+static vector int __ATTRS_o_ai
+vec_vrlw(vector int a, vector unsigned int b)
+{
+  return __builtin_altivec_vrlw(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vrlw(vector unsigned int a, vector unsigned int b)
+{
+  return (vector unsigned int)__builtin_altivec_vrlw((vector int)a, b);
+}
+
+/* vec_round */
+
+static vector float __attribute__((__always_inline__))
+vec_round(vector float a)
+{
+  return __builtin_altivec_vrfin(a);
+}
+
+/* vec_vrfin */
+
+static vector float __attribute__((__always_inline__))
+vec_vrfin(vector float a)
+{
+  return __builtin_altivec_vrfin(a);
+}
+
+/* vec_rsqrte */
+
+static __vector float __attribute__((__always_inline__))
+vec_rsqrte(vector float a)
+{
+  return __builtin_altivec_vrsqrtefp(a);
+}
+
+/* vec_vrsqrtefp */
+
+static __vector float __attribute__((__always_inline__))
+vec_vrsqrtefp(vector float a)
+{
+  return __builtin_altivec_vrsqrtefp(a);
+}
+
+/* vec_sel */
+
+#define __builtin_altivec_vsel_4si vec_sel
+
+static vector signed char __ATTRS_o_ai
+vec_sel(vector signed char a, vector signed char b, vector unsigned char c)
+{
+  return (a & ~(vector signed char)c) | (b & (vector signed char)c);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_sel(vector signed char a, vector signed char b, vector bool char c)
+{
+  return (a & ~(vector signed char)c) | (b & (vector signed char)c);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sel(vector unsigned char a, vector unsigned char b, vector unsigned char c)
+{
+  return (a & ~c) | (b & c);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sel(vector unsigned char a, vector unsigned char b, vector bool char c)
+{
+  return (a & ~(vector unsigned char)c) | (b & (vector unsigned char)c);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_sel(vector bool char a, vector bool char b, vector unsigned char c)
+{
+  return (a & ~(vector bool char)c) | (b & (vector bool char)c);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_sel(vector bool char a, vector bool char b, vector bool char c)
+{
+  return (a & ~c) | (b & c);
+}
+
+static vector short __ATTRS_o_ai
+vec_sel(vector short a, vector short b, vector unsigned short c)
+{
+  return (a & ~(vector short)c) | (b & (vector short)c);
+}
+
+static vector short __ATTRS_o_ai
+vec_sel(vector short a, vector short b, vector bool short c)
+{
+  return (a & ~(vector short)c) | (b & (vector short)c);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sel(vector unsigned short a, vector unsigned short b, vector unsigned short c)
+{
+  return (a & ~c) | (b & c);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sel(vector unsigned short a, vector unsigned short b, vector bool short c)
+{
+  return (a & ~(vector unsigned short)c) | (b & (vector unsigned short)c);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_sel(vector bool short a, vector bool short b, vector unsigned short c)
+{
+  return (a & ~(vector bool short)c) | (b & (vector bool short)c);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_sel(vector bool short a, vector bool short b, vector bool short c)
+{
+  return (a & ~c) | (b & c);
+}
+
+static vector int __ATTRS_o_ai
+vec_sel(vector int a, vector int b, vector unsigned int c)
+{
+  return (a & ~(vector int)c) | (b & (vector int)c);
+}
+
+static vector int __ATTRS_o_ai
+vec_sel(vector int a, vector int b, vector bool int c)
+{
+  return (a & ~(vector int)c) | (b & (vector int)c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sel(vector unsigned int a, vector unsigned int b, vector unsigned int c)
+{
+  return (a & ~c) | (b & c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sel(vector unsigned int a, vector unsigned int b, vector bool int c)
+{
+  return (a & ~(vector unsigned int)c) | (b & (vector unsigned int)c);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_sel(vector bool int a, vector bool int b, vector unsigned int c)
+{
+  return (a & ~(vector bool int)c) | (b & (vector bool int)c);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_sel(vector bool int a, vector bool int b, vector bool int c)
+{
+  return (a & ~c) | (b & c);
+}
+
+static vector float __ATTRS_o_ai
+vec_sel(vector float a, vector float b, vector unsigned int c)
+{
+  vector int res = ((vector int)a & ~(vector int)c) | ((vector int)b & (vector int)c);
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_sel(vector float a, vector float b, vector bool int c)
+{
+  vector int res = ((vector int)a & ~(vector int)c) | ((vector int)b & (vector int)c);
+  return (vector float)res;
+}
+
+/* vec_vsel */
+
+static vector signed char __ATTRS_o_ai
+vec_vsel(vector signed char a, vector signed char b, vector unsigned char c)
+{
+  return (a & ~(vector signed char)c) | (b & (vector signed char)c);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsel(vector signed char a, vector signed char b, vector bool char c)
+{
+  return (a & ~(vector signed char)c) | (b & (vector signed char)c);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsel(vector unsigned char a, vector unsigned char b, vector unsigned char c)
+{
+  return (a & ~c) | (b & c);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsel(vector unsigned char a, vector unsigned char b, vector bool char c)
+{
+  return (a & ~(vector unsigned char)c) | (b & (vector unsigned char)c);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsel(vector bool char a, vector bool char b, vector unsigned char c)
+{
+  return (a & ~(vector bool char)c) | (b & (vector bool char)c);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsel(vector bool char a, vector bool char b, vector bool char c)
+{
+  return (a & ~c) | (b & c);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsel(vector short a, vector short b, vector unsigned short c)
+{
+  return (a & ~(vector short)c) | (b & (vector short)c);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsel(vector short a, vector short b, vector bool short c)
+{
+  return (a & ~(vector short)c) | (b & (vector short)c);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsel(vector unsigned short a, vector unsigned short b, vector unsigned short c)
+{
+  return (a & ~c) | (b & c);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsel(vector unsigned short a, vector unsigned short b, vector bool short c)
+{
+  return (a & ~(vector unsigned short)c) | (b & (vector unsigned short)c);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsel(vector bool short a, vector bool short b, vector unsigned short c)
+{
+  return (a & ~(vector bool short)c) | (b & (vector bool short)c);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsel(vector bool short a, vector bool short b, vector bool short c)
+{
+  return (a & ~c) | (b & c);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsel(vector int a, vector int b, vector unsigned int c)
+{
+  return (a & ~(vector int)c) | (b & (vector int)c);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsel(vector int a, vector int b, vector bool int c)
+{
+  return (a & ~(vector int)c) | (b & (vector int)c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsel(vector unsigned int a, vector unsigned int b, vector unsigned int c)
+{
+  return (a & ~c) | (b & c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsel(vector unsigned int a, vector unsigned int b, vector bool int c)
+{
+  return (a & ~(vector unsigned int)c) | (b & (vector unsigned int)c);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsel(vector bool int a, vector bool int b, vector unsigned int c)
+{
+  return (a & ~(vector bool int)c) | (b & (vector bool int)c);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsel(vector bool int a, vector bool int b, vector bool int c)
+{
+  return (a & ~c) | (b & c);
+}
+
+static vector float __ATTRS_o_ai
+vec_vsel(vector float a, vector float b, vector unsigned int c)
+{
+  vector int res = ((vector int)a & ~(vector int)c) | ((vector int)b & (vector int)c);
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vsel(vector float a, vector float b, vector bool int c)
+{
+  vector int res = ((vector int)a & ~(vector int)c) | ((vector int)b & (vector int)c);
+  return (vector float)res;
+}
+
+/* vec_sl */
+
+static vector signed char __ATTRS_o_ai
+vec_sl(vector signed char a, vector unsigned char b)
+{
+  return a << (vector signed char)b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sl(vector unsigned char a, vector unsigned char b)
+{
+  return a << b;
+}
+
+static vector short __ATTRS_o_ai
+vec_sl(vector short a, vector unsigned short b)
+{
+  return a << (vector short)b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sl(vector unsigned short a, vector unsigned short b)
+{
+  return a << b;
+}
+
+static vector int __ATTRS_o_ai
+vec_sl(vector int a, vector unsigned int b)
+{
+  return a << (vector int)b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sl(vector unsigned int a, vector unsigned int b)
+{
+  return a << b;
+}
+
+/* vec_vslb */
+
+#define __builtin_altivec_vslb vec_vslb
+
+static vector signed char __ATTRS_o_ai
+vec_vslb(vector signed char a, vector unsigned char b)
+{
+  return vec_sl(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vslb(vector unsigned char a, vector unsigned char b)
+{
+  return vec_sl(a, b);
+}
+
+/* vec_vslh */
+
+#define __builtin_altivec_vslh vec_vslh
+
+static vector short __ATTRS_o_ai
+vec_vslh(vector short a, vector unsigned short b)
+{
+  return vec_sl(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vslh(vector unsigned short a, vector unsigned short b)
+{
+  return vec_sl(a, b);
+}
+
+/* vec_vslw */
+
+#define __builtin_altivec_vslw vec_vslw
+
+static vector int __ATTRS_o_ai
+vec_vslw(vector int a, vector unsigned int b)
+{
+  return vec_sl(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vslw(vector unsigned int a, vector unsigned int b)
+{
+  return vec_sl(a, b);
+}
+
+/* vec_sld */
+
+#define __builtin_altivec_vsldoi_4si vec_sld
+
+static vector signed char __ATTRS_o_ai
+vec_sld(vector signed char a, vector signed char b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sld(vector unsigned char a, vector unsigned char b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+static vector short __ATTRS_o_ai
+vec_sld(vector short a, vector short b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sld(vector unsigned short a, vector unsigned short b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_sld(vector pixel a, vector pixel b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+static vector int __ATTRS_o_ai
+vec_sld(vector int a, vector int b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sld(vector unsigned int a, vector unsigned int b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+static vector float __ATTRS_o_ai
+vec_sld(vector float a, vector float b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+/* vec_vsldoi */
+
+static vector signed char __ATTRS_o_ai
+vec_vsldoi(vector signed char a, vector signed char b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsldoi(vector unsigned char a, vector unsigned char b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+static vector short __ATTRS_o_ai
+vec_vsldoi(vector short a, vector short b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsldoi(vector unsigned short a, vector unsigned short b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsldoi(vector pixel a, vector pixel b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+static vector int __ATTRS_o_ai
+vec_vsldoi(vector int a, vector int b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsldoi(vector unsigned int a, vector unsigned int b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+static vector float __ATTRS_o_ai
+vec_vsldoi(vector float a, vector float b, unsigned char c)
+{
+  return vec_perm(a, b, (vector unsigned char)
+    (c,   c+1, c+2,  c+3,  c+4,  c+5,  c+6,  c+7, 
+     c+8, c+9, c+10, c+11, c+12, c+13, c+14, c+15));
+}
+
+/* vec_sll */
+
+static vector signed char __ATTRS_o_ai
+vec_sll(vector signed char a, vector unsigned char b)
+{
+  return (vector signed char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_sll(vector signed char a, vector unsigned short b)
+{
+  return (vector signed char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_sll(vector signed char a, vector unsigned int b)
+{
+  return (vector signed char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sll(vector unsigned char a, vector unsigned char b)
+{
+  return (vector unsigned char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sll(vector unsigned char a, vector unsigned short b)
+{
+  return (vector unsigned char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sll(vector unsigned char a, vector unsigned int b)
+{
+  return (vector unsigned char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_sll(vector bool char a, vector unsigned char b)
+{
+  return (vector bool char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_sll(vector bool char a, vector unsigned short b)
+{
+  return (vector bool char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_sll(vector bool char a, vector unsigned int b)
+{
+  return (vector bool char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_sll(vector short a, vector unsigned char b)
+{
+  return (vector short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_sll(vector short a, vector unsigned short b)
+{
+  return (vector short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_sll(vector short a, vector unsigned int b)
+{
+  return (vector short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sll(vector unsigned short a, vector unsigned char b)
+{
+  return (vector unsigned short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sll(vector unsigned short a, vector unsigned short b)
+{
+  return (vector unsigned short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sll(vector unsigned short a, vector unsigned int b)
+{
+  return (vector unsigned short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_sll(vector bool short a, vector unsigned char b)
+{
+  return (vector bool short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_sll(vector bool short a, vector unsigned short b)
+{
+  return (vector bool short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_sll(vector bool short a, vector unsigned int b)
+{
+  return (vector bool short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_sll(vector pixel a, vector unsigned char b)
+{
+  return (vector pixel)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_sll(vector pixel a, vector unsigned short b)
+{
+  return (vector pixel)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_sll(vector pixel a, vector unsigned int b)
+{
+  return (vector pixel)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_sll(vector int a, vector unsigned char b)
+{
+  return (vector int)__builtin_altivec_vsl(a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_sll(vector int a, vector unsigned short b)
+{
+  return (vector int)__builtin_altivec_vsl(a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_sll(vector int a, vector unsigned int b)
+{
+  return (vector int)__builtin_altivec_vsl(a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sll(vector unsigned int a, vector unsigned char b)
+{
+  return (vector unsigned int)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sll(vector unsigned int a, vector unsigned short b)
+{
+  return (vector unsigned int)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sll(vector unsigned int a, vector unsigned int b)
+{
+  return (vector unsigned int)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_sll(vector bool int a, vector unsigned char b)
+{
+  return (vector bool int)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_sll(vector bool int a, vector unsigned short b)
+{
+  return (vector bool int)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_sll(vector bool int a, vector unsigned int b)
+{
+  return (vector bool int)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+/* vec_vsl */
+
+static vector signed char __ATTRS_o_ai
+vec_vsl(vector signed char a, vector unsigned char b)
+{
+  return (vector signed char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsl(vector signed char a, vector unsigned short b)
+{
+  return (vector signed char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsl(vector signed char a, vector unsigned int b)
+{
+  return (vector signed char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsl(vector unsigned char a, vector unsigned char b)
+{
+  return (vector unsigned char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsl(vector unsigned char a, vector unsigned short b)
+{
+  return (vector unsigned char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsl(vector unsigned char a, vector unsigned int b)
+{
+  return (vector unsigned char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsl(vector bool char a, vector unsigned char b)
+{
+  return (vector bool char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsl(vector bool char a, vector unsigned short b)
+{
+  return (vector bool char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsl(vector bool char a, vector unsigned int b)
+{
+  return (vector bool char)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsl(vector short a, vector unsigned char b)
+{
+  return (vector short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsl(vector short a, vector unsigned short b)
+{
+  return (vector short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsl(vector short a, vector unsigned int b)
+{
+  return (vector short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsl(vector unsigned short a, vector unsigned char b)
+{
+  return (vector unsigned short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsl(vector unsigned short a, vector unsigned short b)
+{
+  return (vector unsigned short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsl(vector unsigned short a, vector unsigned int b)
+{
+  return (vector unsigned short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsl(vector bool short a, vector unsigned char b)
+{
+  return (vector bool short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsl(vector bool short a, vector unsigned short b)
+{
+  return (vector bool short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsl(vector bool short a, vector unsigned int b)
+{
+  return (vector bool short)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsl(vector pixel a, vector unsigned char b)
+{
+  return (vector pixel)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsl(vector pixel a, vector unsigned short b)
+{
+  return (vector pixel)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsl(vector pixel a, vector unsigned int b)
+{
+  return (vector pixel)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsl(vector int a, vector unsigned char b)
+{
+  return (vector int)__builtin_altivec_vsl(a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsl(vector int a, vector unsigned short b)
+{
+  return (vector int)__builtin_altivec_vsl(a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsl(vector int a, vector unsigned int b)
+{
+  return (vector int)__builtin_altivec_vsl(a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsl(vector unsigned int a, vector unsigned char b)
+{
+  return (vector unsigned int)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsl(vector unsigned int a, vector unsigned short b)
+{
+  return (vector unsigned int)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsl(vector unsigned int a, vector unsigned int b)
+{
+  return (vector unsigned int)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsl(vector bool int a, vector unsigned char b)
+{
+  return (vector bool int)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsl(vector bool int a, vector unsigned short b)
+{
+  return (vector bool int)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsl(vector bool int a, vector unsigned int b)
+{
+  return (vector bool int)__builtin_altivec_vsl((vector int)a, (vector int)b);
+}
+
+/* vec_slo */
+
+static vector signed char __ATTRS_o_ai
+vec_slo(vector signed char a, vector signed char b)
+{
+  return (vector signed char)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_slo(vector signed char a, vector unsigned char b)
+{
+  return (vector signed char)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_slo(vector unsigned char a, vector signed char b)
+{
+  return (vector unsigned char)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_slo(vector unsigned char a, vector unsigned char b)
+{
+  return (vector unsigned char)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_slo(vector short a, vector signed char b)
+{
+  return (vector short)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_slo(vector short a, vector unsigned char b)
+{
+  return (vector short)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_slo(vector unsigned short a, vector signed char b)
+{
+  return (vector unsigned short)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_slo(vector unsigned short a, vector unsigned char b)
+{
+  return (vector unsigned short)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_slo(vector pixel a, vector signed char b)
+{
+  return (vector pixel)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_slo(vector pixel a, vector unsigned char b)
+{
+  return (vector pixel)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_slo(vector int a, vector signed char b)
+{
+  return (vector int)__builtin_altivec_vslo(a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_slo(vector int a, vector unsigned char b)
+{
+  return (vector int)__builtin_altivec_vslo(a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_slo(vector unsigned int a, vector signed char b)
+{
+  return (vector unsigned int)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_slo(vector unsigned int a, vector unsigned char b)
+{
+  return (vector unsigned int)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector float __ATTRS_o_ai
+vec_slo(vector float a, vector signed char b)
+{
+  return (vector float)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector float __ATTRS_o_ai
+vec_slo(vector float a, vector unsigned char b)
+{
+  return (vector float)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+/* vec_vslo */
+
+static vector signed char __ATTRS_o_ai
+vec_vslo(vector signed char a, vector signed char b)
+{
+  return (vector signed char)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vslo(vector signed char a, vector unsigned char b)
+{
+  return (vector signed char)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vslo(vector unsigned char a, vector signed char b)
+{
+  return (vector unsigned char)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vslo(vector unsigned char a, vector unsigned char b)
+{
+  return (vector unsigned char)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vslo(vector short a, vector signed char b)
+{
+  return (vector short)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vslo(vector short a, vector unsigned char b)
+{
+  return (vector short)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vslo(vector unsigned short a, vector signed char b)
+{
+  return (vector unsigned short)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vslo(vector unsigned short a, vector unsigned char b)
+{
+  return (vector unsigned short)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vslo(vector pixel a, vector signed char b)
+{
+  return (vector pixel)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vslo(vector pixel a, vector unsigned char b)
+{
+  return (vector pixel)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vslo(vector int a, vector signed char b)
+{
+  return (vector int)__builtin_altivec_vslo(a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vslo(vector int a, vector unsigned char b)
+{
+  return (vector int)__builtin_altivec_vslo(a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vslo(vector unsigned int a, vector signed char b)
+{
+  return (vector unsigned int)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vslo(vector unsigned int a, vector unsigned char b)
+{
+  return (vector unsigned int)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector float __ATTRS_o_ai
+vec_vslo(vector float a, vector signed char b)
+{
+  return (vector float)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+static vector float __ATTRS_o_ai
+vec_vslo(vector float a, vector unsigned char b)
+{
+  return (vector float)__builtin_altivec_vslo((vector int)a, (vector int)b);
+}
+
+/* vec_splat */
+
+static vector signed char __ATTRS_o_ai
+vec_splat(vector signed char a, unsigned char b)
+{
+  return vec_perm(a, a, (vector unsigned char)(b));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_splat(vector unsigned char a, unsigned char b)
+{
+  return vec_perm(a, a, (vector unsigned char)(b));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_splat(vector bool char a, unsigned char b)
+{
+  return vec_perm(a, a, (vector unsigned char)(b));
+}
+
+static vector short __ATTRS_o_ai
+vec_splat(vector short a, unsigned char b)
+{ 
+  b *= 2;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_splat(vector unsigned short a, unsigned char b)
+{ 
+  b *= 2;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_splat(vector bool short a, unsigned char b)
+{ 
+  b *= 2;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_splat(vector pixel a, unsigned char b)
+{ 
+  b *= 2;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1));
+}
+
+static vector int __ATTRS_o_ai
+vec_splat(vector int a, unsigned char b)
+{ 
+  b *= 4;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_splat(vector unsigned int a, unsigned char b)
+{ 
+  b *= 4;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_splat(vector bool int a, unsigned char b)
+{ 
+  b *= 4;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3));
+}
+
+static vector float __ATTRS_o_ai
+vec_splat(vector float a, unsigned char b)
+{ 
+  b *= 4;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3));
+}
+
+/* vec_vspltb */
+
+#define __builtin_altivec_vspltb vec_vspltb
+
+static vector signed char __ATTRS_o_ai
+vec_vspltb(vector signed char a, unsigned char b)
+{
+  return vec_perm(a, a, (vector unsigned char)(b));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vspltb(vector unsigned char a, unsigned char b)
+{
+  return vec_perm(a, a, (vector unsigned char)(b));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vspltb(vector bool char a, unsigned char b)
+{
+  return vec_perm(a, a, (vector unsigned char)(b));
+}
+
+/* vec_vsplth */
+
+#define __builtin_altivec_vsplth vec_vsplth
+
+static vector short __ATTRS_o_ai
+vec_vsplth(vector short a, unsigned char b)
+{
+  b *= 2;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsplth(vector unsigned short a, unsigned char b)
+{
+  b *= 2;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsplth(vector bool short a, unsigned char b)
+{
+  b *= 2;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsplth(vector pixel a, unsigned char b)
+{
+  b *= 2;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1, b, b+1));
+}
+
+/* vec_vspltw */
+
+#define __builtin_altivec_vspltw vec_vspltw
+
+static vector int __ATTRS_o_ai
+vec_vspltw(vector int a, unsigned char b)
+{
+  b *= 4;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vspltw(vector unsigned int a, unsigned char b)
+{
+  b *= 4;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vspltw(vector bool int a, unsigned char b)
+{
+  b *= 4;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3));
+}
+
+static vector float __ATTRS_o_ai
+vec_vspltw(vector float a, unsigned char b)
+{
+  b *= 4;
+  return vec_perm(a, a, (vector unsigned char)
+    (b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3, b, b+1, b+2, b+3));
+}
+
+/* vec_splat_s8 */
+
+#define __builtin_altivec_vspltisb vec_splat_s8
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector signed char __ATTRS_o_ai
+vec_splat_s8(signed char a)
+{
+  return (vector signed char)(a);
+}
+
+/* vec_vspltisb */
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector signed char __ATTRS_o_ai
+vec_vspltisb(signed char a)
+{
+  return (vector signed char)(a);
+}
+
+/* vec_splat_s16 */
+
+#define __builtin_altivec_vspltish vec_splat_s16
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector short __ATTRS_o_ai
+vec_splat_s16(signed char a)
+{
+  return (vector short)(a);
+}
+
+/* vec_vspltish */
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector short __ATTRS_o_ai
+vec_vspltish(signed char a)
+{
+  return (vector short)(a);
+}
+
+/* vec_splat_s32 */
+
+#define __builtin_altivec_vspltisw vec_splat_s32
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector int __ATTRS_o_ai
+vec_splat_s32(signed char a)
+{
+  return (vector int)(a);
+}
+
+/* vec_vspltisw */
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector int __ATTRS_o_ai
+vec_vspltisw(signed char a)
+{
+  return (vector int)(a);
+}
+
+/* vec_splat_u8 */
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector unsigned char __ATTRS_o_ai
+vec_splat_u8(unsigned char a)
+{
+  return (vector unsigned char)(a);
+}
+
+/* vec_splat_u16 */
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector unsigned short __ATTRS_o_ai
+vec_splat_u16(signed char a)
+{
+  return (vector unsigned short)(a);
+}
+
+/* vec_splat_u32 */
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector unsigned int __ATTRS_o_ai
+vec_splat_u32(signed char a)
+{
+  return (vector unsigned int)(a);
+}
+
+/* vec_sr */
+
+static vector signed char __ATTRS_o_ai
+vec_sr(vector signed char a, vector unsigned char b)
+{
+  return a >> (vector signed char)b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sr(vector unsigned char a, vector unsigned char b)
+{
+  return a >> b;
+}
+
+static vector short __ATTRS_o_ai
+vec_sr(vector short a, vector unsigned short b)
+{
+  return a >> (vector short)b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sr(vector unsigned short a, vector unsigned short b)
+{
+  return a >> b;
+}
+
+static vector int __ATTRS_o_ai
+vec_sr(vector int a, vector unsigned int b)
+{
+  return a >> (vector int)b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sr(vector unsigned int a, vector unsigned int b)
+{
+  return a >> b;
+}
+
+/* vec_vsrb */
+
+#define __builtin_altivec_vsrb vec_vsrb
+
+static vector signed char __ATTRS_o_ai
+vec_vsrb(vector signed char a, vector unsigned char b)
+{
+  return a >> (vector signed char)b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsrb(vector unsigned char a, vector unsigned char b)
+{
+  return a >> b;
+}
+
+/* vec_vsrh */
+
+#define __builtin_altivec_vsrh vec_vsrh
+
+static vector short __ATTRS_o_ai
+vec_vsrh(vector short a, vector unsigned short b)
+{
+  return a >> (vector short)b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsrh(vector unsigned short a, vector unsigned short b)
+{
+  return a >> b;
+}
+
+/* vec_vsrw */
+
+#define __builtin_altivec_vsrw vec_vsrw
+
+static vector int __ATTRS_o_ai
+vec_vsrw(vector int a, vector unsigned int b)
+{
+  return a >> (vector int)b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsrw(vector unsigned int a, vector unsigned int b)
+{
+  return a >> b;
+}
+
+/* vec_sra */
+
+static vector signed char __ATTRS_o_ai
+vec_sra(vector signed char a, vector unsigned char b)
+{
+  return (vector signed char)__builtin_altivec_vsrab((vector char)a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sra(vector unsigned char a, vector unsigned char b)
+{
+  return (vector unsigned char)__builtin_altivec_vsrab((vector char)a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_sra(vector short a, vector unsigned short b)
+{
+  return __builtin_altivec_vsrah(a, (vector unsigned short)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sra(vector unsigned short a, vector unsigned short b)
+{
+  return (vector unsigned short)__builtin_altivec_vsrah((vector short)a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_sra(vector int a, vector unsigned int b)
+{
+  return __builtin_altivec_vsraw(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sra(vector unsigned int a, vector unsigned int b)
+{
+  return (vector unsigned int)__builtin_altivec_vsraw((vector int)a, b);
+}
+
+/* vec_vsrab */
+
+static vector signed char __ATTRS_o_ai
+vec_vsrab(vector signed char a, vector unsigned char b)
+{
+  return (vector signed char)__builtin_altivec_vsrab((vector char)a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsrab(vector unsigned char a, vector unsigned char b)
+{
+  return (vector unsigned char)__builtin_altivec_vsrab((vector char)a, b);
+}
+
+/* vec_vsrah */
+
+static vector short __ATTRS_o_ai
+vec_vsrah(vector short a, vector unsigned short b)
+{
+  return __builtin_altivec_vsrah(a, (vector unsigned short)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsrah(vector unsigned short a, vector unsigned short b)
+{
+  return (vector unsigned short)__builtin_altivec_vsrah((vector short)a, b);
+}
+
+/* vec_vsraw */
+
+static vector int __ATTRS_o_ai
+vec_vsraw(vector int a, vector unsigned int b)
+{
+  return __builtin_altivec_vsraw(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsraw(vector unsigned int a, vector unsigned int b)
+{
+  return (vector unsigned int)__builtin_altivec_vsraw((vector int)a, b);
+}
+
+/* vec_srl */
+
+static vector signed char __ATTRS_o_ai
+vec_srl(vector signed char a, vector unsigned char b)
+{
+  return (vector signed char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_srl(vector signed char a, vector unsigned short b)
+{
+  return (vector signed char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_srl(vector signed char a, vector unsigned int b)
+{
+  return (vector signed char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_srl(vector unsigned char a, vector unsigned char b)
+{
+  return (vector unsigned char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_srl(vector unsigned char a, vector unsigned short b)
+{
+  return (vector unsigned char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_srl(vector unsigned char a, vector unsigned int b)
+{
+  return (vector unsigned char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_srl(vector bool char a, vector unsigned char b)
+{
+  return (vector bool char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_srl(vector bool char a, vector unsigned short b)
+{
+  return (vector bool char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_srl(vector bool char a, vector unsigned int b)
+{
+  return (vector bool char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_srl(vector short a, vector unsigned char b)
+{
+  return (vector short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_srl(vector short a, vector unsigned short b)
+{
+  return (vector short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_srl(vector short a, vector unsigned int b)
+{
+  return (vector short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_srl(vector unsigned short a, vector unsigned char b)
+{
+  return (vector unsigned short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_srl(vector unsigned short a, vector unsigned short b)
+{
+  return (vector unsigned short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_srl(vector unsigned short a, vector unsigned int b)
+{
+  return (vector unsigned short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_srl(vector bool short a, vector unsigned char b)
+{
+  return (vector bool short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_srl(vector bool short a, vector unsigned short b)
+{
+  return (vector bool short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_srl(vector bool short a, vector unsigned int b)
+{
+  return (vector bool short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_srl(vector pixel a, vector unsigned char b)
+{
+  return (vector pixel)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_srl(vector pixel a, vector unsigned short b)
+{
+  return (vector pixel)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_srl(vector pixel a, vector unsigned int b)
+{
+  return (vector pixel)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_srl(vector int a, vector unsigned char b)
+{
+  return (vector int)__builtin_altivec_vsr(a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_srl(vector int a, vector unsigned short b)
+{
+  return (vector int)__builtin_altivec_vsr(a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_srl(vector int a, vector unsigned int b)
+{
+  return (vector int)__builtin_altivec_vsr(a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_srl(vector unsigned int a, vector unsigned char b)
+{
+  return (vector unsigned int)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_srl(vector unsigned int a, vector unsigned short b)
+{
+  return (vector unsigned int)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_srl(vector unsigned int a, vector unsigned int b)
+{
+  return (vector unsigned int)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_srl(vector bool int a, vector unsigned char b)
+{
+  return (vector bool int)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_srl(vector bool int a, vector unsigned short b)
+{
+  return (vector bool int)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_srl(vector bool int a, vector unsigned int b)
+{
+  return (vector bool int)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+/* vec_vsr */
+
+static vector signed char __ATTRS_o_ai
+vec_vsr(vector signed char a, vector unsigned char b)
+{
+  return (vector signed char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsr(vector signed char a, vector unsigned short b)
+{
+  return (vector signed char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsr(vector signed char a, vector unsigned int b)
+{
+  return (vector signed char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsr(vector unsigned char a, vector unsigned char b)
+{
+  return (vector unsigned char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsr(vector unsigned char a, vector unsigned short b)
+{
+  return (vector unsigned char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsr(vector unsigned char a, vector unsigned int b)
+{
+  return (vector unsigned char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsr(vector bool char a, vector unsigned char b)
+{
+  return (vector bool char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsr(vector bool char a, vector unsigned short b)
+{
+  return (vector bool char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsr(vector bool char a, vector unsigned int b)
+{
+  return (vector bool char)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsr(vector short a, vector unsigned char b)
+{
+  return (vector short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsr(vector short a, vector unsigned short b)
+{
+  return (vector short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsr(vector short a, vector unsigned int b)
+{
+  return (vector short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsr(vector unsigned short a, vector unsigned char b)
+{
+  return (vector unsigned short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsr(vector unsigned short a, vector unsigned short b)
+{
+  return (vector unsigned short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsr(vector unsigned short a, vector unsigned int b)
+{
+  return (vector unsigned short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsr(vector bool short a, vector unsigned char b)
+{
+  return (vector bool short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsr(vector bool short a, vector unsigned short b)
+{
+  return (vector bool short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsr(vector bool short a, vector unsigned int b)
+{
+  return (vector bool short)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsr(vector pixel a, vector unsigned char b)
+{
+  return (vector pixel)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsr(vector pixel a, vector unsigned short b)
+{
+  return (vector pixel)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsr(vector pixel a, vector unsigned int b)
+{
+  return (vector pixel)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsr(vector int a, vector unsigned char b)
+{
+  return (vector int)__builtin_altivec_vsr(a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsr(vector int a, vector unsigned short b)
+{
+  return (vector int)__builtin_altivec_vsr(a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsr(vector int a, vector unsigned int b)
+{
+  return (vector int)__builtin_altivec_vsr(a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsr(vector unsigned int a, vector unsigned char b)
+{
+  return (vector unsigned int)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsr(vector unsigned int a, vector unsigned short b)
+{
+  return (vector unsigned int)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsr(vector unsigned int a, vector unsigned int b)
+{
+  return (vector unsigned int)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsr(vector bool int a, vector unsigned char b)
+{
+  return (vector bool int)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsr(vector bool int a, vector unsigned short b)
+{
+  return (vector bool int)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsr(vector bool int a, vector unsigned int b)
+{
+  return (vector bool int)__builtin_altivec_vsr((vector int)a, (vector int)b);
+}
+
+/* vec_sro */
+
+static vector signed char __ATTRS_o_ai
+vec_sro(vector signed char a, vector signed char b)
+{
+  return (vector signed char)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_sro(vector signed char a, vector unsigned char b)
+{
+  return (vector signed char)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sro(vector unsigned char a, vector signed char b)
+{
+  return (vector unsigned char)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sro(vector unsigned char a, vector unsigned char b)
+{
+  return (vector unsigned char)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_sro(vector short a, vector signed char b)
+{
+  return (vector short)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_sro(vector short a, vector unsigned char b)
+{
+  return (vector short)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sro(vector unsigned short a, vector signed char b)
+{
+  return (vector unsigned short)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sro(vector unsigned short a, vector unsigned char b)
+{
+  return (vector unsigned short)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_sro(vector pixel a, vector signed char b)
+{
+  return (vector pixel)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_sro(vector pixel a, vector unsigned char b)
+{
+  return (vector pixel)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_sro(vector int a, vector signed char b)
+{
+  return (vector int)__builtin_altivec_vsro(a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_sro(vector int a, vector unsigned char b)
+{
+  return (vector int)__builtin_altivec_vsro(a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sro(vector unsigned int a, vector signed char b)
+{
+  return (vector unsigned int)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sro(vector unsigned int a, vector unsigned char b)
+{
+  return (vector unsigned int)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector float __ATTRS_o_ai
+vec_sro(vector float a, vector signed char b)
+{
+  return (vector float)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector float __ATTRS_o_ai
+vec_sro(vector float a, vector unsigned char b)
+{
+  return (vector float)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+/* vec_vsro */
+
+static vector signed char __ATTRS_o_ai
+vec_vsro(vector signed char a, vector signed char b)
+{
+  return (vector signed char)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsro(vector signed char a, vector unsigned char b)
+{
+  return (vector signed char)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsro(vector unsigned char a, vector signed char b)
+{
+  return (vector unsigned char)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsro(vector unsigned char a, vector unsigned char b)
+{
+  return (vector unsigned char)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsro(vector short a, vector signed char b)
+{
+  return (vector short)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsro(vector short a, vector unsigned char b)
+{
+  return (vector short)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsro(vector unsigned short a, vector signed char b)
+{
+  return (vector unsigned short)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsro(vector unsigned short a, vector unsigned char b)
+{
+  return (vector unsigned short)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsro(vector pixel a, vector signed char b)
+{
+  return (vector pixel)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsro(vector pixel a, vector unsigned char b)
+{
+  return (vector pixel)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsro(vector int a, vector signed char b)
+{
+  return (vector int)__builtin_altivec_vsro(a, (vector int)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsro(vector int a, vector unsigned char b)
+{
+  return (vector int)__builtin_altivec_vsro(a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsro(vector unsigned int a, vector signed char b)
+{
+  return (vector unsigned int)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsro(vector unsigned int a, vector unsigned char b)
+{
+  return (vector unsigned int)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector float __ATTRS_o_ai
+vec_vsro(vector float a, vector signed char b)
+{
+  return (vector float)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+static vector float __ATTRS_o_ai
+vec_vsro(vector float a, vector unsigned char b)
+{
+  return (vector float)__builtin_altivec_vsro((vector int)a, (vector int)b);
+}
+
+/* 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, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector signed char a, int b, signed char *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, 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, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector unsigned char a, int b, unsigned char *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool char a, int b, signed char *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool char a, int b, unsigned char *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool char a, int b, vector bool char *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector short a, int b, vector short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector short a, int b, short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, 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, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector unsigned short a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool short a, int b, short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool short a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool short a, int b, vector bool short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector pixel a, int b, short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector pixel a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector pixel a, int b, vector pixel *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector int a, int b, vector int *c)
+{
+  __builtin_altivec_stvx(a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector int a, int b, int *c)
+{
+  __builtin_altivec_stvx(a, b, 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, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector unsigned int a, int b, unsigned int *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool int a, int b, int *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool int a, int b, unsigned int *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool int a, int b, vector bool int *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector float a, int b, vector float *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector float a, int b, float *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+/* vec_stvx */
+
+static void __ATTRS_o_ai
+vec_stvx(vector signed char a, int b, vector signed char *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector signed char a, int b, signed char *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector unsigned char a, int b, vector unsigned char *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector unsigned char a, int b, unsigned char *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool char a, int b, signed char *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool char a, int b, unsigned char *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool char a, int b, vector bool char *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector short a, int b, vector short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector short a, int b, short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector unsigned short a, int b, vector unsigned short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector unsigned short a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool short a, int b, short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool short a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool short a, int b, vector bool short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector pixel a, int b, short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector pixel a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector pixel a, int b, vector pixel *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector int a, int b, vector int *c)
+{
+  __builtin_altivec_stvx(a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector int a, int b, int *c)
+{
+  __builtin_altivec_stvx(a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector unsigned int a, int b, vector unsigned int *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector unsigned int a, int b, unsigned int *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool int a, int b, int *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool int a, int b, unsigned int *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool int a, int b, vector bool int *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector float a, int b, vector float *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector float a, int b, float *c)
+{
+  __builtin_altivec_stvx((vector int)a, b, c);
+}
+
+/* vec_ste */
+
+static void __ATTRS_o_ai
+vec_ste(vector signed char a, int b, signed char *c)
+{
+  __builtin_altivec_stvebx((vector char)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector unsigned char a, int b, unsigned char *c)
+{
+  __builtin_altivec_stvebx((vector char)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector bool char a, int b, signed char *c)
+{
+  __builtin_altivec_stvebx((vector char)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector bool char a, int b, unsigned char *c)
+{
+  __builtin_altivec_stvebx((vector char)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector short a, int b, short *c)
+{
+  __builtin_altivec_stvehx(a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector unsigned short a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvehx((vector short)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector bool short a, int b, short *c)
+{
+  __builtin_altivec_stvehx((vector short)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector bool short a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvehx((vector short)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector pixel a, int b, short *c)
+{
+  __builtin_altivec_stvehx((vector short)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector pixel a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvehx((vector short)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector int a, int b, int *c)
+{
+  __builtin_altivec_stvewx(a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector unsigned int a, int b, unsigned int *c)
+{
+  __builtin_altivec_stvewx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector bool int a, int b, int *c)
+{
+  __builtin_altivec_stvewx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector bool int a, int b, unsigned int *c)
+{
+  __builtin_altivec_stvewx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector float a, int b, float *c)
+{
+  __builtin_altivec_stvewx((vector int)a, b, c);
+}
+
+/* vec_stvebx */
+
+static void __ATTRS_o_ai
+vec_stvebx(vector signed char a, int b, signed char *c)
+{
+  __builtin_altivec_stvebx((vector char)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvebx(vector unsigned char a, int b, unsigned char *c)
+{
+  __builtin_altivec_stvebx((vector char)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvebx(vector bool char a, int b, signed char *c)
+{
+  __builtin_altivec_stvebx((vector char)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvebx(vector bool char a, int b, unsigned char *c)
+{
+  __builtin_altivec_stvebx((vector char)a, b, c);
+}
+
+/* vec_stvehx */
+
+static void __ATTRS_o_ai
+vec_stvehx(vector short a, int b, short *c)
+{
+  __builtin_altivec_stvehx(a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvehx(vector unsigned short a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvehx((vector short)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvehx(vector bool short a, int b, short *c)
+{
+  __builtin_altivec_stvehx((vector short)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvehx(vector bool short a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvehx((vector short)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvehx(vector pixel a, int b, short *c)
+{
+  __builtin_altivec_stvehx((vector short)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvehx(vector pixel a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvehx((vector short)a, b, c);
+}
+
+/* vec_stvewx */
+
+static void __ATTRS_o_ai
+vec_stvewx(vector int a, int b, int *c)
+{
+  __builtin_altivec_stvewx(a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvewx(vector unsigned int a, int b, unsigned int *c)
+{
+  __builtin_altivec_stvewx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvewx(vector bool int a, int b, int *c)
+{
+  __builtin_altivec_stvewx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvewx(vector bool int a, int b, unsigned int *c)
+{
+  __builtin_altivec_stvewx((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvewx(vector float a, int b, float *c)
+{
+  __builtin_altivec_stvewx((vector int)a, b, c);
+}
+
+/* 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, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector signed char a, int b, signed char *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, 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, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector unsigned char a, int b, unsigned char *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool char a, int b, signed char *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool char a, int b, unsigned char *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool char a, int b, vector bool char *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector short a, int b, vector short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector short a, int b, short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, 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, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector unsigned short a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool short a, int b, short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool short a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool short a, int b, vector bool short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector pixel a, int b, short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector pixel a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector pixel a, int b, vector pixel *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector int a, int b, vector int *c)
+{
+  __builtin_altivec_stvxl(a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector int a, int b, int *c)
+{
+  __builtin_altivec_stvxl(a, b, 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, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector unsigned int a, int b, unsigned int *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool int a, int b, int *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool int a, int b, unsigned int *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool int a, int b, vector bool int *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector float a, int b, vector float *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector float a, int b, float *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+/* vec_stvxl */
+
+static void __ATTRS_o_ai
+vec_stvxl(vector signed char a, int b, vector signed char *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector signed char a, int b, signed char *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector unsigned char a, int b, vector unsigned char *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector unsigned char a, int b, unsigned char *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool char a, int b, signed char *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool char a, int b, unsigned char *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool char a, int b, vector bool char *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector short a, int b, vector short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector short a, int b, short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector unsigned short a, int b, vector unsigned short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector unsigned short a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool short a, int b, short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool short a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool short a, int b, vector bool short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector pixel a, int b, short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector pixel a, int b, unsigned short *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector pixel a, int b, vector pixel *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector int a, int b, vector int *c)
+{
+  __builtin_altivec_stvxl(a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector int a, int b, int *c)
+{
+  __builtin_altivec_stvxl(a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector unsigned int a, int b, vector unsigned int *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector unsigned int a, int b, unsigned int *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool int a, int b, int *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool int a, int b, unsigned int *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool int a, int b, vector bool int *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector float a, int b, vector float *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector float a, int b, float *c)
+{
+  __builtin_altivec_stvxl((vector int)a, b, c);
+}
+
+/* vec_sub */
+
+static vector signed char __ATTRS_o_ai
+vec_sub(vector signed char a, vector signed char b)
+{
+  return a - b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_sub(vector bool char a, vector signed char b)
+{
+  return (vector signed char)a - b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_sub(vector signed char a, vector bool char b)
+{
+  return a - (vector signed char)b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sub(vector unsigned char a, vector unsigned char b)
+{
+  return a - b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sub(vector bool char a, vector unsigned char b)
+{
+  return (vector unsigned char)a - b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sub(vector unsigned char a, vector bool char b)
+{
+  return a - (vector unsigned char)b;
+}
+
+static vector short __ATTRS_o_ai
+vec_sub(vector short a, vector short b)
+{
+  return a - b;
+}
+
+static vector short __ATTRS_o_ai
+vec_sub(vector bool short a, vector short b)
+{
+  return (vector short)a - b;
+}
+
+static vector short __ATTRS_o_ai
+vec_sub(vector short a, vector bool short b)
+{
+  return a - (vector short)b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sub(vector unsigned short a, vector unsigned short b)
+{
+  return a - b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sub(vector bool short a, vector unsigned short b)
+{
+  return (vector unsigned short)a - b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sub(vector unsigned short a, vector bool short b)
+{
+  return a - (vector unsigned short)b;
+}
+
+static vector int __ATTRS_o_ai
+vec_sub(vector int a, vector int b)
+{
+  return a - b;
+}
+
+static vector int __ATTRS_o_ai
+vec_sub(vector bool int a, vector int b)
+{
+  return (vector int)a - b;
+}
+
+static vector int __ATTRS_o_ai
+vec_sub(vector int a, vector bool int b)
+{
+  return a - (vector int)b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sub(vector unsigned int a, vector unsigned int b)
+{
+  return a - b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sub(vector bool int a, vector unsigned int b)
+{
+  return (vector unsigned int)a - b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sub(vector unsigned int a, vector bool int b)
+{
+  return a - (vector unsigned int)b;
+}
+
+static vector float __ATTRS_o_ai
+vec_sub(vector float a, vector float b)
+{
+  return a - b;
+}
+
+/* vec_vsububm */
+
+#define __builtin_altivec_vsububm vec_vsububm
+
+static vector signed char __ATTRS_o_ai
+vec_vsububm(vector signed char a, vector signed char b)
+{
+  return a - b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsububm(vector bool char a, vector signed char b)
+{
+  return (vector signed char)a - b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsububm(vector signed char a, vector bool char b)
+{
+  return a - (vector signed char)b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsububm(vector unsigned char a, vector unsigned char b)
+{
+  return a - b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsububm(vector bool char a, vector unsigned char b)
+{
+  return (vector unsigned char)a - b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsububm(vector unsigned char a, vector bool char b)
+{
+  return a - (vector unsigned char)b;
+}
+
+/* vec_vsubuhm */
+
+#define __builtin_altivec_vsubuhm vec_vsubuhm
+
+static vector short __ATTRS_o_ai
+vec_vsubuhm(vector short a, vector short b)
+{
+  return a - b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vsubuhm(vector bool short a, vector short b)
+{
+  return (vector short)a - b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vsubuhm(vector short a, vector bool short b)
+{
+  return a - (vector short)b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsubuhm(vector unsigned short a, vector unsigned short b)
+{
+  return a - b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsubuhm(vector bool short a, vector unsigned short b)
+{
+  return (vector unsigned short)a - b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsubuhm(vector unsigned short a, vector bool short b)
+{
+  return a - (vector unsigned short)b;
+}
+
+/* vec_vsubuwm */
+
+#define __builtin_altivec_vsubuwm vec_vsubuwm
+
+static vector int __ATTRS_o_ai
+vec_vsubuwm(vector int a, vector int b)
+{
+  return a - b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vsubuwm(vector bool int a, vector int b)
+{
+  return (vector int)a - b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vsubuwm(vector int a, vector bool int b)
+{
+  return a - (vector int)b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsubuwm(vector unsigned int a, vector unsigned int b)
+{
+  return a - b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsubuwm(vector bool int a, vector unsigned int b)
+{
+  return (vector unsigned int)a - b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsubuwm(vector unsigned int a, vector bool int b)
+{
+  return a - (vector unsigned int)b;
+}
+
+/* vec_vsubfp */
+
+#define __builtin_altivec_vsubfp vec_vsubfp
+
+static vector float __attribute__((__always_inline__))
+vec_vsubfp(vector float a, vector float b)
+{
+  return a - b;
+}
+
+/* vec_subc */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_subc(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vsubcuw(a, b);
+}
+
+/* vec_vsubcuw */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vsubcuw(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vsubcuw(a, b);
+}
+
+/* vec_subs */
+
+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 signed char __ATTRS_o_ai
+vec_subs(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vsubsbs((vector signed char)a, b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_subs(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vsubsbs(a, (vector signed char)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 unsigned char __ATTRS_o_ai
+vec_subs(vector bool char a, vector unsigned char b)
+{
+  return __builtin_altivec_vsububs((vector unsigned char)a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_subs(vector unsigned char a, vector bool char b)
+{
+  return __builtin_altivec_vsububs(a, (vector unsigned char)b);
+}
+
+static vector short __ATTRS_o_ai
+vec_subs(vector short a, vector short b)
+{
+  return __builtin_altivec_vsubshs(a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_subs(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vsubshs((vector short)a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_subs(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vsubshs(a, (vector short)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 unsigned short __ATTRS_o_ai
+vec_subs(vector bool short a, vector unsigned short b)
+{
+  return __builtin_altivec_vsubuhs((vector unsigned short)a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_subs(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vsubuhs(a, (vector unsigned short)b);
+}
+
+static vector int __ATTRS_o_ai
+vec_subs(vector int a, vector int b)
+{
+  return __builtin_altivec_vsubsws(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_subs(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vsubsws((vector int)a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_subs(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vsubsws(a, (vector int)b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_subs(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vsubuws(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_subs(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vsubuws((vector unsigned int)a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_subs(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vsubuws(a, (vector unsigned int)b);
+}
+
+/* vec_vsubsbs */
+
+static vector signed char __ATTRS_o_ai
+vec_vsubsbs(vector signed char a, vector signed char b)
+{
+  return __builtin_altivec_vsubsbs(a, b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsubsbs(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vsubsbs((vector signed char)a, b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsubsbs(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vsubsbs(a, (vector signed char)b);
+}
+
+/* vec_vsububs */
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsububs(vector unsigned char a, vector unsigned char b)
+{
+  return __builtin_altivec_vsububs(a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsububs(vector bool char a, vector unsigned char b)
+{
+  return __builtin_altivec_vsububs((vector unsigned char)a, b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsububs(vector unsigned char a, vector bool char b)
+{
+  return __builtin_altivec_vsububs(a, (vector unsigned char)b);
+}
+
+/* vec_vsubshs */
+
+static vector short __ATTRS_o_ai
+vec_vsubshs(vector short a, vector short b)
+{
+  return __builtin_altivec_vsubshs(a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsubshs(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vsubshs((vector short)a, b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsubshs(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vsubshs(a, (vector short)b);
+}
+
+/* vec_vsubuhs */
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsubuhs(vector unsigned short a, vector unsigned short b)
+{
+  return __builtin_altivec_vsubuhs(a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsubuhs(vector bool short a, vector unsigned short b)
+{
+  return __builtin_altivec_vsubuhs((vector unsigned short)a, b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsubuhs(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vsubuhs(a, (vector unsigned short)b);
+}
+
+/* vec_vsubsws */
+
+static vector int __ATTRS_o_ai
+vec_vsubsws(vector int a, vector int b)
+{
+  return __builtin_altivec_vsubsws(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsubsws(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vsubsws((vector int)a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsubsws(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vsubsws(a, (vector int)b);
+}
+
+/* vec_vsubuws */
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsubuws(vector unsigned int a, vector unsigned int b)
+{
+  return __builtin_altivec_vsubuws(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsubuws(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vsubuws((vector unsigned int)a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsubuws(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vsubuws(a, (vector unsigned int)b);
+}
+
+/* vec_sum4s */
+
+static vector int __ATTRS_o_ai
+vec_sum4s(vector signed char a, vector int b)
+{
+  return __builtin_altivec_vsum4sbs(a, b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sum4s(vector unsigned char a, vector unsigned int b)
+{
+  return __builtin_altivec_vsum4ubs(a, b);
+}
+
+static vector int __ATTRS_o_ai
+vec_sum4s(vector signed short a, vector int b)
+{
+  return __builtin_altivec_vsum4shs(a, b);
+}
+
+/* vec_vsum4sbs */
+
+static vector int __attribute__((__always_inline__))
+vec_vsum4sbs(vector signed char a, vector int b)
+{
+  return __builtin_altivec_vsum4sbs(a, b);
+}
+
+/* vec_vsum4ubs */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vsum4ubs(vector unsigned char a, vector unsigned int b)
+{
+  return __builtin_altivec_vsum4ubs(a, b);
+}
+
+/* vec_vsum4shs */
+
+static vector int __attribute__((__always_inline__))
+vec_vsum4shs(vector signed short a, vector int b)
+{
+  return __builtin_altivec_vsum4shs(a, b);
+}
+
+/* vec_sum2s */
+
+static vector signed int __attribute__((__always_inline__))
+vec_sum2s(vector int a, vector int b)
+{
+  return __builtin_altivec_vsum2sws(a, b);
+}
+
+/* vec_vsum2sws */
+
+static vector signed int __attribute__((__always_inline__))
+vec_vsum2sws(vector int a, vector int b)
+{
+  return __builtin_altivec_vsum2sws(a, b);
+}
+
+/* vec_sums */
+
+static vector signed int __attribute__((__always_inline__))
+vec_sums(vector signed int a, vector signed int b)
+{
+  return __builtin_altivec_vsumsws(a, b);
+}
+
+/* vec_vsumsws */
+
+static vector signed int __attribute__((__always_inline__))
+vec_vsumsws(vector signed int a, vector signed int b)
+{
+  return __builtin_altivec_vsumsws(a, b);
+}
+
+/* vec_trunc */
+
+static vector float __attribute__((__always_inline__))
+vec_trunc(vector float a)
+{
+  return __builtin_altivec_vrfiz(a);
+}
+
+/* vec_vrfiz */
+
+static vector float __attribute__((__always_inline__))
+vec_vrfiz(vector float a)
+{
+  return __builtin_altivec_vrfiz(a);
+}
+
+/* vec_unpackh */
+
+static vector short __ATTRS_o_ai
+vec_unpackh(vector signed char a)
+{
+  return __builtin_altivec_vupkhsb((vector char)a);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_unpackh(vector bool char a)
+{
+  return (vector bool short)__builtin_altivec_vupkhsb((vector char)a);
+}
+
+static vector int __ATTRS_o_ai
+vec_unpackh(vector short a)
+{
+  return __builtin_altivec_vupkhsh(a);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_unpackh(vector bool short a)
+{
+  return (vector bool int)__builtin_altivec_vupkhsh((vector short)a);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_unpackh(vector pixel a)
+{
+  return (vector unsigned int)__builtin_altivec_vupkhsh((vector short)a);
+}
+
+/* vec_vupkhsb */
+
+static vector short __ATTRS_o_ai
+vec_vupkhsb(vector signed char a)
+{
+  return __builtin_altivec_vupkhsb((vector char)a);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vupkhsb(vector bool char a)
+{
+  return (vector bool short)__builtin_altivec_vupkhsb((vector char)a);
+}
+
+/* vec_vupkhsh */
+
+static vector int __ATTRS_o_ai
+vec_vupkhsh(vector short a)
+{
+  return __builtin_altivec_vupkhsh(a);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vupkhsh(vector bool short a)
+{
+  return (vector bool int)__builtin_altivec_vupkhsh((vector short)a);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vupkhsh(vector pixel a)
+{
+  return (vector unsigned int)__builtin_altivec_vupkhsh((vector short)a);
+}
+
+/* vec_unpackl */
+
+static vector short __ATTRS_o_ai
+vec_unpackl(vector signed char a)
+{
+  return __builtin_altivec_vupklsb((vector char)a);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_unpackl(vector bool char a)
+{
+  return (vector bool short)__builtin_altivec_vupklsb((vector char)a);
+}
+
+static vector int __ATTRS_o_ai
+vec_unpackl(vector short a)
+{
+  return __builtin_altivec_vupklsh(a);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_unpackl(vector bool short a)
+{
+  return (vector bool int)__builtin_altivec_vupklsh((vector short)a);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_unpackl(vector pixel a)
+{
+  return (vector unsigned int)__builtin_altivec_vupklsh((vector short)a);
+}
+
+/* vec_vupklsb */
+
+static vector short __ATTRS_o_ai
+vec_vupklsb(vector signed char a)
+{
+  return __builtin_altivec_vupklsb((vector char)a);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vupklsb(vector bool char a)
+{
+  return (vector bool short)__builtin_altivec_vupklsb((vector char)a);
+}
+
+/* vec_vupklsh */
+
+static vector int __ATTRS_o_ai
+vec_vupklsh(vector short a)
+{
+  return __builtin_altivec_vupklsh(a);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vupklsh(vector bool short a)
+{
+  return (vector bool int)__builtin_altivec_vupklsh((vector short)a);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vupklsh(vector pixel a)
+{
+  return (vector unsigned int)__builtin_altivec_vupklsh((vector short)a);
+}
+
+/* vec_xor */
+
+#define __builtin_altivec_vxor vec_xor
+
+static vector signed char __ATTRS_o_ai
+vec_xor(vector signed char a, vector signed char b)
+{
+  return a ^ b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_xor(vector bool char a, vector signed char b)
+{
+  return (vector signed char)a ^ b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_xor(vector signed char a, vector bool char b)
+{
+  return a ^ (vector signed char)b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_xor(vector unsigned char a, vector unsigned char b)
+{
+  return a ^ b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_xor(vector bool char a, vector unsigned char b)
+{
+  return (vector unsigned char)a ^ b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_xor(vector unsigned char a, vector bool char b)
+{
+  return a ^ (vector unsigned char)b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_xor(vector bool char a, vector bool char b)
+{
+  return a ^ b;
+}
+
+static vector short __ATTRS_o_ai
+vec_xor(vector short a, vector short b)
+{
+  return a ^ b;
+}
+
+static vector short __ATTRS_o_ai
+vec_xor(vector bool short a, vector short b)
+{
+  return (vector short)a ^ b;
+}
+
+static vector short __ATTRS_o_ai
+vec_xor(vector short a, vector bool short b)
+{
+  return a ^ (vector short)b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_xor(vector unsigned short a, vector unsigned short b)
+{
+  return a ^ b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_xor(vector bool short a, vector unsigned short b)
+{
+  return (vector unsigned short)a ^ b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_xor(vector unsigned short a, vector bool short b)
+{
+  return a ^ (vector unsigned short)b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_xor(vector bool short a, vector bool short b)
+{
+  return a ^ b;
+}
+
+static vector int __ATTRS_o_ai
+vec_xor(vector int a, vector int b)
+{
+  return a ^ b;
+}
+
+static vector int __ATTRS_o_ai
+vec_xor(vector bool int a, vector int b)
+{
+  return (vector int)a ^ b;
+}
+
+static vector int __ATTRS_o_ai
+vec_xor(vector int a, vector bool int b)
+{
+  return a ^ (vector int)b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_xor(vector unsigned int a, vector unsigned int b)
+{
+  return a ^ b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_xor(vector bool int a, vector unsigned int b)
+{
+  return (vector unsigned int)a ^ b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_xor(vector unsigned int a, vector bool int b)
+{
+  return a ^ (vector unsigned int)b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_xor(vector bool int a, vector bool int b)
+{
+  return a ^ b;
+}
+
+static vector float __ATTRS_o_ai
+vec_xor(vector float a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a ^ (vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_xor(vector bool int a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a ^ (vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_xor(vector float a, vector bool int b)
+{
+  vector unsigned int res = (vector unsigned int)a ^ (vector unsigned int)b;
+  return (vector float)res;
+}
+
+/* vec_vxor */
+
+static vector signed char __ATTRS_o_ai
+vec_vxor(vector signed char a, vector signed char b)
+{
+  return a ^ b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vxor(vector bool char a, vector signed char b)
+{
+  return (vector signed char)a ^ b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vxor(vector signed char a, vector bool char b)
+{
+  return a ^ (vector signed char)b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vxor(vector unsigned char a, vector unsigned char b)
+{
+  return a ^ b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vxor(vector bool char a, vector unsigned char b)
+{
+  return (vector unsigned char)a ^ b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vxor(vector unsigned char a, vector bool char b)
+{
+  return a ^ (vector unsigned char)b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vxor(vector bool char a, vector bool char b)
+{
+  return a ^ b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vxor(vector short a, vector short b)
+{
+  return a ^ b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vxor(vector bool short a, vector short b)
+{
+  return (vector short)a ^ b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vxor(vector short a, vector bool short b)
+{
+  return a ^ (vector short)b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vxor(vector unsigned short a, vector unsigned short b)
+{
+  return a ^ b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vxor(vector bool short a, vector unsigned short b)
+{
+  return (vector unsigned short)a ^ b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vxor(vector unsigned short a, vector bool short b)
+{
+  return a ^ (vector unsigned short)b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vxor(vector bool short a, vector bool short b)
+{
+  return a ^ b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vxor(vector int a, vector int b)
+{
+  return a ^ b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vxor(vector bool int a, vector int b)
+{
+  return (vector int)a ^ b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vxor(vector int a, vector bool int b)
+{
+  return a ^ (vector int)b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vxor(vector unsigned int a, vector unsigned int b)
+{
+  return a ^ b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vxor(vector bool int a, vector unsigned int b)
+{
+  return (vector unsigned int)a ^ b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vxor(vector unsigned int a, vector bool int b)
+{
+  return a ^ (vector unsigned int)b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vxor(vector bool int a, vector bool int b)
+{
+  return a ^ b;
+}
+
+static vector float __ATTRS_o_ai
+vec_vxor(vector float a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a ^ (vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vxor(vector bool int a, vector float b)
+{
+  vector unsigned int res = (vector unsigned int)a ^ (vector unsigned int)b;
+  return (vector float)res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vxor(vector float a, vector bool int b)
+{
+  vector unsigned int res = (vector unsigned int)a ^ (vector unsigned int)b;
+  return (vector float)res;
+}
 
 /* ------------------------------ 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
+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
+static int __ATTRS_o_ai
+vec_all_eq(vector signed char a, vector bool 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
+static int __ATTRS_o_ai
+vec_all_eq(vector unsigned char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)a, (vector char)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector bool 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 bool 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 bool char a, vector bool 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
+static int __ATTRS_o_ai
+vec_all_eq(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT, a, (vector short)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
+static int __ATTRS_o_ai
+vec_all_eq(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)a, (vector short)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)a, (vector short)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector bool 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 bool short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)a, (vector short)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector pixel a, vector pixel 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
+static int __ATTRS_o_ai
+vec_all_eq(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT, a, (vector int)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
+static int __ATTRS_o_ai
+vec_all_eq(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT, (vector int)a, (vector int)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT, (vector int)a, (vector int)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector bool 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 bool int a, vector bool 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);
@@ -884,87 +8523,279 @@
 
 /* vec_all_ge */
 
-static int _ATTRS_o_ai
+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);
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ, b, a);
 }
 
-static int _ATTRS_o_ai
+static int __ATTRS_o_ai
+vec_all_ge(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ, (vector signed char)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);
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, b, a);
 }
 
-static int _ATTRS_o_ai
+static int __ATTRS_o_ai
+vec_all_ge(vector unsigned char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, (vector unsigned char)b, a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, (vector unsigned char)b, 
+                                                (vector unsigned char)a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, b, (vector unsigned char)a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, (vector unsigned char)b, 
+                                                (vector unsigned char)a);
+}
+
+static int __ATTRS_o_ai
 vec_all_ge(vector short a, vector short b)
 {
-  return __builtin_altivec_vcmpgtsh_p(__CR6_LT, b, a);
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ, b, a);
 }
 
-static int _ATTRS_o_ai
+static int __ATTRS_o_ai
+vec_all_ge(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ, (vector short)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);
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, b, a);
 }
 
-static int _ATTRS_o_ai
+static int __ATTRS_o_ai
+vec_all_ge(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, (vector unsigned short)b, a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, (vector unsigned short)b, 
+                                                (vector unsigned short)a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, b, (vector unsigned short)a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, (vector unsigned short)b, 
+                                                (vector unsigned short)a);
+}
+
+static int __ATTRS_o_ai
 vec_all_ge(vector int a, vector int b)
 {
-  return __builtin_altivec_vcmpgtsw_p(__CR6_LT, b, a);
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ, b, a);
 }
 
-static int _ATTRS_o_ai
+static int __ATTRS_o_ai
+vec_all_ge(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ, (vector int)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);
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, b, a);
 }
 
-static int _ATTRS_o_ai
+static int __ATTRS_o_ai
+vec_all_ge(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, (vector unsigned int)b, a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, (vector unsigned int)b, 
+                                                (vector unsigned int)a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, b, (vector unsigned int)a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, (vector unsigned int)b, 
+                                                (vector unsigned int)a);
+}
+
+static int __ATTRS_o_ai
 vec_all_ge(vector float a, vector float b)
 {
-  return __builtin_altivec_vcmpgtfp_p(__CR6_LT, b, a);
+  return __builtin_altivec_vcmpgefp_p(__CR6_LT, a, b);
 }
 
 /* vec_all_gt */
 
-static int _ATTRS_o_ai
+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
+static int __ATTRS_o_ai
+vec_all_gt(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT, a, (vector signed char)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
+static int __ATTRS_o_ai
+vec_all_gt(vector unsigned char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, a, (vector unsigned char)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, (vector unsigned char)a, 
+                                                (vector unsigned char)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, (vector unsigned char)a, b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, (vector unsigned char)a, 
+                                                (vector unsigned char)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
+static int __ATTRS_o_ai
+vec_all_gt(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT, a, (vector short)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
+static int __ATTRS_o_ai
+vec_all_gt(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, a, (vector unsigned short)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, (vector unsigned short)a, 
+                                                (vector unsigned short)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, (vector unsigned short)a, b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, (vector unsigned short)a, 
+                                                (vector unsigned short)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
+static int __ATTRS_o_ai
+vec_all_gt(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT, a, (vector int)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
+static int __ATTRS_o_ai
+vec_all_gt(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, a, (vector unsigned int)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, (vector unsigned int)a, 
+                                                (vector unsigned int)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, (vector unsigned int)a, b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, (vector unsigned int)a, 
+                                                (vector unsigned int)b);
+}
+
+static int __ATTRS_o_ai
 vec_all_gt(vector float a, vector float b)
 {
   return __builtin_altivec_vcmpgtfp_p(__CR6_LT, a, b);
@@ -980,87 +8811,279 @@
 
 /* vec_all_le */
 
-static int _ATTRS_o_ai
+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
+static int __ATTRS_o_ai
+vec_all_le(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ, a, (vector signed char)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
+static int __ATTRS_o_ai
+vec_all_le(vector unsigned char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, a, (vector unsigned char)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, (vector unsigned char)a, 
+                                                (vector unsigned char)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, (vector unsigned char)a, b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, (vector unsigned char)a, 
+                                                (vector unsigned char)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
+static int __ATTRS_o_ai
+vec_all_le(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ, a, (vector short)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
+static int __ATTRS_o_ai
+vec_all_le(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, a, (vector unsigned short)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, (vector unsigned short)a, 
+                                                (vector unsigned short)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, (vector unsigned short)a, b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, (vector unsigned short)a, 
+                                                (vector unsigned short)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
+static int __ATTRS_o_ai
+vec_all_le(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ, a, (vector int)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
+static int __ATTRS_o_ai
+vec_all_le(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, a, (vector unsigned int)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, (vector unsigned int)a, 
+                                                (vector unsigned int)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, (vector unsigned int)a, b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, (vector unsigned int)a, 
+                                                (vector unsigned int)b);
+}
+
+static int __ATTRS_o_ai
 vec_all_le(vector float a, vector float b)
 {
-  return __builtin_altivec_vcmpgtfp_p(__CR6_EQ, a, b);
+  return __builtin_altivec_vcmpgefp_p(__CR6_LT, b, a);
 }
 
 /* vec_all_lt */
 
-static int _ATTRS_o_ai
+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
+static int __ATTRS_o_ai
+vec_all_lt(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT, (vector signed char)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
+static int __ATTRS_o_ai
+vec_all_lt(vector unsigned char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, (vector unsigned char)b, a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, (vector unsigned char)b, 
+                                                (vector unsigned char)a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, b, (vector unsigned char)a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, (vector unsigned char)b, 
+                                                (vector unsigned char)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
+static int __ATTRS_o_ai
+vec_all_lt(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT, (vector short)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
+static int __ATTRS_o_ai
+vec_all_lt(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, (vector unsigned short)b, a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, (vector unsigned short)b, 
+                                                (vector unsigned short)a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, b, (vector unsigned short)a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, (vector unsigned short)b, 
+                                                (vector unsigned short)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
+static int __ATTRS_o_ai
+vec_all_lt(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT, (vector int)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
+static int __ATTRS_o_ai
+vec_all_lt(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, (vector unsigned int)b, a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, (vector unsigned int)b, 
+                                                (vector unsigned int)a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, b, (vector unsigned int)a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, (vector unsigned int)b, 
+                                                (vector unsigned int)a);
+}
+
+static int __ATTRS_o_ai
 vec_all_lt(vector float a, vector float b)
 {
   return __builtin_altivec_vcmpgtfp_p(__CR6_LT, b, a);
@@ -1076,43 +9099,139 @@
 
 /* vec_all_ne */
 
-static int _ATTRS_o_ai
+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
+static int __ATTRS_o_ai
+vec_all_ne(vector signed char a, vector bool 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
+static int __ATTRS_o_ai
+vec_all_ne(vector unsigned char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)a, (vector char)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector bool 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 bool 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 bool char a, vector bool 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
+static int __ATTRS_o_ai
+vec_all_ne(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ, a, (vector short)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
+static int __ATTRS_o_ai
+vec_all_ne(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)a, (vector short)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)a, (vector short)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector bool 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 bool short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)a, (vector short)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector pixel a, vector pixel 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
+static int __ATTRS_o_ai
+vec_all_ne(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ, a, (vector int)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
+static int __ATTRS_o_ai
+vec_all_ne(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ, (vector int)a, (vector int)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ, (vector int)a, (vector int)b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector bool 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 bool int a, vector bool 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);
@@ -1160,43 +9279,139 @@
 
 /* vec_any_eq */
 
-static int _ATTRS_o_ai
+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
+static int __ATTRS_o_ai
+vec_any_eq(vector signed char a, vector bool 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
+static int __ATTRS_o_ai
+vec_any_eq(vector unsigned char a, vector bool 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 bool 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 bool 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 bool char a, vector bool 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
+static int __ATTRS_o_ai
+vec_any_eq(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, a, (vector short)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
+static int __ATTRS_o_ai
+vec_any_eq(vector unsigned short a, vector bool 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 bool short a, vector 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 bool 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 bool short a, vector bool 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 pixel a, vector pixel 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
+static int __ATTRS_o_ai
+vec_any_eq(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, a, (vector int)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
+static int __ATTRS_o_ai
+vec_any_eq(vector unsigned int a, vector bool 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 bool int a, vector 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 bool 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 bool int a, vector bool 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);
@@ -1204,87 +9419,283 @@
 
 /* vec_any_ge */
 
-static int _ATTRS_o_ai
+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
+static int __ATTRS_o_ai
+vec_any_ge(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT_REV, (vector signed char)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
+static int __ATTRS_o_ai
+vec_any_ge(vector unsigned char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, (vector unsigned char)b, a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, (vector unsigned char)b, 
+                                                    (vector unsigned char)a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool char a, vector unsigned char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, b, (vector unsigned char)a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, (vector unsigned char)b, 
+                                                    (vector unsigned char)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
+static int __ATTRS_o_ai
+vec_any_ge(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT_REV, (vector short)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
+static int __ATTRS_o_ai
+vec_any_ge(vector unsigned short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, (vector unsigned short)b, a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, (vector unsigned short)b, 
+                                                    (vector unsigned short)a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool short a, vector unsigned short b)
+{
+  return 
+    __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, b, (vector unsigned short)a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, (vector unsigned short)b, 
+                                                    (vector unsigned short)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
+static int __ATTRS_o_ai
+vec_any_ge(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT_REV, (vector int)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
+static int __ATTRS_o_ai
+vec_any_ge(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, (vector unsigned int)b, a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, (vector unsigned int)b, 
+                                                    (vector unsigned int)a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, b, (vector unsigned int)a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, (vector unsigned int)b, 
+                                                    (vector unsigned int)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);
+  return __builtin_altivec_vcmpgefp_p(__CR6_EQ_REV, a, b);
 }
 
 /* vec_any_gt */
 
-static int _ATTRS_o_ai
+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
+static int __ATTRS_o_ai
+vec_any_gt(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ_REV, a, (vector signed char)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
+static int __ATTRS_o_ai
+vec_any_gt(vector unsigned char a, vector bool char b)
+{
+  return 
+    __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, a, (vector unsigned char)b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, (vector unsigned char)a,
+                                                    (vector unsigned char)b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool char a, vector unsigned char b)
+{
+  return 
+    __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, (vector unsigned char)a, b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, (vector unsigned char)a,
+                                                    (vector unsigned char)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
+static int __ATTRS_o_ai
+vec_any_gt(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ_REV, a, (vector short)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
+static int __ATTRS_o_ai
+vec_any_gt(vector unsigned short a, vector bool short b)
+{
+  return 
+    __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, a, (vector unsigned short)b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, (vector unsigned short)a,
+                                                    (vector unsigned short)b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool short a, vector unsigned short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, (vector unsigned short)a, b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, (vector unsigned short)a, 
+                                                    (vector unsigned short)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
+static int __ATTRS_o_ai
+vec_any_gt(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ_REV, a, (vector int)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
+static int __ATTRS_o_ai
+vec_any_gt(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, a, (vector unsigned int)b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, (vector unsigned int)a,
+                                                    (vector unsigned int)b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, (vector unsigned int)a, b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, (vector unsigned int)a,
+                                                    (vector unsigned int)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);
@@ -1292,87 +9703,287 @@
 
 /* vec_any_le */
 
-static int _ATTRS_o_ai
+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
+static int __ATTRS_o_ai
+vec_any_le(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT_REV, a, (vector signed char)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
+static int __ATTRS_o_ai
+vec_any_le(vector unsigned char a, vector bool char b)
+{
+  return 
+    __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, a, (vector unsigned char)b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, (vector unsigned char)a,
+                                                    (vector unsigned char)b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool char a, vector unsigned char b)
+{
+  return 
+    __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, (vector unsigned char)a, b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, (vector unsigned char)a,
+                                                    (vector unsigned char)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
+static int __ATTRS_o_ai
+vec_any_le(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT_REV, a, (vector short)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
+static int __ATTRS_o_ai
+vec_any_le(vector unsigned short a, vector bool short b)
+{
+  return 
+    __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, a, (vector unsigned short)b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, (vector unsigned short)a,
+                                                    (vector unsigned short)b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool short a, vector unsigned short b)
+{
+  return 
+    __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, (vector unsigned short)a, b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, (vector unsigned short)a,
+                                                    (vector unsigned short)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
+static int __ATTRS_o_ai
+vec_any_le(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT_REV, a, (vector int)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
+static int __ATTRS_o_ai
+vec_any_le(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, a, (vector unsigned int)b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, (vector unsigned int)a,
+                                                    (vector unsigned int)b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, (vector unsigned int)a, b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, (vector unsigned int)a,
+                                                    (vector unsigned int)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);
+  return __builtin_altivec_vcmpgefp_p(__CR6_EQ_REV, b, a);
 }
 
 /* vec_any_lt */
 
-static int _ATTRS_o_ai
+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
+static int __ATTRS_o_ai
+vec_any_lt(vector signed char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ_REV, (vector signed char)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
+static int __ATTRS_o_ai
+vec_any_lt(vector unsigned char a, vector bool char b)
+{
+  return 
+    __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, (vector unsigned char)b, a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool char a, vector signed char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, (vector unsigned char)b,
+                                                    (vector unsigned char)a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool char a, vector unsigned char b)
+{
+  return 
+    __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, b, (vector unsigned char)a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool char a, vector bool char b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, (vector unsigned char)b,
+                                                    (vector unsigned char)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
+static int __ATTRS_o_ai
+vec_any_lt(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ_REV, (vector short)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
+static int __ATTRS_o_ai
+vec_any_lt(vector unsigned short a, vector bool short b)
+{
+  return 
+    __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, (vector unsigned short)b, a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool short a, vector short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, (vector unsigned short)b,
+                                                    (vector unsigned short)a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool short a, vector unsigned short b)
+{
+  return 
+    __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, b, (vector unsigned short)a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, (vector unsigned short)b,
+                                                    (vector unsigned short)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
+static int __ATTRS_o_ai
+vec_any_lt(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ_REV, (vector int)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
+static int __ATTRS_o_ai
+vec_any_lt(vector unsigned int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, (vector unsigned int)b, a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool int a, vector int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, (vector unsigned int)b,
+                                                    (vector unsigned int)a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool int a, vector unsigned int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, b, (vector unsigned int)a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, (vector unsigned int)b,
+                                                    (vector unsigned int)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);
@@ -1388,43 +9999,139 @@
 
 /* vec_any_ne */
 
-static int _ATTRS_o_ai
+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
+static int __ATTRS_o_ai
+vec_any_ne(vector signed char a, vector bool 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
+static int __ATTRS_o_ai
+vec_any_ne(vector unsigned char a, vector bool 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 bool 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 bool 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 bool char a, vector bool 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
+static int __ATTRS_o_ai
+vec_any_ne(vector short a, vector bool short b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT_REV, a, (vector short)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
+static int __ATTRS_o_ai
+vec_any_ne(vector unsigned short a, vector bool 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 bool short a, vector 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 bool 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 bool short a, vector bool 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 pixel a, vector pixel 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
+static int __ATTRS_o_ai
+vec_any_ne(vector int a, vector bool int b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT_REV, a, (vector int)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
+static int __ATTRS_o_ai
+vec_any_ne(vector unsigned int a, vector bool 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 bool int a, vector 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 bool 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 bool int a, vector bool 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);
@@ -1478,6 +10185,6 @@
   return __builtin_altivec_vcmpbfp_p(__CR6_EQ_REV, a, b);
 }
 
-#undef _ATTRS_o_ai
+#undef __ATTRS_o_ai
 
 #endif /* __ALTIVEC_H */
diff --git a/lib/Headers/avxintrin.h b/lib/Headers/avxintrin.h
new file mode 100644
index 0000000..884d31c
--- /dev/null
+++ b/lib/Headers/avxintrin.h
@@ -0,0 +1,1156 @@
+/*===---- avxintrin.h - AVX 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 __IMMINTRIN_H
+#error "Never use <avxintrin.h> directly; include <immintrin.h> instead."
+#endif
+
+typedef double __v4df __attribute__ ((__vector_size__ (32)));
+typedef float __v8sf __attribute__ ((__vector_size__ (32)));
+typedef long long __v4di __attribute__ ((__vector_size__ (32)));
+typedef int __v8si __attribute__ ((__vector_size__ (32)));
+typedef short __v16hi __attribute__ ((__vector_size__ (32)));
+typedef char __v32qi __attribute__ ((__vector_size__ (32)));
+
+typedef float __m256 __attribute__ ((__vector_size__ (32)));
+typedef double __m256d __attribute__((__vector_size__(32)));
+typedef long long __m256i __attribute__((__vector_size__(32)));
+
+/* Arithmetic */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_add_pd(__m256d a, __m256d b)
+{
+  return a+b;
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_add_ps(__m256 a, __m256 b)
+{
+  return a+b;
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_sub_pd(__m256d a, __m256d b)
+{
+  return a-b;
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_sub_ps(__m256 a, __m256 b)
+{
+  return a-b;
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_addsub_pd(__m256d a, __m256d b)
+{
+  return (__m256d)__builtin_ia32_addsubpd256((__v4df)a, (__v4df)b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_addsub_ps(__m256 a, __m256 b)
+{
+  return (__m256)__builtin_ia32_addsubps256((__v8sf)a, (__v8sf)b);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_div_pd(__m256d a, __m256d b)
+{
+  return a / b;
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_div_ps(__m256 a, __m256 b)
+{
+  return a / b;
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_max_pd(__m256d a, __m256d b)
+{
+  return (__m256d)__builtin_ia32_maxpd256((__v4df)a, (__v4df)b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_max_ps(__m256 a, __m256 b)
+{
+  return (__m256)__builtin_ia32_maxps256((__v8sf)a, (__v8sf)b);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_min_pd(__m256d a, __m256d b)
+{
+  return (__m256d)__builtin_ia32_minpd256((__v4df)a, (__v4df)b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_min_ps(__m256 a, __m256 b)
+{
+  return (__m256)__builtin_ia32_minps256((__v8sf)a, (__v8sf)b);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_mul_pd(__m256d a, __m256d b)
+{
+  return a * b;
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_mul_ps(__m256 a, __m256 b)
+{
+  return a * b;
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_sqrt_pd(__m256d a)
+{
+  return (__m256d)__builtin_ia32_sqrtpd256((__v4df)a);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_sqrt_ps(__m256 a)
+{
+  return (__m256)__builtin_ia32_sqrtps256((__v8sf)a);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_rsqrt_ps(__m256 a)
+{
+  return (__m256)__builtin_ia32_rsqrtps256((__v8sf)a);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_rcp_ps(__m256 a)
+{
+  return (__m256)__builtin_ia32_rcpps256((__v8sf)a);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_round_pd(__m256d v, const int m)
+{
+  return (__m256d)__builtin_ia32_roundpd256((__v4df)v, m);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_round_ps(__m256 v, const int m)
+{
+  return (__m256)__builtin_ia32_roundps256((__v8sf)v, m);
+}
+
+#define _mm256_ceil_pd(V)  _mm256_round_pd((V), _MM_FROUND_CEIL)
+#define _mm256_floor_pd(V) _mm256_round_pd((V), _MM_FROUND_FLOOR)
+#define _mm256_ceil_ps(V)  _mm256_round_ps((V), _MM_FROUND_CEIL)
+#define _mm256_floor_ps(V) _mm256_round_ps((V), _MM_FROUND_FLOOR)
+
+/* Logical */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_and_pd(__m256d a, __m256d b)
+{
+  return (__m256d)((__v4di)a & (__v4di)b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_and_ps(__m256 a, __m256 b)
+{
+  return (__m256)((__v8si)a & (__v8si)b);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_andnot_pd(__m256d a, __m256d b)
+{
+  return (__m256d)(~(__v4di)a & (__v4di)b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_andnot_ps(__m256 a, __m256 b)
+{
+  return (__m256)(~(__v8si)a & (__v8si)b);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_or_pd(__m256d a, __m256d b)
+{
+  return (__m256d)((__v4di)a | (__v4di)b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_or_ps(__m256 a, __m256 b)
+{
+  return (__m256)((__v8si)a | (__v8si)b);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_xor_pd(__m256d a, __m256d b)
+{
+  return (__m256d)((__v4di)a ^ (__v4di)b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_xor_ps(__m256 a, __m256 b)
+{
+  return (__m256)((__v8si)a ^ (__v8si)b);
+}
+
+/* Horizontal arithmetic */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_hadd_pd(__m256d a, __m256d b)
+{
+  return (__m256d)__builtin_ia32_haddpd256((__v4df)a, (__v4df)b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_hadd_ps(__m256 a, __m256 b)
+{
+  return (__m256)__builtin_ia32_haddps256((__v8sf)a, (__v8sf)b);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_hsub_pd(__m256d a, __m256d b)
+{
+  return (__m256d)__builtin_ia32_hsubpd256((__v4df)a, (__v4df)b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_hsub_ps(__m256 a, __m256 b)
+{
+  return (__m256)__builtin_ia32_hsubps256((__v8sf)a, (__v8sf)b);
+}
+
+/* Vector permutations */
+static __inline __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_permutevar_pd(__m128d a, __m128i c)
+{
+  return (__m128d)__builtin_ia32_vpermilvarpd((__v2df)a, (__v2di)c);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_permutevar_pd(__m256d a, __m256i c)
+{
+  return (__m256d)__builtin_ia32_vpermilvarpd256((__v4df)a, (__v4di)c);
+}
+
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_permutevar_ps(__m128 a, __m128i c)
+{
+  return (__m128)__builtin_ia32_vpermilvarps((__v4sf)a, (__v4si)c);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_permutevar_ps(__m256 a, __m256i c)
+{
+  return (__m256)__builtin_ia32_vpermilvarps256((__v8sf)a,
+						  (__v8si)c);
+}
+
+static __inline __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_permute_pd(__m128d a, const int c)
+{
+  return (__m128d)__builtin_ia32_vpermilpd((__v2df)a, c);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_permute_pd(__m256d a, const int c)
+{
+  return (__m256d)__builtin_ia32_vpermilpd256((__v4df)a, c);
+}
+
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_permute_ps(__m128 a, const int c)
+{
+  return (__m128)__builtin_ia32_vpermilps((__v4sf)a, c);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_permute_ps(__m256 a, const int c)
+{
+  return (__m256)__builtin_ia32_vpermilps256((__v8sf)a, c);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_permute2f128_pd(__m256d a, __m256d b, const int c)
+{
+  return (__m256d)__builtin_ia32_vperm2f128_pd256((__v4df)a, (__v4df)b, c);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_permute2f128_ps(__m256 a, __m256 b, const int c)
+{
+  return (__m256)__builtin_ia32_vperm2f128_ps256((__v8sf)a, (__v8sf)b, c);
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_permute2f128_si256(__m256i a, __m256i b, const int c)
+{
+  return (__m256i)__builtin_ia32_vperm2f128_si256((__v8si)a, (__v8si)b, c);
+}
+
+/* Vector Blend */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_blend_pd(__m256d a, __m256d b, const int c)
+{
+  return (__m256d)__builtin_ia32_blendpd256((__v4df)a, (__v4df)b, c);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_blend_ps(__m256 a, __m256 b, const int c)
+{
+  return (__m256)__builtin_ia32_blendps256((__v8sf)a, (__v8sf)b, c);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_blendv_pd(__m256d a, __m256d b, __m256d c)
+{
+  return (__m256d)__builtin_ia32_blendvpd256((__v4df)a, (__v4df)b, (__v4df)c);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_blendv_ps(__m256 a, __m256 b, __m256 c)
+{
+  return (__m256)__builtin_ia32_blendvps256((__v8sf)a, (__v8sf)b, (__v8sf)c);
+}
+
+/* Vector Dot Product */
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_dp_ps(__m256 a, __m256 b, const int c)
+{
+  return (__m256)__builtin_ia32_dpps256((__v8sf)a, (__v8sf)b, c);
+}
+
+/* Vector shuffle */
+#define _mm256_shuffle_ps(a, b, mask) \
+        (__builtin_shufflevector((__v8sf)(a), (__v8sf)(b), \
+        (mask) & 0x3,                ((mask) & 0xc) >> 2, \
+        (((mask) & 0x30) >> 4) + 8,  (((mask) & 0xc0) >> 6) + 8, \
+        (mask) & 0x3 + 4,            (((mask) & 0xc) >> 2) + 4, \
+        (((mask) & 0x30) >> 4) + 12, (((mask) & 0xc0) >> 6) + 12))
+
+#define _mm256_shuffle_pd(a, b, mask) \
+        (__builtin_shufflevector((__v4df)(a), (__v4df)(b), \
+        (mask) & 0x1, \
+        (((mask) & 0x2) >> 1) + 4, \
+        (((mask) & 0x4) >> 2) + 2, \
+        (((mask) & 0x8) >> 3) + 6))
+
+/* Compare */
+#define _CMP_EQ_OQ    0x00 /* Equal (ordered, non-signaling)  */
+#define _CMP_LT_OS    0x01 /* Less-than (ordered, signaling)  */
+#define _CMP_LE_OS    0x02 /* Less-than-or-equal (ordered, signaling)  */
+#define _CMP_UNORD_Q  0x03 /* Unordered (non-signaling)  */
+#define _CMP_NEQ_UQ   0x04 /* Not-equal (unordered, non-signaling)  */
+#define _CMP_NLT_US   0x05 /* Not-less-than (unordered, signaling)  */
+#define _CMP_NLE_US   0x06 /* Not-less-than-or-equal (unordered, signaling)  */
+#define _CMP_ORD_Q    0x07 /* Ordered (nonsignaling)   */
+#define _CMP_EQ_UQ    0x08 /* Equal (unordered, non-signaling)  */
+#define _CMP_NGE_US   0x09 /* Not-greater-than-or-equal (unord, signaling)  */
+#define _CMP_NGT_US   0x0a /* Not-greater-than (unordered, signaling)  */
+#define _CMP_FALSE_OQ 0x0b /* False (ordered, non-signaling)  */
+#define _CMP_NEQ_OQ   0x0c /* Not-equal (ordered, non-signaling)  */
+#define _CMP_GE_OS    0x0d /* Greater-than-or-equal (ordered, signaling)  */
+#define _CMP_GT_OS    0x0e /* Greater-than (ordered, signaling)  */
+#define _CMP_TRUE_UQ  0x0f /* True (unordered, non-signaling)  */
+#define _CMP_EQ_OS    0x10 /* Equal (ordered, signaling)  */
+#define _CMP_LT_OQ    0x11 /* Less-than (ordered, non-signaling)  */
+#define _CMP_LE_OQ    0x12 /* Less-than-or-equal (ordered, non-signaling)  */
+#define _CMP_UNORD_S  0x13 /* Unordered (signaling)  */
+#define _CMP_NEQ_US   0x14 /* Not-equal (unordered, signaling)  */
+#define _CMP_NLT_UQ   0x15 /* Not-less-than (unordered, non-signaling)  */
+#define _CMP_NLE_UQ   0x16 /* Not-less-than-or-equal (unord, non-signaling)  */
+#define _CMP_ORD_S    0x17 /* Ordered (signaling)  */
+#define _CMP_EQ_US    0x18 /* Equal (unordered, signaling)  */
+#define _CMP_NGE_UQ   0x19 /* Not-greater-than-or-equal (unord, non-sign)  */
+#define _CMP_NGT_UQ   0x1a /* Not-greater-than (unordered, non-signaling)  */
+#define _CMP_FALSE_OS 0x1b /* False (ordered, signaling)  */
+#define _CMP_NEQ_OS   0x1c /* Not-equal (ordered, signaling)  */
+#define _CMP_GE_OQ    0x1d /* Greater-than-or-equal (ordered, non-signaling)  */
+#define _CMP_GT_OQ    0x1e /* Greater-than (ordered, non-signaling)  */
+#define _CMP_TRUE_US  0x1f /* True (unordered, signaling)  */
+
+static __inline __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmp_pd(__m128d a, __m128d b, const int c)
+{
+  return (__m128d)__builtin_ia32_cmppd((__v2df)a, (__v2df)b, c);
+}
+
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmp_ps(__m128 a, __m128 b, const int c)
+{
+  return (__m128)__builtin_ia32_cmpps((__v4sf)a, (__v4sf)b, c);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_cmp_pd(__m256d a, __m256d b, const int c)
+{
+  return (__m256d)__builtin_ia32_cmppd256((__v4df)a, (__v4df)b, c);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_cmp_ps(__m256 a, __m256 b, const int c)
+{
+  return (__m256)__builtin_ia32_cmpps256((__v8sf)a, (__v8sf)b, c);
+}
+
+static __inline __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmp_sd(__m128d a, __m128d b, const int c)
+{
+  return (__m128d)__builtin_ia32_cmpsd((__v2df)a, (__v2df)b, c);
+}
+
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmp_ss(__m128 a, __m128 b, const int c)
+{
+  return (__m128)__builtin_ia32_cmpss((__v4sf)a, (__v4sf)b, c);
+}
+
+/* Vector extract */
+static __inline __m128d __attribute__((__always_inline__, __nodebug__))
+_mm256_extractf128_pd(__m256d a, const int o)
+{
+  return (__m128d)__builtin_ia32_vextractf128_pd256((__v4df)a, o);
+}
+
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm256_extractf128_ps(__m256 a, const int o)
+{
+  return (__m128)__builtin_ia32_vextractf128_ps256((__v8sf)a, o);
+}
+
+static __inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm256_extractf128_si256(__m256i a, const int o)
+{
+  return (__m128i)__builtin_ia32_vextractf128_si256((__v8si)a, o);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_extract_epi32(__m256i a, int const imm)
+{
+  __v8si b = (__v8si)a;
+  return b[imm];
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_extract_epi16(__m256i a, int const imm)
+{
+  __v16hi b = (__v16hi)a;
+  return b[imm];
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_extract_epi8(__m256i a, int const imm)
+{
+  __v32qi b = (__v32qi)a;
+  return b[imm];
+}
+
+#ifdef __x86_64__
+static __inline long long  __attribute__((__always_inline__, __nodebug__))
+_mm256_extract_epi64(__m256i a, const int imm)
+{
+  __v4di b = (__v4di)a;
+  return b[imm];
+}
+#endif
+
+/* Vector insert */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_insertf128_pd(__m256d a, __m128d b, const int o)
+{
+  return (__m256d)__builtin_ia32_vinsertf128_pd256((__v4df)a, (__v2df)b, o);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_insertf128_ps(__m256 a, __m128 b, const int o)
+{
+  return (__m256)__builtin_ia32_vinsertf128_ps256((__v8sf)a, (__v4sf)b, o);
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_insertf128_si256(__m256i a, __m128i b, const int o)
+{
+  return (__m256i)__builtin_ia32_vinsertf128_si256((__v8si)a, (__v4si)b, o);
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_insert_epi32(__m256i a, int b, int const imm)
+{
+  __v8si c = (__v8si)a;
+  c[imm & 7] = b;
+  return (__m256i)c;
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_insert_epi16(__m256i a, int b, int const imm)
+{
+  __v16hi c = (__v16hi)a;
+  c[imm & 15] = b;
+  return (__m256i)c;
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_insert_epi8(__m256i a, int b, int const imm)
+{
+  __v32qi c = (__v32qi)a;
+  c[imm & 31] = b;
+  return (__m256i)c;
+}
+
+#ifdef __x86_64__
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_insert_epi64(__m256i a, int b, int const imm)
+{
+  __v4di c = (__v4di)a;
+  c[imm & 3] = b;
+  return (__m256i)c;
+}
+#endif
+
+/* Conversion */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepi32_pd(__m128i a)
+{
+  return (__m256d)__builtin_ia32_cvtdq2pd256((__v4si) a);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepi32_ps(__m256i a)
+{
+  return (__m256)__builtin_ia32_cvtdq2ps256((__v8si) a);
+}
+
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtpd_ps(__m256d a)
+{
+  return (__m128)__builtin_ia32_cvtpd2ps256((__v4df) a);
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtps_epi32(__m256 a)
+{
+  return (__m256i)__builtin_ia32_cvtps2dq256((__v8sf) a);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtps_pd(__m128 a)
+{
+  return (__m256d)__builtin_ia32_cvtps2pd256((__v4sf) a);
+}
+
+static __inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvttpd_epi32(__m256d a)
+{
+  return (__m128i)__builtin_ia32_cvttpd2dq256((__v4df) a);
+}
+
+static __inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtpd_epi32(__m256d a)
+{
+  return (__m128i)__builtin_ia32_cvtpd2dq256((__v4df) a);
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvttps_epi32(__m256 a)
+{
+  return (__m256i)__builtin_ia32_cvttps2dq256((__v8sf) a);
+}
+
+/* Vector replicate */
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_movehdup_ps(__m256 a)
+{
+  return __builtin_shufflevector(a, a, 1, 1, 3, 3, 5, 5, 7, 7);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_moveldup_ps(__m256 a)
+{
+  return __builtin_shufflevector(a, a, 0, 0, 2, 2, 4, 4, 6, 6);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_movedup_pd(__m256d a)
+{
+  return __builtin_shufflevector(a, a, 0, 0, 2, 2);
+}
+
+/* Unpack and Interleave */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_unpackhi_pd(__m256d a, __m256d b)
+{
+  return __builtin_shufflevector(a, b, 1, 5, 1+2, 5+2);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_unpacklo_pd(__m256d a, __m256d b)
+{
+  return __builtin_shufflevector(a, b, 0, 4, 0+2, 4+2);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_unpackhi_ps(__m256 a, __m256 b)
+{
+  return __builtin_shufflevector(a, b, 2, 10, 2+1, 10+1, 6, 14, 6+1, 14+1);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_unpacklo_ps(__m256 a, __m256 b)
+{
+  return __builtin_shufflevector(a, b, 0, 8, 0+1, 8+1, 4, 12, 4+1, 12+1);
+}
+
+/* Bit Test */
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm_testz_pd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_vtestzpd((__v2df)a, (__v2df)b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm_testc_pd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_vtestcpd((__v2df)a, (__v2df)b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm_testnzc_pd(__m128d a, __m128d b)
+{
+  return __builtin_ia32_vtestnzcpd((__v2df)a, (__v2df)b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm_testz_ps(__m128 a, __m128 b)
+{
+  return __builtin_ia32_vtestzps((__v4sf)a, (__v4sf)b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm_testc_ps(__m128 a, __m128 b)
+{
+  return __builtin_ia32_vtestcps((__v4sf)a, (__v4sf)b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm_testnzc_ps(__m128 a, __m128 b)
+{
+  return __builtin_ia32_vtestnzcps((__v4sf)a, (__v4sf)b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testz_pd(__m256d a, __m256d b)
+{
+  return __builtin_ia32_vtestzpd256((__v4df)a, (__v4df)b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testc_pd(__m256d a, __m256d b)
+{
+  return __builtin_ia32_vtestcpd256((__v4df)a, (__v4df)b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testnzc_pd(__m256d a, __m256d b)
+{
+  return __builtin_ia32_vtestnzcpd256((__v4df)a, (__v4df)b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testz_ps(__m256 a, __m256 b)
+{
+  return __builtin_ia32_vtestzps256((__v8sf)a, (__v8sf)b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testc_ps(__m256 a, __m256 b)
+{
+  return __builtin_ia32_vtestcps256((__v8sf)a, (__v8sf)b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testnzc_ps(__m256 a, __m256 b)
+{
+  return __builtin_ia32_vtestnzcps256((__v8sf)a, (__v8sf)b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testz_si256(__m256i a, __m256i b)
+{
+  return __builtin_ia32_ptestz256((__v4di)a, (__v4di)b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testc_si256(__m256i a, __m256i b)
+{
+  return __builtin_ia32_ptestc256((__v4di)a, (__v4di)b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testnzc_si256(__m256i a, __m256i b)
+{
+  return __builtin_ia32_ptestnzc256((__v4di)a, (__v4di)b);
+}
+
+/* Vector extract sign mask */
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_movemask_pd(__m256d a)
+{
+  return __builtin_ia32_movmskpd256((__v4df)a);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_movemask_ps(__m256 a)
+{
+  return __builtin_ia32_movmskps256((__v8sf)a);
+}
+
+/* Vector zero */
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_zeroall(void)
+{
+  __builtin_ia32_vzeroall();
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_zeroupper(void)
+{
+  __builtin_ia32_vzeroupper();
+}
+
+/* Vector load with broadcast */
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_broadcast_ss(float const *a)
+{
+  return (__m128)__builtin_ia32_vbroadcastss(a);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcast_sd(double const *a)
+{
+  return (__m256d)__builtin_ia32_vbroadcastsd256(a);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcast_ss(float const *a)
+{
+  return (__m256)__builtin_ia32_vbroadcastss256(a);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcast_pd(__m128d const *a)
+{
+  return (__m256d)__builtin_ia32_vbroadcastf128_pd256(a);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcast_ps(__m128 const *a)
+{
+  return (__m256)__builtin_ia32_vbroadcastf128_ps256(a);
+}
+
+/* SIMD load ops */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_load_pd(double const *p)
+{
+  return *(__m256d *)p;
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_load_ps(float const *p)
+{
+  return *(__m256 *)p;
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_loadu_pd(double const *p)
+{
+  return (__m256d)__builtin_ia32_loadupd256(p);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_loadu_ps(float const *p)
+{
+  return (__m256)__builtin_ia32_loadups256(p);
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_load_si256(__m256i const *p)
+{
+  return *p;
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_loadu_si256(__m256i const *p)
+{
+  return (__m256i)__builtin_ia32_loaddqu256((char const *)p);
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_lddqu_si256(__m256i const *p)
+{
+  return (__m256i)__builtin_ia32_lddqu256((char const *)p);
+}
+
+/* SIMD store ops */
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_store_pd(double *p, __m256d a)
+{
+  *(__m256d *)p = a;
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_store_ps(float *p, __m256 a)
+{
+  *(__m256 *)p = a;
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_storeu_pd(double *p, __m256d a)
+{
+  __builtin_ia32_storeupd256(p, (__v4df)a);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_storeu_ps(float *p, __m256 a)
+{
+  __builtin_ia32_storeups256(p, (__v8sf)a);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_store_si256(__m256i *p, __m256i a)
+{
+  *p = a;
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_storeu_si256(__m256i *p, __m256i a)
+{
+  __builtin_ia32_storedqu256((char *)p, (__v32qi)a);
+}
+
+/* Conditional load ops */
+static __inline __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_maskload_pd(double const *p, __m128d m)
+{
+  return (__m128d)__builtin_ia32_maskloadpd((const __v2df *)p, (__v2df)m);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_maskload_pd(double const *p, __m256d m)
+{
+  return (__m256d)__builtin_ia32_maskloadpd256((const __v4df *)p, (__v4df)m);
+}
+
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_maskload_ps(float const *p, __m128 m)
+{
+  return (__m128)__builtin_ia32_maskloadps((const __v4sf *)p, (__v4sf)m);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_maskload_ps(float const *p, __m256 m)
+{
+  return (__m256)__builtin_ia32_maskloadps256((const __v8sf *)p, (__v8sf)m);
+}
+
+/* Conditional store ops */
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_maskstore_ps(float *p, __m256 m, __m256 a)
+{
+  __builtin_ia32_maskstoreps256((__v8sf *)p, (__v8sf)m, (__v8sf)a);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm_maskstore_pd(double *p, __m128d m, __m128d a)
+{
+  __builtin_ia32_maskstorepd((__v2df *)p, (__v2df)m, (__v2df)a);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_maskstore_pd(double *p, __m256d m, __m256d a)
+{
+  __builtin_ia32_maskstorepd256((__v4df *)p, (__v4df)m, (__v4df)a);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm_maskstore_ps(float *p, __m128 m, __m128 a)
+{
+  __builtin_ia32_maskstoreps((__v4sf *)p, (__v4sf)m, (__v4sf)a);
+}
+
+/* Cacheability support ops */
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_stream_si256(__m256i *a, __m256i b)
+{
+  __builtin_ia32_movntdq256((__v4di *)a, (__v4di)b);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_stream_pd(double *a, __m256d b)
+{
+  __builtin_ia32_movntpd256(a, (__v4df)b);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_stream_ps(float *p, __m256 a)
+{
+  __builtin_ia32_movntps256(p, (__v8sf)a);
+}
+
+/* Create vectors */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_set_pd(double a, double b, double c, double d)
+{
+  return (__m256d){ d, c, b, a };
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_set_ps(float a, float b, float c, float d,
+	            float e, float f, float g, float h)
+{
+  return (__m256){ h, g, f, e, d, c, b, a };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set_epi32(int i0, int i1, int i2, int i3,
+		             int i4, int i5, int i6, int i7)
+{
+  return (__m256i)(__v8si){ i7, i6, i5, i4, i3, i2, i1, i0 };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set_epi16(short w15, short w14, short w13, short w12,
+		             short w11, short w10, short w09, short w08,
+		             short w07, short w06, short w05, short w04,
+		             short w03, short w02, short w01, short w00)
+{
+  return (__m256i)(__v16hi){ w00, w01, w02, w03, w04, w05, w06, w07,
+                             w08, w09, w10, w11, w12, w13, w14, w15 };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set_epi8(char b31, char b30, char b29, char b28,
+		            char b27, char b26, char b25, char b24,
+		            char b23, char b22, char b21, char b20,
+		            char b19, char b18, char b17, char b16,
+		            char b15, char b14, char b13, char b12,
+		            char b11, char b10, char b09, char b08,
+		            char b07, char b06, char b05, char b04,
+		            char b03, char b02, char b01, char b00)
+{
+  return (__m256i)(__v32qi){
+    b00, b01, b02, b03, b04, b05, b06, b07,
+    b08, b09, b10, b11, b12, b13, b14, b15,
+    b16, b17, b18, b19, b20, b21, b22, b23,
+    b24, b25, b26, b27, b28, b29, b30, b31
+  };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set_epi64x(long long a, long long b, long long c, long long d)
+{
+  return (__m256i)(__v4di){ d, c, b, a };
+}
+
+/* Create vectors with elements in reverse order */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_setr_pd(double a, double b, double c, double d)
+{
+  return (__m256d){ a, b, c, d };
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_setr_ps(float a, float b, float c, float d,
+		           float e, float f, float g, float h)
+{
+  return (__m256){ a, b, c, d, e, f, g, h };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_setr_epi32(int i0, int i1, int i2, int i3,
+		              int i4, int i5, int i6, int i7)
+{
+  return (__m256i)(__v8si){ i0, i1, i2, i3, i4, i5, i6, i7 };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_setr_epi16(short w15, short w14, short w13, short w12,
+		   short w11, short w10, short w09, short w08,
+		   short w07, short w06, short w05, short w04,
+		   short w03, short w02, short w01, short w00)
+{
+  return (__m256i)(__v16hi){ w15, w14, w13, w12, w11, w10, w09, w08,
+			                       w07, w06, w05, w04, w03, w02, w01, w00 };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_setr_epi8(char b31, char b30, char b29, char b28,
+		             char b27, char b26, char b25, char b24,
+		             char b23, char b22, char b21, char b20,
+		             char b19, char b18, char b17, char b16,
+		             char b15, char b14, char b13, char b12,
+		             char b11, char b10, char b09, char b08,
+		             char b07, char b06, char b05, char b04,
+		             char b03, char b02, char b01, char b00)
+{
+  return (__m256i)(__v32qi){
+    b31, b30, b29, b28, b27, b26, b25, b24,
+		b23, b22, b21, b20, b19, b18, b17, b16,
+		b15, b14, b13, b12, b11, b10, b09, b08,
+		b07, b06, b05, b04, b03, b02, b01, b00 };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_setr_epi64x(long long a, long long b, long long c, long long d)
+{
+  return (__m256i)(__v4di){ a, b, c, d };
+}
+
+/* Create vectors with repeated elements */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_set1_pd(double w)
+{
+  return (__m256d){ w, w, w, w };
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_set1_ps(float w)
+{
+  return (__m256){ w, w, w, w, w, w, w, w };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set1_epi32(int i)
+{
+  return (__m256i)(__v8si){ i, i, i, i, i, i, i, i };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set1_epi16(short w)
+{
+  return (__m256i)(__v16hi){ w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set1_epi8(char b)
+{
+  return (__m256i)(__v32qi){ b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b,
+                             b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set1_epi64x(long long q)
+{
+  return (__m256i)(__v4di){ q, q, q, q };
+}
+
+/* Create zeroed vectors */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_setzero_pd(void)
+{
+  return (__m256d){ 0, 0, 0, 0 };
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_setzero_ps(void)
+{
+  return (__m256){ 0, 0, 0, 0, 0, 0, 0, 0 };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_setzero_si256(void)
+{
+  return (__m256i){ 0LL, 0LL, 0LL, 0LL };
+}
+
+/* Cast between vector types */
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_castpd_ps(__m256d in)
+{
+  return (__m256)in;
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_castpd_si256(__m256d in)
+{
+  return (__m256i)in;
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_castps_pd(__m256 in)
+{
+  return (__m256d)in;
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_castps_si256(__m256 in)
+{
+  return (__m256i)in;
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_castsi256_ps(__m256i in)
+{
+  return (__m256)in;
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_castsi256_pd(__m256i in)
+{
+  return (__m256d)in;
+}
+
+static __inline __m128d __attribute__((__always_inline__, __nodebug__))
+_mm256_castpd256_pd128(__m256d in)
+{
+  return __builtin_shufflevector(in, in, 0, 1);
+}
+
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm256_castps256_ps128(__m256 in)
+{
+  return __builtin_shufflevector(in, in, 0, 1, 2, 3);
+}
+
+static __inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm256_castsi256_si128(__m256i in)
+{
+  return __builtin_shufflevector(in, in, 0, 1);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_castpd128_pd256(__m128d in)
+{
+  __m128d zero = _mm_setzero_pd();
+  return __builtin_shufflevector(in, zero, 0, 1, 2, 2);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_castps128_ps256(__m128 in)
+{
+  __m128 zero = _mm_setzero_ps();
+  return __builtin_shufflevector(in, zero, 0, 1, 2, 3, 4, 4, 4, 4);
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_castsi128_si256(__m128i in)
+{
+  __m128i zero = _mm_setzero_si128();
+  return __builtin_shufflevector(in, zero, 0, 1, 2, 2);
+}
diff --git a/lib/Headers/emmintrin.h b/lib/Headers/emmintrin.h
index 6b9dd2a..e5dfe26 100644
--- a/lib/Headers/emmintrin.h
+++ b/lib/Headers/emmintrin.h
@@ -1,4 +1,4 @@
-/*===---- xmmintrin.h - SSE intrinsics -------------------------------------===
+/*===---- emmintrin.h - SSE2 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
@@ -20,7 +20,7 @@
  *
  *===-----------------------------------------------------------------------===
  */
- 
+
 #ifndef __EMMINTRIN_H
 #define __EMMINTRIN_H
 
@@ -33,6 +33,9 @@
 typedef double __m128d __attribute__((__vector_size__(16)));
 typedef long long __m128i __attribute__((__vector_size__(16)));
 
+/* Type defines.  */
+typedef double __v2df __attribute__ ((__vector_size__ (16)));
+typedef long long __v2di __attribute__ ((__vector_size__ (16)));
 typedef short __v8hi __attribute__((__vector_size__(16)));
 typedef char __v16qi __attribute__((__vector_size__(16)));
 
@@ -1194,7 +1197,7 @@
 _mm_extract_epi16(__m128i a, int imm)
 {
   __v8hi b = (__v8hi)a;
-  return b[imm];
+  return (unsigned short)b[imm];
 }
 
 static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
@@ -1222,9 +1225,10 @@
                                     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))
+                                    4 + (((imm) & 0x03) >> 0), \
+                                    4 + (((imm) & 0x0c) >> 2), \
+                                    4 + (((imm) & 0x30) >> 4), \
+                                    4 + (((imm) & 0xc0) >> 6)))
 
 static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
 _mm_unpackhi_epi8(__m128i a, __m128i b)
@@ -1310,8 +1314,9 @@
   return __builtin_ia32_movmskpd(a);
 }
 
-#define _mm_shuffle_pd(a, b, i) (__builtin_shufflevector((a), (b), (i) & 1, \
-                                                         (((i) & 2) >> 1) + 2))
+#define _mm_shuffle_pd(a, b, i) \
+  (__builtin_shufflevector((__m128d)(a), (__m128d)(b), (i) & 1, \
+                                                       (((i) & 2) >> 1) + 2))
 
 static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
 _mm_castpd_ps(__m128d in)
diff --git a/lib/Headers/immintrin.h b/lib/Headers/immintrin.h
new file mode 100644
index 0000000..a19deaa
--- /dev/null
+++ b/lib/Headers/immintrin.h
@@ -0,0 +1,59 @@
+/*===---- immintrin.h - Intel 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 __IMMINTRIN_H
+#define __IMMINTRIN_H
+
+#ifdef __MMX__
+#include <mmintrin.h>
+#endif
+
+#ifdef __SSE__
+#include <xmmintrin.h>
+#endif
+
+#ifdef __SSE2__
+#include <emmintrin.h>
+#endif
+
+#ifdef __SSE3__
+#include <pmmintrin.h>
+#endif
+
+#ifdef __SSSE3__
+#include <tmmintrin.h>
+#endif
+
+#if defined (__SSE4_2__) || defined (__SSE4_1__)
+#include <smmintrin.h>
+#endif
+
+#if defined (__AES__) || defined (__PCLMUL__)
+#include <wmmintrin.h>
+#endif
+
+#ifdef __AVX__
+#include <avxintrin.h>
+#endif
+
+#endif /* __IMMINTRIN_H */
diff --git a/lib/Headers/mmintrin.h b/lib/Headers/mmintrin.h
index 401d8a7..bad9e1c 100644
--- a/lib/Headers/mmintrin.h
+++ b/lib/Headers/mmintrin.h
@@ -443,6 +443,64 @@
     return (__m64)(__v8qi){ __b7, __b6, __b5, __b4, __b3, __b2, __b1, __b0 };
 }
 
+
+/* Aliases for compatibility. */
+#define _m_empty _mm_empty
+#define _m_from_int _mm_cvtsi32_si64
+#define _m_to_int _mm_cvtsi64_si32
+#define _m_packsswb _mm_packs_pi16
+#define _m_packssdw _mm_packs_pi32
+#define _m_packuswb _mm_packs_pu16
+#define _m_punpckhbw _mm_unpackhi_pi8
+#define _m_punpckhwd _mm_unpackhi_pi16
+#define _m_punpckhdq _mm_unpackhi_pi32
+#define _m_punpcklbw _mm_unpacklo_pi8
+#define _m_punpcklwd _mm_unpacklo_pi16
+#define _m_punpckldq _mm_unpacklo_pi32
+#define _m_paddb _mm_add_pi8
+#define _m_paddw _mm_add_pi16
+#define _m_paddd _mm_add_pi32
+#define _m_paddsb _mm_adds_pi8
+#define _m_paddsw _mm_adds_pi16
+#define _m_paddusb _mm_adds_pu8
+#define _m_paddusw _mm_adds_pu16
+#define _m_psubb _mm_sub_pi8
+#define _m_psubw _mm_sub_pi16
+#define _m_psubd _mm_sub_pi32
+#define _m_psubsb _mm_subs_pi8
+#define _m_psubsw _mm_subs_pi16
+#define _m_psubusb _mm_subs_pu8
+#define _m_psubusw _mm_subs_pu16
+#define _m_pmaddwd _mm_madd_pi16
+#define _m_pmulhw _mm_mulhi_pi16
+#define _m_pmullw _mm_mullo_pi16
+#define _m_psllw _mm_sll_pi16
+#define _m_psllwi _mm_slli_pi16
+#define _m_pslld _mm_sll_pi32
+#define _m_pslldi _mm_slli_pi32
+#define _m_psllq _mm_sll_si64
+#define _m_psllqi _mm_slli_si64
+#define _m_psraw _mm_sra_pi16
+#define _m_psrawi _mm_srai_pi16
+#define _m_psrad _mm_sra_pi32
+#define _m_psradi _mm_srai_pi32
+#define _m_psrlw _mm_srl_pi16
+#define _m_psrlwi _mm_srli_pi16
+#define _m_psrld _mm_srl_pi32
+#define _m_psrldi _mm_srli_pi32
+#define _m_psrlq _mm_srl_si64
+#define _m_psrlqi _mm_srli_si64
+#define _m_pand _mm_and_si64
+#define _m_pandn _mm_andnot_si64
+#define _m_por _mm_or_si64
+#define _m_pxor _mm_xor_si64
+#define _m_pcmpeqb _mm_cmpeq_pi8
+#define _m_pcmpeqw _mm_cmpeq_pi16
+#define _m_pcmpeqd _mm_cmpeq_pi32
+#define _m_pcmpgtb _mm_cmpgt_pi8
+#define _m_pcmpgtw _mm_cmpgt_pi16
+#define _m_pcmpgtd _mm_cmpgt_pi32
+
 #endif /* __MMX__ */
 
 #endif /* __MMINTRIN_H */
diff --git a/lib/Headers/nmmintrin.h b/lib/Headers/nmmintrin.h
index cc213ce..f12622d 100644
--- a/lib/Headers/nmmintrin.h
+++ b/lib/Headers/nmmintrin.h
@@ -1,25 +1,25 @@
-/*===---- 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.
-*
-*===-----------------------------------------------------------------------===
-*/
+/*===---- nmmintrin.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 _NMMINTRIN_H
 #define _NMMINTRIN_H
diff --git a/lib/Headers/smmintrin.h b/lib/Headers/smmintrin.h
index e271f99..2b8b321 100644
--- a/lib/Headers/smmintrin.h
+++ b/lib/Headers/smmintrin.h
@@ -30,10 +30,6 @@
 
 #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
@@ -183,13 +179,13 @@
 #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;         \
+                                 __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; \
+#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
@@ -201,25 +197,27 @@
                                              _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; \
+#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; \
+#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; \
+#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];}))
+/* Extract int from packed integer array at index.  This returns the element
+ * as a zero extended value, so it is unsigned.
+ */
+#define _mm_extract_epi8(X, N) (__extension__ ({ __v16qi __a = (__v16qi)(X); \
+                                                 (unsigned char)__a[N];}))
+#define _mm_extract_epi32(X, N) (__extension__ ({ __v4si __a = (__v4si)(X); \
+                                                  (unsigned)__a[N];}))
 #ifdef __x86_64__
-#define _mm_extract_epi64(X, N) (__extension__ ({ __v2di __a = (__v2di)X; \
+#define _mm_extract_epi64(X, N) (__extension__ ({ __v2di __a = (__v2di)(X); \
                                                   __a[N];}))
 #endif /* __x86_64 */
 
diff --git a/lib/Headers/stddef.h b/lib/Headers/stddef.h
index 6868ad3..fdd4815 100644
--- a/lib/Headers/stddef.h
+++ b/lib/Headers/stddef.h
@@ -40,11 +40,19 @@
 
 #undef NULL
 #ifdef __cplusplus
+#undef __null  // VC++ hack.
 #define NULL __null
 #else
 #define NULL ((void*)0)
 #endif
 
+// Some C libraries expect to see a wint_t here. Others (notably MinGW) will use
+// __WINT_TYPE__ directly; accomodate both by requiring __need_wint_t
+#if defined(__need_wint_t) && !defined(_WINT_T)
+#define _WINT_T
+typedef __WINT_TYPE__ wint_t;
+#endif
+
 #define offsetof(t, d) __builtin_offsetof(t, d)
 
 #endif /* __STDDEF_H */
diff --git a/lib/Headers/stdint.h b/lib/Headers/stdint.h
index 1785f31..9498ed5 100644
--- a/lib/Headers/stdint.h
+++ b/lib/Headers/stdint.h
@@ -233,8 +233,8 @@
 
 /* C99 7.18.1.5 Greatest-width integer types.
  */
-typedef  __intn_t(__INTMAX_WIDTH__)  intmax_t;
-typedef __uintn_t(__INTMAX_WIDTH__) uintmax_t;
+typedef __INTMAX_TYPE__  intmax_t;
+typedef __UINTMAX_TYPE__ uintmax_t;
 
 /* C99 7.18.4 Macros for minimum-width integer constants.
  *
diff --git a/lib/Headers/x86intrin.h b/lib/Headers/x86intrin.h
new file mode 100644
index 0000000..e5e7a6a
--- /dev/null
+++ b/lib/Headers/x86intrin.h
@@ -0,0 +1,31 @@
+/*===---- x86intrin.h - X86 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 __X86INTRIN_H
+#define __X86INTRIN_H
+
+#include <immintrin.h>
+
+// FIXME: SSE4A, 3dNOW, FMA4, XOP, LWP, ABM, POPCNT
+
+#endif /* __X86INTRIN_H */
diff --git a/lib/Headers/xmmintrin.h b/lib/Headers/xmmintrin.h
index 4e313b2..8363b45 100644
--- a/lib/Headers/xmmintrin.h
+++ b/lib/Headers/xmmintrin.h
@@ -416,6 +416,12 @@
   return (__m64)__builtin_ia32_cvtps2pi(a);
 }
 
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvt_ps2pi(__m128 a)
+{
+  return _mm_cvtps_pi32(a);
+}
+
 static __inline__ int __attribute__((__always_inline__, __nodebug__))
 _mm_cvttss_si32(__m128 a)
 {
@@ -440,6 +446,12 @@
   return (__m64)__builtin_ia32_cvttps2pi(a);
 }
 
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtt_ps2pi(__m128 a)
+{
+  return _mm_cvttps_pi32(a);
+}
+
 static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
 _mm_cvtsi32_ss(__m128 a, int b)
 {
@@ -447,6 +459,12 @@
   return a;
 }
 
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvt_si2ss(__m128 a, int b)
+{
+  return _mm_cvtsi32_ss(a, b);
+}
+
 #ifdef __x86_64__
 
 static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
@@ -464,6 +482,12 @@
   return __builtin_ia32_cvtpi2ps(a, (__v2si)b);
 }
 
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvt_pi2ps(__m128 a, __m64 b)
+{
+  return _mm_cvtpi32_ps(a, b);
+}
+
 static __inline__ float __attribute__((__always_inline__, __nodebug__))
 _mm_cvtss_f32(__m128 a)
 {
@@ -590,6 +614,12 @@
 }
 
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_store_ps1(float *p, __m128 a)
+{
+    return _mm_store1_ps(p, a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
 _mm_store_ps(float *p, __m128 a)
 {
   *(__m128 *)p = a;
@@ -602,15 +632,15 @@
   _mm_store_ps(p, a);
 }
 
-#define _MM_HINT_T0 1
+#define _MM_HINT_T0 3
 #define _MM_HINT_T1 2
-#define _MM_HINT_T2 3
+#define _MM_HINT_T2 1
 #define _MM_HINT_NTA 0
 
-/* FIXME: We have to #define this because "sel" must be a constant integer, and 
+/* 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))
+#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)
@@ -723,7 +753,8 @@
 }
 
 #define _mm_shuffle_ps(a, b, mask) \
-        (__builtin_shufflevector(a, b, (mask) & 0x3, ((mask) & 0xc) >> 2, \
+        (__builtin_shufflevector((__v4sf)(a), (__v4sf)(b),                \
+                                 (mask) & 0x3, ((mask) & 0xc) >> 2, \
                                  (((mask) & 0x30) >> 4) + 4, \
                                  (((mask) & 0xc0) >> 6) + 4))
 
@@ -907,6 +938,23 @@
   (row3) = _mm_movehl_ps(tmp3, tmp1); \
 } while (0)
 
+/* Aliases for compatibility. */
+#define _m_pextrw _mm_extract_pi16
+#define _m_pinsrw _mm_insert_pi16
+#define _m_pmaxsw _mm_max_pi16
+#define _m_pmaxub _mm_max_pu8
+#define _m_pminsw _mm_min_pi16
+#define _m_pminub _mm_min_pu8
+#define _m_pmovmskb _mm_movemask_pi8
+#define _m_pmulhuw _mm_mulhi_pu16
+#define _m_pshufw _mm_shuffle_pi16
+#define _m_maskmovq _mm_maskmove_si64
+#define _m_pavgb _mm_avg_pu8
+#define _m_pavgw _mm_avg_pu16
+#define _m_psadbw _mm_sad_pu8
+#define _m_ _mm_
+#define _m_ _mm_
+
 /* Ugly hack for backwards-compatibility (compatible with gcc) */
 #ifdef __SSE2__
 #include <emmintrin.h>
diff --git a/lib/Index/ASTLocation.cpp b/lib/Index/ASTLocation.cpp
index 091bc78..bd3b5ee 100644
--- a/lib/Index/ASTLocation.cpp
+++ b/lib/Index/ASTLocation.cpp
@@ -69,7 +69,7 @@
   case N_NamedRef:
     return SourceRange(AsNamedRef().Loc, AsNamedRef().Loc);
   case N_Type:
-    return AsTypeLoc().getSourceRange();
+    return AsTypeLoc().getLocalSourceRange();
   }
   
   return SourceRange();
diff --git a/lib/Index/Analyzer.cpp b/lib/Index/Analyzer.cpp
index 1354fe6..6be35ab 100644
--- a/lib/Index/Analyzer.cpp
+++ b/lib/Index/Analyzer.cpp
@@ -180,7 +180,7 @@
       if (IsInstanceMethod)
         return false;
 
-      MsgD = Msg->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+      MsgD = Msg->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
       break;
     }
 
@@ -189,7 +189,7 @@
       if (IsInstanceMethod)
         return false;
 
-      MsgD = Msg->getSuperType()->getAs<ObjCInterfaceType>()->getDecl();
+      MsgD = Msg->getSuperType()->getAs<ObjCObjectType>()->getInterface();
       break;
 
     case ObjCMessageExpr::SuperInstance:
@@ -292,12 +292,12 @@
         
       case ObjCMessageExpr::Class:
         CanBeClassMethod = true;
-        MsgD = Msg->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+        MsgD = Msg->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
         break;
 
       case ObjCMessageExpr::SuperClass:
         CanBeClassMethod = true;
-        MsgD = Msg->getSuperType()->getAs<ObjCInterfaceType>()->getDecl();
+        MsgD = Msg->getSuperType()->getAs<ObjCObjectType>()->getInterface();
         break;
 
       case ObjCMessageExpr::SuperInstance:
diff --git a/lib/Index/Android.mk b/lib/Index/Android.mk
deleted file mode 100644
index a811d6c..0000000
--- a/lib/Index/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-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
index 4d67035..61f69b2 100644
--- a/lib/Index/CMakeLists.txt
+++ b/lib/Index/CMakeLists.txt
@@ -11,6 +11,5 @@
   IndexProvider.cpp
   Indexer.cpp
   Program.cpp
-  ResolveLocation.cpp
   SelectorMap.cpp
   )
diff --git a/lib/Index/CallGraph.cpp b/lib/Index/CallGraph.cpp
index 6403319..dedcc0e 100644
--- a/lib/Index/CallGraph.cpp
+++ b/lib/Index/CallGraph.cpp
@@ -55,7 +55,7 @@
   }
 }
 
-CallGraph::CallGraph() : Root(0) {
+CallGraph::CallGraph(Program &P) : Prog(P), Root(0) {
   ExternalCallingNode = getOrInsertFunction(Entity());
 }
 
diff --git a/lib/Index/Entity.cpp b/lib/Index/Entity.cpp
index cd9d277..749dcc8 100644
--- a/lib/Index/Entity.cpp
+++ b/lib/Index/Entity.cpp
@@ -42,14 +42,48 @@
   EntityGetter(Program &prog, ProgramImpl &progImpl)
     : Prog(prog), ProgImpl(progImpl) { }
 
+  // Get an Entity.
+  Entity getEntity(Entity Parent, DeclarationName Name, 
+                   unsigned IdNS, bool isObjCInstanceMethod);
+
+  // Get an Entity associated with the name in the global namespace.
+  Entity getGlobalEntity(llvm::StringRef Name);
+
   Entity VisitNamedDecl(NamedDecl *D);
   Entity VisitVarDecl(VarDecl *D);
+  Entity VisitFieldDecl(FieldDecl *D);
   Entity VisitFunctionDecl(FunctionDecl *D);
+  Entity VisitTypeDecl(TypeDecl *D);
 };
 
 }
 }
 
+Entity EntityGetter::getEntity(Entity Parent, DeclarationName Name, 
+                               unsigned IdNS, bool isObjCInstanceMethod) {
+  llvm::FoldingSetNodeID ID;
+  EntityImpl::Profile(ID, Parent, Name, 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, Name, IdNS, isObjCInstanceMethod);
+  Entities.InsertNode(New, InsertPos);
+
+  return Entity(New);
+}
+
+Entity EntityGetter::getGlobalEntity(llvm::StringRef Name) {
+  IdentifierInfo *II = &ProgImpl.getIdents().get(Name);
+  DeclarationName GlobName(II);
+  unsigned IdNS = Decl::IDNS_Ordinary;
+  return getEntity(Entity(), GlobName, IdNS, false);
+}
+
 Entity EntityGetter::VisitNamedDecl(NamedDecl *D) {
   Entity Parent;
   if (!D->getDeclContext()->isTranslationUnit()) {
@@ -91,26 +125,16 @@
 
   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);
+  return getEntity(Parent, GlobName, IdNS, isObjCInstanceMethod);
 }
 
 Entity EntityGetter::VisitVarDecl(VarDecl *D) {
+  // Local variables have no linkage, make invalid Entities.
+  if (D->hasLocalStorage())
+    return Entity();
+
   // If it's static it cannot be referred to by another translation unit.
-  if (D->getStorageClass() == VarDecl::Static)
+  if (D->getStorageClass() == SC_Static)
     return Entity(D);
 
   return VisitNamedDecl(D);
@@ -118,12 +142,24 @@
 
 Entity EntityGetter::VisitFunctionDecl(FunctionDecl *D) {
   // If it's static it cannot be refered to by another translation unit.
-  if (D->getStorageClass() == FunctionDecl::Static)
+  if (D->getStorageClass() == SC_Static)
     return Entity(D);
 
   return VisitNamedDecl(D);
 }
 
+Entity EntityGetter::VisitFieldDecl(FieldDecl *D) {
+  // Make FieldDecl an invalid Entity since it has no linkage.
+  return Entity();
+}
+
+Entity EntityGetter::VisitTypeDecl(TypeDecl *D) {
+  // Although in C++ class name has external linkage, usually the definition of
+  // the class is available in the same translation unit when it's needed. So we
+  // make all of them invalid Entity.
+  return Entity();
+}
+
 //===----------------------------------------------------------------------===//
 // EntityImpl Implementation
 //===----------------------------------------------------------------------===//
@@ -172,6 +208,12 @@
   return EntityGetter(Prog, ProgImpl).Visit(D);
 }
 
+/// \brief Get an Entity associated with a global name.
+Entity EntityImpl::get(llvm::StringRef Name, Program &Prog, 
+                       ProgramImpl &ProgImpl) {
+  return EntityGetter(Prog, ProgImpl).getGlobalEntity(Name);
+}
+
 std::string EntityImpl::getPrintableName() {
   return Name.getAsString();
 }
@@ -217,6 +259,11 @@
   return EntityImpl::get(D, Prog, ProgImpl);
 }
 
+Entity Entity::get(llvm::StringRef Name, Program &Prog) {
+  ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl);
+  return EntityImpl::get(Name, 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
index cbce934..da52ccf 100644
--- a/lib/Index/EntityImpl.h
+++ b/lib/Index/EntityImpl.h
@@ -47,6 +47,7 @@
   /// \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);
+  static Entity get(llvm::StringRef Name, Program &Prog, ProgramImpl &ProgImpl);
 
   std::string getPrintableName();
 
diff --git a/lib/Index/Indexer.cpp b/lib/Index/Indexer.cpp
index 57bfc5b..7f21c4f 100644
--- a/lib/Index/Indexer.cpp
+++ b/lib/Index/Indexer.cpp
@@ -25,14 +25,22 @@
 class EntityIndexer : public EntityHandler {
   TranslationUnit *TU;
   Indexer::MapTy &Map;
+  Indexer::DefMapTy &DefMap;
 
 public:
-  EntityIndexer(TranslationUnit *tu, Indexer::MapTy &map) : TU(tu), Map(map) { }
+  EntityIndexer(TranslationUnit *tu, Indexer::MapTy &map, 
+                Indexer::DefMapTy &defmap) 
+    : TU(tu), Map(map), DefMap(defmap) { }
 
   virtual void Handle(Entity Ent) {
     if (Ent.isInternalToTU())
       return;
     Map[Ent].insert(TU);
+
+    Decl *D = Ent.getDecl(TU->getASTContext());
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+      if (FD->isThisDeclarationADefinition())
+        DefMap[Ent] = std::make_pair(FD, TU);
   }
 };
 
@@ -62,7 +70,7 @@
   assert(TU && "Passed null TranslationUnit");
   ASTContext &Ctx = TU->getASTContext();
   CtxTUMap[&Ctx] = TU;
-  EntityIndexer Idx(TU, Map);
+  EntityIndexer Idx(TU, Map, DefMap);
   Prog.FindEntities(Ctx, Idx);
 
   SelectorIndexer SelIdx(Prog, TU, SelMap);
@@ -102,3 +110,12 @@
   for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I)
     Handler.Handle(*I);
 }
+
+std::pair<FunctionDecl *, TranslationUnit *> 
+Indexer::getDefinitionFor(Entity Ent) {
+  DefMapTy::iterator I = DefMap.find(Ent);
+  if (I == DefMap.end())
+    return std::make_pair((FunctionDecl *)0, (TranslationUnit *)0);
+  else
+    return I->second;
+}
diff --git a/lib/Index/Makefile b/lib/Index/Makefile
index 4d86713..8607d78 100644
--- a/lib/Index/Makefile
+++ b/lib/Index/Makefile
@@ -11,17 +11,8 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
-include $(LEVEL)/Makefile.config
-
+CLANG_LEVEL := ../..
 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
+include $(CLANG_LEVEL)/Makefile
 
diff --git a/lib/Index/ResolveLocation.cpp b/lib/Index/ResolveLocation.cpp
deleted file mode 100644
index 4bb1594..0000000
--- a/lib/Index/ResolveLocation.cpp
+++ /dev/null
@@ -1,613 +0,0 @@
-//===--- 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/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 74e8d74..6cd1873 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -27,7 +27,9 @@
 #include "clang/Lex/Lexer.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/CodeCompletionHandler.h"
 #include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include <cctype>
@@ -247,6 +249,200 @@
   return TheTok.getLength();
 }
 
+SourceLocation Lexer::GetBeginningOfToken(SourceLocation Loc,
+                                          const SourceManager &SM,
+                                          const LangOptions &LangOpts) {
+  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
+  bool Invalid = false;
+  llvm::StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid);
+  if (Invalid)
+    return Loc;
+
+  // Back up from the current location until we hit the beginning of a line
+  // (or the buffer). We'll relex from that point.
+  const char *BufStart = Buffer.data();
+  const char *StrData = BufStart+LocInfo.second;
+  if (StrData[0] == '\n' || StrData[0] == '\r')
+    return Loc;
+
+  const char *LexStart = StrData;
+  while (LexStart != BufStart) {
+    if (LexStart[0] == '\n' || LexStart[0] == '\r') {
+      ++LexStart;
+      break;
+    }
+
+    --LexStart;
+  }
+  
+  // Create a lexer starting at the beginning of this token.
+  SourceLocation LexerStartLoc = Loc.getFileLocWithOffset(-LocInfo.second);
+  Lexer TheLexer(LexerStartLoc, LangOpts, BufStart, LexStart, Buffer.end());
+  TheLexer.SetCommentRetentionState(true);
+  
+  // Lex tokens until we find the token that contains the source location.
+  Token TheTok;
+  do {
+    TheLexer.LexFromRawLexer(TheTok);
+    
+    if (TheLexer.getBufferLocation() > StrData) {
+      // Lexing this token has taken the lexer past the source location we're
+      // looking for. If the current token encompasses our source location,
+      // return the beginning of that token.
+      if (TheLexer.getBufferLocation() - TheTok.getLength() <= StrData)
+        return TheTok.getLocation();
+      
+      // We ended up skipping over the source location entirely, which means
+      // that it points into whitespace. We're done here.
+      break;
+    }
+  } while (TheTok.getKind() != tok::eof);
+  
+  // We've passed our source location; just return the original source location.
+  return Loc;
+}
+
+namespace {
+  enum PreambleDirectiveKind {
+    PDK_Skipped,
+    PDK_StartIf,
+    PDK_EndIf,
+    PDK_Unknown
+  };
+}
+
+std::pair<unsigned, bool>
+Lexer::ComputePreamble(const llvm::MemoryBuffer *Buffer, unsigned MaxLines) {
+  // Create a lexer starting at the beginning of the file. Note that we use a
+  // "fake" file source location at offset 1 so that the lexer will track our
+  // position within the file.
+  const unsigned StartOffset = 1;
+  SourceLocation StartLoc = SourceLocation::getFromRawEncoding(StartOffset);
+  LangOptions LangOpts;
+  Lexer TheLexer(StartLoc, LangOpts, Buffer->getBufferStart(), 
+                 Buffer->getBufferStart(), Buffer->getBufferEnd());
+  
+  bool InPreprocessorDirective = false;
+  Token TheTok;
+  Token IfStartTok;
+  unsigned IfCount = 0;
+  unsigned Line = 0;
+
+  do {
+    TheLexer.LexFromRawLexer(TheTok);
+
+    if (InPreprocessorDirective) {
+      // If we've hit the end of the file, we're done.
+      if (TheTok.getKind() == tok::eof) {
+        InPreprocessorDirective = false;
+        break;
+      }
+      
+      // If we haven't hit the end of the preprocessor directive, skip this
+      // token.
+      if (!TheTok.isAtStartOfLine())
+        continue;
+        
+      // We've passed the end of the preprocessor directive, and will look
+      // at this token again below.
+      InPreprocessorDirective = false;
+    }
+    
+    // Keep track of the # of lines in the preamble.
+    if (TheTok.isAtStartOfLine()) {
+      ++Line;
+
+      // If we were asked to limit the number of lines in the preamble,
+      // and we're about to exceed that limit, we're done.
+      if (MaxLines && Line >= MaxLines)
+        break;
+    }
+
+    // Comments are okay; skip over them.
+    if (TheTok.getKind() == tok::comment)
+      continue;
+    
+    if (TheTok.isAtStartOfLine() && TheTok.getKind() == tok::hash) {
+      // This is the start of a preprocessor directive. 
+      Token HashTok = TheTok;
+      InPreprocessorDirective = true;
+      
+      // Figure out which direective this is. Since we're lexing raw tokens,
+      // we don't have an identifier table available. Instead, just look at
+      // the raw identifier to recognize and categorize preprocessor directives.
+      TheLexer.LexFromRawLexer(TheTok);
+      if (TheTok.getKind() == tok::identifier && !TheTok.needsCleaning()) {
+        const char *IdStart = Buffer->getBufferStart() 
+                            + TheTok.getLocation().getRawEncoding() - 1;
+        llvm::StringRef Keyword(IdStart, TheTok.getLength());
+        PreambleDirectiveKind PDK
+          = llvm::StringSwitch<PreambleDirectiveKind>(Keyword)
+              .Case("include", PDK_Skipped)
+              .Case("__include_macros", PDK_Skipped)
+              .Case("define", PDK_Skipped)
+              .Case("undef", PDK_Skipped)
+              .Case("line", PDK_Skipped)
+              .Case("error", PDK_Skipped)
+              .Case("pragma", PDK_Skipped)
+              .Case("import", PDK_Skipped)
+              .Case("include_next", PDK_Skipped)
+              .Case("warning", PDK_Skipped)
+              .Case("ident", PDK_Skipped)
+              .Case("sccs", PDK_Skipped)
+              .Case("assert", PDK_Skipped)
+              .Case("unassert", PDK_Skipped)
+              .Case("if", PDK_StartIf)
+              .Case("ifdef", PDK_StartIf)
+              .Case("ifndef", PDK_StartIf)
+              .Case("elif", PDK_Skipped)
+              .Case("else", PDK_Skipped)
+              .Case("endif", PDK_EndIf)
+              .Default(PDK_Unknown);
+
+        switch (PDK) {
+        case PDK_Skipped:
+          continue;
+
+        case PDK_StartIf:
+          if (IfCount == 0)
+            IfStartTok = HashTok;
+            
+          ++IfCount;
+          continue;
+            
+        case PDK_EndIf:
+          // Mismatched #endif. The preamble ends here.
+          if (IfCount == 0)
+            break;
+
+          --IfCount;
+          continue;
+            
+        case PDK_Unknown:
+          // We don't know what this directive is; stop at the '#'.
+          break;
+        }
+      }
+      
+      // We only end up here if we didn't recognize the preprocessor
+      // directive or it was one that can't occur in the preamble at this
+      // point. Roll back the current token to the location of the '#'.
+      InPreprocessorDirective = false;
+      TheTok = HashTok;
+    }
+
+    // We hit a token that we don't recognize as being in the
+    // "preprocessing only" part of the file, so we're no longer in
+    // the preamble.
+    break;
+  } while (true);
+  
+  SourceLocation End = IfCount? IfStartTok.getLocation() : TheTok.getLocation();
+  return std::make_pair(End.getRawEncoding() - StartLoc.getRawEncoding(),
+                        IfCount? IfStartTok.isAtStartOfLine()
+                               : TheTok.isAtStartOfLine());
+}
+
 //===----------------------------------------------------------------------===//
 // Character information.
 //===----------------------------------------------------------------------===//
@@ -476,7 +672,7 @@
   }
 
   if (!L->isLexingRawMode())
-    L->Diag(CP-2, diag::trigraph_converted) << std::string()+Res;
+    L->Diag(CP-2, diag::trigraph_converted) << llvm::StringRef(&Res, 1);
   return Res;
 }
 
@@ -647,6 +843,14 @@
 // Helper methods for lexing.
 //===----------------------------------------------------------------------===//
 
+/// \brief Routine that indiscriminately skips bytes in the source file.
+void Lexer::SkipBytes(unsigned Bytes, bool StartOfLine) {
+  BufferPtr += Bytes;
+  if (BufferPtr > BufferEnd)
+    BufferPtr = BufferEnd;
+  IsAtStartOfLine = StartOfLine;
+}
+
 void Lexer::LexIdentifier(Token &Result, const char *CurPtr) {
   // Match [_A-Za-z0-9]*, we have already matched [_A-Za-z$]
   unsigned Size;
@@ -752,19 +956,23 @@
 
   char C = getAndAdvanceChar(CurPtr, Result);
   while (C != '"') {
-    // Skip escaped characters.
-    if (C == '\\') {
-      // Skip the escaped character.
+    // Skip escaped characters.  Escaped newlines will already be processed by
+    // getAndAdvanceChar.
+    if (C == '\\')
       C = getAndAdvanceChar(CurPtr, Result);
-    } else if (C == '\n' || C == '\r' ||             // Newline.
-               (C == 0 && CurPtr-1 == BufferEnd)) {  // End of file.
-      if (!isLexingRawMode() && !Features.AsmPreprocessor)
+    
+    if (C == '\n' || C == '\r' ||             // Newline.
+        (C == 0 && CurPtr-1 == BufferEnd)) {  // End of file.
+      if (C == 0 && PP && PP->isCodeCompletionFile(FileLoc))
+        PP->CodeCompleteNaturalLanguage();
+      else if (!isLexingRawMode() && !Features.AsmPreprocessor)
         Diag(BufferPtr, diag::err_unterminated_string);
       FormTokenWithChars(Result, CurPtr-1, tok::unknown);
       return;
-    } else if (C == 0) {
-      NulCharacter = CurPtr-1;
     }
+    
+    if (C == 0)
+      NulCharacter = CurPtr-1;
     C = getAndAdvanceChar(CurPtr, Result);
   }
 
@@ -818,41 +1026,35 @@
 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.
+  }
+
+  while (C != '\'') {
+    // Skip escaped characters.
+    if (C == '\\') {
+      // Skip the escaped character.
+      // FIXME: UCN's
+      C = getAndAdvanceChar(CurPtr, Result);
+    } else if (C == '\n' || C == '\r' ||             // Newline.
+               (C == 0 && CurPtr-1 == BufferEnd)) {  // End of file.
+      if (C == 0 && PP && PP->isCodeCompletionFile(FileLoc))
+        PP->CodeCompleteNaturalLanguage();
+      else 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);
   }
 
-  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 a nul character existed in the character, warn about it.
   if (NulCharacter && !isLexingRawMode())
     Diag(NulCharacter, diag::null_in_char);
 
@@ -986,7 +1188,13 @@
         }
     }
 
-    if (CurPtr == BufferEnd+1) { --CurPtr; break; }
+    if (CurPtr == BufferEnd+1) { 
+      if (PP && PP->isCodeCompletionFile(FileLoc))
+        PP->CodeCompleteNaturalLanguage();
+
+      --CurPtr; 
+      break; 
+    }
   } while (C != '\n' && C != '\r');
 
   // Found but did not consume the newline.  Notify comment handlers about the
@@ -1141,7 +1349,8 @@
   unsigned char C = getCharAndSize(CurPtr, CharSize);
   CurPtr += CharSize;
   if (C == 0 && CurPtr == BufferEnd+1) {
-    if (!isLexingRawMode())
+    if (!isLexingRawMode() &&
+        !PP->isCodeCompletionFile(FileLoc))
       Diag(BufferPtr, diag::err_unterminated_block_comment);
     --CurPtr;
 
@@ -1224,7 +1433,9 @@
           Diag(CurPtr-1, diag::warn_nested_block_comment);
       }
     } else if (C == 0 && CurPtr == BufferEnd+1) {
-      if (!isLexingRawMode())
+      if (PP && PP->isCodeCompletionFile(FileLoc))
+        PP->CodeCompleteNaturalLanguage();
+      else 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
@@ -1310,6 +1521,11 @@
 
       // Next, lex the character, which should handle the EOM transition.
       Lex(Tmp);
+      if (Tmp.is(tok::code_completion)) {
+        if (PP && PP->getCodeCompletionHandler())
+          PP->getCodeCompletionHandler()->CodeCompleteNaturalLanguage();
+        Lex(Tmp);
+      }
       assert(Tmp.is(tok::eom) && "Unexpected token!");
 
       // Finally, we're done, return the string we found.
@@ -1323,6 +1539,22 @@
 /// This returns true if Result contains a token, false if PP.Lex should be
 /// called again.
 bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) {
+  // Check if we are performing code completion.
+  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);
+    
+    // Silence any diagnostics that occur once we hit the code-completion point.
+    PP->getDiagnostics().setSuppressAllDiagnostics(true);
+    return true;
+  }
+
   // 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.
@@ -1345,26 +1577,14 @@
     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;
-  }
   
+  // Issue diagnostics for unterminated #if and missing newline.
+
   // If we are in a #if directive, emit an error.
   while (!ConditionalStack.empty()) {
-    PP->Diag(ConditionalStack.back().IfLoc,
-             diag::err_pp_unterminated_conditional);
+    if (!PP->isCodeCompletionFile(FileLoc))
+      PP->Diag(ConditionalStack.back().IfLoc,
+               diag::err_pp_unterminated_conditional);
     ConditionalStack.pop_back();
   }
 
@@ -1421,6 +1641,7 @@
     if (RestOfBuffer[Pos-1] != '\r' &&
         RestOfBuffer[Pos-1] != '\n') {
       RestOfBuffer = RestOfBuffer.substr(Pos+7);
+      Pos = RestOfBuffer.find(">>>>>>>");
       continue;
     }
     return RestOfBuffer.data()+Pos;
@@ -1450,7 +1671,7 @@
   
   // 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)) {
+  if (FindConflictEnd(CurPtr, 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);
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index f425582..a12c4ae 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -34,7 +34,7 @@
 static unsigned ProcessCharEscape(const char *&ThisTokBuf,
                                   const char *ThisTokEnd, bool &HadError,
                                   SourceLocation Loc, bool IsWide,
-                                  Preprocessor &PP) {
+                                  Preprocessor &PP, bool Complain) {
   // Skip the '\' char.
   ++ThisTokBuf;
 
@@ -54,11 +54,13 @@
     ResultChar = 8;
     break;
   case 'e':
-    PP.Diag(Loc, diag::ext_nonstandard_escape) << "e";
+    if (Complain)
+      PP.Diag(Loc, diag::ext_nonstandard_escape) << "e";
     ResultChar = 27;
     break;
   case 'E':
-    PP.Diag(Loc, diag::ext_nonstandard_escape) << "E";
+    if (Complain)
+      PP.Diag(Loc, diag::ext_nonstandard_escape) << "E";
     ResultChar = 27;
     break;
   case 'f':
@@ -79,7 +81,8 @@
   case 'x': { // Hex escape.
     ResultChar = 0;
     if (ThisTokBuf == ThisTokEnd || !isxdigit(*ThisTokBuf)) {
-      PP.Diag(Loc, diag::err_hex_escape_no_digits);
+      if (Complain)
+        PP.Diag(Loc, diag::err_hex_escape_no_digits);
       HadError = 1;
       break;
     }
@@ -106,7 +109,7 @@
     }
 
     // Check for overflow.
-    if (Overflow)   // Too many digits to fit in
+    if (Overflow && Complain)   // Too many digits to fit in
       PP.Diag(Loc, diag::warn_hex_escape_too_large);
     break;
   }
@@ -132,7 +135,8 @@
                        : PP.getTargetInfo().getCharWidth();
 
     if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
-      PP.Diag(Loc, diag::warn_octal_escape_too_large);
+      if (Complain)
+        PP.Diag(Loc, diag::warn_octal_escape_too_large);
       ResultChar &= ~0U >> (32-CharWidth);
     }
     break;
@@ -141,10 +145,14 @@
     // 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;
+    if (Complain)
+      PP.Diag(Loc, diag::ext_nonstandard_escape)
+        << std::string()+(char)ResultChar;
     break;
   default:
+    if (!Complain)
+      break;
+      
     if (isgraph(ThisTokBuf[0]))
       PP.Diag(Loc, diag::ext_unknown_escape) << std::string()+(char)ResultChar;
     else
@@ -161,8 +169,8 @@
 /// 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)
-{
+                             SourceLocation Loc, Preprocessor &PP,
+                             bool Complain) {
   // FIXME: Add a warning - UCN's are only valid in C++ & C99.
   // FIXME: Handle wide strings.
 
@@ -173,7 +181,8 @@
   ThisTokBuf += 2;
 
   if (ThisTokBuf == ThisTokEnd || !isxdigit(*ThisTokBuf)) {
-    PP.Diag(Loc, diag::err_ucn_escape_no_digits);
+    if (Complain)
+      PP.Diag(Loc, diag::err_ucn_escape_no_digits);
     HadError = 1;
     return;
   }
@@ -189,8 +198,9 @@
   }
   // 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);
+    if (Complain)
+      PP.Diag(PP.AdvanceToTokenCharacter(Loc, ThisTokBuf-ThisTokBegin),
+              diag::err_ucn_escape_incomplete);
     HadError = 1;
     return;
   }
@@ -199,7 +209,8 @@
       (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);
+    if (Complain)
+      PP.Diag(Loc, diag::err_ucn_escape_invalid);
     HadError = 1;
     return;
   }
@@ -312,7 +323,7 @@
       // 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);
+              diag::err_invalid_decimal_digit) << llvm::StringRef(s, 1);
       hadError = true;
       return;
     } else if (*s == '.') {
@@ -428,7 +439,7 @@
     PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-begin),
             isFPConstant ? diag::err_invalid_suffix_float_constant :
                            diag::err_invalid_suffix_integer_constant)
-      << std::string(SuffixBegin, ThisTokEnd);
+      << llvm::StringRef(SuffixBegin, ThisTokEnd-SuffixBegin);
     hadError = true;
     return;
   }
@@ -499,7 +510,7 @@
       // Done.
     } else if (isxdigit(*s)) {
       PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
-              diag::err_invalid_binary_digit) << std::string(s, s+1);
+              diag::err_invalid_binary_digit) << llvm::StringRef(s, 1);
       hadError = true;
     }
     // Other suffixes will be diagnosed by the caller.
@@ -529,7 +540,7 @@
   // 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);
+            diag::err_invalid_octal_digit) << llvm::StringRef(s, 1);
     hadError = true;
     return;
   }
@@ -660,7 +671,8 @@
     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);
+      ResultChar = ProcessCharEscape(begin, end, HadError, Loc, IsWide, PP,
+                                     /*Complain=*/true);
 
     // If this is a multi-character constant (e.g. 'abc'), handle it.  These are
     // implementation defined (C99 6.4.4.4p10).
@@ -746,7 +758,7 @@
 ///
 StringLiteralParser::
 StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
-                    Preprocessor &pp) : PP(pp) {
+                    Preprocessor &pp, bool Complain) : 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
@@ -822,11 +834,8 @@
     // TODO: Input character set mapping support.
 
     // Skip L marker for wide strings.
-    bool ThisIsWide = false;
-    if (ThisTokBuf[0] == 'L') {
+    if (ThisTokBuf[0] == 'L')
       ++ThisTokBuf;
-      ThisIsWide = true;
-    }
 
     assert(ThisTokBuf[0] == '"' && "Expected quote, lexer broken?");
     ++ThisTokBuf;
@@ -871,13 +880,13 @@
       // Is this a Universal Character Name escape?
       if (ThisTokBuf[1] == 'u' || ThisTokBuf[1] == 'U') {
         ProcessUCNEscape(ThisTokBuf, ThisTokEnd, ResultPtr,
-                         hadError, StringToks[i].getLocation(), ThisIsWide, PP);
+                         hadError, StringToks[i].getLocation(), PP, Complain);
         continue;
       }
       // Otherwise, this is a non-UCN escape character.  Process it.
       unsigned ResultChar = ProcessCharEscape(ThisTokBuf, ThisTokEnd, hadError,
                                               StringToks[i].getLocation(),
-                                              ThisIsWide, PP);
+                                              AnyWide, PP, Complain);
 
       // Note: our internal rep of wide char tokens is always little-endian.
       *ResultPtr++ = ResultChar & 0xFF;
@@ -891,15 +900,31 @@
 
   if (Pascal) {
     ResultBuf[0] = ResultPtr-&ResultBuf[0]-1;
+    if (AnyWide)
+      ResultBuf[0] /= wchar_tByteWidth;
 
     // Verify that pascal strings aren't too large.
-    if (GetStringLength() > 256) {
+    if (GetStringLength() > 256 && Complain) {
       PP.Diag(StringToks[0].getLocation(), diag::err_pascal_string_too_long)
         << SourceRange(StringToks[0].getLocation(),
                        StringToks[NumStringToks-1].getLocation());
       hadError = 1;
       return;
     }
+  } else if (Complain) {
+    // Complain if this string literal has too many characters.
+    unsigned MaxChars = PP.getLangOptions().CPlusPlus? 65536
+                      : PP.getLangOptions().C99 ? 4095
+                      : 509;
+    
+    if (GetNumStringChars() > MaxChars)
+      PP.Diag(StringToks[0].getLocation(), diag::ext_string_too_long)
+        << GetNumStringChars() << MaxChars
+        << (PP.getLangOptions().CPlusPlus? 2
+            : PP.getLangOptions().C99 ? 1
+            : 0)
+        << SourceRange(StringToks[0].getLocation(),
+                       StringToks[NumStringToks-1].getLocation());
   }
 }
 
@@ -909,7 +934,8 @@
 /// advancing over escape sequences in the string.
 unsigned StringLiteralParser::getOffsetOfStringByte(const Token &Tok,
                                                     unsigned ByteNo,
-                                                    Preprocessor &PP) {
+                                                    Preprocessor &PP, 
+                                                    bool Complain) {
   // Get the spelling of the token.
   llvm::SmallString<16> SpellingBuffer;
   SpellingBuffer.resize(Tok.getLength());
@@ -945,7 +971,7 @@
     // Otherwise, this is an escape character.  Advance over it.
     bool HadError = false;
     ProcessCharEscape(SpellingPtr, SpellingEnd, HadError,
-                      Tok.getLocation(), false, PP);
+                      Tok.getLocation(), false, PP, Complain);
     assert(!HadError && "This method isn't valid on erroneous strings");
     --ByteNo;
   }
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp
index fda884c..c6d0934 100644
--- a/lib/Lex/MacroInfo.cpp
+++ b/lib/Lex/MacroInfo.cpp
@@ -20,13 +20,32 @@
   IsC99Varargs = false;
   IsGNUVarargs = false;
   IsBuiltinMacro = false;
+  IsFromAST = false;
   IsDisabled = false;
   IsUsed = true;
+  IsAllowRedefinitionsWithoutWarning = false;
 
   ArgumentList = 0;
   NumArguments = 0;
 }
 
+MacroInfo::MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator) {
+  Location = MI.Location;
+  EndLocation = MI.EndLocation;
+  ReplacementTokens = MI.ReplacementTokens;
+  IsFunctionLike = MI.IsFunctionLike;
+  IsC99Varargs = MI.IsC99Varargs;
+  IsGNUVarargs = MI.IsGNUVarargs;
+  IsBuiltinMacro = MI.IsBuiltinMacro;
+  IsFromAST = MI.IsFromAST;
+  IsDisabled = MI.IsDisabled;
+  IsUsed = MI.IsUsed;
+  IsAllowRedefinitionsWithoutWarning = MI.IsAllowRedefinitionsWithoutWarning;
+  ArgumentList = 0;
+  NumArguments = 0;
+  setArgumentList(MI.ArgumentList, MI.NumArguments, PPAllocator);
+}
+
 /// 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.
diff --git a/lib/Lex/Makefile b/lib/Lex/Makefile
index bd3c7a8..d80fb55 100644
--- a/lib/Lex/Makefile
+++ b/lib/Lex/Makefile
@@ -11,17 +11,14 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
-include $(LEVEL)/Makefile.config
+CLANG_LEVEL := ../..
+include $(CLANG_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
+include $(CLANG_LEVEL)/Makefile
 
diff --git a/lib/Lex/PPCaching.cpp b/lib/Lex/PPCaching.cpp
index 6aeb6fa..3310659 100644
--- a/lib/Lex/PPCaching.cpp
+++ b/lib/Lex/PPCaching.cpp
@@ -45,6 +45,9 @@
 }
 
 void Preprocessor::CachingLex(Token &Result) {
+  if (!InCachingLexMode())
+    return;
+
   if (CachedLexPos < CachedTokens.size()) {
     Result = CachedTokens[CachedLexPos++];
     return;
@@ -60,13 +63,10 @@
     return;
   }
 
-  // We should cache the lexed token.
-
+  // Cache the lexed token.
   EnterCachingLexMode();
-  if (Result.isNot(tok::eof)) {
-    CachedTokens.push_back(Result);
-    ++CachedLexPos;
-  }
+  CachedTokens.push_back(Result);
+  ++CachedLexPos;
 }
 
 void Preprocessor::EnterCachingLexMode() {
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 417724b..8da7def 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -16,6 +16,7 @@
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/MacroInfo.h"
 #include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/CodeCompletionHandler.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/APInt.h"
@@ -25,7 +26,7 @@
 // Utility Methods for Preprocessor Directive Handling.
 //===----------------------------------------------------------------------===//
 
-MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) {
+MacroInfo *Preprocessor::AllocateMacroInfo() {
   MacroInfo *MI;
 
   if (!MICache.empty()) {
@@ -33,15 +34,26 @@
     MICache.pop_back();
   } else
     MI = (MacroInfo*) BP.Allocate<MacroInfo>();
+  return MI;
+}
+
+MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) {
+  MacroInfo *MI = AllocateMacroInfo();
   new (MI) MacroInfo(L);
   return MI;
 }
 
+MacroInfo *Preprocessor::CloneMacroInfo(const MacroInfo &MacroToClone) {
+  MacroInfo *MI = AllocateMacroInfo();
+  new (MI) MacroInfo(MacroToClone, BP);
+  return MI;
+}
+
 /// ReleaseMacroInfo - Release the specified MacroInfo.  This memory will
 ///  be reused for allocating new MacroInfo objects.
-void Preprocessor::ReleaseMacroInfo(MacroInfo* MI) {
+void Preprocessor::ReleaseMacroInfo(MacroInfo *MI) {
   MICache.push_back(MI);
-  MI->FreeArgumentList(BP);
+  MI->FreeArgumentList();
 }
 
 
@@ -63,6 +75,13 @@
   // Read the token, don't allow macro expansion on it.
   LexUnexpandedToken(MacroNameTok);
 
+  if (MacroNameTok.is(tok::code_completion)) {
+    if (CodeComplete)
+      CodeComplete->CodeCompleteMacroName(isDefineUndef == 1);
+    LexUnexpandedToken(MacroNameTok);
+    return;
+  }
+  
   // Missing macro name?
   if (MacroNameTok.is(tok::eom)) {
     Diag(MacroNameTok, diag::err_pp_missing_macro_name);
@@ -166,13 +185,20 @@
   while (1) {
     CurLexer->Lex(Tok);
 
+    if (Tok.is(tok::code_completion)) {
+      if (CodeComplete)
+        CodeComplete->CodeCompleteInConditionalExclusion();
+      continue;
+    }
+    
     // 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);
+        if (!isCodeCompletionFile(Tok.getLocation()))
+          Diag(CurPPLexer->ConditionalStack.back().IfLoc,
+               diag::err_pp_unterminated_conditional);
         CurPPLexer->ConditionalStack.pop_back();
       }
 
@@ -510,7 +536,11 @@
     // Handle stuff like "# /*foo*/ define X" in -E -C mode.
     LexUnexpandedToken(Result);
     goto TryAgain;
-
+  case tok::code_completion:
+    if (CodeComplete)
+      CodeComplete->CodeCompleteDirective(
+                                    CurPPLexer->getConditionalStackDepth() > 0);
+    return;
   case tok::numeric_constant:  // # 7  GNU line marker directive.
     if (getLangOptions().AsmPreprocessor)
       break;  // # 4 is not a preprocessor directive in .S files.
@@ -1445,15 +1475,15 @@
       if (!OtherMI->isUsed())
         Diag(OtherMI->getDefinitionLoc(), diag::pp_macro_not_used);
 
-      // Macros must be identical.  This means all tokes and whitespace
+      // Macros must be identical.  This means all tokens and whitespace
       // separation must be the same.  C99 6.10.3.2.
-      if (!MI->isIdenticalTo(*OtherMI, *this)) {
+      if (!OtherMI->isAllowRedefinitionsWithoutWarning() &&
+          !MI->isIdenticalTo(*OtherMI, *this)) {
         Diag(MI->getDefinitionLoc(), diag::ext_pp_macro_redef)
           << MacroNameTok.getIdentifierInfo();
         Diag(OtherMI->getDefinitionLoc(), diag::note_previous_definition);
       }
     }
-
     ReleaseMacroInfo(OtherMI);
   }
 
@@ -1490,7 +1520,8 @@
 
   // If the callbacks want to know, tell them about the macro #undef.
   if (Callbacks)
-    Callbacks->MacroUndefined(MacroNameTok.getIdentifierInfo(), MI);
+    Callbacks->MacroUndefined(MacroNameTok.getLocation(),
+                              MacroNameTok.getIdentifierInfo(), MI);
 
   // Free macro definition.
   ReleaseMacroInfo(MI);
diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
index 756ce27..163e869 100644
--- a/lib/Lex/PPExpressions.cpp
+++ b/lib/Lex/PPExpressions.cpp
@@ -19,11 +19,14 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/MacroInfo.h"
 #include "clang/Lex/LiteralSupport.h"
+#include "clang/Lex/CodeCompletionHandler.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/LexDiagnostic.h"
 #include "llvm/ADT/APSInt.h"
 using namespace clang;
 
+namespace {
+
 /// PPValue - Represents the value of a subexpression of a preprocessor
 /// conditional and the source range covered by it.
 class PPValue {
@@ -47,6 +50,8 @@
   void setEnd(SourceLocation L) { Range.setEnd(L); }
 };
 
+}
+
 static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
                                      Token &PeekTok, bool ValueLive,
                                      Preprocessor &PP);
@@ -88,6 +93,12 @@
     PP.LexUnexpandedToken(PeekTok);
   }
 
+  if (PeekTok.is(tok::code_completion)) {
+    if (PP.getCodeCompletionHandler())
+      PP.getCodeCompletionHandler()->CodeCompleteMacroName(false);
+    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);
@@ -138,6 +149,12 @@
                           bool ValueLive, Preprocessor &PP) {
   DT.State = DefinedTracker::Unknown;
 
+  if (PeekTok.is(tok::code_completion)) {
+    if (PP.getCodeCompletionHandler())
+      PP.getCodeCompletionHandler()->CodeCompletePreprocessorExpression();
+    PP.LexUnexpandedToken(PeekTok);
+  }
+      
   // 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.
@@ -693,7 +710,7 @@
   // 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();
 
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 1c6a5ad..894dc36 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -17,7 +17,9 @@
 #include "clang/Lex/MacroInfo.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/CodeCompletionHandler.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdio>
@@ -322,6 +324,13 @@
       // an argument value in a macro could expand to ',' or '(' or ')'.
       LexUnexpandedToken(Tok);
 
+      if (Tok.is(tok::code_completion)) {
+        if (CodeComplete)
+          CodeComplete->CodeCompleteMacroArgument(MacroName.getIdentifierInfo(),
+                                                  MI, NumActuals);
+        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.
@@ -487,28 +496,33 @@
   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_ext_vector_type", true)
            .Case("attribute_ns_returns_not_retained", true)
            .Case("attribute_ns_returns_retained", true)
            .Case("attribute_objc_ivar_unused", true)
+           .Case("attribute_overloadable", true)
+           .Case("blocks", LangOpts.Blocks)
+           .Case("cxx_attributes", LangOpts.CPlusPlus0x)
+           .Case("cxx_auto_type", LangOpts.CPlusPlus0x)
+           .Case("cxx_decltype", LangOpts.CPlusPlus0x)
+           .Case("cxx_deleted_functions", LangOpts.CPlusPlus0x)
+           .Case("cxx_exceptions", LangOpts.Exceptions)
+           .Case("cxx_rtti", LangOpts.RTTI)
+           .Case("cxx_static_assert", LangOpts.CPlusPlus0x)
+           .Case("objc_nonfragile_abi", LangOpts.ObjCNonFragileABI)
+           .Case("objc_weak_class", LangOpts.ObjCNonFragileABI)
+           .Case("ownership_holds", true)
+           .Case("ownership_returns", true)
+           .Case("ownership_takes", true)
+         //.Case("cxx_concepts", false)
+         //.Case("cxx_lambdas", false)
+         //.Case("cxx_nullptr", false)
+         //.Case("cxx_rvalue_references", false)
+         //.Case("cxx_variadic_templates", false)
+           .Case("tls", PP.getTargetInfo().isTLSSupported())
            .Default(false);
 }
 
diff --git a/lib/Lex/PTHLexer.cpp b/lib/Lex/PTHLexer.cpp
index 3b949d0..63b4823 100644
--- a/lib/Lex/PTHLexer.cpp
+++ b/lib/Lex/PTHLexer.cpp
@@ -101,16 +101,15 @@
     // Save the end-of-file token.
     EofToken = Tok;
 
+    // Save 'PP' to 'PPCache' as LexEndOfFile can delete 'this'.
     Preprocessor *PPCache = PP;
 
     assert(!ParsingPreprocessorDirective);
     assert(!LexingRawMode);
-
-    // FIXME: Issue diagnostics similar to Lexer.
-    if (PP->HandleEndOfFile(Tok, false))
+    
+    if (LexEndOfFile(Tok))
       return;
 
-    assert(PPCache && "Raw buffer::LexEndOfFile should return a token");
     return PPCache->Lex(Tok);
   }
 
@@ -134,6 +133,29 @@
   MIOpt.ReadToken();
 }
 
+bool PTHLexer::LexEndOfFile(Token &Result) {
+  // 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) {
+    ParsingPreprocessorDirective = false; // Done parsing the "line".
+    return true;  // Have a token.
+  }
+  
+  assert(!LexingRawMode);
+
+  // If we are in a #if directive, emit an error.
+  while (!ConditionalStack.empty()) {
+    if (!PP->isCodeCompletionFile(FileStartLoc))
+      PP->Diag(ConditionalStack.back().IfLoc,
+               diag::err_pp_unterminated_conditional);
+    ConditionalStack.pop_back();
+  }
+
+  // Finally, let the preprocessor handle this.
+  return PP->HandleEndOfFile(Result);
+}
+
 // FIXME: We can just grab the last token instead of storing a copy
 // into EofToken.
 void PTHLexer::getEOF(Token& Tok) {
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 92332a0..f0f3bce 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -16,9 +16,12 @@
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/MacroInfo.h"
 #include "clang/Lex/LexDiagnostic.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
+#include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/ErrorHandling.h"
 #include <algorithm>
 using namespace clang;
 
@@ -27,41 +30,47 @@
 }
 
 //===----------------------------------------------------------------------===//
+// EmptyPragmaHandler Implementation.
+//===----------------------------------------------------------------------===//
+
+EmptyPragmaHandler::EmptyPragmaHandler() {}
+
+void EmptyPragmaHandler::HandlePragma(Preprocessor &PP, Token &FirstToken) {}
+
+//===----------------------------------------------------------------------===//
 // PragmaNamespace Implementation.
 //===----------------------------------------------------------------------===//
 
 
 PragmaNamespace::~PragmaNamespace() {
-  for (unsigned i = 0, e = Handlers.size(); i != e; ++i)
-    delete Handlers[i];
+  for (llvm::StringMap<PragmaHandler*>::iterator
+         I = Handlers.begin(), E = Handlers.end(); I != E; ++I)
+    delete I->second;
 }
 
 /// 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,
+PragmaHandler *PragmaNamespace::FindHandler(llvm::StringRef 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 (PragmaHandler *Handler = Handlers.lookup(Name))
+    return Handler;
+  return IgnoreNull ? 0 : Handlers.lookup(llvm::StringRef());
+}
 
-    if (Handlers[i]->getName() == 0)
-      NullHandler = Handlers[i];
-  }
-  return IgnoreNull ? 0 : NullHandler;
+void PragmaNamespace::AddPragma(PragmaHandler *Handler) {
+  assert(!Handlers.lookup(Handler->getName()) &&
+         "A handler with this name is already registered in this namespace");
+  llvm::StringMapEntry<PragmaHandler *> &Entry =
+    Handlers.GetOrCreateValue(Handler->getName());
+  Entry.setValue(Handler);
 }
 
 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");
+  assert(Handlers.lookup(Handler->getName()) &&
+         "Handler not registered in this namespace");
+  Handlers.erase(Handler->getName());
 }
 
 void PragmaNamespace::HandlePragma(Preprocessor &PP, Token &Tok) {
@@ -70,7 +79,10 @@
   PP.LexUnexpandedToken(Tok);
 
   // Get the handler for this token.  If there is no handler, ignore the pragma.
-  PragmaHandler *Handler = FindHandler(Tok.getIdentifierInfo(), false);
+  PragmaHandler *Handler
+    = FindHandler(Tok.getIdentifierInfo() ? Tok.getIdentifierInfo()->getName()
+                                          : llvm::StringRef(),
+                  /*IgnoreNull=*/false);
   if (Handler == 0) {
     PP.Diag(Tok, diag::warn_pragma_ignored);
     return;
@@ -411,31 +423,193 @@
     Callbacks->PragmaComment(CommentLoc, II, ArgumentString);
 }
 
+/// HandlePragmaMessage - Handle the microsoft #pragma message extension.  The
+/// syntax is:
+///   #pragma message(messagestring)
+/// messagestring is a string, which is fully macro expanded, and permits string
+/// concatenation, embedded escape characters etc.  See MSDN for more details.
+void Preprocessor::HandlePragmaMessage(Token &Tok) {
+  SourceLocation MessageLoc = Tok.getLocation();
+  Lex(Tok);
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(MessageLoc, diag::err_pragma_message_malformed);
+    return;
+  }
 
+  // Read the string.
+  Lex(Tok);
+  
 
+  // We need at least one string.
+  if (Tok.isNot(tok::string_literal)) {
+    Diag(Tok.getLocation(), diag::err_pragma_message_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_message_malformed);
+    return;
+  }
+
+  llvm::StringRef MessageString(Literal.GetString(), Literal.GetStringLength());
+
+  if (Tok.isNot(tok::r_paren)) {
+    Diag(Tok.getLocation(), diag::err_pragma_message_malformed);
+    return;
+  }
+  Lex(Tok);  // eat the r_paren.
+
+  if (Tok.isNot(tok::eom)) {
+    Diag(Tok.getLocation(), diag::err_pragma_message_malformed);
+    return;
+  }
+
+  // Output the message.
+  Diag(MessageLoc, diag::warn_pragma_message) << MessageString;
+
+  // If the pragma is lexically sound, notify any interested PPCallbacks.
+  if (Callbacks)
+    Callbacks->PragmaMessage(MessageLoc, MessageString);
+}
+
+/// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.  
+/// Return the IdentifierInfo* associated with the macro to push or pop.
+IdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {
+  // Remember the pragma token location.
+  Token PragmaTok = Tok;
+
+  // Read the '('.
+  Lex(Tok);
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
+      << getSpelling(PragmaTok);
+    return 0;
+  }
+
+  // Read the macro name string.
+  Lex(Tok);
+  if (Tok.isNot(tok::string_literal)) {
+    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
+      << getSpelling(PragmaTok);
+    return 0;
+  }
+
+  // Remember the macro string.
+  std::string StrVal = getSpelling(Tok);
+
+  // Read the ')'.
+  Lex(Tok);
+  if (Tok.isNot(tok::r_paren)) {
+    Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
+      << getSpelling(PragmaTok);
+    return 0;
+  }
+
+  assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
+         "Invalid string token!");
+
+  // Create a Token from the string.
+  Token MacroTok;
+  MacroTok.startToken();
+  MacroTok.setKind(tok::identifier);
+  CreateString(&StrVal[1], StrVal.size() - 2, MacroTok);
+
+  // Get the IdentifierInfo of MacroToPushTok.
+  return LookUpIdentifierInfo(MacroTok);
+}
+
+/// HandlePragmaPushMacro - Handle #pragma push_macro.  
+/// The syntax is:
+///   #pragma push_macro("macro")
+void Preprocessor::HandlePragmaPushMacro(Token &PushMacroTok) {
+  // Parse the pragma directive and get the macro IdentifierInfo*.
+  IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PushMacroTok);
+  if (!IdentInfo) return;
+
+  // Get the MacroInfo associated with IdentInfo.
+  MacroInfo *MI = getMacroInfo(IdentInfo);
+ 
+  MacroInfo *MacroCopyToPush = 0;
+  if (MI) {
+    // Make a clone of MI.
+    MacroCopyToPush = CloneMacroInfo(*MI);
+    
+    // Allow the original MacroInfo to be redefined later.
+    MI->setIsAllowRedefinitionsWithoutWarning(true);
+  }
+
+  // Push the cloned MacroInfo so we can retrieve it later.
+  PragmaPushMacroInfo[IdentInfo].push_back(MacroCopyToPush);
+}
+
+/// HandlePragmaPopMacro - Handle #pragma push_macro.  
+/// The syntax is:
+///   #pragma pop_macro("macro")
+void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
+  SourceLocation MessageLoc = PopMacroTok.getLocation();
+
+  // Parse the pragma directive and get the macro IdentifierInfo*.
+  IdentifierInfo *IdentInfo = ParsePragmaPushOrPopMacro(PopMacroTok);
+  if (!IdentInfo) return;
+
+  // Find the vector<MacroInfo*> associated with the macro.
+  llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> >::iterator iter =
+    PragmaPushMacroInfo.find(IdentInfo);
+  if (iter != PragmaPushMacroInfo.end()) {
+    // Release the MacroInfo currently associated with IdentInfo.
+    MacroInfo *CurrentMI = getMacroInfo(IdentInfo);
+    if (CurrentMI) ReleaseMacroInfo(CurrentMI);
+
+    // Get the MacroInfo we want to reinstall.
+    MacroInfo *MacroToReInstall = iter->second.back();
+
+    // Reinstall the previously pushed macro.
+    setMacroInfo(IdentInfo, MacroToReInstall);
+
+    // Pop PragmaPushMacroInfo stack.
+    iter->second.pop_back();
+    if (iter->second.size() == 0)
+      PragmaPushMacroInfo.erase(iter);
+  } else {
+    Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
+      << IdentInfo->getName();
+  }
+}
 
 /// 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,
+void Preprocessor::AddPragmaHandler(llvm::StringRef 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 (!Namespace.empty()) {
     // 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)) {
+    if (PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
       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);
+      InsertNS = new PragmaNamespace(Namespace);
       PragmaHandlers->AddPragma(InsertNS);
     }
   }
@@ -450,14 +624,13 @@
 /// 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,
+void Preprocessor::RemovePragmaHandler(llvm::StringRef 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);
+  if (!Namespace.empty()) {
+    PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
     assert(Existing && "Namespace containing handler does not exist!");
 
     NS = Existing->getIfNamespace();
@@ -475,7 +648,7 @@
 namespace {
 /// PragmaOnceHandler - "#pragma once" marks the file as atomically included.
 struct PragmaOnceHandler : public PragmaHandler {
-  PragmaOnceHandler(const IdentifierInfo *OnceID) : PragmaHandler(OnceID) {}
+  PragmaOnceHandler() : PragmaHandler("once") {}
   virtual void HandlePragma(Preprocessor &PP, Token &OnceTok) {
     PP.CheckEndOfDirective("pragma once");
     PP.HandlePragmaOnce(OnceTok);
@@ -485,7 +658,7 @@
 /// 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) {}
+  PragmaMarkHandler() : PragmaHandler("mark") {}
   virtual void HandlePragma(Preprocessor &PP, Token &MarkTok) {
     PP.HandlePragmaMark();
   }
@@ -493,7 +666,7 @@
 
 /// PragmaPoisonHandler - "#pragma poison x" marks x as not usable.
 struct PragmaPoisonHandler : public PragmaHandler {
-  PragmaPoisonHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
+  PragmaPoisonHandler() : PragmaHandler("poison") {}
   virtual void HandlePragma(Preprocessor &PP, Token &PoisonTok) {
     PP.HandlePragmaPoison(PoisonTok);
   }
@@ -502,19 +675,55 @@
 /// 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) {}
+  PragmaSystemHeaderHandler() : PragmaHandler("system_header") {}
   virtual void HandlePragma(Preprocessor &PP, Token &SHToken) {
     PP.HandlePragmaSystemHeader(SHToken);
     PP.CheckEndOfDirective("pragma");
   }
 };
 struct PragmaDependencyHandler : public PragmaHandler {
-  PragmaDependencyHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
+  PragmaDependencyHandler() : PragmaHandler("dependency") {}
   virtual void HandlePragma(Preprocessor &PP, Token &DepToken) {
     PP.HandlePragmaDependency(DepToken);
   }
 };
 
+struct PragmaDebugHandler : public PragmaHandler {
+  PragmaDebugHandler() : PragmaHandler("__debug") {}
+  virtual void HandlePragma(Preprocessor &PP, Token &DepToken) {
+    Token Tok;
+    PP.LexUnexpandedToken(Tok);
+    if (Tok.isNot(tok::identifier)) {
+      PP.Diag(Tok, diag::warn_pragma_diagnostic_clang_invalid);
+      return;
+    }
+    IdentifierInfo *II = Tok.getIdentifierInfo();
+
+    if (II->isStr("assert")) {
+      assert(0 && "This is an assertion!");
+    } else if (II->isStr("crash")) {
+      *(volatile int*) 0x11 = 0;
+    } else if (II->isStr("llvm_fatal_error")) {
+      llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");
+    } else if (II->isStr("llvm_unreachable")) {
+      llvm_unreachable("#pragma clang __debug llvm_unreachable");
+    } else if (II->isStr("overflow_stack")) {
+      DebugOverflowStack();
+    } else if (II->isStr("handle_crash")) {
+      llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
+      if (CRC)
+        CRC->HandleCrash();
+    } else {
+      PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
+        << II->getName();
+    }
+  }
+
+  void DebugOverflowStack() {
+    DebugOverflowStack();
+  }
+};
+
 /// 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
@@ -523,9 +732,9 @@
 private:
   const bool ClangMode;
 public:
-  PragmaDiagnosticHandler(const IdentifierInfo *ID,
-                          const bool clangMode) : PragmaHandler(ID),
-                                                  ClangMode(clangMode) {}
+  explicit PragmaDiagnosticHandler(const bool clangMode)
+    : PragmaHandler("diagnostic"), ClangMode(clangMode) {}
+
   virtual void HandlePragma(Preprocessor &PP, Token &DiagToken) {
     Token Tok;
     PP.LexUnexpandedToken(Tok);
@@ -618,12 +827,39 @@
 
 /// PragmaCommentHandler - "#pragma comment ...".
 struct PragmaCommentHandler : public PragmaHandler {
-  PragmaCommentHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
+  PragmaCommentHandler() : PragmaHandler("comment") {}
   virtual void HandlePragma(Preprocessor &PP, Token &CommentTok) {
     PP.HandlePragmaComment(CommentTok);
   }
 };
 
+/// PragmaMessageHandler - "#pragma message("...")".
+struct PragmaMessageHandler : public PragmaHandler {
+  PragmaMessageHandler() : PragmaHandler("message") {}
+  virtual void HandlePragma(Preprocessor &PP, Token &CommentTok) {
+    PP.HandlePragmaMessage(CommentTok);
+  }
+};
+
+/// PragmaPushMacroHandler - "#pragma push_macro" saves the value of the
+/// macro on the top of the stack.
+struct PragmaPushMacroHandler : public PragmaHandler {
+  PragmaPushMacroHandler() : PragmaHandler("push_macro") {}
+  virtual void HandlePragma(Preprocessor &PP, Token &PushMacroTok) {
+    PP.HandlePragmaPushMacro(PushMacroTok);
+  }
+};
+
+
+/// PragmaPopMacroHandler - "#pragma pop_macro" sets the value of the
+/// macro to the value on the top of the stack.
+struct PragmaPopMacroHandler : public PragmaHandler {
+  PragmaPopMacroHandler() : PragmaHandler("pop_macro") {}
+  virtual void HandlePragma(Preprocessor &PP, Token &PopMacroTok) {
+    PP.HandlePragmaPopMacro(PopMacroTok);
+  }
+};
+
 // Pragma STDC implementations.
 
 enum STDCSetting {
@@ -660,7 +896,7 @@
 
 /// PragmaSTDC_FP_CONTRACTHandler - "#pragma STDC FP_CONTRACT ...".
 struct PragmaSTDC_FP_CONTRACTHandler : public PragmaHandler {
-  PragmaSTDC_FP_CONTRACTHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
+  PragmaSTDC_FP_CONTRACTHandler() : PragmaHandler("FP_CONTRACT") {}
   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
@@ -672,7 +908,7 @@
 
 /// PragmaSTDC_FENV_ACCESSHandler - "#pragma STDC FENV_ACCESS ...".
 struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
-  PragmaSTDC_FENV_ACCESSHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
+  PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
   virtual void HandlePragma(Preprocessor &PP, Token &Tok) {
     if (LexOnOffSwitch(PP) == STDC_ON)
       PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
@@ -681,8 +917,8 @@
 
 /// 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) {}
+  PragmaSTDC_CX_LIMITED_RANGEHandler()
+    : PragmaHandler("CX_LIMITED_RANGE") {}
   virtual void HandlePragma(Preprocessor &PP, Token &Tok) {
     LexOnOffSwitch(PP);
   }
@@ -690,7 +926,7 @@
 
 /// PragmaSTDC_UnknownHandler - "#pragma STDC ...".
 struct PragmaSTDC_UnknownHandler : public PragmaHandler {
-  PragmaSTDC_UnknownHandler() : PragmaHandler(0) {}
+  PragmaSTDC_UnknownHandler() {}
   virtual void HandlePragma(Preprocessor &PP, Token &UnknownTok) {
     // C99 6.10.6p2, unknown forms are not allowed.
     PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
@@ -703,38 +939,31 @@
 /// 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")));
+  AddPragmaHandler(new PragmaOnceHandler());
+  AddPragmaHandler(new PragmaMarkHandler());
+  AddPragmaHandler(new PragmaPushMacroHandler());
+  AddPragmaHandler(new PragmaPopMacroHandler());
 
   // #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));
+  AddPragmaHandler("GCC", new PragmaPoisonHandler());
+  AddPragmaHandler("GCC", new PragmaSystemHeaderHandler());
+  AddPragmaHandler("GCC", new PragmaDependencyHandler());
+  AddPragmaHandler("GCC", new PragmaDiagnosticHandler(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("clang", new PragmaPoisonHandler());
+  AddPragmaHandler("clang", new PragmaSystemHeaderHandler());
+  AddPragmaHandler("clang", new PragmaDebugHandler());
+  AddPragmaHandler("clang", new PragmaDependencyHandler());
+  AddPragmaHandler("clang", new PragmaDiagnosticHandler(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_FP_CONTRACTHandler());
+  AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler());
+  AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler());
   AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler());
 
   // MS extensions.
-  if (Features.Microsoft)
-    AddPragmaHandler(0, new PragmaCommentHandler(getIdentifierInfo("comment")));
+  if (Features.Microsoft) {
+    AddPragmaHandler(new PragmaCommentHandler());
+    AddPragmaHandler(new PragmaMessageHandler());
+  }
 }
diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp
index 6966c38..c446d96 100644
--- a/lib/Lex/PreprocessingRecord.cpp
+++ b/lib/Lex/PreprocessingRecord.cpp
@@ -118,7 +118,8 @@
   PreprocessedEntities.push_back(Def);
 }
 
-void PreprocessingRecord::MacroUndefined(const IdentifierInfo *II, 
+void PreprocessingRecord::MacroUndefined(SourceLocation Loc,
+                                         const IdentifierInfo *II,
                                          const MacroInfo *MI) {
   llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
     = MacroDefinitions.find(MI);
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index ce6d9ab..5160acf 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -34,6 +34,7 @@
 #include "clang/Lex/PreprocessingRecord.h"
 #include "clang/Lex/ScratchBuffer.h"
 #include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/CodeCompletionHandler.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -53,8 +54,9 @@
                            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) {
+    Identifiers(opts, IILookup), BuiltinInfo(Target), CodeComplete(0),
+    CodeCompletionFile(0), SkipMainFilePreamble(0, true), CurPPLexer(0), 
+    CurDirLookup(0), Callbacks(0), MacroArgCache(0), Record(0) {
   ScratchBuf = new ScratchBuffer(SourceMgr);
   CounterValue = 0; // __COUNTER__ starts at 0.
   OwnsHeaderSearch = OwnsHeaders;
@@ -87,7 +89,7 @@
   (Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned();
 
   // Initialize the pragma handlers.
-  PragmaHandlers = new PragmaNamespace(0);
+  PragmaHandlers = new PragmaNamespace(llvm::StringRef());
   RegisterBuiltinPragmas();
 
   // Initialize builtin macros like __LINE__ and friends.
@@ -110,9 +112,17 @@
     // 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->second->Destroy();
     I->first->setHasMacroDefinition(false);
   }
+  for (std::vector<MacroInfo*>::iterator I = MICache.begin(),
+                                         E = MICache.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)->Destroy();
+  }
 
   // Free any cached macro expanders.
   for (unsigned i = 0, e = NumCachedTokenLexers; i != e; ++i)
@@ -155,7 +165,7 @@
     llvm::errs() << " [ExpandDisabled]";
   if (Tok.needsCleaning()) {
     const char *Start = SourceMgr.getCharacterData(Tok.getLocation());
-    llvm::errs() << " [UnClean='" << std::string(Start, Start+Tok.getLength())
+    llvm::errs() << " [UnClean='" << llvm::StringRef(Start, Tok.getLength())
                  << "']";
   }
 
@@ -274,6 +284,13 @@
       == CodeCompletionFile;
 }
 
+void Preprocessor::CodeCompleteNaturalLanguage() {
+  SetCodeCompletionPoint(0, 0, 0);
+  getDiagnostics().setSuppressAllDiagnostics(true);
+  if (CodeComplete)
+    CodeComplete->CodeCompleteNaturalLanguage();
+}
+
 //===----------------------------------------------------------------------===//
 // Token Spelling
 //===----------------------------------------------------------------------===//
@@ -500,6 +517,12 @@
   // Enter the main file source buffer.
   EnterSourceFile(MainFileID, 0, SourceLocation());
 
+  // If we've been asked to skip bytes in the main file (e.g., as part of a
+  // precompiled preamble), do so now.
+  if (SkipMainFilePreamble.first > 0)
+    CurLexer->SkipBytes(SkipMainFilePreamble.first, 
+                        SkipMainFilePreamble.second);
+  
   // 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))
@@ -508,7 +531,7 @@
   // 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");
+  assert(SB && "Cannot create predefined source buffer");
   FileID FID = SourceMgr.createFileIDForMemBuffer(SB);
   assert(!FID.isInvalid() && "Could not create FileID for predefines?");
 
@@ -631,6 +654,8 @@
 
 CommentHandler::~CommentHandler() { }
 
+CodeCompletionHandler::~CodeCompletionHandler() { }
+
 void Preprocessor::createPreprocessingRecord() {
   if (Record)
     return;
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index 56bb073..94719b0 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -268,6 +268,13 @@
       // Remove the paste operator, report use of the extension.
       PP.Diag(ResultToks.back().getLocation(), diag::ext_paste_comma);
       ResultToks.pop_back();
+      
+      // If the comma was right after another paste (e.g. "X##,##__VA_ARGS__"),
+      // then removal of the comma should produce a placemarker token (in C99
+      // terms) which we model by popping off the previous ##, giving us a plain
+      // "X" when __VA_ARGS__ is empty.
+      if (!ResultToks.empty() && ResultToks.back().is(tok::hashhash))
+        ResultToks.pop_back();
     }
     continue;
   }
@@ -478,7 +485,7 @@
           return true;
         }
 
-        // Do not emit the warning when preprocessing assembler code.
+        // Do not emit the error 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.
@@ -486,8 +493,13 @@
           SourceLocation Loc =
             SM.createInstantiationLoc(PasteOpLoc, InstantiateLocStart,
                                       InstantiateLocEnd, 2);
-          PP.Diag(Loc, diag::err_pp_bad_paste)
-            << std::string(Buffer.begin(), Buffer.end());
+          // If we're in microsoft extensions mode, downgrade this from a hard
+          // error to a warning that defaults to an error.  This allows
+          // disabling it.
+          PP.Diag(Loc,
+                  PP.getLangOptions().Microsoft ? diag::err_pp_bad_paste_ms 
+                                                : diag::err_pp_bad_paste)
+            << Buffer.str();
         }
 
         // Do not consume the RHS.
diff --git a/lib/Makefile b/lib/Makefile
index 538bf43..dbd0eb6 100755
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -6,10 +6,10 @@
 # License. See LICENSE.TXT for details.
 # 
 ##===----------------------------------------------------------------------===##
-LEVEL = ../../..
+CLANG_LEVEL := ..
 
-PARALLEL_DIRS = Headers Runtime Basic Lex Parse AST Sema CodeGen Analysis \
-                Checker Rewrite Frontend Index Driver
+PARALLEL_DIRS = Headers Basic Lex Parse AST Sema CodeGen Analysis \
+                Checker Rewrite Serialization Frontend FrontendTool Index Driver
 
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
 
diff --git a/lib/Parse/Android.mk b/lib/Parse/Android.mk
index 918a42c..597fd49 100644
--- a/lib/Parse/Android.mk
+++ b/lib/Parse/Android.mk
@@ -6,13 +6,15 @@
 include $(CLEAR_TBLGEN_VARS)
 
 TBLGEN_TABLES :=    \
+	AttrList.inc	\
+	Attrs.inc	\
+	DeclNodes.inc	\
 	DiagnosticParseKinds.inc	\
-    DiagnosticCommonKinds.inc
+    DiagnosticCommonKinds.inc	\
+	StmtNodes.inc
 
 clang_parse_SRC_FILES :=	\
-	AttributeList.cpp	\
-	DeclSpec.cpp	\
-	MinimalAction.cpp	\
+	ParseAST.cpp	\
 	ParseCXXInlineMethods.cpp	\
 	ParseDecl.cpp	\
 	ParseDeclCXX.cpp	\
diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp
deleted file mode 100644
index 0ab6710..0000000
--- a/lib/Parse/AttributeList.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-//===--- 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
index bec1c6e..189af3d 100644
--- a/lib/Parse/CMakeLists.txt
+++ b/lib/Parse/CMakeLists.txt
@@ -1,9 +1,7 @@
 set(LLVM_NO_RTTI 1)
 
 add_clang_library(clangParse
-  AttributeList.cpp
-  DeclSpec.cpp
-  MinimalAction.cpp
+  ParseAST.cpp
   ParseCXXInlineMethods.cpp
   ParseDecl.cpp
   ParseDeclCXX.cpp
@@ -18,4 +16,4 @@
   Parser.cpp
   )
 
-add_dependencies(clangParse ClangDiagnosticParse)
+add_dependencies(clangParse ClangAttrClasses ClangAttrList ClangDeclNodes ClangDiagnosticParse ClangStmtNodes)
diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp
deleted file mode 100644
index 5dc08b3..0000000
--- a/lib/Parse/DeclSpec.cpp
+++ /dev/null
@@ -1,556 +0,0 @@
-//===--- 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
index 6a5540f..5ec7c33 100644
--- a/lib/Parse/Makefile
+++ b/lib/Parse/Makefile
@@ -11,11 +11,8 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
+CLANG_LEVEL := ../..
 LIBRARYNAME := clangParse
-BUILD_ARCHIVE = 1
 
-CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
 
diff --git a/lib/Parse/MinimalAction.cpp b/lib/Parse/MinimalAction.cpp
deleted file mode 100644
index 5a03767..0000000
--- a/lib/Parse/MinimalAction.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-//===--- 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/ParseAST.cpp b/lib/Parse/ParseAST.cpp
new file mode 100644
index 0000000..d027879
--- /dev/null
+++ b/lib/Parse/ParseAST.cpp
@@ -0,0 +1,114 @@
+//===--- 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/Parse/ParseAST.h"
+#include "clang/Sema/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/DeclCXX.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) {
+  Sema S(PP, Ctx, *Consumer, CompleteTranslationUnit, CompletionConsumer);
+  ParseAST(S, PrintStats);
+}
+
+void clang::ParseAST(Sema &S, bool PrintStats) {
+  // Collect global stats on Decls/Stmts (until we have a module streamer).
+  if (PrintStats) {
+    Decl::CollectingStats(true);
+    Stmt::CollectingStats(true);
+  }
+
+  ASTConsumer *Consumer = &S.getASTConsumer();
+
+  Parser P(S.getPreprocessor(), S);
+  S.getPreprocessor().EnterMainSourceFile();
+  P.Initialize();
+  S.Initialize();
+  
+  if (ExternalASTSource *External = S.getASTContext().getExternalSource())
+    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.get());
+  };
+  // Check for any pending objective-c implementation decl.
+  while ((ADecl = P.FinishPendingObjCActions()))
+    Consumer->HandleTopLevelDecl(ADecl.get());
+  
+  // 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 (S.getLangOptions().DumpRecordLayouts)
+    DumpRecordLayouts(S.getASTContext());
+  
+  Consumer->HandleTranslationUnit(S.getASTContext());
+  
+  if (PrintStats) {
+    fprintf(stderr, "\nSTATISTICS:\n");
+    P.getActions().PrintStats();
+    S.getASTContext().PrintStats();
+    Decl::PrintStats();
+    Stmt::PrintStats();
+    Consumer->PrintStats();
+  }
+}
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index 5405c0c..d327db4 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -13,32 +13,31 @@
 
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/Parser.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/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,
+Decl *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,
+  MultiTemplateParamsArg TemplateParams(Actions,
           TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data() : 0,
           TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
 
-  DeclPtrTy FnD;
+  Decl *FnD;
   if (D.getDeclSpec().isFriendSpecified())
     // FIXME: Friend templates
-    FnD = Actions.ActOnFriendFunctionDecl(CurScope, D, true,
+    FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D, true,
                                           move(TemplateParams));
   else // FIXME: pass template information through
-    FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D,
+    FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D,
                                            move(TemplateParams), 0, 0,
                                            /*IsDefinition*/true);
 
@@ -48,7 +47,7 @@
 
   getCurrentClass().MethodDefs.push_back(LexedMethod(FnD));
   getCurrentClass().MethodDefs.back().TemplateScope
-    = CurScope->isTemplateParamScope();
+    = getCurScope()->isTemplateParamScope();
   CachedTokens &Toks = getCurrentClass().MethodDefs.back().Toks;
 
   tok::TokenKind kind = Tok.getKind();
@@ -95,7 +94,7 @@
   bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
   ParseScope TemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
   if (HasTemplateScope)
-    Actions.ActOnReenterTemplateScope(CurScope, Class.TagOrTemplate);
+    Actions.ActOnReenterTemplateScope(getCurScope(), 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.
@@ -103,7 +102,7 @@
   ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
                         HasClassScope);
   if (HasClassScope)
-    Actions.ActOnStartDelayedMemberDeclarations(CurScope, Class.TagOrTemplate);
+    Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate);
 
   for (; !Class.MethodDecls.empty(); Class.MethodDecls.pop_front()) {
     LateParsedMethodDeclaration &LM = Class.MethodDecls.front();
@@ -111,10 +110,10 @@
     // 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);
+      Actions.ActOnReenterTemplateScope(getCurScope(), LM.Method);
 
     // Start the delayed C++ method declaration
-    Actions.ActOnStartDelayedCXXMethodDeclaration(CurScope, LM.Method);
+    Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
 
     // Introduce the parameters into scope and parse their default
     // arguments.
@@ -122,7 +121,7 @@
                               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);
+      Actions.ActOnDelayedCXXMethodParameter(getCurScope(), LM.DefaultArgs[I].Param);
 
       if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) {
         // Save the current token position.
@@ -139,19 +138,24 @@
         assert(Tok.is(tok::equal) && "Default argument not starting with '='");
         SourceLocation EqualLoc = ConsumeToken();
 
-        OwningExprResult DefArgResult(ParseAssignmentExpression());
+        ExprResult DefArgResult(ParseAssignmentExpression());
         if (DefArgResult.isInvalid())
           Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param);
-        else
+        else {
+          if (Tok.is(tok::cxx_defaultarg_end))
+            ConsumeToken();
+          else
+            Diag(Tok.getLocation(), diag::err_default_arg_unparsed);
           Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc,
-                                            move(DefArgResult));
+                                            DefArgResult.take());
+        }
 
         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)
+        while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
           ConsumeAnyToken();
 
         delete Toks;
@@ -161,14 +165,14 @@
     PrototypeScope.Exit();
 
     // Finish the delayed C++ method declaration.
-    Actions.ActOnFinishDelayedCXXMethodDeclaration(CurScope, LM.Method);
+    Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
   }
 
   for (unsigned I = 0, N = Class.NestedClasses.size(); I != N; ++I)
     ParseLexedMethodDeclarations(*Class.NestedClasses[I]);
 
   if (HasClassScope)
-    Actions.ActOnFinishDelayedMemberDeclarations(CurScope, Class.TagOrTemplate);
+    Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate);
 }
 
 /// ParseLexedMethodDefs - We finished parsing the member specification of a top
@@ -178,7 +182,7 @@
   bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
   ParseScope TemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
   if (HasTemplateScope)
-    Actions.ActOnReenterTemplateScope(CurScope, Class.TagOrTemplate);
+    Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
 
   bool HasClassScope = !Class.TopLevelClass;
   ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
@@ -190,7 +194,7 @@
     // 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);
+      Actions.ActOnReenterTemplateScope(getCurScope(), LM.D);
 
     // Save the current token position.
     SourceLocation origLoc = Tok.getLocation();
@@ -209,15 +213,17 @@
     // 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);
+    Actions.ActOnStartOfFunctionDef(getCurScope(), 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!");
+      // There could be leftover tokens (e.g. because of an error).
+      // Skip through until we reach the original token position.
+      while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
+        ConsumeAnyToken();
       continue;
     }
     if (Tok.is(tok::colon)) {
@@ -225,18 +231,26 @@
 
       // Error recovery.
       if (!Tok.is(tok::l_brace)) {
-        Actions.ActOnFinishFunctionBody(LM.D, Action::StmtArg(Actions));
+        Actions.ActOnFinishFunctionBody(LM.D, 0);
         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!");
+
+    if (Tok.getLocation() != origLoc) {
+      // Due to parsing error, we either went over the cached tokens or
+      // there are still cached tokens left. If it's the latter case skip the
+      // leftover tokens.
+      // Since this is an uncommon situation that should be avoided, use the
+      // expensive isBeforeInTranslationUnit call.
+      if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
+                                                          origLoc))
+        while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
+          ConsumeAnyToken();
+
+    }
   }
 
   for (unsigned I = 0, N = Class.NestedClasses.size(); I != N; ++I)
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 6669d40..1f81202 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -13,8 +13,9 @@
 
 #include "clang/Parse/Parser.h"
 #include "clang/Parse/ParseDiagnostic.h"
-#include "clang/Parse/Scope.h"
-#include "clang/Parse/Template.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Sema/PrettyDeclStackTrace.h"
 #include "RAIIObjectsForParser.h"
 #include "llvm/ADT/SmallSet.h"
 using namespace clang;
@@ -28,7 +29,7 @@
 ///         specifier-qualifier-list abstract-declarator[opt]
 ///
 /// Called type-id in C++.
-Action::TypeResult Parser::ParseTypeName(SourceRange *Range) {
+TypeResult Parser::ParseTypeName(SourceRange *Range) {
   // Parse the common declaration-specifiers piece.
   DeclSpec DS;
   ParseSpecifierQualifierList(DS);
@@ -42,7 +43,7 @@
   if (DeclaratorInfo.isInvalidType())
     return true;
 
-  return Actions.ActOnTypeName(CurScope, DeclaratorInfo);
+  return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
 }
 
 /// ParseGNUAttributes - Parse a non-empty attributes list.
@@ -131,7 +132,7 @@
 
             // now parse the non-empty comma separated list of expressions
             while (1) {
-              OwningExprResult ArgExpr(ParseAssignmentExpression());
+              ExprResult ArgExpr(ParseAssignmentExpression());
               if (ArgExpr.isInvalid()) {
                 ArgExprsOk = false;
                 SkipUntil(tok::r_paren);
@@ -174,11 +175,13 @@
           case tok::kw_double:
           case tok::kw_void:
           case tok::kw_typeof:
+            CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                                         0, SourceLocation(), 0, 0, CurrAttr);
+            if (CurrAttr->getKind() == AttributeList::AT_IBOutletCollection)
+              Diag(Tok, diag::err_iboutletcollection_builtintype);
             // 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;
@@ -189,7 +192,7 @@
 
             // now parse the list of expressions
             while (1) {
-              OwningExprResult ArgExpr(ParseAssignmentExpression());
+              ExprResult ArgExpr(ParseAssignmentExpression());
               if (ArgExpr.isInvalid()) {
                 ArgExprsOk = false;
                 SkipUntil(tok::r_paren);
@@ -254,9 +257,9 @@
       ConsumeParen();
       // FIXME: This doesn't parse __declspec(property(get=get_func_name))
       // correctly.
-      OwningExprResult ArgExpr(ParseAssignmentExpression());
+      ExprResult ArgExpr(ParseAssignmentExpression());
       if (!ArgExpr.isInvalid()) {
-        ExprTy* ExprList = ArgExpr.take();
+        Expr *ExprList = ArgExpr.take();
         CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
                                      SourceLocation(), &ExprList, 1,
                                      CurrAttr, true);
@@ -277,8 +280,8 @@
   // 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)) {
+         Tok.is(tok::kw___thiscall) || 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))
@@ -309,7 +312,9 @@
 Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
                                                 SourceLocation &DeclEnd,
                                                 CXX0XAttributeList Attr) {
-  DeclPtrTy SingleDecl;
+  ParenBraceBracketBalancer BalancerRAIIObj(*this);
+  
+  Decl *SingleDecl = 0;
   switch (Tok.getKind()) {
   case tok::kw_template:
   case tok::kw_export:
@@ -318,6 +323,17 @@
         << Attr.Range;
     SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
     break;
+  case tok::kw_inline:
+    // Could be the start of an inline namespace.
+    if (getLang().CPlusPlus0x && NextToken().is(tok::kw_namespace)) {
+      if (Attr.HasAttr)
+        Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
+          << Attr.Range;
+      SourceLocation InlineLoc = ConsumeToken();
+      SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc);
+      break;
+    }
+    return ParseSimpleDeclaration(Context, DeclEnd, Attr.AttrList, true);
   case tok::kw_namespace:
     if (Attr.HasAttr)
       Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
@@ -364,7 +380,8 @@
   // declaration-specifiers init-declarator-list[opt] ';'
   if (Tok.is(tok::semi)) {
     if (RequireSemi) ConsumeToken();
-    DeclPtrTy TheDecl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
+    Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
+                                                           DS);
     DS.complete(TheDecl);
     return Actions.ConvertDeclToDeclGroup(TheDecl);
   }
@@ -392,12 +409,14 @@
     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()) {
+  // Check to see if we have a function *definition* which must have a body.
+  if (AllowFunctionDefinitions && D.isFunctionDeclarator() &&
+      // Look at the next token to make sure that this isn't a function
+      // declaration.  We have to check this because __attribute__ might be the
+      // start of a function definition in GCC-extended K&R C.
+      !isDeclarationAfterDeclarator()) {
+    
+    if (isStartOfFunctionDefinition(D)) {
       if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
         Diag(Tok, diag::err_function_declared_typedef);
 
@@ -405,8 +424,16 @@
         DS.ClearStorageClassSpecs();
       }
 
-      DeclPtrTy TheDecl = ParseFunctionDefinition(D);
+      Decl *TheDecl = ParseFunctionDefinition(D);
       return Actions.ConvertDeclToDeclGroup(TheDecl);
+    }
+    
+    if (isDeclarationSpecifier()) {
+      // If there is an invalid declaration specifier right after the function
+      // prototype, then we must be in a missing semicolon case where this isn't
+      // actually a body.  Just fall through into the code that handles it as a
+      // prototype, and let the top-level code handle the erroneous declspec
+      // where it would otherwise expect a comma or semicolon.
     } else {
       Diag(Tok, diag::err_expected_fn_body);
       SkipUntil(tok::semi);
@@ -414,10 +441,10 @@
     }
   }
 
-  llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup;
-  DeclPtrTy FirstDecl = ParseDeclarationAfterDeclarator(D);
+  llvm::SmallVector<Decl *, 8> DeclsInGroup;
+  Decl *FirstDecl = ParseDeclarationAfterDeclarator(D);
   D.complete(FirstDecl);
-  if (FirstDecl.get())
+  if (FirstDecl)
     DeclsInGroup.push_back(FirstDecl);
 
   // If we don't have a comma, it is either the end of the list (a ';') or an
@@ -444,9 +471,9 @@
 
     ParseDeclarator(D);
 
-    DeclPtrTy ThisDecl = ParseDeclarationAfterDeclarator(D);
+    Decl *ThisDecl = ParseDeclarationAfterDeclarator(D);
     D.complete(ThisDecl);
-    if (ThisDecl.get())
+    if (ThisDecl)
       DeclsInGroup.push_back(ThisDecl);    
   }
 
@@ -458,12 +485,17 @@
                        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();
+    // Okay, there was no semicolon and one was expected.  If we see a
+    // declaration specifier, just assume it was missing and continue parsing.
+    // Otherwise things are very confused and we skip to recover.
+    if (!isDeclarationSpecifier()) {
+      SkipUntil(tok::r_brace, true, true);
+      if (Tok.is(tok::semi))
+        ConsumeToken();
+    }
   }
 
-  return Actions.FinalizeDeclaratorGroup(CurScope, DS,
+  return Actions.FinalizeDeclaratorGroup(getCurScope(), DS,
                                          DeclsInGroup.data(),
                                          DeclsInGroup.size());
 }
@@ -489,15 +521,15 @@
 /// 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,
+Decl *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));
+    ExprResult AsmLabel(ParseSimpleAsm(&Loc));
     if (AsmLabel.isInvalid()) {
       SkipUntil(tok::semi, true, true);
-      return DeclPtrTy();
+      return 0;
     }
 
     D.setAsmLabel(AsmLabel.release());
@@ -512,30 +544,30 @@
   }
 
   // Inform the current actions module that we just parsed this declarator.
-  DeclPtrTy ThisDecl;
+  Decl *ThisDecl = 0;
   switch (TemplateInfo.Kind) {
   case ParsedTemplateInfo::NonTemplate:
-    ThisDecl = Actions.ActOnDeclarator(CurScope, D);
+    ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
     break;
       
   case ParsedTemplateInfo::Template:
   case ParsedTemplateInfo::ExplicitSpecialization:
-    ThisDecl = Actions.ActOnTemplateDeclarator(CurScope,
-                             Action::MultiTemplateParamsArg(Actions,
+    ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
+                             MultiTemplateParamsArg(Actions,
                                           TemplateInfo.TemplateParams->data(),
                                           TemplateInfo.TemplateParams->size()),
                                                D);
     break;
       
   case ParsedTemplateInfo::ExplicitInstantiation: {
-    Action::DeclResult ThisRes 
-      = Actions.ActOnExplicitInstantiation(CurScope,
+    DeclResult ThisRes 
+      = Actions.ActOnExplicitInstantiation(getCurScope(),
                                            TemplateInfo.ExternLoc,
                                            TemplateInfo.TemplateLoc,
                                            D);
     if (ThisRes.isInvalid()) {
       SkipUntil(tok::semi, true, true);
-      return DeclPtrTy();
+      return 0;
     }
     
     ThisDecl = ThisRes.get();
@@ -552,13 +584,20 @@
     } else {
       if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
         EnterScope(0);
-        Actions.ActOnCXXEnterDeclInitializer(CurScope, ThisDecl);
+        Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
       }
 
-      OwningExprResult Init(ParseInitializer());
+      if (Tok.is(tok::code_completion)) {
+        Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
+        ConsumeCodeCompletionToken();
+        SkipUntil(tok::comma, true, true);
+        return ThisDecl;
+      }
+      
+      ExprResult Init(ParseInitializer());
 
       if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
-        Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl);
+        Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
         ExitScope();
       }
 
@@ -566,7 +605,7 @@
         SkipUntil(tok::comma, true, true);
         Actions.ActOnInitializerError(ThisDecl);
       } else
-        Actions.AddInitializerToDecl(ThisDecl, move(Init));
+        Actions.AddInitializerToDecl(ThisDecl, Init.take());
     }
   } else if (Tok.is(tok::l_paren)) {
     // Parse C++ direct initializer: '(' expression-list ')'
@@ -576,14 +615,14 @@
 
     if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
       EnterScope(0);
-      Actions.ActOnCXXEnterDeclInitializer(CurScope, ThisDecl);
+      Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
     }
 
     if (ParseExpressionList(Exprs, CommaLocs)) {
       SkipUntil(tok::r_paren);
 
       if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
-        Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl);
+        Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
         ExitScope();
       }
     } else {
@@ -594,7 +633,7 @@
              "Unexpected number of commas!");
 
       if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
-        Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl);
+        Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
         ExitScope();
       }
 
@@ -722,7 +761,7 @@
     const char *TagName = 0;
     tok::TokenKind TagKind = tok::unknown;
 
-    switch (Actions.isTagName(*Tok.getIdentifierInfo(), CurScope)) {
+    switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) {
       default: break;
       case DeclSpec::TST_enum:  TagName="enum"  ;TagKind=tok::kw_enum  ;break;
       case DeclSpec::TST_union: TagName="union" ;TagKind=tok::kw_union ;break;
@@ -746,9 +785,9 @@
 
   // This is almost certainly an invalid type name. Let the action emit a 
   // diagnostic and attempt to recover.
-  Action::TypeTy *T = 0;
+  ParsedType T;
   if (Actions.DiagnoseUnknownTypeName(*Tok.getIdentifierInfo(), Loc,
-                                      CurScope, SS, T)) {
+                                      getCurScope(), 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
@@ -756,8 +795,7 @@
       // name token, and we're done.
       const char *PrevSpec;
       unsigned DiagID;
-      DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T, 
-                         false);
+      DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T);
       DS.SetRangeEnd(Tok.getLocation());
       ConsumeToken();
       
@@ -826,21 +864,7 @@
 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();
-  }
-  
+                                        DeclSpecContext DSContext) {  
   DS.SetRangeStart(Tok.getLocation());
   while (1) {
     bool isInvalid = false;
@@ -857,6 +881,38 @@
       DS.Finish(Diags, PP);
       return;
 
+    case tok::code_completion: {
+      Sema::ParserCompletionContext CCC = Sema::PCC_Namespace;
+      if (DS.hasTypeSpecifier()) {
+        bool AllowNonIdentifiers
+          = (getCurScope()->getFlags() & (Scope::ControlScope |
+                                          Scope::BlockScope |
+                                          Scope::TemplateParamScope |
+                                          Scope::FunctionPrototypeScope |
+                                          Scope::AtCatchScope)) == 0;
+        bool AllowNestedNameSpecifiers
+          = DSContext == DSC_top_level || 
+            (DSContext == DSC_class && DS.isFriendSpecified());
+
+        Actions.CodeCompleteDeclarator(getCurScope(), AllowNonIdentifiers, 
+                                       AllowNestedNameSpecifiers);
+        ConsumeCodeCompletionToken();
+        return;
+      } 
+      
+      if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
+        CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate 
+                                    : Sema::PCC_Template;
+      else if (DSContext == DSC_class)
+        CCC = Sema::PCC_Class;
+      else if (ObjCImpDecl)
+        CCC = Sema::PCC_ObjCImplementation;
+      
+      Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
+      ConsumeCodeCompletionToken();
+      return;
+    }
+
     case tok::coloncolon: // ::foo::bar
       // C++ scope specifier.  Annotate and loop, or bail out on error.
       if (TryAnnotateCXXScopeToken(true)) {
@@ -873,7 +929,7 @@
         goto DoneWithDeclSpec;
 
       CXXScopeSpec SS;
-      SS.setScopeRep(Tok.getAnnotationValue());
+      SS.setScopeRep((NestedNameSpecifier*) Tok.getAnnotationValue());
       SS.setRange(Tok.getAnnotationRange());
 
       // We are looking for a qualified typename.
@@ -907,7 +963,7 @@
         if ((DSContext == DSC_top_level ||
              (DSContext == DSC_class && DS.isFriendSpecified())) &&
             TemplateId->Name &&
-            Actions.isCurrentClassName(*TemplateId->Name, CurScope, &SS)) {
+            Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {
           if (isConstructorDeclarator()) {
             // The user meant this to be an out-of-line constructor
             // definition, but template arguments are not allowed
@@ -936,10 +992,11 @@
       if (Next.is(tok::annot_typename)) {
         DS.getTypeSpecScope() = SS;
         ConsumeToken(); // The C++ scope.
-        if (Tok.getAnnotationValue())
+        if (Tok.getAnnotationValue()) {
+          ParsedType T = getTypeAnnotation(Tok);
           isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, 
-                                         PrevSpec, DiagID, 
-                                         Tok.getAnnotationValue());
+                                         PrevSpec, DiagID, T);
+        }
         else
           DS.SetTypeSpecError();
         DS.SetRangeEnd(Tok.getAnnotationEndLoc());
@@ -953,7 +1010,7 @@
       // check whether this is a constructor declaration.
       if ((DSContext == DSC_top_level ||
            (DSContext == DSC_class && DS.isFriendSpecified())) &&
-          Actions.isCurrentClassName(*Next.getIdentifierInfo(), CurScope, 
+          Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(), 
                                      &SS)) {
         if (isConstructorDeclarator())
           goto DoneWithDeclSpec;
@@ -968,8 +1025,9 @@
           << Next.getIdentifierInfo();
       }
 
-      TypeTy *TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
-                                            Next.getLocation(), CurScope, &SS);
+      ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
+                                               Next.getLocation(),
+                                               getCurScope(), &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
@@ -996,10 +1054,11 @@
     }
 
     case tok::annot_typename: {
-      if (Tok.getAnnotationValue())
+      if (Tok.getAnnotationValue()) {
+        ParsedType T = getTypeAnnotation(Tok);
         isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
-                                       DiagID, Tok.getAnnotationValue());
-      else
+                                       DiagID, T);
+      } else
         DS.SetTypeSpecError();
       
       if (isInvalid)
@@ -1016,7 +1075,7 @@
         continue;
 
       SourceLocation LAngleLoc, EndProtoLoc;
-      llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
+      llvm::SmallVector<Decl *, 8> ProtocolDecl;
       llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
       ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
                                   LAngleLoc, EndProtoLoc);
@@ -1052,12 +1111,13 @@
         break;
 
       // It has to be available as a typedef too!
-      TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(),
-                                            Tok.getLocation(), CurScope);
+      ParsedType TypeRep =
+        Actions.getTypeName(*Tok.getIdentifierInfo(),
+                            Tok.getLocation(), getCurScope());
 
       // 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 (!TypeRep) {
         if (ParseImplicitInt(DS, 0, TemplateInfo, AS)) continue;
         goto DoneWithDeclSpec;
       }
@@ -1065,7 +1125,7 @@
       // 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) &&
+          Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
           isConstructorDeclarator())
         goto DoneWithDeclSpec;
 
@@ -1085,7 +1145,7 @@
         continue;
 
       SourceLocation LAngleLoc, EndProtoLoc;
-      llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
+      llvm::SmallVector<Decl *, 8> ProtocolDecl;
       llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
       ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
                                   LAngleLoc, EndProtoLoc);
@@ -1113,7 +1173,7 @@
       // constructor name or specialization, check whether this is a
       // constructor declaration.
       if (getLang().CPlusPlus && DSContext == DSC_class &&
-          Actions.isCurrentClassName(*TemplateId->Name, CurScope) &&
+          Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&
           isConstructorDeclarator())
         goto DoneWithDeclSpec;
 
@@ -1143,6 +1203,7 @@
     case tok::kw___cdecl:
     case tok::kw___stdcall:
     case tok::kw___fastcall:
+    case tok::kw___thiscall:
       DS.AddAttributes(ParseMicrosoftTypeAttributes());
       continue;
 
@@ -1357,7 +1418,7 @@
 
       {
         SourceLocation LAngleLoc, EndProtoLoc;
-        llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
+        llvm::SmallVector<Decl *, 8> ProtocolDecl;
         llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
         ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
                                     LAngleLoc, EndProtoLoc);
@@ -1377,7 +1438,12 @@
     if (isInvalid) {
       assert(PrevSpec && "Method did not return previous specifier!");
       assert(DiagID);
-      Diag(Tok, DiagID) << PrevSpec;
+      
+      if (DiagID == diag::ext_duplicate_declspec)
+        Diag(Tok, DiagID)
+          << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
+      else
+        Diag(Tok, DiagID) << PrevSpec;
     }
     DS.SetRangeEnd(Tok.getLocation());
     ConsumeToken();
@@ -1469,10 +1535,10 @@
 
   // simple-type-specifier:
   case tok::annot_typename: {
-    if (Tok.getAnnotationValue())
+    if (ParsedType T = getTypeAnnotation(Tok)) {
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
-                                     DiagID, Tok.getAnnotationValue());
-    else
+                                     DiagID, T);
+    } else
       DS.SetTypeSpecError();
     DS.SetRangeEnd(Tok.getAnnotationEndLoc());
     ConsumeToken(); // The typename
@@ -1485,7 +1551,7 @@
       return true;
 
     SourceLocation LAngleLoc, EndProtoLoc;
-    llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
+    llvm::SmallVector<Decl *, 8> ProtocolDecl;
     llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
     ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
                                 LAngleLoc, EndProtoLoc);
@@ -1622,6 +1688,7 @@
   case tok::kw___cdecl:
   case tok::kw___stdcall:
   case tok::kw___fastcall:
+  case tok::kw___thiscall:
     DS.AddAttributes(ParseMicrosoftTypeAttributes());
     return true;
 
@@ -1674,7 +1741,7 @@
   // 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);
+    Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, DS);
     return;
   }
 
@@ -1701,7 +1768,7 @@
 
     if (Tok.is(tok::colon)) {
       ConsumeToken();
-      OwningExprResult Res(ParseConstantExpression());
+      ExprResult Res(ParseConstantExpression());
       if (Res.isInvalid())
         SkipUntil(tok::semi, true, true);
       else
@@ -1716,7 +1783,7 @@
     }
 
     // We're done with this declarator;  invoke the callback.
-    DeclPtrTy D = Fields.invoke(DeclaratorInfo);
+    Decl *D = Fields.invoke(DeclaratorInfo);
     PD.complete(D);
 
     // If we don't have a comma, it is either the end of the list (a ';')
@@ -1742,23 +1809,22 @@
 /// [OBC]   '@' 'defs' '(' class-name ')'
 ///
 void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
-                                  unsigned TagType, DeclPtrTy TagDecl) {
-  PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
-                                        PP.getSourceManager(),
-                                        "parsing struct/union body");
+                                  unsigned TagType, Decl *TagDecl) {
+  PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
+                                      "parsing struct/union body");
 
   SourceLocation LBraceLoc = ConsumeBrace();
 
   ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
-  Actions.ActOnTagStartDefinition(CurScope, TagDecl);
+  Actions.ActOnTagStartDefinition(getCurScope(), 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);
+    Diag(Tok, diag::ext_empty_struct_union)
+      << (TagType == TST_union);
 
-  llvm::SmallVector<DeclPtrTy, 32> FieldDecls;
+  llvm::SmallVector<Decl *, 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)) {
@@ -1767,6 +1833,7 @@
     // Check for extraneous top-level semicolon.
     if (Tok.is(tok::semi)) {
       Diag(Tok, diag::ext_extra_struct_semi)
+        << DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
         << FixItHint::CreateRemoval(Tok.getLocation());
       ConsumeToken();
       continue;
@@ -1778,16 +1845,16 @@
     if (!Tok.is(tok::at)) {
       struct CFieldCallback : FieldCallback {
         Parser &P;
-        DeclPtrTy TagDecl;
-        llvm::SmallVectorImpl<DeclPtrTy> &FieldDecls;
+        Decl *TagDecl;
+        llvm::SmallVectorImpl<Decl *> &FieldDecls;
 
-        CFieldCallback(Parser &P, DeclPtrTy TagDecl,
-                       llvm::SmallVectorImpl<DeclPtrTy> &FieldDecls) :
+        CFieldCallback(Parser &P, Decl *TagDecl,
+                       llvm::SmallVectorImpl<Decl *> &FieldDecls) :
           P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
 
-        virtual DeclPtrTy invoke(FieldDeclarator &FD) {
+        virtual Decl *invoke(FieldDeclarator &FD) {
           // Install the declarator into the current TagDecl.
-          DeclPtrTy Field = P.Actions.ActOnField(P.CurScope, TagDecl,
+          Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl,
                               FD.D.getDeclSpec().getSourceRange().getBegin(),
                                                  FD.D, FD.BitfieldSize);
           FieldDecls.push_back(Field);
@@ -1810,8 +1877,8 @@
         SkipUntil(tok::semi, true);
         continue;
       }
-      llvm::SmallVector<DeclPtrTy, 16> Fields;
-      Actions.ActOnDefs(CurScope, TagDecl, Tok.getLocation(),
+      llvm::SmallVector<Decl *, 16> Fields;
+      Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(),
                         Tok.getIdentifierInfo(), Fields);
       FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
       ConsumeToken();
@@ -1839,12 +1906,12 @@
   if (Tok.is(tok::kw___attribute))
     AttrList.reset(ParseGNUAttributes());
 
-  Actions.ActOnFields(CurScope,
+  Actions.ActOnFields(getCurScope(),
                       RecordLoc, TagDecl, FieldDecls.data(), FieldDecls.size(),
                       LBraceLoc, RBraceLoc,
                       AttrList.get());
   StructScope.Exit();
-  Actions.ActOnTagFinishDefinition(CurScope, TagDecl, RBraceLoc);
+  Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, RBraceLoc);
 }
 
 
@@ -1866,8 +1933,8 @@
   // 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();
+    Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);
+    ConsumeCodeCompletionToken();
   }
   
   llvm::OwningPtr<AttributeList> Attr;
@@ -1875,9 +1942,9 @@
   if (Tok.is(tok::kw___attribute))
     Attr.reset(ParseGNUAttributes());
 
-  CXXScopeSpec SS;
+  CXXScopeSpec &SS = DS.getTypeSpecScope();
   if (getLang().CPlusPlus) {
-    if (ParseOptionalCXXScopeSpecifier(SS, 0, false))
+    if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false))
       return;
 
     if (SS.isSet() && Tok.isNot(tok::identifier)) {
@@ -1900,15 +1967,6 @@
     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;
@@ -1925,23 +1983,35 @@
   // enum foo {..};  void bar() { enum foo; }    <- new foo in bar.
   // enum foo {..};  void bar() { enum foo x; }  <- use of old foo.
   //
-  Action::TagUseKind TUK;
+  Sema::TagUseKind TUK;
   if (Tok.is(tok::l_brace))
-    TUK = Action::TUK_Definition;
+    TUK = Sema::TUK_Definition;
   else if (Tok.is(tok::semi))
-    TUK = Action::TUK_Declaration;
+    TUK = Sema::TUK_Declaration;
   else
-    TUK = Action::TUK_Reference;
+    TUK = Sema::TUK_Reference;
+  
+  // enums cannot be templates, although they can be referenced from a 
+  // template.
+  if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
+      TUK != Sema::TUK_Reference) {
+    Diag(Tok, diag::err_enum_template);
+    
+    // Skip the rest of this declarator, up until the comma or semicolon.
+    SkipUntil(tok::comma, true);
+    return;      
+  }
+  
   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);
+  Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
+                                   StartLoc, SS, Name, NameLoc, Attr.get(),
+                                   AS,
+                                   MultiTemplateParamsArg(Actions),
+                                   Owned, IsDependent);
   if (IsDependent) {
     // This enum has a dependent nested-name-specifier. Handle it as a 
     // dependent tag.
@@ -1951,7 +2021,7 @@
       return;
     }
     
-    TypeResult Type = Actions.ActOnDependentTag(CurScope, DeclSpec::TST_enum,
+    TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum,
                                                 TUK, SS, Name, StartLoc, 
                                                 NameLoc);
     if (Type.isInvalid()) {
@@ -1960,13 +2030,13 @@
     }
     
     if (DS.SetTypeSpecType(DeclSpec::TST_typename, TSTLoc, PrevSpec, DiagID,
-                           Type.get(), false))
+                           Type.get()))
       Diag(StartLoc, DiagID) << PrevSpec;
     
     return;
   }
 
-  if (!TagDecl.get()) {
+  if (!TagDecl) {
     // The action failed to produce an enumeration tag. If this is a 
     // definition, consume the entire definition.
     if (Tok.is(tok::l_brace)) {
@@ -1981,10 +2051,10 @@
   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).
+  // 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))
+                         TagDecl, Owned))
     Diag(StartLoc, DiagID) << PrevSpec;
 }
 
@@ -1998,20 +2068,20 @@
 ///       enumeration-constant:
 ///         identifier
 ///
-void Parser::ParseEnumBody(SourceLocation StartLoc, DeclPtrTy EnumDecl) {
+void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
   // Enter the scope of the enum body and start the definition.
   ParseScope EnumScope(this, Scope::DeclScope);
-  Actions.ActOnTagStartDefinition(CurScope, EnumDecl);
+  Actions.ActOnTagStartDefinition(getCurScope(), 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";
+    Diag(Tok, diag::error_empty_enum);
 
-  llvm::SmallVector<DeclPtrTy, 32> EnumConstantDecls;
+  llvm::SmallVector<Decl *, 32> EnumConstantDecls;
 
-  DeclPtrTy LastEnumConstDecl;
+  Decl *LastEnumConstDecl = 0;
 
   // Parse the enumerator-list.
   while (Tok.is(tok::identifier)) {
@@ -2019,7 +2089,7 @@
     SourceLocation IdentLoc = ConsumeToken();
 
     SourceLocation EqualLoc;
-    OwningExprResult AssignedVal(Actions);
+    ExprResult AssignedVal;
     if (Tok.is(tok::equal)) {
       EqualLoc = ConsumeToken();
       AssignedVal = ParseConstantExpression();
@@ -2028,11 +2098,11 @@
     }
 
     // Install the enumerator constant into EnumDecl.
-    DeclPtrTy EnumConstDecl = Actions.ActOnEnumConstant(CurScope, EnumDecl,
-                                                        LastEnumConstDecl,
-                                                        IdentLoc, Ident,
-                                                        EqualLoc,
-                                                        AssignedVal.release());
+    Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
+                                                    LastEnumConstDecl,
+                                                    IdentLoc, Ident,
+                                                    EqualLoc,
+                                                    AssignedVal.release());
     EnumConstantDecls.push_back(EnumConstDecl);
     LastEnumConstDecl = EnumConstDecl;
 
@@ -2057,10 +2127,10 @@
 
   Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl,
                         EnumConstantDecls.data(), EnumConstantDecls.size(),
-                        CurScope, Attr.get());
+                        getCurScope(), Attr.get());
 
   EnumScope.Exit();
-  Actions.ActOnTagFinishDefinition(CurScope, EnumDecl, RBraceLoc);
+  Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, RBraceLoc);
 }
 
 /// isTypeSpecifierQualifier - Return true if the current token could be the
@@ -2195,6 +2265,7 @@
   case tok::kw___cdecl:
   case tok::kw___stdcall:
   case tok::kw___fastcall:
+  case tok::kw___thiscall:
   case tok::kw___w64:
   case tok::kw___ptr64:
     return true;
@@ -2301,6 +2372,7 @@
   case tok::kw___cdecl:
   case tok::kw___stdcall:
   case tok::kw___fastcall:
+  case tok::kw___thiscall:
   case tok::kw___w64:
   case tok::kw___ptr64:
   case tok::kw___forceinline:
@@ -2313,7 +2385,7 @@
 
   // Parse the C++ scope specifier.
   CXXScopeSpec SS;
-  if (ParseOptionalCXXScopeSpecifier(SS, 0, true)) {
+  if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), true)) {
     TPA.Revert();
     return false;
   }
@@ -2343,7 +2415,7 @@
 
   // If we need to, enter the specified scope.
   DeclaratorScopeObj DeclScopeObj(*this, SS);
-  if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(CurScope, SS))
+  if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))
     DeclScopeObj.EnterDeclaratorScope();
 
   // Check whether the next token(s) are part of a declaration
@@ -2381,6 +2453,11 @@
     SourceLocation Loc = Tok.getLocation();
 
     switch (Tok.getKind()) {
+    case tok::code_completion:
+      Actions.CodeCompleteTypeQualifiers(DS);
+      ConsumeCodeCompletionToken();
+      break;
+        
     case tok::kw_const:
       isInvalid = DS.SetTypeQual(DeclSpec::TQ_const   , Loc, PrevSpec, DiagID,
                                  getLang());
@@ -2398,6 +2475,7 @@
     case tok::kw___cdecl:
     case tok::kw___stdcall:
     case tok::kw___fastcall:
+    case tok::kw___thiscall:
       if (GNUAttributesAllowed) {
         DS.AddAttributes(ParseMicrosoftTypeAttributes());
         continue;
@@ -2460,6 +2538,7 @@
                                      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.
@@ -2467,7 +2546,7 @@
       (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
        Tok.is(tok::annot_cxxscope))) {
     CXXScopeSpec SS;
-    ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true); // ignore fail
+    ParseOptionalCXXScopeSpecifier(SS, ParsedType(), true); // ignore fail
 
     if (SS.isNotEmpty()) {
       if (Tok.isNot(tok::star)) {
@@ -2626,12 +2705,11 @@
   if (getLang().CPlusPlus && D.mayHaveIdentifier()) {
     // ParseDeclaratorInternal might already have parsed the scope.
     if (D.getCXXScopeSpec().isEmpty()) {
-      ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), /*ObjectType=*/0,
-                                     true);
+      ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(), true);
     }
 
     if (D.getCXXScopeSpec().isValid()) {
-      if (Actions.ShouldEnterDeclaratorScope(CurScope, D.getCXXScopeSpec()))
+      if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
         // Change the declaration context for name lookup, until this function
         // is exited (and the declarator has been parsed).
         DeclScopeObj.EnterDeclaratorScope();
@@ -2656,7 +2734,7 @@
                              /*EnteringContext=*/true, 
                              /*AllowDestructorName=*/true, 
                              AllowConstructorName,
-                             /*ObjectType=*/0,
+                             ParsedType(),
                              D.getName()) ||
           // Once we're past the identifier, if the scope was bad, mark the
           // whole declarator bad.
@@ -2690,7 +2768,10 @@
     // 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()))
+      // If there was an error parsing parenthesized declarator, declarator
+      // scope may have been enterred before. Don't do it again.
+      if (!D.isInvalidType() &&
+          Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
         // Change the declaration context for name lookup, until this function
         // is exited (and the declarator has been parsed).
         DeclScopeObj.EnterDeclaratorScope();
@@ -2782,8 +2863,8 @@
   }
   // 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)) {
+       Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___fastcall) ||
+       Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64)) {
     AttrList.reset(ParseMicrosoftTypeAttributes(AttrList.take()));
   }
 
@@ -2888,7 +2969,7 @@
     bool hasExceptionSpec = false;
     SourceLocation ThrowLoc;
     bool hasAnyExceptionSpec = false;
-    llvm::SmallVector<TypeTy*, 2> Exceptions;
+    llvm::SmallVector<ParsedType, 2> Exceptions;
     llvm::SmallVector<SourceRange, 2> ExceptionRanges;
     if (getLang().CPlusPlus) {
       ParseTypeQualifierListOpt(DS, false /*no attributes*/);
@@ -2934,9 +3015,33 @@
         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);
+      // normal declarators, not for abstract-declarators.  Get the first
+      // identifier.
+      Token FirstTok = Tok;
+      ConsumeToken();  // eat the first identifier.
+      
+      // Identifier lists follow a really simple grammar: the identifiers can
+      // be followed *only* by a ", moreidentifiers" or ")".  However, K&R
+      // identifier lists are really rare in the brave new modern world, and it
+      // is very common for someone to typo a type in a non-k&r style list.  If
+      // we are presented with something like: "void foo(intptr x, float y)",
+      // we don't want to start parsing the function declarator as though it is
+      // a K&R style declarator just because intptr is an invalid type.
+      //
+      // To handle this, we check to see if the token after the first identifier
+      // is a "," or ")".  Only if so, do we parse it as an identifier list.
+      if (Tok.is(tok::comma) || Tok.is(tok::r_paren))
+        return ParseFunctionDeclaratorIdentifierList(LParenLoc,
+                                                   FirstTok.getIdentifierInfo(),
+                                                     FirstTok.getLocation(), D);
+      
+      // If we get here, the code is invalid.  Push the first identifier back
+      // into the token stream and parse the first argument as an (invalid)
+      // normal argument declarator.
+      PP.EnterToken(Tok);
+      Tok = FirstTok;
     }
   }
 
@@ -3003,7 +3108,7 @@
 
       // Inform the actions module about the parameter declarator, so it gets
       // added to the current scope.
-      DeclPtrTy Param = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
+      Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
 
       // Parse the default argument, if any. We parse the default
       // arguments in all dialects; the semantic analysis in
@@ -3027,21 +3132,29 @@
             delete DefArgToks;
             DefArgToks = 0;
             Actions.ActOnParamDefaultArgumentError(Param);
-          } else
+          } else {
+            // Mark the end of the default argument so that we know when to
+            // stop when we parse it later on.
+            Token DefArgEnd;
+            DefArgEnd.startToken();
+            DefArgEnd.setKind(tok::cxx_defaultarg_end);
+            DefArgEnd.setLocation(Tok.getLocation());
+            DefArgToks->push_back(DefArgEnd);
             Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
                                                 (*DefArgToks)[1].getLocation());
+          }
         } else {
           // Consume the '='.
           ConsumeToken();
 
-          OwningExprResult DefArgResult(ParseAssignmentExpression());
+          ExprResult 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));
+                                              DefArgResult.take());
           }
         }
       }
@@ -3083,7 +3196,7 @@
   bool hasExceptionSpec = false;
   SourceLocation ThrowLoc;
   bool hasAnyExceptionSpec = false;
-  llvm::SmallVector<TypeTy*, 2> Exceptions;
+  llvm::SmallVector<ParsedType, 2> Exceptions;
   llvm::SmallVector<SourceRange, 2> ExceptionRanges;
   
   if (getLang().CPlusPlus) {
@@ -3119,13 +3232,16 @@
 
 /// 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.
+/// first identifier has already been consumed, and the current token is the
+/// token right after it.
 ///
 ///       identifier-list: [C99 6.7.5]
 ///         identifier
 ///         identifier-list ',' identifier
 ///
 void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
+                                                   IdentifierInfo *FirstIdent,
+                                                   SourceLocation FirstIdentLoc,
                                                    Declarator &D) {
   // Build up an array of information about the parsed arguments.
   llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
@@ -3136,16 +3252,12 @@
   // to be abstract.  In abstract-declarators, identifier lists are not valid:
   // diagnose this.
   if (!D.getIdentifier())
-    Diag(Tok, diag::ext_ident_list_in_param);
+    Diag(FirstIdentLoc, 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.
+  // The first identifier was already read, and is known to be the first
+  // identifier in the list.  Remember this identifier in ParamInfo.
+  ParamsSoFar.insert(FirstIdent);
+  ParamInfo.push_back(DeclaratorChunk::ParamInfo(FirstIdent, FirstIdentLoc, 0));
 
   while (Tok.is(tok::comma)) {
     // Eat the comma.
@@ -3161,7 +3273,7 @@
     IdentifierInfo *ParmII = Tok.getIdentifierInfo();
 
     // Reject 'typedef int y; int test(x, y)', but continue parsing.
-    if (Actions.getTypeName(*ParmII, Tok.getLocation(), CurScope))
+    if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope()))
       Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
 
     // Verify that the argument identifier has not already been mentioned.
@@ -3171,7 +3283,7 @@
       // Remember this identifier in ParamInfo.
       ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
                                                      Tok.getLocation(),
-                                                     DeclPtrTy()));
+                                                     0));
     }
 
     // Eat the identifier.
@@ -3213,7 +3325,7 @@
     }
     
     // Remember that we parsed the empty array type.
-    OwningExprResult NumElements(Actions);
+    ExprResult NumElements;
     D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
                                             StartLoc, EndLoc),
                   EndLoc);
@@ -3221,7 +3333,7 @@
   } 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));
+    ExprResult ExprRes(Actions.ActOnNumericConstant(Tok));
     ConsumeToken();
 
     SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
@@ -3259,7 +3371,7 @@
 
   // Handle "direct-declarator [ type-qual-list[opt] * ]".
   bool isStar = false;
-  OwningExprResult NumElements(Actions);
+  ExprResult NumElements;
 
   // 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
@@ -3324,12 +3436,12 @@
   const bool hasParens = Tok.is(tok::l_paren);
 
   bool isCastExpr;
-  TypeTy *CastTy;
+  ParsedType CastTy;
   SourceRange CastRange;
-  OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok,
-                                                               isCastExpr,
-                                                               CastTy,
-                                                               CastRange);
+  ExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok,
+                                                         isCastExpr,
+                                                         CastTy,
+                                                         CastRange);
   if (hasParens)
     DS.setTypeofParensRange(CastRange);
 
@@ -3364,7 +3476,7 @@
   unsigned DiagID;
   // Check for duplicate type specifiers (e.g. "int typeof(int)").
   if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
-                         DiagID, Operand.release()))
+                         DiagID, Operand.get()))
     Diag(StartLoc, DiagID) << PrevSpec;
 }
 
@@ -3425,7 +3537,7 @@
     default:
       break;
     }
-  } else if (Tok.getIdentifierInfo() == Ident_pixel &&
+  } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
              DS.isTypeAltiVecVector()) {
     isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
     return true;
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 60aee6a..26d460c 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -14,43 +14,48 @@
 #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 "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Sema/PrettyDeclStackTrace.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.
+/// may either be a top level namespace or a block-level namespace alias. If
+/// there was an inline keyword, it has already been parsed.
 ///
 ///       namespace-definition: [C++ 7.3: basic.namespace]
 ///         named-namespace-definition
 ///         unnamed-namespace-definition
 ///
 ///       unnamed-namespace-definition:
-///         'namespace' attributes[opt] '{' namespace-body '}'
+///         'inline'[opt] 'namespace' attributes[opt] '{' namespace-body '}'
 ///
 ///       named-namespace-definition:
 ///         original-namespace-definition
 ///         extension-namespace-definition
 ///
 ///       original-namespace-definition:
-///         'namespace' identifier attributes[opt] '{' namespace-body '}'
+///         'inline'[opt] 'namespace' identifier attributes[opt]
+///             '{' namespace-body '}'
 ///
 ///       extension-namespace-definition:
-///         'namespace' original-namespace-name '{' namespace-body '}'
+///         'inline'[opt] '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) {
+Decl *Parser::ParseNamespace(unsigned Context,
+                             SourceLocation &DeclEnd,
+                             SourceLocation InlineLoc) {
   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();
+    Actions.CodeCompleteNamespaceDecl(getCurScope());
+    ConsumeCodeCompletionToken();
   }
 
   SourceLocation IdentLoc;
@@ -75,6 +80,9 @@
   if (Tok.is(tok::equal)) {
     if (AttrList)
       Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
+    if (InlineLoc.isValid())
+      Diag(InlineLoc, diag::err_inline_namespace_alias)
+          << FixItHint::CreateRemoval(InlineLoc);
 
     return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
   }
@@ -82,21 +90,28 @@
   if (Tok.isNot(tok::l_brace)) {
     Diag(Tok, Ident ? diag::err_expected_lbrace :
          diag::err_expected_ident_lbrace);
-    return DeclPtrTy();
+    return 0;
   }
 
   SourceLocation LBrace = ConsumeBrace();
 
+  if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() || 
+      getCurScope()->isInObjcMethodScope() || getCurScope()->getBlockParent() || 
+      getCurScope()->getFnParent()) {
+    Diag(LBrace, diag::err_namespace_nonnamespace_scope);
+    SkipUntil(tok::r_brace, false);
+    return 0;
+  }
+
   // Enter a scope for the namespace.
   ParseScope NamespaceScope(this, Scope::DeclScope);
 
-  DeclPtrTy NamespcDecl =
-    Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace,
-                                   AttrList.get());
+  Decl *NamespcDecl =
+    Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, IdentLoc, Ident,
+                                   LBrace, AttrList.get());
 
-  PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions,
-                                        PP.getSourceManager(),
-                                        "parsing namespace");
+  PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc,
+                                      "parsing namespace");
 
   while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
     CXX0XAttributeList Attr;
@@ -118,7 +133,7 @@
 /// ParseNamespaceAlias - Parse the part after the '=' in a namespace
 /// alias definition.
 ///
-Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
+Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
                                               SourceLocation AliasLoc,
                                               IdentifierInfo *Alias,
                                               SourceLocation &DeclEnd) {
@@ -127,19 +142,19 @@
   ConsumeToken(); // eat the '='.
 
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteNamespaceAliasDecl(CurScope);
-    ConsumeToken();
+    Actions.CodeCompleteNamespaceAliasDecl(getCurScope());
+    ConsumeCodeCompletionToken();
   }
 
   CXXScopeSpec SS;
   // Parse (optional) nested-name-specifier.
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 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();
+    return 0;
   }
 
   // Parse identifier.
@@ -151,7 +166,7 @@
   ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name,
                    "", tok::semi);
 
-  return Actions.ActOnNamespaceAliasDef(CurScope, NamespaceLoc, AliasLoc, Alias,
+  return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc, Alias,
                                         SS, IdentLoc, Ident);
 }
 
@@ -162,7 +177,7 @@
 ///         'extern' string-literal '{' declaration-seq[opt] '}'
 ///         'extern' string-literal declaration
 ///
-Parser::DeclPtrTy Parser::ParseLinkage(ParsingDeclSpec &DS,
+Decl *Parser::ParseLinkage(ParsingDeclSpec &DS,
                                        unsigned Context) {
   assert(Tok.is(tok::string_literal) && "Not a string literal!");
   llvm::SmallString<8> LangBuffer;
@@ -170,15 +185,15 @@
   bool Invalid = false;
   llvm::StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid);
   if (Invalid)
-    return DeclPtrTy();
+    return 0;
 
   SourceLocation Loc = ConsumeStringToken();
 
   ParseScope LinkageScope(this, Scope::DeclScope);
-  DeclPtrTy LinkageSpec
-    = Actions.ActOnStartLinkageSpecification(CurScope,
+  Decl *LinkageSpec
+    = Actions.ActOnStartLinkageSpecification(getCurScope(),
                                              /*FIXME: */SourceLocation(),
-                                             Loc, Lang.data(), Lang.size(),
+                                             Loc, Lang,
                                        Tok.is(tok::l_brace)? Tok.getLocation()
                                                            : SourceLocation());
 
@@ -188,8 +203,9 @@
   }
 
   if (Tok.isNot(tok::l_brace)) {
-    ParseDeclarationOrFunctionDefinition(DS, Attr.AttrList);
-    return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec,
+    DS.setExternInLinkageSpec(true);
+    ParseExternalDeclaration(Attr, &DS);
+    return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
                                                    SourceLocation());
   }
 
@@ -208,12 +224,12 @@
   }
 
   SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
-  return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, RBrace);
+  return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec, RBrace);
 }
 
 /// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
 /// using-directive. Assumes that current token is 'using'.
-Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
+Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
                                                      SourceLocation &DeclEnd,
                                                      CXX0XAttributeList Attr) {
   assert(Tok.is(tok::kw_using) && "Not using token");
@@ -222,8 +238,8 @@
   SourceLocation UsingLoc = ConsumeToken();
 
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteUsing(CurScope);
-    ConsumeToken();
+    Actions.CodeCompleteUsing(getCurScope());
+    ConsumeCodeCompletionToken();
   }
 
   if (Tok.is(tok::kw_namespace))
@@ -249,7 +265,7 @@
 ///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
 ///                 namespace-name attributes[opt] ;
 ///
-Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
+Decl *Parser::ParseUsingDirective(unsigned Context,
                                               SourceLocation UsingLoc,
                                               SourceLocation &DeclEnd,
                                               AttributeList *Attr) {
@@ -259,13 +275,13 @@
   SourceLocation NamespcLoc = ConsumeToken();
 
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteUsingDirective(CurScope);
-    ConsumeToken();
+    Actions.CodeCompleteUsingDirective(getCurScope());
+    ConsumeCodeCompletionToken();
   }
 
   CXXScopeSpec SS;
   // Parse (optional) nested-name-specifier.
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
 
   IdentifierInfo *NamespcName = 0;
   SourceLocation IdentLoc = SourceLocation();
@@ -276,7 +292,7 @@
     // 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();
+    return 0;
   }
 
   // Parse identifier.
@@ -296,7 +312,7 @@
                    GNUAttr ? diag::err_expected_semi_after_attribute_list :
                    diag::err_expected_semi_after_namespace_name, "", tok::semi);
 
-  return Actions.ActOnUsingDirective(CurScope, UsingLoc, NamespcLoc, SS,
+  return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
                                       IdentLoc, NamespcName, Attr);
 }
 
@@ -308,7 +324,7 @@
 ///               unqualified-id
 ///       'using' :: unqualified-id
 ///
-Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
+Decl *Parser::ParseUsingDeclaration(unsigned Context,
                                                 SourceLocation UsingLoc,
                                                 SourceLocation &DeclEnd,
                                                 AccessSpecifier AS) {
@@ -327,12 +343,12 @@
     IsTypeName = false;
 
   // Parse nested-name-specifier.
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
 
   // Check nested-name specifier.
   if (SS.isInvalid()) {
     SkipUntil(tok::semi);
-    return DeclPtrTy();
+    return 0;
   }
 
   // Parse the unqualified-id. We allow parsing of both constructor and
@@ -343,10 +359,10 @@
                          /*EnteringContext=*/false,
                          /*AllowDestructorName=*/true,
                          /*AllowConstructorName=*/true,
-                         /*ObjectType=*/0,
+                         ParsedType(),
                          Name)) {
     SkipUntil(tok::semi);
-    return DeclPtrTy();
+    return 0;
   }
 
   // Parse (optional) attributes (most likely GNU strong-using extension).
@@ -360,7 +376,7 @@
                    AttrList ? "attributes list" : "using declaration",
                    tok::semi);
 
-  return Actions.ActOnUsingDeclaration(CurScope, AS, true, UsingLoc, SS, Name,
+  return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS, Name,
                                        AttrList.get(), IsTypeName, TypenameLoc);
 }
 
@@ -369,43 +385,44 @@
 ///      static_assert-declaration:
 ///        static_assert ( constant-expression  ,  string-literal  ) ;
 ///
-Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
+Decl *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();
+    return 0;
   }
 
   SourceLocation LParenLoc = ConsumeParen();
 
-  OwningExprResult AssertExpr(ParseConstantExpression());
+  ExprResult AssertExpr(ParseConstantExpression());
   if (AssertExpr.isInvalid()) {
     SkipUntil(tok::semi);
-    return DeclPtrTy();
+    return 0;
   }
 
   if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
-    return DeclPtrTy();
+    return 0;
 
   if (Tok.isNot(tok::string_literal)) {
     Diag(Tok, diag::err_expected_string_literal);
     SkipUntil(tok::semi);
-    return DeclPtrTy();
+    return 0;
   }
 
-  OwningExprResult AssertMessage(ParseStringLiteralExpression());
+  ExprResult AssertMessage(ParseStringLiteralExpression());
   if (AssertMessage.isInvalid())
-    return DeclPtrTy();
+    return 0;
 
   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));
+  return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc,
+                                              AssertExpr.take(),
+                                              AssertMessage.take());
 }
 
 /// ParseDecltypeSpecifier - Parse a C++0x decltype specifier.
@@ -429,8 +446,8 @@
   // C++0x [dcl.type.simple]p4:
   //   The operand of the decltype specifier is an unevaluated operand.
   EnterExpressionEvaluationContext Unevaluated(Actions,
-                                               Action::Unevaluated);
-  OwningExprResult Result = ParseExpression();
+                                               Sema::Unevaluated);
+  ExprResult Result = ParseExpression();
   if (Result.isInvalid()) {
     SkipUntil(tok::r_paren);
     return;
@@ -475,7 +492,7 @@
       AnnotateTemplateIdTokenAsType(SS);
 
       assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
-      TypeTy *Type = Tok.getAnnotationValue();
+      ParsedType Type = getTypeAnnotation(Tok);
       EndLocation = Tok.getAnnotationEndLoc();
       ConsumeToken();
 
@@ -500,7 +517,7 @@
     // template-name was wrong. Try to fix that.
     TemplateNameKind TNK = TNK_Type_template;
     TemplateTy Template;
-    if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, CurScope,
+    if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(),
                                              SS, Template, TNK)) {
       Diag(IdLoc, diag::err_unknown_template_name)
         << Id;
@@ -528,13 +545,13 @@
     // Retrieve the type from the annotation token, consume that token, and
     // return.
     EndLocation = Tok.getAnnotationEndLoc();
-    TypeTy *Type = Tok.getAnnotationValue();
+    ParsedType Type = getTypeAnnotation(Tok);
     ConsumeToken();
     return Type;
   }
 
   // We have an identifier; check whether it is actually a type.
-  TypeTy *Type = Actions.getTypeName(*Id, IdLoc, CurScope, SS, true);
+  ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), SS, true);
   if (!Type) {
     Diag(IdLoc, diag::err_expected_class_name);
     return true;
@@ -542,7 +559,19 @@
 
   // Consume the identifier.
   EndLocation = IdLoc;
-  return Type;
+
+  // Fake up a Declarator to use with ActOnTypeName.
+  DeclSpec DS;
+  DS.SetRangeStart(IdLoc);
+  DS.SetRangeEnd(EndLocation);
+  DS.getTypeSpecScope() = *SS;
+
+  const char *PrevSpec = 0;
+  unsigned DiagID;
+  DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type);
+
+  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+  return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
 }
 
 /// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
@@ -601,8 +630,22 @@
 
   if (Tok.is(tok::code_completion)) {
     // Code completion for a struct, class, or union name.
-    Actions.CodeCompleteTag(CurScope, TagType);
-    ConsumeToken();
+    Actions.CodeCompleteTag(getCurScope(), TagType);
+    ConsumeCodeCompletionToken();
+  }
+
+  // C++03 [temp.explicit] 14.7.2/8:
+  //   The usual access checking rules do not apply to names used to specify
+  //   explicit instantiations.
+  //
+  // As an extension we do not perform access checking on the names used to
+  // specify explicit specializations either. This is important to allow
+  // specializing traits classes for private types.
+  bool SuppressingAccessChecks = false;
+  if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
+      TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization) {
+    Actions.ActOnStartSuppressingAccessChecks();
+    SuppressingAccessChecks = true;
   }
 
   AttributeList *AttrList = 0;
@@ -611,7 +654,7 @@
     AttrList = ParseGNUAttributes();
 
   // If declspecs exist after tag, parse them.
-  if (Tok.is(tok::kw___declspec))
+  while (Tok.is(tok::kw___declspec))
     AttrList = ParseMicrosoftDeclSpec(AttrList);
 
   // If C++0x attributes exist here, parse them.
@@ -626,7 +669,7 @@
     // 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.getIdentifierInfo()->RevertTokenIDToIdentifier();
     Tok.setKind(tok::identifier);
   }
 
@@ -636,7 +679,7 @@
     // 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.getIdentifierInfo()->RevertTokenIDToIdentifier();
     Tok.setKind(tok::identifier);
   }
 
@@ -646,7 +689,8 @@
     // "FOO : BAR" is not a potential typo for "FOO::BAR".
     ColonProtectionRAIIObject X(*this);
 
-    ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true);
+    if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), true))
+      DS.SetTypeSpecError();
     if (SS.isSet())
       if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
         Diag(Tok, diag::err_expected_ident);
@@ -662,7 +706,7 @@
     Name = Tok.getIdentifierInfo();
     NameLoc = ConsumeToken();
 
-    if (Tok.is(tok::less)) {
+    if (Tok.is(tok::less) && getLang().CPlusPlus) {
       // 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).
@@ -705,8 +749,6 @@
         const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc
           = SourceLocation();
       }
-
-
     }
   } else if (Tok.is(tok::annot_template_id)) {
     TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
@@ -726,10 +768,18 @@
       DS.SetTypeSpecError();
       SkipUntil(tok::semi, false, true);
       TemplateId->Destroy();
+      if (SuppressingAccessChecks)
+        Actions.ActOnStopSuppressingAccessChecks();
+
       return;
     }
   }
 
+  // As soon as we're finished parsing the class's template-id, turn access
+  // checking back on.
+  if (SuppressingAccessChecks)
+    Actions.ActOnStopSuppressingAccessChecks();
+
   // 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
@@ -741,9 +791,9 @@
   // or
   // &T::operator struct s;
   // For these, SuppressDeclarations is true.
-  Action::TagUseKind TUK;
+  Sema::TagUseKind TUK;
   if (SuppressDeclarations)
-    TUK = Action::TUK_Reference;
+    TUK = Sema::TUK_Reference;
   else if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))){
     if (DS.isFriendSpecified()) {
       // C++ [class.friend]p2:
@@ -754,20 +804,23 @@
       // 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;
+      TUK = Sema::TUK_Friend;
     } else {
       // Okay, this is a class definition.
-      TUK = Action::TUK_Definition;
+      TUK = Sema::TUK_Definition;
     }
   } else if (Tok.is(tok::semi))
-    TUK = DS.isFriendSpecified() ? Action::TUK_Friend : Action::TUK_Declaration;
+    TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
   else
-    TUK = Action::TUK_Reference;
+    TUK = Sema::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);
+  if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error ||
+                               TUK != Sema::TUK_Definition)) {
+    if (DS.getTypeSpecType() != DeclSpec::TST_error) {
+      // We have a declaration or reference to an anonymous class.
+      Diag(StartLoc, diag::err_anon_type_definition)
+        << DeclSpec::getSpecifierName(TagType);
+    }
 
     SkipUntil(tok::comma, true);
 
@@ -777,8 +830,8 @@
   }
 
   // Create the tag portion of the class or class template.
-  Action::DeclResult TagOrTempResult = true; // invalid
-  Action::TypeResult TypeResult = true; // invalid
+  DeclResult TagOrTempResult = true; // invalid
+  TypeResult TypeResult = true; // invalid
 
   bool Owned = false;
   if (TemplateId) {
@@ -788,16 +841,16 @@
                                        TemplateId->getTemplateArgs(),
                                        TemplateId->NumArgs);
     if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
-        TUK == Action::TUK_Declaration) {
+        TUK == Sema::TUK_Declaration) {
       // This is an explicit instantiation of a class template.
       TagOrTempResult
-        = Actions.ActOnExplicitInstantiation(CurScope,
+        = Actions.ActOnExplicitInstantiation(getCurScope(),
                                              TemplateInfo.ExternLoc,
                                              TemplateInfo.TemplateLoc,
                                              TagType,
                                              StartLoc,
                                              SS,
-                                     TemplateTy::make(TemplateId->Template),
+                                             TemplateId->Template,
                                              TemplateId->TemplateNameLoc,
                                              TemplateId->LAngleLoc,
                                              TemplateArgsPtr,
@@ -808,11 +861,11 @@
     // 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 &&
+    } else if (TUK == Sema::TUK_Reference ||
+               (TUK == Sema::TUK_Friend &&
                 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
       TypeResult
-        = Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+        = Actions.ActOnTemplateIdType(TemplateId->Template,
                                       TemplateId->TemplateNameLoc,
                                       TemplateId->LAngleLoc,
                                       TemplateArgsPtr,
@@ -834,7 +887,7 @@
         // 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");
+        assert(TUK == Sema::TUK_Definition && "Expected a definition here");
 
         SourceLocation LAngleLoc
           = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
@@ -857,44 +910,44 @@
 
       // Build the class template specialization.
       TagOrTempResult
-        = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TUK,
+        = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK,
                        StartLoc, SS,
-                       TemplateTy::make(TemplateId->Template),
+                       TemplateId->Template,
                        TemplateId->TemplateNameLoc,
                        TemplateId->LAngleLoc,
                        TemplateArgsPtr,
                        TemplateId->RAngleLoc,
                        AttrList,
-                       Action::MultiTemplateParamsArg(Actions,
+                       MultiTemplateParamsArg(Actions,
                                     TemplateParams? &(*TemplateParams)[0] : 0,
                                  TemplateParams? TemplateParams->size() : 0));
     }
     TemplateId->Destroy();
   } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
-             TUK == Action::TUK_Declaration) {
+             TUK == Sema::TUK_Declaration) {
     // Explicit instantiation of a member of a class template
     // specialization, e.g.,
     //
     //   template struct Outer<int>::Inner;
     //
     TagOrTempResult
-      = Actions.ActOnExplicitInstantiation(CurScope,
+      = Actions.ActOnExplicitInstantiation(getCurScope(),
                                            TemplateInfo.ExternLoc,
                                            TemplateInfo.TemplateLoc,
                                            TagType, StartLoc, SS, Name,
                                            NameLoc, AttrList);
   } else {
     if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
-        TUK == Action::TUK_Definition) {
+        TUK == Sema::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,
+    TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc, SS,
                                        Name, NameLoc, AttrList, AS,
-                                  Action::MultiTemplateParamsArg(Actions,
+                                       MultiTemplateParamsArg(Actions,
                                     TemplateParams? &(*TemplateParams)[0] : 0,
                                     TemplateParams? TemplateParams->size() : 0),
                                        Owned, IsDependent);
@@ -902,12 +955,12 @@
     // If ActOnTag said the type was dependent, try again with the
     // less common call.
     if (IsDependent)
-      TypeResult = Actions.ActOnDependentTag(CurScope, TagType, TUK,
+      TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK,
                                              SS, Name, StartLoc, NameLoc);
   }
 
   // If there is a body, parse it and inform the actions module.
-  if (TUK == Action::TUK_Definition) {
+  if (TUK == Sema::TUK_Definition) {
     assert(Tok.is(tok::l_brace) ||
            (getLang().CPlusPlus && Tok.is(tok::colon)));
     if (getLang().CPlusPlus)
@@ -916,27 +969,25 @@
       ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
   }
 
-  void *Result;
+  // FIXME: The DeclSpec should keep the locations of both the keyword and the
+  // name (if there is one).
+  SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc;
+
+  const char *PrevSpec = 0;
+  unsigned DiagID;
+  bool Result;
   if (!TypeResult.isInvalid()) {
-    TagType = DeclSpec::TST_typename;
-    Result = TypeResult.get();
-    Owned = false;
+    Result = DS.SetTypeSpecType(DeclSpec::TST_typename, TSTLoc,
+                                PrevSpec, DiagID, TypeResult.get());
   } else if (!TagOrTempResult.isInvalid()) {
-    Result = TagOrTempResult.get().getAs<void>();
+    Result = DS.SetTypeSpecType(TagType, TSTLoc, PrevSpec, DiagID,
+                                TagOrTempResult.get(), Owned);
   } 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))
+  if (Result)
     Diag(StartLoc, DiagID) << PrevSpec;
 
   // At this point, we've successfully parsed a class-specifier in 'definition'
@@ -946,7 +997,7 @@
   // the end of the declaration and recover that way.
   //
   // This switch enumerates the valid "follow" set for definition.
-  if (TUK == Action::TUK_Definition) {
+  if (TUK == Sema::TUK_Definition) {
     bool ExpectedSemi = true;
     switch (Tok.getKind()) {
     default: break;
@@ -973,6 +1024,7 @@
     case tok::kw_typedef:         // struct foo {...} typedef   x;
     case tok::kw_register:        // struct foo {...} register  x;
     case tok::kw_auto:            // struct foo {...} auto      x;
+    case tok::kw_mutable:         // struct foo {...} mutable      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,
@@ -1019,12 +1071,12 @@
 ///       base-specifier-list:
 ///         base-specifier '...'[opt]
 ///         base-specifier-list ',' base-specifier '...'[opt]
-void Parser::ParseBaseClause(DeclPtrTy ClassDecl) {
+void Parser::ParseBaseClause(Decl *ClassDecl) {
   assert(Tok.is(tok::colon) && "Not a base clause");
   ConsumeToken();
 
   // Build up an array of parsed base specifiers.
-  llvm::SmallVector<BaseTy *, 8> BaseInfo;
+  llvm::SmallVector<CXXBaseSpecifier *, 8> BaseInfo;
 
   while (true) {
     // Parse a base-specifier.
@@ -1061,7 +1113,7 @@
 ///                        class-name
 ///         access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
 ///                        class-name
-Parser::BaseResult Parser::ParseBaseSpecifier(DeclPtrTy ClassDecl) {
+Parser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {
   bool IsVirtual = false;
   SourceLocation StartLoc = Tok.getLocation();
 
@@ -1091,8 +1143,7 @@
 
   // Parse optional '::' and optional nested-name-specifier.
   CXXScopeSpec SS;
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0,
-                                 /*EnteringContext=*/false);
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
 
   // The location of the base class itself.
   SourceLocation BaseLoc = Tok.getLocation();
@@ -1129,7 +1180,7 @@
 }
 
 void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
-                                             DeclPtrTy ThisDecl) {
+                                             Decl *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;
@@ -1143,7 +1194,7 @@
         getCurrentClass().MethodDecls.push_back(
                                 LateParsedMethodDeclaration(ThisDecl));
         LateMethod = &getCurrentClass().MethodDecls.back();
-        LateMethod->TemplateScope = CurScope->isTemplateParamScope();
+        LateMethod->TemplateScope = getCurScope()->isTemplateParamScope();
 
         // Add all of the parameters prior to this one (they don't
         // have default arguments).
@@ -1189,7 +1240,8 @@
 ///         '=' constant-expression
 ///
 void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
-                                       const ParsedTemplateInfo &TemplateInfo) {
+                                       const ParsedTemplateInfo &TemplateInfo,
+                                       ParsingDeclRAIIObject *TemplateDiags) {
   // Access declarations.
   if (!TemplateInfo.Kind &&
       (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) &&
@@ -1204,11 +1256,11 @@
     if (isAccessDecl) {
       // Collect the scope specifier token we annotated earlier.
       CXXScopeSpec SS;
-      ParseOptionalCXXScopeSpecifier(SS, /*ObjectType*/ 0, false);
+      ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
 
       // Try to parse an unqualified-id.
       UnqualifiedId Name;
-      if (ParseUnqualifiedId(SS, false, true, true, /*ObjectType*/ 0, Name)) {
+      if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), Name)) {
         SkipUntil(tok::semi);
         return;
       }
@@ -1220,7 +1272,7 @@
                            tok::semi))
         return;
 
-      Actions.ActOnUsingDeclaration(CurScope, AS,
+      Actions.ActOnUsingDeclaration(getCurScope(), AS,
                                     false, SourceLocation(),
                                     SS, Name,
                                     /* AttrList */ 0,
@@ -1252,7 +1304,7 @@
     // __extension__ silences extension warnings in the subexpression.
     ExtensionRAIIObject O(Diags);  // Use RAII to do this.
     ConsumeToken();
-    return ParseCXXClassMemberDeclaration(AS, TemplateInfo);
+    return ParseCXXClassMemberDeclaration(AS, TemplateInfo, TemplateDiags);
   }
 
   // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it
@@ -1288,17 +1340,19 @@
   SourceLocation DSStart = Tok.getLocation();
   // decl-specifier-seq:
   // Parse the common declaration-specifiers piece.
-  ParsingDeclSpec DS(*this);
+  ParsingDeclSpec DS(*this, TemplateDiags);
   DS.AddAttributes(AttrList.AttrList);
   ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class);
 
-  Action::MultiTemplateParamsArg TemplateParams(Actions,
+  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);
+    Decl *TheDecl =
+      Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS);
+    DS.complete(TheDecl);
     return;
   }
 
@@ -1356,9 +1410,9 @@
   //   member-declarator
   //   member-declarator-list ',' member-declarator
 
-  llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup;
-  OwningExprResult BitfieldSize(Actions);
-  OwningExprResult Init(Actions);
+  llvm::SmallVector<Decl *, 8> DeclsInGroup;
+  ExprResult BitfieldSize;
+  ExprResult Init;
   bool Deleted = false;
 
   while (1) {
@@ -1366,7 +1420,6 @@
     //   declarator pure-specifier[opt]
     //   declarator constant-initializer[opt]
     //   identifier[opt] ':' constant-expression
-
     if (Tok.is(tok::colon)) {
       ConsumeToken();
       BitfieldSize = ParseConstantExpression();
@@ -1383,7 +1436,6 @@
     // defaulted/deleted function-definition:
     //   '=' 'default'                          [TODO]
     //   '=' 'delete'
-
     if (Tok.is(tok::equal)) {
       ConsumeToken();
       if (getLang().CPlusPlus0x && Tok.is(tok::kw_delete)) {
@@ -1396,6 +1448,17 @@
       }
     }
 
+    // If a simple-asm-expr is present, parse it.
+    if (Tok.is(tok::kw_asm)) {
+      SourceLocation Loc;
+      ExprResult AsmLabel(ParseSimpleAsm(&Loc));
+      if (AsmLabel.isInvalid())
+        SkipUntil(tok::comma, true, true);
+ 
+      DeclaratorInfo.setAsmLabel(AsmLabel.release());
+      DeclaratorInfo.SetRangeEnd(Loc);
+    }
+
     // If attributes exist after the declarator, parse them.
     if (Tok.is(tok::kw___attribute)) {
       SourceLocation Loc;
@@ -1407,14 +1470,14 @@
     // this call will *not* return the created decl; It will return null.
     // See Sema::ActOnCXXMemberDeclarator for details.
 
-    DeclPtrTy ThisDecl;
+    Decl *ThisDecl = 0;
     if (DS.isFriendSpecified()) {
       // TODO: handle initializers, bitfields, 'delete'
-      ThisDecl = Actions.ActOnFriendFunctionDecl(CurScope, DeclaratorInfo,
+      ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo,
                                                  /*IsDefinition*/ false,
                                                  move(TemplateParams));
     } else {
-      ThisDecl = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
+      ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS,
                                                   DeclaratorInfo,
                                                   move(TemplateParams),
                                                   BitfieldSize.release(),
@@ -1466,7 +1529,7 @@
     return;
   }
 
-  Actions.FinalizeDeclaratorGroup(CurScope, DS, DeclsInGroup.data(),
+  Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup.data(),
                                   DeclsInGroup.size());
 }
 
@@ -1477,20 +1540,19 @@
 ///         access-specifier ':' member-specification[opt]
 ///
 void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
-                                         unsigned TagType, DeclPtrTy TagDecl) {
+                                         unsigned TagType, Decl *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");
+  PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
+                                      "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()) {
+    for (const Scope *S = getCurScope(); S; S = S->getParent()) {
       if (S->isClassScope()) {
         // We're inside a class scope, so this is a nested class.
         NonNestedClass = false;
@@ -1517,7 +1579,7 @@
   ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass);
 
   if (TagDecl)
-    Actions.ActOnTagStartDefinition(CurScope, TagDecl);
+    Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
 
   if (Tok.is(tok::colon)) {
     ParseBaseClause(TagDecl);
@@ -1526,7 +1588,7 @@
       Diag(Tok, diag::err_expected_lbrace_after_base_specifiers);
 
       if (TagDecl)
-        Actions.ActOnTagDefinitionError(CurScope, TagDecl);
+        Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);
       return;
     }
   }
@@ -1535,12 +1597,8 @@
 
   SourceLocation LBraceLoc = ConsumeBrace();
 
-  if (!TagDecl) {
-    SkipUntil(tok::r_brace, false, false);
-    return;
-  }
-
-  Actions.ActOnStartCXXMemberDeclarations(CurScope, TagDecl, LBraceLoc);
+  if (TagDecl)
+    Actions.ActOnStartCXXMemberDeclarations(getCurScope(), 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
@@ -1551,43 +1609,55 @@
   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.
+  SourceLocation RBraceLoc;
+  if (TagDecl) {
+    // 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;
+      // Check for extraneous top-level semicolon.
+      if (Tok.is(tok::semi)) {
+        Diag(Tok, diag::ext_extra_struct_semi)
+          << DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
+          << FixItHint::CreateRemoval(Tok.getLocation());
+        ConsumeToken();
+        continue;
+      }
+
+      AccessSpecifier AS = getAccessSpecifierIfPresent();
+      if (AS != AS_none) {
+        // Current token is a C++ access specifier.
+        CurAS = AS;
+        SourceLocation ASLoc = Tok.getLocation();
+        ConsumeToken();
+        if (Tok.is(tok::colon))
+          Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
+        else
+          Diag(Tok, diag::err_expected_colon);
+        ConsumeToken();
+        continue;
+      }
+
+      // FIXME: Make sure we don't have a template here.
+
+      // Parse all the comma separated declarators.
+      ParseCXXClassMemberDeclaration(CurAS);
     }
 
-    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);
+    RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
+  } else {
+    SkipUntil(tok::r_brace, false, false);
   }
 
-  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());
+  if (TagDecl)
+    Actions.ActOnFinishCXXMemberSpecification(getCurScope(), 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,
@@ -1596,15 +1666,18 @@
   //
   // FIXME: Only function bodies and constructor ctor-initializers are
   // parsed correctly, fix the rest.
-  if (NonNestedClass) {
+  if (TagDecl && 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.
+    SourceLocation SavedPrevTokLocation = PrevTokLocation;
     ParseLexedMethodDeclarations(getCurrentClass());
     ParseLexedMethodDefs(getCurrentClass());
+    PrevTokLocation = SavedPrevTokLocation;
   }
 
-  Actions.ActOnTagFinishDefinition(CurScope, TagDecl, RBraceLoc);
+  if (TagDecl)
+    Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, RBraceLoc);
 
   // Leave the class scope.
   ParsingDef.Pop();
@@ -1632,21 +1705,28 @@
 /// [C++]  mem-initializer-list:
 ///          mem-initializer
 ///          mem-initializer , mem-initializer-list
-void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) {
+void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
   assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
 
   SourceLocation ColonLoc = ConsumeToken();
 
-  llvm::SmallVector<MemInitTy*, 4> MemInitializers;
+  llvm::SmallVector<CXXBaseOrMemberInitializer*, 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::code_completion)) {
+      Actions.CodeCompleteConstructorInitializer(ConstructorDecl, 
+                                                 MemInitializers.data(), 
+                                                 MemInitializers.size());
+      ConsumeCodeCompletionToken();
+    } else {
+      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))
@@ -1675,11 +1755,11 @@
 /// [C++] mem-initializer-id:
 ///         '::'[opt] nested-name-specifier[opt] class-name
 ///         identifier
-Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
+Parser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
   // parse '::'[opt] nested-name-specifier[opt]
   CXXScopeSpec SS;
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
-  TypeTy *TemplateTypeTy = 0;
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
+  ParsedType TemplateTypeTy;
   if (Tok.is(tok::annot_template_id)) {
     TemplateIdAnnotation *TemplateId
       = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
@@ -1687,7 +1767,7 @@
         TemplateId->Kind == TNK_Dependent_template_name) {
       AnnotateTemplateIdTokenAsType(&SS);
       assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
-      TemplateTypeTy = Tok.getAnnotationValue();
+      TemplateTypeTy = getTypeAnnotation(Tok);
     }
   }
   if (!TemplateTypeTy && Tok.isNot(tok::identifier)) {
@@ -1717,7 +1797,7 @@
 
   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
 
-  return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, SS, II,
+  return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
                                      TemplateTypeTy, IdLoc,
                                      LParenLoc, ArgExprs.take(),
                                      ArgExprs.size(), CommaLocs.data(),
@@ -1736,9 +1816,9 @@
 ///         type-id-list ',' type-id
 ///
 bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc,
-                                         llvm::SmallVector<TypeTy*, 2>
+                                         llvm::SmallVectorImpl<ParsedType>
                                              &Exceptions,
-                                         llvm::SmallVector<SourceRange, 2>
+                                         llvm::SmallVectorImpl<SourceRange>
                                              &Ranges,
                                          bool &hasAnyExceptionSpec) {
   assert(Tok.is(tok::kw_throw) && "expected throw");
@@ -1782,7 +1862,7 @@
 /// \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) {
+void Parser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass) {
   assert((NonNestedClass || !ClassStack.empty()) &&
          "Nested class without outer class");
   ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass));
@@ -1831,9 +1911,9 @@
   // 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?");
+  assert(getCurScope()->isClassScope() && "Nested class outside of class scope?");
   ClassStack.top()->NestedClasses.push_back(Victim);
-  Victim->TemplateScope = CurScope->getParent()->isTemplateParamScope();
+  Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope();
 }
 
 /// ParseCXX0XAttributes - Parse a C++0x attribute-specifier. Currently only
@@ -1948,7 +2028,7 @@
         }
         SourceLocation ParamLoc = ConsumeParen();
 
-        OwningExprResult ArgExpr = ParseCXX0XAlignArgument(ParamLoc);
+        ExprResult ArgExpr = ParseCXX0XAlignArgument(ParamLoc);
 
         MatchRHSPunctuation(tok::r_paren, ParamLoc);
 
@@ -1993,15 +2073,14 @@
 ///
 /// [C++0x] 'align' '(' type-id ')'
 /// [C++0x] 'align' '(' assignment-expression ')'
-Parser::OwningExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) {
+ExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) {
   if (isTypeIdInParens()) {
-    EnterExpressionEvaluationContext Unevaluated(Actions,
-                                                  Action::Unevaluated);
+    EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
     SourceLocation TypeLoc = Tok.getLocation();
-    TypeTy *Ty = ParseTypeName().get();
+    ParsedType Ty = ParseTypeName().get();
     SourceRange TypeRange(Start, Tok.getLocation());
-    return Actions.ActOnSizeOfAlignOfExpr(TypeLoc, false, true, Ty,
-                                              TypeRange);
+    return Actions.ActOnSizeOfAlignOfExpr(TypeLoc, false, true,
+                                          Ty.getAsOpaquePtr(), TypeRange);
   } else
     return ParseConstantExpression();
 }
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index b9e632a..290b72c 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -20,9 +20,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Parse/Parser.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.h"
-#include "clang/Parse/Template.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ParsedTemplate.h"
 #include "clang/Basic/PrettyStackTrace.h"
 #include "RAIIObjectsForParser.h"
 #include "llvm/ADT/SmallVector.h"
@@ -30,8 +30,7 @@
 using namespace clang;
 
 /// getBinOpPrecedence - Return the precedence of the specified binary operator
-/// token.  This returns:
-///
+/// token.
 static prec::Level getBinOpPrecedence(tok::TokenKind Kind,
                                       bool GreaterThanIsOperator,
                                       bool CPlusPlus0x) {
@@ -176,8 +175,8 @@
 ///         assignment-expression
 ///         expression ',' assignment-expression
 ///
-Parser::OwningExprResult Parser::ParseExpression() {
-  OwningExprResult LHS(ParseAssignmentExpression());
+ExprResult Parser::ParseExpression() {
+  ExprResult LHS(ParseAssignmentExpression());
   if (LHS.isInvalid()) return move(LHS);
 
   return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
@@ -188,9 +187,9 @@
 /// routine is necessary to disambiguate @try-statement from,
 /// for example, @encode-expression.
 ///
-Parser::OwningExprResult
+ExprResult
 Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
-  OwningExprResult LHS(ParseObjCAtExpression(AtLoc));
+  ExprResult LHS(ParseObjCAtExpression(AtLoc));
   if (LHS.isInvalid()) return move(LHS);
 
   return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
@@ -199,9 +198,9 @@
 /// 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
+ExprResult
 Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
-  OwningExprResult LHS(Actions, true);
+  ExprResult LHS(true);
   {
     // Silence extension warnings in the sub-expression
     ExtensionRAIIObject O(Diags);
@@ -210,28 +209,28 @@
     if (LHS.isInvalid()) return move(LHS);
   }
 
-  LHS = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__,
-                             move(LHS));
+  LHS = Actions.ActOnUnaryOp(getCurScope(), ExtLoc, tok::kw___extension__,
+                             LHS.take());
   if (LHS.isInvalid()) return move(LHS);
 
-  return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
+  return ParseRHSOfBinaryExpression(LHS.take(), prec::Comma);
 }
 
 /// ParseAssignmentExpression - Parse an expr that doesn't include commas.
 ///
-Parser::OwningExprResult Parser::ParseAssignmentExpression() {
+ExprResult Parser::ParseAssignmentExpression() {
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Expression);
-    ConsumeToken();
+    Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
+    ConsumeCodeCompletionToken();
   }
 
   if (Tok.is(tok::kw_throw))
     return ParseThrowExpression();
 
-  OwningExprResult LHS(ParseCastExpression(false));
+  ExprResult LHS(ParseCastExpression(false));
   if (LHS.isInvalid()) return move(LHS);
 
-  return ParseRHSOfBinaryExpression(move(LHS), prec::Assignment);
+  return ParseRHSOfBinaryExpression(LHS.take(), prec::Assignment);
 }
 
 /// ParseAssignmentExprWithObjCMessageExprStart - Parse an assignment expression
@@ -242,38 +241,38 @@
 ///
 /// Since this handles full assignment-expression's, it handles postfix
 /// expressions and other binary operators for these expressions as well.
-Parser::OwningExprResult
+ExprResult
 Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
                                                     SourceLocation SuperLoc,
-                                                    TypeTy *ReceiverType,
-                                                    ExprArg ReceiverExpr) {
-  OwningExprResult R(ParseObjCMessageExpressionBody(LBracLoc, SuperLoc,
-                                                    ReceiverType,
-                                                    move(ReceiverExpr)));
+                                                    ParsedType ReceiverType,
+                                                    Expr *ReceiverExpr) {
+  ExprResult R
+    = ParseObjCMessageExpressionBody(LBracLoc, SuperLoc,
+                                     ReceiverType, ReceiverExpr);
   if (R.isInvalid()) return move(R);
-  R = ParsePostfixExpressionSuffix(move(R));
+  R = ParsePostfixExpressionSuffix(R.take());
   if (R.isInvalid()) return move(R);
-  return ParseRHSOfBinaryExpression(move(R), prec::Assignment);
+  return ParseRHSOfBinaryExpression(R.take(), prec::Assignment);
 }
 
 
-Parser::OwningExprResult Parser::ParseConstantExpression() {
+ExprResult 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);
+                                               Sema::Unevaluated);
 
-  OwningExprResult LHS(ParseCastExpression(false));
+  ExprResult LHS(ParseCastExpression(false));
   if (LHS.isInvalid()) return move(LHS);
 
-  return ParseRHSOfBinaryExpression(move(LHS), prec::Conditional);
+  return ParseRHSOfBinaryExpression(LHS.take(), 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) {
+ExprResult
+Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
   prec::Level NextTokPrec = getBinOpPrecedence(Tok.getKind(),
                                                GreaterThanIsOperator,
                                                getLang().CPlusPlus0x);
@@ -291,7 +290,7 @@
     ConsumeToken();
 
     // Special case handling for the ternary operator.
-    OwningExprResult TernaryMiddle(Actions, true);
+    ExprResult TernaryMiddle(true);
     if (NextTokPrec == prec::Conditional) {
       if (Tok.isNot(tok::colon)) {
         // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
@@ -315,13 +314,42 @@
         // Eat the colon.
         ColonLoc = ConsumeToken();
       } else {
+        // Otherwise, we're missing a ':'.  Assume that this was a typo that the
+        // user forgot.  If we're not in a macro instantion, we can suggest a
+        // fixit hint.  If there were two spaces before the current token,
+        // suggest inserting the colon in between them, otherwise insert ": ".
+        SourceLocation FILoc = Tok.getLocation();
+        const char *FIText = ": ";
+        if (FILoc.isFileID()) {
+          const SourceManager &SM = PP.getSourceManager();
+          bool IsInvalid = false;
+          const char *SourcePtr =
+            SM.getCharacterData(FILoc.getFileLocWithOffset(-1), &IsInvalid);
+          if (!IsInvalid && *SourcePtr == ' ') {
+            SourcePtr =
+              SM.getCharacterData(FILoc.getFileLocWithOffset(-2), &IsInvalid);
+            if (!IsInvalid && *SourcePtr == ' ') {
+              FILoc = FILoc.getFileLocWithOffset(-1);
+              FIText = ":";
+            }
+          }
+        }
+        
         Diag(Tok, diag::err_expected_colon)
-          << FixItHint::CreateInsertion(Tok.getLocation(), ": ");
+          << FixItHint::CreateInsertion(FILoc, FIText);
         Diag(OpToken, diag::note_matching) << "?";
         ColonLoc = Tok.getLocation();
       }
     }
     
+    // Code completion for the right-hand side of an assignment expression
+    // goes through a special hook that takes the left-hand side into account.
+    if (Tok.is(tok::code_completion) && NextTokPrec == prec::Assignment) {
+      Actions.CodeCompleteAssignmentRHS(getCurScope(), LHS.get());
+      ConsumeCodeCompletionToken();
+      return ExprError();
+    }
+    
     // 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
@@ -329,7 +357,7 @@
     // 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);
+    ExprResult RHS;
     if (getLang().CPlusPlus && NextTokPrec <= prec::Conditional)
       RHS = ParseAssignmentExpression();
     else
@@ -356,7 +384,7 @@
       // 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), 
+      RHS = ParseRHSOfBinaryExpression(RHS.get(), 
                             static_cast<prec::Level>(ThisPrec + !isRightAssoc));
       if (RHS.isInvalid())
         return move(RHS);
@@ -378,12 +406,12 @@
                          SourceRange(Actions.getExprRange(LHS.get()).getBegin(),
                                      Actions.getExprRange(RHS.get()).getEnd()));
 
-        LHS = Actions.ActOnBinOp(CurScope, OpToken.getLocation(),
-                                 OpToken.getKind(), move(LHS), move(RHS));
+        LHS = Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(),
+                                 OpToken.getKind(), LHS.take(), RHS.take());
       } else
         LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
-                                         move(LHS), move(TernaryMiddle),
-                                         move(RHS));
+                                         LHS.take(), TernaryMiddle.take(),
+                                         RHS.take());
     }
   }
 }
@@ -393,11 +421,11 @@
 /// id-expression that is the operand of address-of gets special treatment
 /// due to member pointers.
 ///
-Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
+ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
                                                      bool isAddressOfOperand,
-                                                     TypeTy *TypeOfCast) {
+                                                     ParsedType TypeOfCast) {
   bool NotCastExpr;
-  OwningExprResult Res = ParseCastExpression(isUnaryExpression,
+  ExprResult Res = ParseCastExpression(isUnaryExpression,
                                              isAddressOfOperand,
                                              NotCastExpr,
                                              TypeOfCast);
@@ -517,11 +545,11 @@
 /// [GNU] binary-type-trait:
 ///                   '__is_base_of'                          [TODO]
 ///
-Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
+ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
                                                      bool isAddressOfOperand,
                                                      bool &NotCastExpr,
-                                                     TypeTy *TypeOfCast) {
-  OwningExprResult Res(Actions);
+                                                     ParsedType TypeOfCast) {
+  ExprResult Res;
   tok::TokenKind SavedKind = Tok.getKind();
   NotCastExpr = false;
 
@@ -532,16 +560,17 @@
   // 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.
+  // break out of the switch;  at the end we 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;
+      (isUnaryExpression && !getLang().CPlusPlus)? CompoundLiteral : CastExpr;
+    ParsedType CastTy;
     SourceLocation LParenLoc = Tok.getLocation();
     SourceLocation RParenLoc;
     
@@ -551,7 +580,8 @@
     
       Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/,
                                  TypeOfCast, CastTy, RParenLoc);
-      if (Res.isInvalid()) return move(Res);
+      if (Res.isInvalid()) 
+        return move(Res);
     }
 
     switch (ParenExprType) {
@@ -567,8 +597,7 @@
       return move(Res);
     }
 
-    // These can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(move(Res));
+    break;
   }
 
     // primary-expression
@@ -578,9 +607,7 @@
 
     Res = Actions.ActOnNumericConstant(Tok);
     ConsumeToken();
-
-    // These can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(move(Res));
+    break;
 
   case tok::kw_true:
   case tok::kw_false:
@@ -617,9 +644,9 @@
     
     // Support 'Class.property' and 'super.property' notation.
     if (getLang().ObjC1 && Tok.is(tok::period) &&
-        (Actions.getTypeName(II, ILoc, CurScope) ||
+        (Actions.getTypeName(II, ILoc, getCurScope()) ||
          // Allow the base to be 'super' if in an objc-method.
-         (&II == Ident_super && CurScope->isInObjcMethodScope()))) {
+         (&II == Ident_super && getCurScope()->isInObjcMethodScope()))) {
       SourceLocation DotLoc = ConsumeToken();
       
       if (Tok.isNot(tok::identifier)) {
@@ -631,9 +658,12 @@
       
       Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName,
                                               ILoc, PropertyLoc);
-      // These can be followed by postfix-expr pieces.
-      return ParsePostfixExpressionSuffix(move(Res));
+      break;
     }
+
+    // Make sure to pass down the right value for isAddressOfOperand.
+    if (isAddressOfOperand && isPostfixExpressionSuffixStart())
+      isAddressOfOperand = false;
    
     // 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
@@ -641,29 +671,24 @@
     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));
+    Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, Name, 
+                                    Tok.is(tok::l_paren), isAddressOfOperand);
+    break;
   }
   case tok::char_constant:     // constant: character-constant
     Res = Actions.ActOnCharacterConstant(Tok);
     ConsumeToken();
-    // These can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(move(Res));
+    break;
   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));
+    break;
   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));
+    break;
   case tok::kw___builtin_va_arg:
   case tok::kw___builtin_offsetof:
   case tok::kw___builtin_choose_expr:
@@ -672,12 +697,16 @@
   case tok::kw___null:
     return Actions.ActOnGNUNullExpr(ConsumeToken());
     break;
-  case tok::plusplus:      // unary-expression: '++' unary-expression
-  case tok::minusminus: {  // unary-expression: '--' unary-expression
+  case tok::plusplus:      // unary-expression: '++' unary-expression [C99]
+  case tok::minusminus: {  // unary-expression: '--' unary-expression [C99]
+    // C++ [expr.unary] has:
+    //   unary-expression:
+    //     ++ cast-expression
+    //     -- cast-expression
     SourceLocation SavedLoc = ConsumeToken();
-    Res = ParseCastExpression(true);
+    Res = ParseCastExpression(!getLang().CPlusPlus);
     if (!Res.isInvalid())
-      Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
+      Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
     return move(Res);
   }
   case tok::amp: {         // unary-expression: '&' cast-expression
@@ -685,7 +714,7 @@
     SourceLocation SavedLoc = ConsumeToken();
     Res = ParseCastExpression(false, true);
     if (!Res.isInvalid())
-      Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
+      Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
     return move(Res);
   }
 
@@ -699,7 +728,7 @@
     SourceLocation SavedLoc = ConsumeToken();
     Res = ParseCastExpression(false);
     if (!Res.isInvalid())
-      Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
+      Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
     return move(Res);
   }
 
@@ -709,7 +738,7 @@
     SourceLocation SavedLoc = ConsumeToken();
     Res = ParseCastExpression(false);
     if (!Res.isInvalid())
-      Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
+      Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
     return move(Res);
   }
   case tok::kw_sizeof:     // unary-expression: 'sizeof' unary-expression
@@ -735,16 +764,13 @@
   case tok::kw_reinterpret_cast:
   case tok::kw_static_cast:
     Res = ParseCXXCasts();
-    // These can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(move(Res));
+    break;
   case tok::kw_typeid:
     Res = ParseCXXTypeid();
-    // This can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(move(Res));
+    break;
   case tok::kw_this:
     Res = ParseCXXThis();
-    // This can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(move(Res));
+    break;
 
   case tok::kw_char:
   case tok::kw_wchar_t:
@@ -783,8 +809,7 @@
                          << DS.getSourceRange());
 
     Res = ParseCXXTypeConstructExpression(DS);
-    // This can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(move(Res));
+    break;
   }
 
   case tok::annot_cxxscope: { // [C++] id-expression: qualified-id
@@ -805,7 +830,7 @@
         // type, translate it into a type and continue parsing as a
         // cast expression.
         CXXScopeSpec SS;
-        ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+        ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
         AnnotateTemplateIdTokenAsType(&SS);
         return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
                                    NotCastExpr, TypeOfCast);
@@ -814,7 +839,7 @@
 
     // Parse as an id-expression.
     Res = ParseCXXIdExpression(isAddressOfOperand);
-    return ParsePostfixExpressionSuffix(move(Res));
+    break;
   }
 
   case tok::annot_template_id: { // [C++]          template-id
@@ -834,7 +859,7 @@
 
   case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
     Res = ParseCXXIdExpression(isAddressOfOperand);
-    return ParsePostfixExpressionSuffix(move(Res));
+    break;
 
   case tok::coloncolon: {
     // ::foo::bar -> global qualified name etc.   If TryAnnotateTypeOrScopeToken
@@ -884,8 +909,8 @@
   case tok::caret:
     return ParsePostfixExpressionSuffix(ParseBlockLiteralExpression());
   case tok::code_completion:
-    Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Expression);
-    ConsumeToken();
+    Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
+    ConsumeCodeCompletionToken();
     return ParseCastExpression(isUnaryExpression, isAddressOfOperand, 
                                NotCastExpr, TypeOfCast);
   case tok::l_square:
@@ -898,8 +923,9 @@
     return ExprError();
   }
 
-  // unreachable.
-  abort();
+  // These can be followed by postfix-expr pieces.
+  if (Res.isInvalid()) return move(Res);
+  return ParsePostfixExpressionSuffix(Res.get());
 }
 
 /// ParsePostfixExpressionSuffix - Once the leading part of a postfix-expression
@@ -920,8 +946,8 @@
 ///         argument-expression
 ///         argument-expression-list ',' assignment-expression
 ///
-Parser::OwningExprResult
-Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
+ExprResult
+Parser::ParsePostfixExpressionSuffix(ExprResult 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;
@@ -930,14 +956,24 @@
     default:  // Not a postfix-expression suffix.
       return move(LHS);
     case tok::l_square: {  // postfix-expression: p-e '[' expression ']'
+      // If we have a array postfix expression that starts on a new line and
+      // Objective-C is enabled, it is highly likely that the user forgot a
+      // semicolon after the base expression and that the array postfix-expr is
+      // actually another message send.  In this case, do some look-ahead to see
+      // if the contents of the square brackets are obviously not a valid
+      // expression and recover by pretending there is no suffix.
+      if (getLang().ObjC1 && Tok.isAtStartOfLine() &&
+          isSimpleObjCMessageExpression())
+        return move(LHS);
+          
       Loc = ConsumeBracket();
-      OwningExprResult Idx(ParseExpression());
+      ExprResult 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);
+        LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.take(), Loc,
+                                              Idx.take(), RLoc);
       } else
         LHS = ExprError();
 
@@ -952,13 +988,18 @@
 
       Loc = ConsumeParen();
 
+      if (LHS.isInvalid()) {
+        SkipUntil(tok::r_paren);
+        return ExprError();
+      }
+
       if (Tok.is(tok::code_completion)) {
-        Actions.CodeCompleteCall(CurScope, LHS.get(), 0, 0);
-        ConsumeToken();
+        Actions.CodeCompleteCall(getCurScope(), LHS.get(), 0, 0);
+        ConsumeCodeCompletionToken();
       }
       
       if (Tok.isNot(tok::r_paren)) {
-        if (ParseExpressionList(ArgExprs, CommaLocs, &Action::CodeCompleteCall,
+        if (ParseExpressionList(ArgExprs, CommaLocs, &Sema::CodeCompleteCall,
                                 LHS.get())) {
           SkipUntil(tok::r_paren);
           return ExprError();
@@ -974,7 +1015,7 @@
       if (!LHS.isInvalid()) {
         assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&&
                "Unexpected number of commas!");
-        LHS = Actions.ActOnCallExpr(CurScope, move(LHS), Loc,
+        LHS = Actions.ActOnCallExpr(getCurScope(), LHS.take(), Loc,
                                     move_arg(ArgExprs), CommaLocs.data(),
                                     Tok.getLocation());
       }
@@ -990,10 +1031,10 @@
       SourceLocation OpLoc = ConsumeToken();  // Eat the "." or "->" token.
 
       CXXScopeSpec SS;
-      Action::TypeTy *ObjectType = 0;
+      ParsedType ObjectType;
       bool MayBePseudoDestructor = false;
       if (getLang().CPlusPlus && !LHS.isInvalid()) {
-        LHS = Actions.ActOnStartCXXMemberReference(CurScope, move(LHS),
+        LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), LHS.take(),
                                                    OpLoc, OpKind, ObjectType,
                                                    MayBePseudoDestructor);
         if (LHS.isInvalid())
@@ -1001,18 +1042,20 @@
 
         ParseOptionalCXXScopeSpecifier(SS, ObjectType, false,
                                        &MayBePseudoDestructor);
+        if (SS.isNotEmpty())
+          ObjectType = ParsedType();
       }
 
       if (Tok.is(tok::code_completion)) {
         // Code completion for a member access expression.
-        Actions.CodeCompleteMemberReferenceExpr(CurScope, LHS.get(),
+        Actions.CodeCompleteMemberReferenceExpr(getCurScope(), LHS.get(),
                                                 OpLoc, OpKind == tok::arrow);
         
-        ConsumeToken();
+        ConsumeCodeCompletionToken();
       }
       
-      if (MayBePseudoDestructor) {
-        LHS = ParseCXXPseudoDestructor(move(LHS), OpLoc, OpKind, SS, 
+      if (MayBePseudoDestructor && !LHS.isInvalid()) {
+        LHS = ParseCXXPseudoDestructor(LHS.take(), OpLoc, OpKind, SS, 
                                        ObjectType);
         break;
       }
@@ -1032,7 +1075,7 @@
         return ExprError();
       
       if (!LHS.isInvalid())
-        LHS = Actions.ActOnMemberAccessExpr(CurScope, move(LHS), OpLoc, 
+        LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.take(), OpLoc, 
                                             OpKind, SS, Name, ObjCImpDecl,
                                             Tok.is(tok::l_paren));
       break;
@@ -1040,8 +1083,8 @@
     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));
+        LHS = Actions.ActOnPostfixUnaryOp(getCurScope(), Tok.getLocation(),
+                                          Tok.getKind(), LHS.take());
       }
       ConsumeToken();
       break;
@@ -1066,17 +1109,17 @@
 ///           typeof ( type-name )
 /// [GNU/C++] typeof unary-expression
 ///
-Parser::OwningExprResult
+ExprResult
 Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok,
                                           bool &isCastExpr,
-                                          TypeTy *&CastTy,
+                                          ParsedType &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);
+  ExprResult Operand;
 
   // If the operand doesn't start with an '(', it must be an expression.
   if (Tok.isNot(tok::l_paren)) {
@@ -1093,7 +1136,7 @@
     // The GNU typeof and alignof extensions also behave as unevaluated
     // operands.
     EnterExpressionEvaluationContext Unevaluated(Actions,
-                                                 Action::Unevaluated);
+                                                 Sema::Unevaluated);
     Operand = ParseCastExpression(true/*isUnaryExpression*/);
   } else {
     // If it starts with a '(', we know that it is either a parenthesized
@@ -1110,10 +1153,9 @@
     // The GNU typeof and alignof extensions also behave as unevaluated
     // operands.
     EnterExpressionEvaluationContext Unevaluated(Actions,
-                                                 Action::Unevaluated);
+                                                 Sema::Unevaluated);
     Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, 
-                                   0/*TypeOfCast*/,
-                                   CastTy, RParenLoc);
+                                   ParsedType(), CastTy, RParenLoc);
     CastRange = SourceRange(LParenLoc, RParenLoc);
 
     // If ParseParenExpression parsed a '(typename)' sequence only, then this is
@@ -1123,10 +1165,14 @@
       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 (getLang().CPlusPlus || OpTok.isNot(tok::kw_typeof)) {
+      // GNU typeof in C requires the expression to be parenthesized. Not so for
+      // sizeof/alignof or in C++. Therefore, the parenthesized expression is
+      // the start of a unary-expression, but doesn't include any postfix 
+      // pieces. Parse these now if present.
+      if (!Operand.isInvalid())
+        Operand = ParsePostfixExpressionSuffix(Operand.get());
+    }
   }
 
   // If we get here, the operand to the typeof/sizeof/alignof was an expresion.
@@ -1142,7 +1188,7 @@
 /// [GNU]   '__alignof' unary-expression
 /// [GNU]   '__alignof' '(' type-name ')'
 /// [C++0x] 'alignof' '(' type-id ')'
-Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() {
+ExprResult Parser::ParseSizeofAlignofExpression() {
   assert((Tok.is(tok::kw_sizeof) || Tok.is(tok::kw___alignof)
           || Tok.is(tok::kw_alignof)) &&
          "Not a sizeof/alignof expression!");
@@ -1150,9 +1196,9 @@
   ConsumeToken();
 
   bool isCastExpr;
-  TypeTy *CastTy;
+  ParsedType CastTy;
   SourceRange CastRange;
-  OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok,
+  ExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok,
                                                                isCastExpr,
                                                                CastTy,
                                                                CastRange);
@@ -1160,7 +1206,8 @@
   if (isCastExpr)
     return Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
                                           OpTok.is(tok::kw_sizeof),
-                                          /*isType=*/true, CastTy,
+                                          /*isType=*/true,
+                                          CastTy.getAsOpaquePtr(),
                                           CastRange);
 
   // If we get here, the operand to the sizeof/alignof was an expresion.
@@ -1186,8 +1233,8 @@
 /// [GNU]   offsetof-member-designator '.' identifier
 /// [GNU]   offsetof-member-designator '[' expression ']'
 ///
-Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() {
-  OwningExprResult Res(Actions);
+ExprResult Parser::ParseBuiltinPrimaryExpression() {
+  ExprResult Res;
   const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
 
   tok::TokenKind T = Tok.getKind();
@@ -1204,7 +1251,7 @@
   switch (T) {
   default: assert(0 && "Not a builtin primary expression!");
   case tok::kw___builtin_va_arg: {
-    OwningExprResult Expr(ParseAssignmentExpression());
+    ExprResult Expr(ParseAssignmentExpression());
     if (Expr.isInvalid()) {
       SkipUntil(tok::r_paren);
       return ExprError();
@@ -1222,7 +1269,7 @@
     if (Ty.isInvalid())
       Res = ExprError();
     else
-      Res = Actions.ActOnVAArg(StartLoc, move(Expr), Ty.get(), ConsumeParen());
+      Res = Actions.ActOnVAArg(StartLoc, Expr.take(), Ty.get(), ConsumeParen());
     break;
   }
   case tok::kw___builtin_offsetof: {
@@ -1244,9 +1291,9 @@
     }
 
     // Keep track of the various subcomponents we see.
-    llvm::SmallVector<Action::OffsetOfComponent, 4> Comps;
+    llvm::SmallVector<Sema::OffsetOfComponent, 4> Comps;
 
-    Comps.push_back(Action::OffsetOfComponent());
+    Comps.push_back(Sema::OffsetOfComponent());
     Comps.back().isBrackets = false;
     Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
     Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken();
@@ -1255,7 +1302,7 @@
     while (1) {
       if (Tok.is(tok::period)) {
         // offsetof-member-designator: offsetof-member-designator '.' identifier
-        Comps.push_back(Action::OffsetOfComponent());
+        Comps.push_back(Sema::OffsetOfComponent());
         Comps.back().isBrackets = false;
         Comps.back().LocStart = ConsumeToken();
 
@@ -1269,7 +1316,7 @@
 
       } else if (Tok.is(tok::l_square)) {
         // offsetof-member-designator: offsetof-member-design '[' expression ']'
-        Comps.push_back(Action::OffsetOfComponent());
+        Comps.push_back(Sema::OffsetOfComponent());
         Comps.back().isBrackets = true;
         Comps.back().LocStart = ConsumeBracket();
         Res = ParseExpression();
@@ -1288,7 +1335,7 @@
         } else if (Ty.isInvalid()) {
           Res = ExprError();
         } else {
-          Res = Actions.ActOnBuiltinOffsetOf(CurScope, StartLoc, TypeLoc,
+          Res = Actions.ActOnBuiltinOffsetOf(getCurScope(), StartLoc, TypeLoc,
                                              Ty.get(), &Comps[0],
                                              Comps.size(), ConsumeParen());
         }
@@ -1298,7 +1345,7 @@
     break;
   }
   case tok::kw___builtin_choose_expr: {
-    OwningExprResult Cond(ParseAssignmentExpression());
+    ExprResult Cond(ParseAssignmentExpression());
     if (Cond.isInvalid()) {
       SkipUntil(tok::r_paren);
       return move(Cond);
@@ -1306,7 +1353,7 @@
     if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
       return ExprError();
 
-    OwningExprResult Expr1(ParseAssignmentExpression());
+    ExprResult Expr1(ParseAssignmentExpression());
     if (Expr1.isInvalid()) {
       SkipUntil(tok::r_paren);
       return move(Expr1);
@@ -1314,7 +1361,7 @@
     if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
       return ExprError();
 
-    OwningExprResult Expr2(ParseAssignmentExpression());
+    ExprResult Expr2(ParseAssignmentExpression());
     if (Expr2.isInvalid()) {
       SkipUntil(tok::r_paren);
       return move(Expr2);
@@ -1323,8 +1370,8 @@
       Diag(Tok, diag::err_expected_rparen);
       return ExprError();
     }
-    Res = Actions.ActOnChooseExpr(StartLoc, move(Cond), move(Expr1),
-                                  move(Expr2), ConsumeParen());
+    Res = Actions.ActOnChooseExpr(StartLoc, Cond.take(), Expr1.take(),
+                                  Expr2.take(), ConsumeParen());
     break;
   }
   case tok::kw___builtin_types_compatible_p:
@@ -1348,9 +1395,12 @@
     break;
   }
 
+  if (Res.isInvalid())
+    return ExprError();
+
   // These can be followed by postfix-expr pieces because they are
   // primary-expressions.
-  return ParsePostfixExpressionSuffix(move(Res));
+  return ParsePostfixExpressionSuffix(Res.take());
 }
 
 /// ParseParenExpression - This parses the unit that starts with a '(' token,
@@ -1367,25 +1417,25 @@
 ///       cast-expression: [C99 6.5.4]
 ///         '(' type-name ')' cast-expression
 ///
-Parser::OwningExprResult
+ExprResult
 Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
-                             TypeTy *TypeOfCast, TypeTy *&CastTy,
+                             ParsedType TypeOfCast, ParsedType &CastTy,
                              SourceLocation &RParenLoc) {
   assert(Tok.is(tok::l_paren) && "Not a paren expr!");
   GreaterThanIsOperatorScope G(GreaterThanIsOperator, true);
   SourceLocation OpenLoc = ConsumeParen();
-  OwningExprResult Result(Actions, true);
+  ExprResult Result(true);
   bool isAmbiguousTypeId;
-  CastTy = 0;
+  CastTy = ParsedType();
 
   if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
     Diag(Tok, diag::ext_gnu_statement_expr);
-    OwningStmtResult Stmt(ParseCompoundStatement(0, true));
+    StmtResult 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());
+      Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.take(), Tok.getLocation());
 
   } else if (ExprType >= CompoundLiteral &&
              isTypeIdInParens(isAmbiguousTypeId)) {
@@ -1425,12 +1475,12 @@
       // Note that this doesn't parse the subsequent cast-expression, it just
       // returns the parsed type to the callee.
       if (stopIfCastExpr)
-        return OwningExprResult(Actions);
+        return ExprResult();
       
       // Reject the cast of super idiom in ObjC.
       if (Tok.is(tok::identifier) && getLang().ObjC1 &&
           Tok.getIdentifierInfo() == Ident_super && 
-          CurScope->isInObjcMethodScope() &&
+          getCurScope()->isInObjcMethodScope() &&
           GetLookAheadToken(1).isNot(tok::period)) {
         Diag(Tok.getLocation(), diag::err_illegal_super_cast)
           << SourceRange(OpenLoc, RParenLoc);
@@ -1441,8 +1491,8 @@
       // TODO: For cast expression with CastTy.
       Result = ParseCastExpression(false, false, CastTy);
       if (!Result.isInvalid())
-        Result = Actions.ActOnCastExpr(CurScope, OpenLoc, CastTy, RParenLoc,
-                                       move(Result));
+        Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, CastTy, RParenLoc,
+                                       Result.take());
       return move(Result);
     }
 
@@ -1462,7 +1512,7 @@
     Result = ParseExpression();
     ExprType = SimpleExpr;
     if (!Result.isInvalid() && Tok.is(tok::r_paren))
-      Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), move(Result));
+      Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.take());
   }
 
   // Match the ')'.
@@ -1486,16 +1536,16 @@
 ///         '(' type-name ')' '{' initializer-list '}'
 ///         '(' type-name ')' '{' initializer-list ',' '}'
 ///
-Parser::OwningExprResult
-Parser::ParseCompoundLiteralExpression(TypeTy *Ty,
+ExprResult
+Parser::ParseCompoundLiteralExpression(ParsedType 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();
+  ExprResult Result = ParseInitializer();
   if (!Result.isInvalid() && Ty)
-    return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, move(Result));
+    return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.take());
   return move(Result);
 }
 
@@ -1505,7 +1555,7 @@
 ///
 ///       primary-expression: [C99 6.5.1]
 ///         string-literal
-Parser::OwningExprResult Parser::ParseStringLiteralExpression() {
+ExprResult Parser::ParseStringLiteralExpression() {
   assert(isTokenStringLiteral() && "Not a string literal!");
 
   // String concat.  Note that keywords like __func__ and __FUNCTION__ are not
@@ -1531,20 +1581,21 @@
 /// [C++]   assignment-expression
 /// [C++]   expression-list , assignment-expression
 ///
-bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs,
-                                 void (Action::*Completer)(Scope *S, 
-                                                           void *Data,
-                                                           ExprTy **Args,
+bool Parser::ParseExpressionList(llvm::SmallVectorImpl<Expr*> &Exprs,
+                            llvm::SmallVectorImpl<SourceLocation> &CommaLocs,
+                                 void (Sema::*Completer)(Scope *S, 
+                                                           Expr *Data,
+                                                           Expr **Args,
                                                            unsigned NumArgs),
-                                 void *Data) {
+                                 Expr *Data) {
   while (1) {
     if (Tok.is(tok::code_completion)) {
       if (Completer)
-        (Actions.*Completer)(CurScope, Data, Exprs.data(), Exprs.size());
-      ConsumeToken();
+        (Actions.*Completer)(getCurScope(), Data, Exprs.data(), Exprs.size());
+      ConsumeCodeCompletionToken();
     }
     
-    OwningExprResult Expr(ParseAssignmentExpression());
+    ExprResult Expr(ParseAssignmentExpression());
     if (Expr.isInvalid())
       return true;
 
@@ -1582,7 +1633,7 @@
   }
 
   // Inform sema that we are starting a block.
-  Actions.ActOnBlockArguments(DeclaratorInfo, CurScope);
+  Actions.ActOnBlockArguments(DeclaratorInfo, getCurScope());
 }
 
 /// ParseBlockLiteralExpression - Parse a block literal, which roughly looks
@@ -1594,7 +1645,7 @@
 /// [clang] block-args:
 /// [clang]   '(' parameter-list ')'
 ///
-Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {
+ExprResult Parser::ParseBlockLiteralExpression() {
   assert(Tok.is(tok::caret) && "block literal starts with ^");
   SourceLocation CaretLoc = ConsumeToken();
 
@@ -1610,7 +1661,7 @@
                               Scope::DeclScope);
 
   // Inform sema that we are starting a block.
-  Actions.ActOnBlockStart(CaretLoc, CurScope);
+  Actions.ActOnBlockStart(CaretLoc, getCurScope());
 
   // Parse the return type if present.
   DeclSpec DS;
@@ -1633,7 +1684,7 @@
       // 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);
+      Actions.ActOnBlockError(CaretLoc, getCurScope());
       return ExprError();
     }
 
@@ -1644,7 +1695,7 @@
     }
 
     // Inform sema that we are starting a block.
-    Actions.ActOnBlockArguments(ParamInfo, CurScope);
+    Actions.ActOnBlockArguments(ParamInfo, getCurScope());
   } else if (!Tok.is(tok::l_brace)) {
     ParseBlockId();
   } else {
@@ -1665,22 +1716,22 @@
     }
 
     // Inform sema that we are starting a block.
-    Actions.ActOnBlockArguments(ParamInfo, CurScope);
+    Actions.ActOnBlockArguments(ParamInfo, getCurScope());
   }
 
 
-  OwningExprResult Result(Actions, true);
+  ExprResult Result(true);
   if (!Tok.is(tok::l_brace)) {
     // Saw something like: ^expr
     Diag(Tok, diag::err_expected_expression);
-    Actions.ActOnBlockError(CaretLoc, CurScope);
+    Actions.ActOnBlockError(CaretLoc, getCurScope());
     return ExprError();
   }
 
-  OwningStmtResult Stmt(ParseCompoundStatementBody());
+  StmtResult Stmt(ParseCompoundStatementBody());
   if (!Stmt.isInvalid())
-    Result = Actions.ActOnBlockStmtExpr(CaretLoc, move(Stmt), CurScope);
+    Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.take(), getCurScope());
   else
-    Actions.ActOnBlockError(CaretLoc, CurScope);
+    Actions.ActOnBlockError(CaretLoc, getCurScope());
   return move(Result);
 }
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 146762b..5041a21 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -13,8 +13,8 @@
 
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/Parser.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Template.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/ParsedTemplate.h"
 #include "llvm/Support/ErrorHandling.h"
 
 using namespace clang;
@@ -57,14 +57,14 @@
 ///
 /// \returns true if there was an error parsing a scope specifier
 bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
-                                            Action::TypeTy *ObjectType,
+                                            ParsedType 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.setScopeRep(static_cast<NestedNameSpecifier*>(Tok.getAnnotationValue()));
     SS.setRange(Tok.getAnnotationRange());
     ConsumeToken();
     return false;
@@ -81,7 +81,7 @@
     // '::' - Global scope qualifier.
     SourceLocation CCLoc = ConsumeToken();
     SS.setBeginLoc(CCLoc);
-    SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
+    SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(getCurScope(), CCLoc));
     SS.setEndLoc(CCLoc);
     HasScopeSpecifier = true;
   }
@@ -104,13 +104,13 @@
       //
       // 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;
+      ObjectType = ParsedType();
       
       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();
+        Actions.CodeCompleteQualifiedId(getCurScope(), SS, EnteringContext);
+        ConsumeCodeCompletionToken();
       }
     }
 
@@ -164,13 +164,18 @@
       
       // 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))
+      TemplateTy Template;
+      if (TemplateNameKind TNK = Actions.ActOnDependentTemplateName(getCurScope(), 
+                                                                TemplateKWLoc, 
+                                                                    SS, 
+                                                                  TemplateName,
+                                                                    ObjectType, 
+                                                                EnteringContext,
+                                                                    Template)) {
+        if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName, 
+                                    TemplateKWLoc, false))
+          return true;
+      } else
         return true;
 
       continue;
@@ -207,13 +212,13 @@
           HasScopeSpecifier = true;
         }
 
-        if (TypeToken.getAnnotationValue())
-          SS.setScopeRep(
-            Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
-                                                TypeToken.getAnnotationValue(),
+        if (ParsedType T = getTypeAnnotation(TypeToken)) {
+          CXXScopeTy *Scope =
+            Actions.ActOnCXXNestedNameSpecifier(getCurScope(), SS, T,
                                                 TypeToken.getAnnotationRange(),
-                                                CCLoc));
-        else
+                                                CCLoc);
+          SS.setScopeRep(Scope);
+        } else
           SS.setScopeRep(0);
         SS.setEndLoc(CCLoc);
         continue;
@@ -239,7 +244,7 @@
     // 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, 
+      if (Actions.IsInvalidUnlessNestedName(getCurScope(), 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
@@ -255,7 +260,7 @@
     
     if (Next.is(tok::coloncolon)) {
       if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde) &&
-          !Actions.isNonTypeNestedNameSpecifier(CurScope, SS, Tok.getLocation(),
+          !Actions.isNonTypeNestedNameSpecifier(getCurScope(), SS, Tok.getLocation(),
                                                 II, ObjectType)) {
         *MayBePseudoDestructor = true;
         return false;
@@ -273,12 +278,10 @@
         HasScopeSpecifier = true;
       }
 
-      if (SS.isInvalid())
-        continue;
-
-      SS.setScopeRep(
-        Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, II,
-                                            ObjectType, EnteringContext));
+      if (!SS.isInvalid())
+        SS.setScopeRep(
+            Actions.ActOnCXXNestedNameSpecifier(getCurScope(), SS, IdLoc, CCLoc, II,
+                                                ObjectType, EnteringContext));
       SS.setEndLoc(CCLoc);
       continue;
     }
@@ -289,11 +292,14 @@
       TemplateTy Template;
       UnqualifiedId TemplateName;
       TemplateName.setIdentifier(&II, Tok.getLocation());
-      if (TemplateNameKind TNK = Actions.isTemplateName(CurScope, SS, 
+      bool MemberOfUnknownSpecialization;
+      if (TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS, 
+                                              /*hasTemplateKeyword=*/false,
                                                         TemplateName,
                                                         ObjectType,
                                                         EnteringContext,
-                                                        Template)) {
+                                                        Template,
+                                              MemberOfUnknownSpecialization)) {
         // 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,
@@ -305,6 +311,33 @@
                                     SourceLocation(), false))
           return true;
         continue;
+      } 
+      
+      if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) && 
+          IsTemplateArgumentList(1)) {
+        // We have something like t::getAs<T>, where getAs is a 
+        // member of an unknown specialization. However, this will only
+        // parse correctly as a template, so suggest the keyword 'template'
+        // before 'getAs' and treat this as a dependent template name.
+        Diag(Tok.getLocation(), diag::err_missing_dependent_template_keyword)
+          << II.getName()
+          << FixItHint::CreateInsertion(Tok.getLocation(), "template ");
+        
+        if (TemplateNameKind TNK 
+              = Actions.ActOnDependentTemplateName(getCurScope(), 
+                                                   Tok.getLocation(), SS, 
+                                                   TemplateName, ObjectType,
+                                                   EnteringContext, Template)) {
+          // Consume the identifier.
+          ConsumeToken();
+          if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName, 
+                                      SourceLocation(), false))
+            return true;                
+        }
+        else
+          return true;     
+                
+        continue;        
       }
     }
 
@@ -364,42 +397,29 @@
 /// the only place where a qualified-id naming a non-static class member may
 /// appear.
 ///
-Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
+ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
   // qualified-id:
   //   '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
   //   '::' unqualified-id
   //
   CXXScopeSpec SS;
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
   
   UnqualifiedId Name;
   if (ParseUnqualifiedId(SS, 
                          /*EnteringContext=*/false, 
                          /*AllowDestructorName=*/false, 
                          /*AllowConstructorName=*/false, 
-                         /*ObjectType=*/0,
+                         /*ObjectType=*/ ParsedType(),
                          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;
-    }
-  }
+  if (isAddressOfOperand && isPostfixExpressionSuffixStart())
+    isAddressOfOperand = false;
   
-  return Actions.ActOnIdExpression(CurScope, SS, Name, Tok.is(tok::l_paren),
+  return Actions.ActOnIdExpression(getCurScope(), SS, Name, Tok.is(tok::l_paren),
                                    isAddressOfOperand);
   
 }
@@ -413,7 +433,7 @@
 ///         'reinterpret_cast' '<' type-name '>' '(' expression ')'
 ///         'const_cast' '<' type-name '>' '(' expression ')'
 ///
-Parser::OwningExprResult Parser::ParseCXXCasts() {
+ExprResult Parser::ParseCXXCasts() {
   tok::TokenKind Kind = Tok.getKind();
   const char *CastName = 0;     // For error messages
 
@@ -442,7 +462,7 @@
   if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, CastName))
     return ExprError();
 
-  OwningExprResult Result = ParseExpression();
+  ExprResult Result = ParseExpression();
 
   // Match the ')'.
   RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
@@ -451,7 +471,7 @@
     Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
                                        LAngleBracketLoc, CastTy.get(),
                                        RAngleBracketLoc,
-                                       LParenLoc, move(Result), RParenLoc);
+                                       LParenLoc, Result.take(), RParenLoc);
 
   return move(Result);
 }
@@ -462,7 +482,7 @@
 ///         'typeid' '(' expression ')'
 ///         'typeid' '(' type-id ')'
 ///
-Parser::OwningExprResult Parser::ParseCXXTypeid() {
+ExprResult Parser::ParseCXXTypeid() {
   assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");
 
   SourceLocation OpLoc = ConsumeToken();
@@ -474,7 +494,7 @@
       "typeid"))
     return ExprError();
 
-  OwningExprResult Result(Actions);
+  ExprResult Result;
 
   if (isTypeIdInParens()) {
     TypeResult Ty = ParseTypeName();
@@ -486,7 +506,7 @@
       return ExprError();
 
     Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
-                                    Ty.get(), RParenLoc);
+                                    Ty.get().getAsOpaquePtr(), RParenLoc);
   } else {
     // C++0x [expr.typeid]p3:
     //   When typeid is applied to an expression other than an lvalue of a
@@ -497,7 +517,7 @@
     // polymorphic class type until after we've parsed the expression, so
     // we the expression is potentially potentially evaluated.
     EnterExpressionEvaluationContext Unevaluated(Actions,
-                                       Action::PotentiallyPotentiallyEvaluated);
+                                       Sema::PotentiallyPotentiallyEvaluated);
     Result = ParseExpression();
 
     // Match the ')'.
@@ -528,11 +548,11 @@
 ///                 ~type-name 
 ///         ::[opt] nested-name-specifier[opt] ~type-name
 ///       
-Parser::OwningExprResult 
+ExprResult 
 Parser::ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc,
                                  tok::TokenKind OpKind,
                                  CXXScopeSpec &SS,
-                                 Action::TypeTy *ObjectType) {
+                                 ParsedType 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
@@ -576,10 +596,12 @@
   // it as such.
   if (Tok.is(tok::less) &&
       ParseUnqualifiedIdTemplateId(SS, Name, NameLoc, false, ObjectType,
-                                   SecondTypeName, /*AssumeTemplateName=*/true))
+                                   SecondTypeName, /*AssumeTemplateName=*/true,
+                                   /*TemplateKWLoc*/SourceLocation()))
     return ExprError();
 
-  return Actions.ActOnPseudoDestructorExpr(CurScope, move(Base), OpLoc, OpKind,
+  return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base,
+                                           OpLoc, OpKind,
                                            SS, FirstTypeName, CCLoc,
                                            TildeLoc, SecondTypeName,
                                            Tok.is(tok::l_paren));
@@ -590,7 +612,7 @@
 ///       boolean-literal: [C++ 2.13.5]
 ///         'true'
 ///         'false'
-Parser::OwningExprResult Parser::ParseCXXBoolLiteral() {
+ExprResult Parser::ParseCXXBoolLiteral() {
   tok::TokenKind Kind = Tok.getKind();
   return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
 }
@@ -599,7 +621,7 @@
 ///
 ///       throw-expression: [C++ 15]
 ///         'throw' assignment-expression[opt]
-Parser::OwningExprResult Parser::ParseThrowExpression() {
+ExprResult Parser::ParseThrowExpression() {
   assert(Tok.is(tok::kw_throw) && "Not throw!");
   SourceLocation ThrowLoc = ConsumeToken();           // Eat the throw token.
 
@@ -613,12 +635,12 @@
   case tok::r_brace:
   case tok::colon:
   case tok::comma:
-    return Actions.ActOnCXXThrow(ThrowLoc, ExprArg(Actions));
+    return Actions.ActOnCXXThrow(ThrowLoc, 0);
 
   default:
-    OwningExprResult Expr(ParseAssignmentExpression());
+    ExprResult Expr(ParseAssignmentExpression());
     if (Expr.isInvalid()) return move(Expr);
-    return Actions.ActOnCXXThrow(ThrowLoc, move(Expr));
+    return Actions.ActOnCXXThrow(ThrowLoc, Expr.take());
   }
 }
 
@@ -627,7 +649,7 @@
 /// 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() {
+ExprResult Parser::ParseCXXThis() {
   assert(Tok.is(tok::kw_this) && "Not 'this'!");
   SourceLocation ThisLoc = ConsumeToken();
   return Actions.ActOnCXXThis(ThisLoc);
@@ -642,10 +664,10 @@
 ///         simple-type-specifier '(' expression-list[opt] ')'      [C++ 5.2.3]
 ///         typename-specifier '(' expression-list[opt] ')'         [TODO]
 ///
-Parser::OwningExprResult
+ExprResult
 Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
   Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
-  TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).get();
+  ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
 
   assert(Tok.is(tok::l_paren) && "Expected '('!");
   SourceLocation LParenLoc = ConsumeParen();
@@ -688,18 +710,34 @@
 /// \param DeclResult if the condition was parsed as a declaration, the
 /// parsed declaration.
 ///
+/// \param Loc The location of the start of the statement that requires this
+/// condition, e.g., the "for" in a for loop.
+///
+/// \param ConvertToBoolean Whether the condition expression should be
+/// converted to a boolean value.
+///
 /// \returns true if there was a parsing, false otherwise.
-bool Parser::ParseCXXCondition(OwningExprResult &ExprResult,
-                               DeclPtrTy &DeclResult) {
+bool Parser::ParseCXXCondition(ExprResult &ExprOut,
+                               Decl *&DeclOut,
+                               SourceLocation Loc,
+                               bool ConvertToBoolean) {
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Condition);
-    ConsumeToken();
+    Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition);
+    ConsumeCodeCompletionToken();
   }
 
   if (!isCXXConditionDeclaration()) {
-    ExprResult = ParseExpression(); // expression
-    DeclResult = DeclPtrTy();
-    return ExprResult.isInvalid();
+    // Parse the expression.
+    ExprOut = ParseExpression(); // expression
+    DeclOut = 0;
+    if (ExprOut.isInvalid())
+      return true;
+
+    // If required, convert to a boolean value.
+    if (ConvertToBoolean)
+      ExprOut
+        = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprOut.get());
+    return ExprOut.isInvalid();
   }
 
   // type-specifier-seq
@@ -713,7 +751,7 @@
   // simple-asm-expr[opt]
   if (Tok.is(tok::kw_asm)) {
     SourceLocation Loc;
-    OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
+    ExprResult AsmLabel(ParseSimpleAsm(&Loc));
     if (AsmLabel.isInvalid()) {
       SkipUntil(tok::semi);
       return true;
@@ -730,22 +768,25 @@
   }
 
   // Type-check the declaration itself.
-  Action::DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(CurScope, 
+  DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(), 
                                                                 DeclaratorInfo);
-  DeclResult = Dcl.get();
-  ExprResult = ExprError();
+  DeclOut = Dcl.get();
+  ExprOut = ExprError();
   
   // '=' assignment-expression
   if (Tok.is(tok::equal)) {
     SourceLocation EqualLoc = ConsumeToken();
-    OwningExprResult AssignExpr(ParseAssignmentExpression());
+    ExprResult AssignExpr(ParseAssignmentExpression());
     if (!AssignExpr.isInvalid()) 
-      Actions.AddInitializerToDecl(DeclResult, move(AssignExpr));
+      Actions.AddInitializerToDecl(DeclOut, AssignExpr.take());
   } else {
     // FIXME: C++0x allows a braced-init-list
     Diag(Tok, diag::err_expected_equal_after_declarator);
   }
   
+  // FIXME: Build a reference to this declaration? Convert it to bool?
+  // (This is currently handled by Sema).
+  
   return false;
 }
 
@@ -822,7 +863,7 @@
   // type-name
   case tok::annot_typename: {
     DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID,
-                       Tok.getAnnotationValue());
+                       getTypeAnnotation(Tok));
     break;
   }
 
@@ -950,10 +991,12 @@
                                           IdentifierInfo *Name,
                                           SourceLocation NameLoc,
                                           bool EnteringContext,
-                                          TypeTy *ObjectType,
+                                          ParsedType ObjectType,
                                           UnqualifiedId &Id,
-                                          bool AssumeTemplateId) {
-  assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id");
+                                          bool AssumeTemplateId,
+                                          SourceLocation TemplateKWLoc) {
+  assert((AssumeTemplateId || Tok.is(tok::less)) &&
+         "Expected '<' to finish parsing a template-id");
   
   TemplateTy Template;
   TemplateNameKind TNK = TNK_Non_template;
@@ -962,40 +1005,74 @@
   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);
+      TNK = Actions.ActOnDependentTemplateName(getCurScope(), TemplateKWLoc, SS, 
+                                               Id, ObjectType, EnteringContext,
+                                               Template);
+      if (TNK == TNK_Non_template)
+        return true;
+    } else {
+      bool MemberOfUnknownSpecialization;
+      TNK = Actions.isTemplateName(getCurScope(), SS,
+                                   TemplateKWLoc.isValid(), Id,
+                                   ObjectType, EnteringContext, Template,
+                                   MemberOfUnknownSpecialization);
+      
+      if (TNK == TNK_Non_template && MemberOfUnknownSpecialization &&
+          ObjectType && IsTemplateArgumentList()) {
+        // We have something like t->getAs<T>(), where getAs is a 
+        // member of an unknown specialization. However, this will only
+        // parse correctly as a template, so suggest the keyword 'template'
+        // before 'getAs' and treat this as a dependent template name.
+        std::string Name;
+        if (Id.getKind() == UnqualifiedId::IK_Identifier)
+          Name = Id.Identifier->getName();
+        else {
+          Name = "operator ";
+          if (Id.getKind() == UnqualifiedId::IK_OperatorFunctionId)
+            Name += getOperatorSpelling(Id.OperatorFunctionId.Operator);
+          else
+            Name += Id.Identifier->getName();
+        }
+        Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword)
+          << Name
+          << FixItHint::CreateInsertion(Id.StartLocation, "template ");
+        TNK = Actions.ActOnDependentTemplateName(getCurScope(), TemplateKWLoc,
+                                                 SS, Id, ObjectType,
+                                                 EnteringContext, Template);
+        if (TNK == TNK_Non_template)
+          return true;              
+      }
+    }
     break;
       
   case UnqualifiedId::IK_ConstructorName: {
     UnqualifiedId TemplateName;
+    bool MemberOfUnknownSpecialization;
     TemplateName.setIdentifier(Name, NameLoc);
-    TNK = Actions.isTemplateName(CurScope, SS, TemplateName, ObjectType, 
-                                 EnteringContext, Template);
+    TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(),
+                                 TemplateName, ObjectType, 
+                                 EnteringContext, Template,
+                                 MemberOfUnknownSpecialization);
     break;
   }
       
   case UnqualifiedId::IK_DestructorName: {
     UnqualifiedId TemplateName;
+    bool MemberOfUnknownSpecialization;
     TemplateName.setIdentifier(Name, NameLoc);
     if (ObjectType) {
-      Template = Actions.ActOnDependentTemplateName(SourceLocation(), SS, 
-                                                    TemplateName, ObjectType,
-                                                    EnteringContext);
-      TNK = TNK_Dependent_template_name;
-      if (!Template.get())
+      TNK = Actions.ActOnDependentTemplateName(getCurScope(), TemplateKWLoc, SS, 
+                                               TemplateName, ObjectType,
+                                               EnteringContext, Template);
+      if (TNK == TNK_Non_template)
         return true;
     } else {
-      TNK = Actions.isTemplateName(CurScope, SS, TemplateName, ObjectType, 
-                                   EnteringContext, Template);
+      TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(),
+                                   TemplateName, ObjectType, 
+                                   EnteringContext, Template,
+                                   MemberOfUnknownSpecialization);
       
-      if (TNK == TNK_Non_template && Id.DestructorName == 0) {
+      if (TNK == TNK_Non_template && !Id.DestructorName.get()) {
         Diag(NameLoc, diag::err_destructor_template_id)
           << Name << SS.getRange();
         return true;        
@@ -1014,7 +1091,8 @@
   // Parse the enclosed template argument list.
   SourceLocation LAngleLoc, RAngleLoc;
   TemplateArgList TemplateArgs;
-  if (ParseTemplateIdAfterTemplateName(Template, Id.StartLocation,
+  if (Tok.is(tok::less) &&
+      ParseTemplateIdAfterTemplateName(Template, Id.StartLocation,
                                        &SS, true, LAngleLoc,
                                        TemplateArgs,
                                        RAngleLoc))
@@ -1038,7 +1116,7 @@
       TemplateId->TemplateNameLoc = Id.StartLocation;
     }
 
-    TemplateId->Template = Template.getAs<void*>();
+    TemplateId->Template = Template;
     TemplateId->Kind = TNK;
     TemplateId->LAngleLoc = LAngleLoc;
     TemplateId->RAngleLoc = RAngleLoc;
@@ -1056,7 +1134,7 @@
                                      TemplateArgs.size());
   
   // Constructor and destructor names.
-  Action::TypeResult Type
+  TypeResult Type
     = Actions.ActOnTemplateIdType(Template, NameLoc,
                                   LAngleLoc, TemplateArgsPtr,
                                   RAngleLoc);
@@ -1112,7 +1190,7 @@
 ///
 /// \returns true if parsing fails, false otherwise.
 bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
-                                        TypeTy *ObjectType,
+                                        ParsedType ObjectType,
                                         UnqualifiedId &Result) {
   assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
   
@@ -1187,10 +1265,10 @@
       
     case tok::code_completion: {
       // Code completion for the operator name.
-      Actions.CodeCompleteOperatorName(CurScope);
+      Actions.CodeCompleteOperatorName(getCurScope());
       
       // Consume the operator token.
-      ConsumeToken();
+      ConsumeCodeCompletionToken();
       
       // Don't try to parse any further.
       return true;
@@ -1248,7 +1326,7 @@
   ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
   
   // Finish up the type.
-  Action::TypeResult Ty = Actions.ActOnTypeName(CurScope, D);
+  TypeResult Ty = Actions.ActOnTypeName(getCurScope(), D);
   if (Ty.isInvalid())
     return true;
   
@@ -1291,8 +1369,19 @@
 bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
                                 bool AllowDestructorName,
                                 bool AllowConstructorName,
-                                TypeTy *ObjectType,
+                                ParsedType ObjectType,
                                 UnqualifiedId &Result) {
+
+  // Handle 'A::template B'. This is for template-ids which have not
+  // already been annotated by ParseOptionalCXXScopeSpecifier().
+  bool TemplateSpecified = false;
+  SourceLocation TemplateKWLoc;
+  if (getLang().CPlusPlus && Tok.is(tok::kw_template) &&
+      (ObjectType || SS.isSet())) {
+    TemplateSpecified = true;
+    TemplateKWLoc = ConsumeToken();
+  }
+
   // unqualified-id:
   //   identifier
   //   template-id (when it hasn't already been annotated)
@@ -1309,9 +1398,9 @@
     }
 
     if (AllowConstructorName && 
-        Actions.isCurrentClassName(*Id, CurScope, &SS)) {
+        Actions.isCurrentClassName(*Id, getCurScope(), &SS)) {
       // We have parsed a constructor name.
-      Result.setConstructorName(Actions.getTypeName(*Id, IdLoc, CurScope,
+      Result.setConstructorName(Actions.getTypeName(*Id, IdLoc, getCurScope(),
                                                     &SS, false),
                                 IdLoc, IdLoc);
     } else {
@@ -1320,9 +1409,10 @@
     }
 
     // If the next token is a '<', we may have a template.
-    if (Tok.is(tok::less))
+    if (TemplateSpecified || Tok.is(tok::less))
       return ParseUnqualifiedIdTemplateId(SS, Id, IdLoc, EnteringContext, 
-                                          ObjectType, Result);
+                                          ObjectType, Result,
+                                          TemplateSpecified, TemplateKWLoc);
     
     return false;
   }
@@ -1335,7 +1425,7 @@
 
     // If the template-name names the current class, then this is a constructor 
     if (AllowConstructorName && TemplateId->Name &&
-        Actions.isCurrentClassName(*TemplateId->Name, CurScope, &SS)) {
+        Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &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
@@ -1348,7 +1438,7 @@
                     SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc));
         Result.setConstructorName(Actions.getTypeName(*TemplateId->Name,
                                                   TemplateId->TemplateNameLoc, 
-                                                      CurScope,
+                                                      getCurScope(),
                                                       &SS, false),
                                   TemplateId->TemplateNameLoc, 
                                   TemplateId->RAngleLoc);
@@ -1383,10 +1473,11 @@
     //     operator-function-id < template-argument-list[opt] >
     if ((Result.getKind() == UnqualifiedId::IK_OperatorFunctionId ||
          Result.getKind() == UnqualifiedId::IK_LiteralOperatorId) &&
-        Tok.is(tok::less))
+        (TemplateSpecified || Tok.is(tok::less)))
       return ParseUnqualifiedIdTemplateId(SS, 0, SourceLocation(), 
                                           EnteringContext, ObjectType, 
-                                          Result);
+                                          Result,
+                                          TemplateSpecified, TemplateKWLoc);
     
     return false;
   }
@@ -1411,17 +1502,18 @@
     IdentifierInfo *ClassName = Tok.getIdentifierInfo();
     SourceLocation ClassNameLoc = ConsumeToken();
     
-    if (Tok.is(tok::less)) {
-      Result.setDestructorName(TildeLoc, 0, ClassNameLoc);
+    if (TemplateSpecified || Tok.is(tok::less)) {
+      Result.setDestructorName(TildeLoc, ParsedType(), ClassNameLoc);
       return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc,
-                                          EnteringContext, ObjectType, Result);
+                                          EnteringContext, ObjectType, Result,
+                                          TemplateSpecified, TemplateKWLoc);
     }
     
     // Note that this is a destructor name.
-    Action::TypeTy *Ty = Actions.getDestructorName(TildeLoc, *ClassName, 
-                                                   ClassNameLoc, CurScope,
-                                                   SS, ObjectType,
-                                                   EnteringContext);
+    ParsedType Ty = Actions.getDestructorName(TildeLoc, *ClassName, 
+                                              ClassNameLoc, getCurScope(),
+                                              SS, ObjectType,
+                                              EnteringContext);
     if (!Ty)
       return true;
 
@@ -1461,7 +1553,7 @@
 ///                   '(' expression-list[opt] ')'
 /// [C++0x]           braced-init-list                                   [TODO]
 ///
-Parser::OwningExprResult
+ExprResult
 Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
   assert(Tok.is(tok::kw_new) && "expected 'new' token");
   ConsumeToken();   // Consume 'new'
@@ -1472,7 +1564,7 @@
   ExprVector PlacementArgs(Actions);
   SourceLocation PlacementLParen, PlacementRParen;
 
-  bool ParenTypeId;
+  SourceRange TypeIdParens;
   DeclSpec DS;
   Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
   if (Tok.is(tok::l_paren)) {
@@ -1491,17 +1583,17 @@
 
     if (PlacementArgs.empty()) {
       // Reset the placement locations. There was no placement.
+      TypeIdParens = SourceRange(PlacementLParen, PlacementRParen);
       PlacementLParen = PlacementRParen = SourceLocation();
-      ParenTypeId = true;
     } else {
       // We still need the type.
       if (Tok.is(tok::l_paren)) {
-        SourceLocation LParen = ConsumeParen();
+        TypeIdParens.setBegin(ConsumeParen());
         ParseSpecifierQualifierList(DS);
         DeclaratorInfo.SetSourceRange(DS.getSourceRange());
         ParseDeclarator(DeclaratorInfo);
-        MatchRHSPunctuation(tok::r_paren, LParen);
-        ParenTypeId = true;
+        TypeIdParens.setEnd(MatchRHSPunctuation(tok::r_paren, 
+                                                TypeIdParens.getBegin()));
       } else {
         if (ParseCXXTypeSpecifierSeq(DS))
           DeclaratorInfo.setInvalidType(true);
@@ -1510,7 +1602,6 @@
           ParseDeclaratorInternal(DeclaratorInfo,
                                   &Parser::ParseDirectNewDeclarator);
         }
-        ParenTypeId = false;
       }
     }
   } else {
@@ -1523,7 +1614,6 @@
       ParseDeclaratorInternal(DeclaratorInfo,
                               &Parser::ParseDirectNewDeclarator);
     }
-    ParenTypeId = false;
   }
   if (DeclaratorInfo.isInvalidType()) {
     SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
@@ -1551,7 +1641,7 @@
 
   return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
                              move_arg(PlacementArgs), PlacementRParen,
-                             ParenTypeId, DeclaratorInfo, ConstructorLParen,
+                             TypeIdParens, DeclaratorInfo, ConstructorLParen,
                              move_arg(ConstructorArgs), ConstructorRParen);
 }
 
@@ -1567,7 +1657,7 @@
   bool first = true;
   while (Tok.is(tok::l_square)) {
     SourceLocation LLoc = ConsumeBracket();
-    OwningExprResult Size(first ? ParseExpression()
+    ExprResult Size(first ? ParseExpression()
                                 : ParseConstantExpression());
     if (Size.isInvalid()) {
       // Recover
@@ -1596,7 +1686,8 @@
 ///        new-placement:
 ///                   '(' expression-list ')'
 ///
-bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs,
+bool Parser::ParseExpressionListOrTypeId(
+                                   llvm::SmallVectorImpl<Expr*> &PlacementArgs,
                                          Declarator &D) {
   // The '(' was already consumed.
   if (isTypeIdInParens()) {
@@ -1623,7 +1714,7 @@
 ///        delete-expression:
 ///                   '::'[opt] 'delete' cast-expression
 ///                   '::'[opt] 'delete' '[' ']' cast-expression
-Parser::OwningExprResult
+ExprResult
 Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
   assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
   ConsumeToken(); // Consume 'delete'
@@ -1638,11 +1729,11 @@
       return ExprError();
   }
 
-  OwningExprResult Operand(ParseCastExpression(false));
+  ExprResult Operand(ParseCastExpression(false));
   if (Operand.isInvalid())
     return move(Operand);
 
-  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand));
+  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.take());
 }
 
 static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) {
@@ -1674,7 +1765,7 @@
 ///       primary-expression:
 /// [GNU]             unary-type-trait '(' type-id ')'
 ///
-Parser::OwningExprResult Parser::ParseUnaryTypeTrait() {
+ExprResult Parser::ParseUnaryTypeTrait() {
   UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind());
   SourceLocation Loc = ConsumeToken();
 
@@ -1698,17 +1789,17 @@
 /// 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
+ExprResult
 Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
-                                         TypeTy *&CastTy,
+                                         ParsedType &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;
+  ExprResult Result(true);
+  CastTy = ParsedType();
 
   // We need to disambiguate a very ugly part of the C++ syntax:
   //
@@ -1753,7 +1844,8 @@
       // will be consumed.
       Result = ParseCastExpression(false/*isUnaryExpression*/,
                                    false/*isAddressofOperand*/,
-                                   NotCastExpr, false);
+                                   NotCastExpr,
+                                   ParsedType()/*TypeOfCast*/);
     }
 
     // If we parsed a cast-expression, it's really a type-id, otherwise it's
@@ -1795,8 +1887,8 @@
 
     // Result is what ParseCastExpression returned earlier.
     if (!Result.isInvalid())
-      Result = Actions.ActOnCastExpr(CurScope, LParenLoc, CastTy, RParenLoc,
-                                     move(Result));
+      Result = Actions.ActOnCastExpr(getCurScope(), LParenLoc, CastTy, RParenLoc,
+                                     Result.take());
     return move(Result);
   }
 
@@ -1806,7 +1898,7 @@
   ExprType = SimpleExpr;
   Result = ParseExpression();
   if (!Result.isInvalid() && Tok.is(tok::r_paren))
-    Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), move(Result));
+    Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), Result.take());
 
   // Match the ')'.
   if (Result.isInvalid()) {
diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp
index a382a9a..4347294 100644
--- a/lib/Parse/ParseInit.cpp
+++ b/lib/Parse/ParseInit.cpp
@@ -11,10 +11,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Parse/Designator.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Parse/ParseDiagnostic.h"
-#include "clang/Parse/Scope.h"
+#include "clang/Sema/Designator.h"
+#include "clang/Sema/Scope.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
@@ -71,7 +71,7 @@
 /// initializer (because it is an expression).  We need to consider this case
 /// when parsing array designators.
 ///
-Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() {
+ExprResult Parser::ParseInitializerWithPotentialDesignator() {
 
   // If this is the old-style GNU extension:
   //   designation ::= identifier ':'
@@ -137,7 +137,7 @@
     //   [4][foo bar]      -> obsolete GNU designation with objc message send.
     //
     SourceLocation StartLoc = ConsumeBracket();
-    OwningExprResult Idx(Actions);
+    ExprResult Idx;
 
     // If Objective-C is enabled and this is a typename (class message
     // send) or send to 'super', parse this as a message send
@@ -146,11 +146,12 @@
     if  (getLang().ObjC1 && getLang().CPlusPlus) {
       // Send to 'super'.
       if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
-          NextToken().isNot(tok::period) && CurScope->isInObjcMethodScope()) {
+          NextToken().isNot(tok::period) && getCurScope()->isInObjcMethodScope()) {
         CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
         return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
-                                                           ConsumeToken(), 0, 
-                                                           ExprArg(Actions));
+                                                           ConsumeToken(),
+                                                           ParsedType(), 
+                                                           0);
       }
 
       // Parse the receiver, which is either a type or an expression.
@@ -167,35 +168,35 @@
         CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
         return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 
                                                            SourceLocation(), 
-                                                           TypeOrExpr, 
-                                                           ExprArg(Actions));
+                                   ParsedType::getFromOpaquePtr(TypeOrExpr),
+                                                           0);
       }
 
       // 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);
+      Idx = ExprResult(static_cast<Expr*>(TypeOrExpr));
     } else if (getLang().ObjC1 && Tok.is(tok::identifier)) {
       IdentifierInfo *II = Tok.getIdentifierInfo();
       SourceLocation IILoc = Tok.getLocation();
-      TypeTy *ReceiverType;
+      ParsedType 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, 
+      switch (Sema::ObjCMessageKind Kind
+                = Actions.getObjCMessageKind(getCurScope(), II, IILoc, 
                                              II == Ident_super,
                                              NextToken().is(tok::period),
                                              ReceiverType)) {
-      case Action::ObjCSuperMessage:
-      case Action::ObjCClassMessage:
+      case Sema::ObjCSuperMessage:
+      case Sema::ObjCClassMessage:
         CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
-        if (Kind == Action::ObjCSuperMessage)
+        if (Kind == Sema::ObjCSuperMessage)
           return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
                                                              ConsumeToken(),
-                                                             0,
-                                                             ExprArg(Actions));
+                                                             ParsedType(),
+                                                             0);
         ConsumeToken(); // the identifier
         if (!ReceiverType) {
           SkipUntil(tok::r_square);
@@ -205,9 +206,9 @@
         return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 
                                                            SourceLocation(), 
                                                            ReceiverType, 
-                                                           ExprArg(Actions));
+                                                           0);
 
-      case Action::ObjCInstanceMessage:
+      case Sema::ObjCInstanceMessage:
         // Fall through; we'll just parse the expression and
         // (possibly) treat this like an Objective-C message send
         // later.
@@ -239,7 +240,8 @@
       CheckArrayDesignatorSyntax(*this, Tok.getLocation(), Desig);
       return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
                                                          SourceLocation(),
-                                                         0, move(Idx));
+                                                         ParsedType(),
+                                                         Idx.take());
     }
 
     // If this is a normal array designator, remember it.
@@ -250,7 +252,7 @@
       Diag(Tok, diag::ext_gnu_array_range);
       SourceLocation EllipsisLoc = ConsumeToken();
 
-      OwningExprResult RHS(ParseConstantExpression());
+      ExprResult RHS(ParseConstantExpression());
       if (RHS.isInvalid()) {
         SkipUntil(tok::r_square);
         return move(RHS);
@@ -307,7 +309,7 @@
 ///         designation[opt] initializer
 ///         initializer-list ',' designation[opt] initializer
 ///
-Parser::OwningExprResult Parser::ParseBraceInitializer() {
+ExprResult Parser::ParseBraceInitializer() {
   SourceLocation LBraceLoc = ConsumeBrace();
 
   /// InitExprs - This is the actual list of expressions contained in the
@@ -319,7 +321,7 @@
     if (!getLang().CPlusPlus)
       Diag(LBraceLoc, diag::ext_gnu_empty_initializer);
     // Match the '}'.
-    return Actions.ActOnInitList(LBraceLoc, Action::MultiExprArg(Actions),
+    return Actions.ActOnInitList(LBraceLoc, MultiExprArg(Actions),
                                  ConsumeBrace());
   }
 
@@ -330,7 +332,7 @@
 
     // If we know that this cannot be a designation, just parse the nested
     // initializer directly.
-    OwningExprResult SubElt(Actions);
+    ExprResult SubElt;
     if (MayBeDesignationStart(Tok.getKind(), PP))
       SubElt = ParseInitializerWithPotentialDesignator();
     else
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index 7b1ecf6..c36f09c 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -11,10 +11,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Parse/Parser.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.h"
 #include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/Parser.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/PrettyDeclStackTrace.h"
+#include "clang/Sema/Scope.h"
 #include "llvm/ADT/SmallVector.h"
 using namespace clang;
 
@@ -27,12 +28,12 @@
 /// [OBJC]  objc-protocol-definition
 /// [OBJC]  objc-method-definition
 /// [OBJC]  '@' 'end'
-Parser::DeclPtrTy Parser::ParseObjCAtDirectives() {
+Decl *Parser::ParseObjCAtDirectives() {
   SourceLocation AtLoc = ConsumeToken(); // the "@"
 
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteObjCAtDirective(CurScope, ObjCImpDecl, false);
-    ConsumeToken();
+    Actions.CodeCompleteObjCAtDirective(getCurScope(), ObjCImpDecl, false);
+    ConsumeCodeCompletionToken();
   }
 
   switch (Tok.getObjCKeywordID()) {
@@ -55,7 +56,7 @@
   default:
     Diag(AtLoc, diag::err_unexpected_at);
     SkipUntil(tok::semi);
-    return DeclPtrTy();
+    return 0;
   }
 }
 
@@ -63,7 +64,7 @@
 /// objc-class-declaration:
 ///    '@' 'class' identifier-list ';'
 ///
-Parser::DeclPtrTy Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
+Decl *Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
   ConsumeToken(); // the identifier "class"
   llvm::SmallVector<IdentifierInfo *, 8> ClassNames;
   llvm::SmallVector<SourceLocation, 8> ClassLocs;
@@ -73,7 +74,7 @@
     if (Tok.isNot(tok::identifier)) {
       Diag(Tok, diag::err_expected_ident);
       SkipUntil(tok::semi);
-      return DeclPtrTy();
+      return 0;
     }
     ClassNames.push_back(Tok.getIdentifierInfo());
     ClassLocs.push_back(Tok.getLocation());
@@ -87,7 +88,7 @@
 
   // Consume the ';'.
   if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class"))
-    return DeclPtrTy();
+    return 0;
 
   return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(),
                                               ClassLocs.data(),
@@ -122,7 +123,7 @@
 ///     __attribute__((unavailable))
 ///     __attribute__((objc_exception)) - used by NSException on 64-bit
 ///
-Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
+Decl *Parser::ParseObjCAtInterfaceDeclaration(
   SourceLocation atLoc, AttributeList *attrList) {
   assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
          "ParseObjCAtInterfaceDeclaration(): Expected @interface");
@@ -130,13 +131,13 @@
 
   // Code completion after '@interface'.
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteObjCInterfaceDecl(CurScope);
-    ConsumeToken();
+    Actions.CodeCompleteObjCInterfaceDecl(getCurScope());
+    ConsumeCodeCompletionToken();
   }
 
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_ident); // missing class or category name.
-    return DeclPtrTy();
+    return 0;
   }
 
   // We have a class or category name - consume it.
@@ -148,8 +149,8 @@
     SourceLocation categoryLoc, rparenLoc;
     IdentifierInfo *categoryId = 0;
     if (Tok.is(tok::code_completion)) {
-      Actions.CodeCompleteObjCInterfaceCategory(CurScope, nameId, nameLoc);
-      ConsumeToken();
+      Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc);
+      ConsumeCodeCompletionToken();
     }
     
     // For ObjC2, the category name is optional (not an error).
@@ -159,27 +160,27 @@
     }
     else if (!getLang().ObjC2) {
       Diag(Tok, diag::err_expected_ident); // missing category name.
-      return DeclPtrTy();
+      return 0;
     }
     if (Tok.isNot(tok::r_paren)) {
       Diag(Tok, diag::err_expected_rparen);
       SkipUntil(tok::r_paren, false); // don't stop at ';'
-      return DeclPtrTy();
+      return 0;
     }
     rparenLoc = ConsumeParen();
     // Next, we need to check for any protocol references.
     SourceLocation LAngleLoc, EndProtoLoc;
-    llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
+    llvm::SmallVector<Decl *, 8> ProtocolRefs;
     llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
     if (Tok.is(tok::less) &&
         ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
                                     LAngleLoc, EndProtoLoc))
-      return DeclPtrTy();
+      return 0;
 
     if (attrList) // categories don't support attributes.
       Diag(Tok, diag::err_objc_no_attributes_on_category);
 
-    DeclPtrTy CategoryType =
+    Decl *CategoryType =
     Actions.ActOnStartCategoryInterface(atLoc,
                                         nameId, nameLoc,
                                         categoryId, categoryLoc,
@@ -203,27 +204,27 @@
 
     // Code completion of superclass names.
     if (Tok.is(tok::code_completion)) {
-      Actions.CodeCompleteObjCSuperclass(CurScope, nameId, nameLoc);
-      ConsumeToken();
+      Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc);
+      ConsumeCodeCompletionToken();
     }
 
     if (Tok.isNot(tok::identifier)) {
       Diag(Tok, diag::err_expected_ident); // missing super class name.
-      return DeclPtrTy();
+      return 0;
     }
     superClassId = Tok.getIdentifierInfo();
     superClassLoc = ConsumeToken();
   }
   // Next, we need to check for any protocol references.
-  llvm::SmallVector<Action::DeclPtrTy, 8> ProtocolRefs;
+  llvm::SmallVector<Decl *, 8> ProtocolRefs;
   llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
   SourceLocation LAngleLoc, EndProtoLoc;
   if (Tok.is(tok::less) &&
       ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
                                   LAngleLoc, EndProtoLoc))
-    return DeclPtrTy();
+    return 0;
 
-  DeclPtrTy ClsType =
+  Decl *ClsType =
     Actions.ActOnStartClassInterface(atLoc, nameId, nameLoc,
                                      superClassId, superClassLoc,
                                      ProtocolRefs.data(), ProtocolRefs.size(),
@@ -241,30 +242,30 @@
 /// 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;
+  Decl *IDecl;
+  llvm::SmallVectorImpl<Decl *> &Props;
   ObjCDeclSpec &OCDS;
   SourceLocation AtLoc;
   tok::ObjCKeywordKind MethodImplKind;
         
-  ObjCPropertyCallback(Parser &P, DeclPtrTy IDecl,
-                       llvm::SmallVectorImpl<DeclPtrTy> &Props,
+  ObjCPropertyCallback(Parser &P, Decl *IDecl,
+                       llvm::SmallVectorImpl<Decl *> &Props,
                        ObjCDeclSpec &OCDS, SourceLocation AtLoc,
                        tok::ObjCKeywordKind MethodImplKind) :
     P(P), IDecl(IDecl), Props(Props), OCDS(OCDS), AtLoc(AtLoc),
     MethodImplKind(MethodImplKind) {
   }
 
-  DeclPtrTy invoke(FieldDeclarator &FD) {
+  Decl *invoke(FieldDeclarator &FD) {
     if (FD.D.getIdentifier() == 0) {
       P.Diag(AtLoc, diag::err_objc_property_requires_field_name)
         << FD.D.getSourceRange();
-      return DeclPtrTy();
+      return 0;
     }
     if (FD.BitfieldSize) {
       P.Diag(AtLoc, diag::err_objc_property_bitfield)
         << FD.D.getSourceRange();
-      return DeclPtrTy();
+      return 0;
     }
 
     // Install the property declarator into interfaceDecl.
@@ -282,8 +283,8 @@
                                                      P.PP.getSelectorTable(),
                                                      FD.D.getIdentifier());
     bool isOverridingProperty = false;
-    DeclPtrTy Property =
-      P.Actions.ActOnProperty(P.CurScope, AtLoc, FD, OCDS,
+    Decl *Property =
+      P.Actions.ActOnProperty(P.getCurScope(), AtLoc, FD, OCDS,
                               GetterSel, SetterSel, IDecl,
                               &isOverridingProperty,
                               MethodImplKind);
@@ -306,10 +307,10 @@
 ///     @required
 ///     @optional
 ///
-void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
+void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl,
                                         tok::ObjCKeywordKind contextKey) {
-  llvm::SmallVector<DeclPtrTy, 32> allMethods;
-  llvm::SmallVector<DeclPtrTy, 16> allProperties;
+  llvm::SmallVector<Decl *, 32> allMethods;
+  llvm::SmallVector<Decl *, 16> allProperties;
   llvm::SmallVector<DeclGroupPtrTy, 8> allTUVariables;
   tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
 
@@ -318,7 +319,7 @@
   while (1) {
     // If this is a method prototype, parse it.
     if (Tok.is(tok::minus) || Tok.is(tok::plus)) {
-      DeclPtrTy methodPrototype =
+      Decl *methodPrototype =
         ParseObjCMethodPrototype(interfaceDecl, MethodImplKind);
       allMethods.push_back(methodPrototype);
       // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
@@ -329,10 +330,10 @@
     }
     if (Tok.is(tok::l_paren)) {
       Diag(Tok, diag::err_expected_minus_or_plus);
-      DeclPtrTy methodPrototype = ParseObjCMethodDecl(Tok.getLocation(), 
-                                                      tok::minus, 
-                                                      interfaceDecl,
-                                                      MethodImplKind);
+      ParseObjCMethodDecl(Tok.getLocation(), 
+                          tok::minus, 
+                          interfaceDecl,
+                          MethodImplKind);
       continue;
     }
     // Ignore excess semicolons.
@@ -347,10 +348,10 @@
 
     // Code completion within an Objective-C interface.
     if (Tok.is(tok::code_completion)) {
-      Actions.CodeCompleteOrdinaryName(CurScope, 
-                                  ObjCImpDecl? Action::CCC_ObjCImplementation
-                                             : Action::CCC_ObjCInterface);
-      ConsumeToken();
+      Actions.CodeCompleteOrdinaryName(getCurScope(), 
+                                  ObjCImpDecl? Sema::PCC_ObjCImplementation
+                                             : Sema::PCC_ObjCInterface);
+      ConsumeCodeCompletionToken();
     }
     
     // If we don't have an @ directive, parse it as a function definition.
@@ -370,8 +371,8 @@
     // Otherwise, we have an @ directive, eat the @.
     SourceLocation AtLoc = ConsumeToken(); // the "@"
     if (Tok.is(tok::code_completion)) {
-      Actions.CodeCompleteObjCAtDirective(CurScope, ObjCImpDecl, true);
-      ConsumeToken();
+      Actions.CodeCompleteObjCAtDirective(getCurScope(), ObjCImpDecl, true);
+      ConsumeCodeCompletionToken();
       break;
     }
 
@@ -437,8 +438,8 @@
   // 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();
+    Actions.CodeCompleteObjCAtDirective(getCurScope(), ObjCImpDecl, true);
+    ConsumeCodeCompletionToken();
   } else if (Tok.isObjCAtKeyword(tok::objc_end))
     ConsumeToken(); // the "end" identifier
   else
@@ -446,7 +447,7 @@
 
   // Insert collected methods declarations into the @interface object.
   // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit.
-  Actions.ActOnAtEnd(AtEnd, interfaceDecl,
+  Actions.ActOnAtEnd(getCurScope(), AtEnd, interfaceDecl,
                      allMethods.data(), allMethods.size(),
                      allProperties.data(), allProperties.size(),
                      allTUVariables.data(), allTUVariables.size());
@@ -468,16 +469,16 @@
 ///     copy
 ///     nonatomic
 ///
-void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, DeclPtrTy ClassDecl,
-                                        DeclPtrTy *Methods, 
+void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl,
+                                        Decl **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();
+      Actions.CodeCompleteObjCPropertyFlags(getCurScope(), DS);
+      ConsumeCodeCompletionToken();
     }
     const IdentifierInfo *II = Tok.getIdentifierInfo();
 
@@ -509,12 +510,12 @@
 
       if (Tok.is(tok::code_completion)) {
         if (II->getNameStart()[0] == 's')
-          Actions.CodeCompleteObjCPropertySetter(CurScope, ClassDecl,
+          Actions.CodeCompleteObjCPropertySetter(getCurScope(), ClassDecl,
                                                  Methods, NumMethods);
         else
-          Actions.CodeCompleteObjCPropertyGetter(CurScope, ClassDecl,
+          Actions.CodeCompleteObjCPropertyGetter(getCurScope(), ClassDecl,
                                                  Methods, NumMethods);
-        ConsumeToken();
+        ConsumeCodeCompletionToken();
       }
 
       if (Tok.isNot(tok::identifier)) {
@@ -562,14 +563,14 @@
 ///   objc-method-attributes:         [OBJC2]
 ///     __attribute__((deprecated))
 ///
-Parser::DeclPtrTy Parser::ParseObjCMethodPrototype(DeclPtrTy IDecl,
-                                          tok::ObjCKeywordKind MethodImplKind) {
+Decl *Parser::ParseObjCMethodPrototype(Decl *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);
+  Decl *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;
@@ -680,8 +681,13 @@
 ///     objc-type-qualifier
 ///     objc-type-qualifiers objc-type-qualifier
 ///
-void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS) {
+void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS, bool IsParameter) {
   while (1) {
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteObjCPassingType(getCurScope(), DS);
+      ConsumeCodeCompletionToken();
+    }
+    
     if (Tok.isNot(tok::identifier))
       return;
 
@@ -715,16 +721,16 @@
 ///     '(' objc-type-qualifiers[opt] type-name ')'
 ///     '(' objc-type-qualifiers[opt] ')'
 ///
-Parser::TypeTy *Parser::ParseObjCTypeName(ObjCDeclSpec &DS) {
+ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS, bool IsParameter) {
   assert(Tok.is(tok::l_paren) && "expected (");
 
   SourceLocation LParenLoc = ConsumeParen();
   SourceLocation TypeStartLoc = Tok.getLocation();
 
   // Parse type qualifiers, in, inout, etc.
-  ParseObjCTypeQualifierList(DS);
+  ParseObjCTypeQualifierList(DS, IsParameter);
 
-  TypeTy *Ty = 0;
+  ParsedType Ty;
   if (isTypeSpecifierQualifier()) {
     TypeResult TypeSpec = ParseTypeName();
     if (!TypeSpec.isInvalid())
@@ -773,23 +779,23 @@
 ///   objc-keyword-attributes:         [OBJC2]
 ///     __attribute__((unused))
 ///
-Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc,
-                                              tok::TokenKind mType,
-                                              DeclPtrTy IDecl,
-                                          tok::ObjCKeywordKind MethodImplKind) {
+Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
+                                  tok::TokenKind mType,
+                                  Decl *IDecl,
+                                  tok::ObjCKeywordKind MethodImplKind) {
   ParsingDeclRAIIObject PD(*this);
 
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteObjCMethodDecl(CurScope, mType == tok::minus, 
-                                       /*ReturnType=*/0, IDecl);
-    ConsumeToken();
+    Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, 
+                                       /*ReturnType=*/ ParsedType(), IDecl);
+    ConsumeCodeCompletionToken();
   }
 
   // Parse the return type if present.
-  TypeTy *ReturnType = 0;
+  ParsedType ReturnType;
   ObjCDeclSpec DSRet;
   if (Tok.is(tok::l_paren))
-    ReturnType = ParseObjCTypeName(DSRet);
+    ReturnType = ParseObjCTypeName(DSRet, false);
 
   // If attributes exist before the method, parse them.
   llvm::OwningPtr<AttributeList> MethodAttrs;
@@ -797,9 +803,9 @@
     MethodAttrs.reset(ParseGNUAttributes());
 
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteObjCMethodDecl(CurScope, mType == tok::minus, 
+    Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, 
                                        ReturnType, IDecl);
-    ConsumeToken();
+    ConsumeCodeCompletionToken();
   }
 
   // Now parse the selector.
@@ -812,7 +818,7 @@
       << SourceRange(mLoc, Tok.getLocation());
     // Skip until we get a ; or {}.
     SkipUntil(tok::r_brace);
-    return DeclPtrTy();
+    return 0;
   }
 
   llvm::SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo;
@@ -823,7 +829,7 @@
                                           ParseGNUAttributes()));
 
     Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
-    DeclPtrTy Result
+    Decl *Result
          = Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
                                           mType, IDecl, DSRet, ReturnType, Sel,
                                           0, 
@@ -835,10 +841,10 @@
   }
 
   llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
-  llvm::SmallVector<Action::ObjCArgInfo, 12> ArgInfos;
+  llvm::SmallVector<Sema::ObjCArgInfo, 12> ArgInfos;
 
   while (1) {
-    Action::ObjCArgInfo ArgInfo;
+    Sema::ObjCArgInfo ArgInfo;
 
     // Each iteration parses a single keyword argument.
     if (Tok.isNot(tok::colon)) {
@@ -847,15 +853,29 @@
     }
     ConsumeToken(); // Eat the ':'.
 
-    ArgInfo.Type = 0;
+    ArgInfo.Type = ParsedType();
     if (Tok.is(tok::l_paren)) // Parse the argument type if present.
-      ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec);
+      ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec, true);
 
     // If attributes exist before the argument name, parse them.
     ArgInfo.ArgAttrs = 0;
     if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
       ArgInfo.ArgAttrs = ParseGNUAttributes();
 
+    // Code completion for the next piece of the selector.
+    if (Tok.is(tok::code_completion)) {
+      ConsumeCodeCompletionToken();
+      KeyIdents.push_back(SelIdent);
+      Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(), 
+                                                 mType == tok::minus,
+                                                 /*AtParameterName=*/true,
+                                                 ReturnType,
+                                                 KeyIdents.data(), 
+                                                 KeyIdents.size());
+      KeyIdents.pop_back();
+      break;
+    }
+    
     if (Tok.isNot(tok::identifier)) {
       Diag(Tok, diag::err_expected_ident); // missing argument name.
       break;
@@ -868,6 +888,18 @@
     ArgInfos.push_back(ArgInfo);
     KeyIdents.push_back(SelIdent);
 
+    // Code completion for the next piece of the selector.
+    if (Tok.is(tok::code_completion)) {
+      ConsumeCodeCompletionToken();
+      Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(), 
+                                                 mType == tok::minus,
+                                                 /*AtParameterName=*/false,
+                                                 ReturnType,
+                                                 KeyIdents.data(), 
+                                                 KeyIdents.size());
+      break;
+    }
+    
     // Check for another keyword selector.
     SourceLocation Loc;
     SelIdent = ParseObjCSelectorPiece(Loc);
@@ -892,7 +924,7 @@
     Declarator ParmDecl(DS, Declarator::PrototypeContext);
     ParseDeclarator(ParmDecl);
     IdentifierInfo *ParmII = ParmDecl.getIdentifier();
-    DeclPtrTy Param = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
+    Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
     CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
                                                     ParmDecl.getIdentifierLoc(), 
                                                     Param,
@@ -907,10 +939,10 @@
                                         ParseGNUAttributes()));
 
   if (KeyIdents.size() == 0)
-    return DeclPtrTy();
+    return 0;
   Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
                                                    &KeyIdents[0]);
-  DeclPtrTy Result
+  Decl *Result
        = Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
                                         mType, IDecl, DSRet, ReturnType, Sel,
                                         &ArgInfos[0], 
@@ -920,7 +952,7 @@
   PD.complete(Result);
   
   // Delete referenced AttributeList objects.
-  for (llvm::SmallVectorImpl<Action::ObjCArgInfo>::iterator
+  for (llvm::SmallVectorImpl<Sema::ObjCArgInfo>::iterator
        I = ArgInfos.begin(), E = ArgInfos.end(); I != E; ++I)
     delete I->ArgAttrs;
   
@@ -931,7 +963,7 @@
 ///     '<' identifier-list '>'
 ///
 bool Parser::
-ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &Protocols,
+ParseObjCProtocolReferences(llvm::SmallVectorImpl<Decl *> &Protocols,
                             llvm::SmallVectorImpl<SourceLocation> &ProtocolLocs,
                             bool WarnOnDeclarations,
                             SourceLocation &LAngleLoc, SourceLocation &EndLoc) {
@@ -945,7 +977,7 @@
     if (Tok.is(tok::code_completion)) {
       Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents.data(), 
                                                  ProtocolIdents.size());
-      ConsumeToken();
+      ConsumeCodeCompletionToken();
     }
 
     if (Tok.isNot(tok::identifier)) {
@@ -998,11 +1030,11 @@
 ///   objc-instance-variable-decl:
 ///     struct-declaration
 ///
-void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
+void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
                                              tok::ObjCKeywordKind visibility,
                                              SourceLocation atLoc) {
   assert(Tok.is(tok::l_brace) && "expected {");
-  llvm::SmallVector<DeclPtrTy, 32> AllIvarDecls;
+  llvm::SmallVector<Decl *, 32> AllIvarDecls;
 
   ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
 
@@ -1014,7 +1046,7 @@
 
     // Check for extraneous top-level semicolon.
     if (Tok.is(tok::semi)) {
-      Diag(Tok, diag::ext_extra_struct_semi)
+      Diag(Tok, diag::ext_extra_ivar_semi)
         << FixItHint::CreateRemoval(Tok.getLocation());
       ConsumeToken();
       continue;
@@ -1025,8 +1057,8 @@
       ConsumeToken(); // eat the @ sign
       
       if (Tok.is(tok::code_completion)) {
-        Actions.CodeCompleteObjCAtVisibility(CurScope);
-        ConsumeToken();
+        Actions.CodeCompleteObjCAtVisibility(getCurScope());
+        ConsumeCodeCompletionToken();
       }
       
       switch (Tok.getObjCKeywordID()) {
@@ -1044,26 +1076,26 @@
     }
 
     if (Tok.is(tok::code_completion)) {
-      Actions.CodeCompleteOrdinaryName(CurScope, 
-                                       Action::CCC_ObjCInstanceVariableList);
-      ConsumeToken();
+      Actions.CodeCompleteOrdinaryName(getCurScope(), 
+                                       Sema::PCC_ObjCInstanceVariableList);
+      ConsumeCodeCompletionToken();
     }
     
     struct ObjCIvarCallback : FieldCallback {
       Parser &P;
-      DeclPtrTy IDecl;
+      Decl *IDecl;
       tok::ObjCKeywordKind visibility;
-      llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls;
+      llvm::SmallVectorImpl<Decl *> &AllIvarDecls;
 
-      ObjCIvarCallback(Parser &P, DeclPtrTy IDecl, tok::ObjCKeywordKind V,
-                       llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls) :
+      ObjCIvarCallback(Parser &P, Decl *IDecl, tok::ObjCKeywordKind V,
+                       llvm::SmallVectorImpl<Decl *> &AllIvarDecls) :
         P(P), IDecl(IDecl), visibility(V), AllIvarDecls(AllIvarDecls) {
       }
 
-      DeclPtrTy invoke(FieldDeclarator &FD) {
+      Decl *invoke(FieldDeclarator &FD) {
         // Install the declarator into the interface decl.
-        DeclPtrTy Field
-          = P.Actions.ActOnIvar(P.CurScope,
+        Decl *Field
+          = P.Actions.ActOnIvar(P.getCurScope(),
                                 FD.D.getDeclSpec().getSourceRange().getBegin(),
                                 IDecl, FD.D, FD.BitfieldSize, visibility);
         if (Field)
@@ -1071,7 +1103,7 @@
         return Field;
       }
     } Callback(*this, interfaceDecl, visibility, AllIvarDecls);
-
+    
     // Parse all the comma separated declarators.
     DeclSpec DS;
     ParseStructDeclaration(DS, Callback);
@@ -1085,9 +1117,10 @@
     }
   }
   SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
+  Actions.ActOnLastBitfield(RBraceLoc, interfaceDecl, AllIvarDecls);
   // 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,
+  Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl,
                       AllIvarDecls.data(), AllIvarDecls.size(),
                       LBraceLoc, RBraceLoc, 0);
   return;
@@ -1109,20 +1142,20 @@
 ///   "@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,
+Decl *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();
+    Actions.CodeCompleteObjCProtocolDecl(getCurScope());
+    ConsumeCodeCompletionToken();
   }
 
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_ident); // missing protocol name.
-    return DeclPtrTy();
+    return 0;
   }
   // Save the protocol name, then consume it.
   IdentifierInfo *protocolName = Tok.getIdentifierInfo();
@@ -1145,7 +1178,7 @@
       if (Tok.isNot(tok::identifier)) {
         Diag(Tok, diag::err_expected_ident);
         SkipUntil(tok::semi);
-        return DeclPtrTy();
+        return 0;
       }
       ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(),
                                                Tok.getLocation()));
@@ -1156,7 +1189,7 @@
     }
     // Consume the ';'.
     if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol"))
-      return DeclPtrTy();
+      return 0;
 
     return Actions.ActOnForwardProtocolDeclaration(AtLoc,
                                                    &ProtocolRefs[0],
@@ -1167,14 +1200,14 @@
   // Last, and definitely not least, parse a protocol declaration.
   SourceLocation LAngleLoc, EndProtoLoc;
 
-  llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
+  llvm::SmallVector<Decl *, 8> ProtocolRefs;
   llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
   if (Tok.is(tok::less) &&
       ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false,
                                   LAngleLoc, EndProtoLoc))
-    return DeclPtrTy();
+    return 0;
 
-  DeclPtrTy ProtoType =
+  Decl *ProtoType =
     Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
                                         ProtocolRefs.data(),
                                         ProtocolRefs.size(),
@@ -1194,7 +1227,7 @@
 ///
 ///   objc-category-implementation-prologue:
 ///     @implementation identifier ( identifier )
-Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration(
+Decl *Parser::ParseObjCAtImplementationDeclaration(
   SourceLocation atLoc) {
   assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
          "ParseObjCAtImplementationDeclaration(): Expected @implementation");
@@ -1202,13 +1235,13 @@
 
   // Code completion after '@implementation'.
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteObjCImplementationDecl(CurScope);
-    ConsumeToken();
+    Actions.CodeCompleteObjCImplementationDecl(getCurScope());
+    ConsumeCodeCompletionToken();
   }
 
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_ident); // missing class or category name.
-    return DeclPtrTy();
+    return 0;
   }
   // We have a class or category name - consume it.
   IdentifierInfo *nameId = Tok.getIdentifierInfo();
@@ -1221,8 +1254,8 @@
     IdentifierInfo *categoryId = 0;
 
     if (Tok.is(tok::code_completion)) {
-      Actions.CodeCompleteObjCImplementationCategory(CurScope, nameId, nameLoc);
-      ConsumeToken();
+      Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc);
+      ConsumeCodeCompletionToken();
     }
     
     if (Tok.is(tok::identifier)) {
@@ -1230,20 +1263,20 @@
       categoryLoc = ConsumeToken();
     } else {
       Diag(Tok, diag::err_expected_ident); // missing category name.
-      return DeclPtrTy();
+      return 0;
     }
     if (Tok.isNot(tok::r_paren)) {
       Diag(Tok, diag::err_expected_rparen);
       SkipUntil(tok::r_paren, false); // don't stop at ';'
-      return DeclPtrTy();
+      return 0;
     }
     rparenLoc = ConsumeParen();
-    DeclPtrTy ImplCatType = Actions.ActOnStartCategoryImplementation(
+    Decl *ImplCatType = Actions.ActOnStartCategoryImplementation(
                                     atLoc, nameId, nameLoc, categoryId,
                                     categoryLoc);
     ObjCImpDecl = ImplCatType;
     PendingObjCImpDecl.push_back(ObjCImpDecl);
-    return DeclPtrTy();
+    return 0;
   }
   // We have a class implementation
   SourceLocation superClassLoc;
@@ -1253,12 +1286,12 @@
     ConsumeToken();
     if (Tok.isNot(tok::identifier)) {
       Diag(Tok, diag::err_expected_ident); // missing super class name.
-      return DeclPtrTy();
+      return 0;
     }
     superClassId = Tok.getIdentifierInfo();
     superClassLoc = ConsumeToken(); // Consume super class name
   }
-  DeclPtrTy ImplClsType = Actions.ActOnStartClassImplementation(
+  Decl *ImplClsType = Actions.ActOnStartClassImplementation(
                                   atLoc, nameId, nameLoc,
                                   superClassId, superClassLoc);
 
@@ -1268,17 +1301,17 @@
   ObjCImpDecl = ImplClsType;
   PendingObjCImpDecl.push_back(ObjCImpDecl);
   
-  return DeclPtrTy();
+  return 0;
 }
 
-Parser::DeclPtrTy Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
+Decl *Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
   assert(Tok.isObjCAtKeyword(tok::objc_end) &&
          "ParseObjCAtEndDeclaration(): Expected @end");
-  DeclPtrTy Result = ObjCImpDecl;
+  Decl *Result = ObjCImpDecl;
   ConsumeToken(); // the "end" identifier
   if (ObjCImpDecl) {
-    Actions.ActOnAtEnd(atEnd, ObjCImpDecl);
-    ObjCImpDecl = DeclPtrTy();
+    Actions.ActOnAtEnd(getCurScope(), atEnd, ObjCImpDecl);
+    ObjCImpDecl = 0;
     PendingObjCImpDecl.pop_back();
   }
   else {
@@ -1288,36 +1321,37 @@
   return Result;
 }
 
-Parser::DeclGroupPtrTy Parser::RetrievePendingObjCImpDecl() {
+Parser::DeclGroupPtrTy Parser::FinishPendingObjCActions() {
+  Actions.DiagnoseUseOfUnimplementedSelectors();
   if (PendingObjCImpDecl.empty())
-    return Actions.ConvertDeclToDeclGroup(DeclPtrTy());
-  DeclPtrTy ImpDecl = PendingObjCImpDecl.pop_back_val();
-  Actions.ActOnAtEnd(SourceRange(), ImpDecl);
+    return Actions.ConvertDeclToDeclGroup(0);
+  Decl *ImpDecl = PendingObjCImpDecl.pop_back_val();
+  Actions.ActOnAtEnd(getCurScope(), SourceRange(), ImpDecl);
   return Actions.ConvertDeclToDeclGroup(ImpDecl);
 }
 
 ///   compatibility-alias-decl:
 ///     @compatibility_alias alias-name  class-name ';'
 ///
-Parser::DeclPtrTy Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
+Decl *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();
+    return 0;
   }
   IdentifierInfo *aliasId = Tok.getIdentifierInfo();
   SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_ident);
-    return DeclPtrTy();
+    return 0;
   }
   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 0;
   }
   return Actions.ActOnCompatiblityAlias(atLoc, aliasId, aliasLoc,
                                         classId, classLoc);
@@ -1334,21 +1368,21 @@
 ///     identifier
 ///     identifier '=' identifier
 ///
-Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
+Decl *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();
+      Actions.CodeCompleteObjCPropertyDefinition(getCurScope(), ObjCImpDecl);
+      ConsumeCodeCompletionToken();
     }
     
     if (Tok.isNot(tok::identifier)) {
       Diag(Tok, diag::err_synthesized_property_name);
       SkipUntil(tok::semi);
-      return DeclPtrTy();
+      return 0;
     }
     
     IdentifierInfo *propertyIvar = 0;
@@ -1359,9 +1393,9 @@
       ConsumeToken(); // consume '='
       
       if (Tok.is(tok::code_completion)) {
-        Actions.CodeCompleteObjCPropertySynthesizeIvar(CurScope, propertyId,
+        Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId,
                                                        ObjCImpDecl);
-        ConsumeToken();
+        ConsumeCodeCompletionToken();
       }
       
       if (Tok.isNot(tok::identifier)) {
@@ -1371,7 +1405,7 @@
       propertyIvar = Tok.getIdentifierInfo();
       ConsumeToken(); // consume ivar-name
     }
-    Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, true, ObjCImpDecl,
+    Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, true, ObjCImpDecl,
                                   propertyId, propertyIvar);
     if (Tok.isNot(tok::comma))
       break;
@@ -1383,7 +1417,7 @@
   }
   else
     ConsumeToken(); // consume ';'
-  return DeclPtrTy();
+  return 0;
 }
 
 ///   property-dynamic:
@@ -1393,25 +1427,25 @@
 ///     identifier
 ///     property-list ',' identifier
 ///
-Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
+Decl *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();
+      Actions.CodeCompleteObjCPropertyDefinition(getCurScope(), ObjCImpDecl);
+      ConsumeCodeCompletionToken();
     }
     
     if (Tok.isNot(tok::identifier)) {
       Diag(Tok, diag::err_expected_ident);
       SkipUntil(tok::semi);
-      return DeclPtrTy();
+      return 0;
     }
     
     IdentifierInfo *propertyId = Tok.getIdentifierInfo();
     SourceLocation propertyLoc = ConsumeToken(); // consume property name
-    Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl,
+    Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, false, ObjCImpDecl,
                                   propertyId, 0);
 
     if (Tok.isNot(tok::comma))
@@ -1424,14 +1458,14 @@
   }
   else
     ConsumeToken(); // consume ';'
-  return DeclPtrTy();
+  return 0;
 }
 
 ///  objc-throw-statement:
 ///    throw expression[opt];
 ///
-Parser::OwningStmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
-  OwningExprResult Res(Actions);
+StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
+  ExprResult Res;
   ConsumeToken(); // consume throw
   if (Tok.isNot(tok::semi)) {
     Res = ParseExpression();
@@ -1442,13 +1476,13 @@
   }
   // consume ';'
   ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@throw");
-  return Actions.ActOnObjCAtThrowStmt(atLoc, move(Res), CurScope);
+  return Actions.ActOnObjCAtThrowStmt(atLoc, Res.take(), getCurScope());
 }
 
 /// objc-synchronized-statement:
 ///   @synchronized '(' expression ')' compound-statement
 ///
-Parser::OwningStmtResult
+StmtResult
 Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
   ConsumeToken(); // consume synchronized
   if (Tok.isNot(tok::l_paren)) {
@@ -1456,7 +1490,7 @@
     return StmtError();
   }
   ConsumeParen();  // '('
-  OwningExprResult Res(ParseExpression());
+  ExprResult Res(ParseExpression());
   if (Res.isInvalid()) {
     SkipUntil(tok::semi);
     return StmtError();
@@ -1474,12 +1508,12 @@
   // statements can always hold declarations.
   ParseScope BodyScope(this, Scope::DeclScope);
 
-  OwningStmtResult SynchBody(ParseCompoundStatementBody());
+  StmtResult SynchBody(ParseCompoundStatementBody());
 
   BodyScope.Exit();
   if (SynchBody.isInvalid())
     SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
-  return Actions.ActOnObjCAtSynchronizedStmt(atLoc, move(Res), move(SynchBody));
+  return Actions.ActOnObjCAtSynchronizedStmt(atLoc, Res.take(), SynchBody.take());
 }
 
 ///  objc-try-catch-statement:
@@ -1493,7 +1527,7 @@
 ///     parameter-declaration
 ///     '...' [OBJC2]
 ///
-Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
+StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
   bool catch_or_finally_seen = false;
 
   ConsumeToken(); // consume try
@@ -1502,9 +1536,9 @@
     return StmtError();
   }
   StmtVector CatchStmts(Actions);
-  OwningStmtResult FinallyStmt(Actions);
+  StmtResult FinallyStmt;
   ParseScope TryScope(this, Scope::DeclScope);
-  OwningStmtResult TryBody(ParseCompoundStatementBody());
+  StmtResult TryBody(ParseCompoundStatementBody());
   TryScope.Exit();
   if (TryBody.isInvalid())
     TryBody = Actions.ActOnNullStmt(Tok.getLocation());
@@ -1520,7 +1554,7 @@
 
     SourceLocation AtCatchFinallyLoc = ConsumeToken();
     if (Tok.isObjCAtKeyword(tok::objc_catch)) {
-      DeclPtrTy FirstPart;
+      Decl *FirstPart = 0;
       ConsumeToken(); // consume catch
       if (Tok.is(tok::l_paren)) {
         ConsumeParen();
@@ -1536,7 +1570,7 @@
 
           // Inform the actions module about the declarator, so it
           // gets added to the current scope.
-          FirstPart = Actions.ActOnObjCExceptionDecl(CurScope, ParmDecl);
+          FirstPart = Actions.ActOnObjCExceptionDecl(getCurScope(), ParmDecl);
         } else
           ConsumeToken(); // consume '...'
 
@@ -1547,7 +1581,7 @@
         else // Skip over garbage, until we get to ')'.  Eat the ')'.
           SkipUntil(tok::r_paren, true, false);
 
-        OwningStmtResult CatchBody(Actions, true);
+        StmtResult CatchBody(true);
         if (Tok.is(tok::l_brace))
           CatchBody = ParseCompoundStatementBody();
         else
@@ -1555,10 +1589,10 @@
         if (CatchBody.isInvalid())
           CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
         
-        OwningStmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
+        StmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
                                                               RParenLoc, 
                                                               FirstPart, 
-                                                              move(CatchBody));
+                                                              CatchBody.take());
         if (!Catch.isInvalid())
           CatchStmts.push_back(Catch.release());
         
@@ -1573,7 +1607,7 @@
       ConsumeToken(); // consume finally
       ParseScope FinallyScope(this, Scope::DeclScope);
 
-      OwningStmtResult FinallyBody(Actions, true);
+      StmtResult FinallyBody(true);
       if (Tok.is(tok::l_brace))
         FinallyBody = ParseCompoundStatementBody();
       else
@@ -1581,7 +1615,7 @@
       if (FinallyBody.isInvalid())
         FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
       FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
-                                                   move(FinallyBody));
+                                                   FinallyBody.take());
       catch_or_finally_seen = true;
       break;
     }
@@ -1591,19 +1625,18 @@
     return StmtError();
   }
   
-  return Actions.ActOnObjCAtTryStmt(atLoc, move(TryBody), 
+  return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.take(), 
                                     move_arg(CatchStmts),
-                                    move(FinallyStmt));
+                                    FinallyStmt.take());
 }
 
 ///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
 ///
-Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() {
-  DeclPtrTy MDecl = ParseObjCMethodPrototype(ObjCImpDecl);
+Decl *Parser::ParseObjCMethodDefinition() {
+  Decl *MDecl = ParseObjCMethodPrototype(ObjCImpDecl);
 
-  PrettyStackTraceActionsDecl CrashInfo(MDecl, Tok.getLocation(), Actions,
-                                        PP.getSourceManager(),
-                                        "parsing Objective-C method");
+  PrettyDeclStackTraceEntry CrashInfo(Actions, MDecl, Tok.getLocation(),
+                                      "parsing Objective-C method");
 
   // parse optional ';'
   if (Tok.is(tok::semi)) {
@@ -1623,7 +1656,7 @@
 
     // If we didn't find the '{', bail out.
     if (Tok.isNot(tok::l_brace))
-      return DeclPtrTy();
+      return 0;
   }
   SourceLocation BraceLoc = Tok.getLocation();
 
@@ -1633,9 +1666,9 @@
 
   // Tell the actions module that we have entered a method definition with the
   // specified Declarator for the method.
-  Actions.ActOnStartOfObjCMethodDef(CurScope, MDecl);
+  Actions.ActOnStartOfObjCMethodDef(getCurScope(), MDecl);
 
-  OwningStmtResult FnBody(ParseCompoundStatementBody());
+  StmtResult FnBody(ParseCompoundStatementBody());
 
   // If the function body could not be parsed, make a bogus compoundstmt.
   if (FnBody.isInvalid())
@@ -1643,7 +1676,7 @@
                                        MultiStmtArg(Actions), false);
 
   // TODO: Pass argument information.
-  Actions.ActOnFinishFunctionBody(MDecl, move(FnBody));
+  Actions.ActOnFinishFunctionBody(MDecl, FnBody.take());
 
   // Leave the function body scope.
   BodyScope.Exit();
@@ -1651,10 +1684,10 @@
   return MDecl;
 }
 
-Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
+StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteObjCAtStatement(CurScope);
-    ConsumeToken();
+    Actions.CodeCompleteObjCAtStatement(getCurScope());
+    ConsumeCodeCompletionToken();
     return StmtError();
   }
   
@@ -1667,7 +1700,7 @@
   if (Tok.isObjCAtKeyword(tok::objc_synchronized))
     return ParseObjCSynchronizedStmt(AtLoc);
   
-  OwningExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
+  ExprResult 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
@@ -1678,14 +1711,14 @@
   
   // Otherwise, eat the semicolon.
   ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
-  return Actions.ActOnExprStmt(Actions.MakeFullExpr(Res));
+  return Actions.ActOnExprStmt(Actions.MakeFullExpr(Res.take()));
 }
 
-Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
+ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
   switch (Tok.getKind()) {
   case tok::code_completion:
-    Actions.CodeCompleteObjCAtExpression(CurScope);
-    ConsumeToken();
+    Actions.CodeCompleteObjCAtExpression(getCurScope());
+    ConsumeCodeCompletionToken();
     return ExprError();
 
   case tok::string_literal:    // primary-expression: string-literal
@@ -1730,7 +1763,6 @@
 ///     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))
@@ -1739,7 +1771,7 @@
   if (!isCXXSimpleTypeSpecifier()) {
     //   objc-receiver:
     //     expression
-    OwningExprResult Receiver = ParseExpression();
+    ExprResult Receiver = ParseExpression();
     if (Receiver.isInvalid())
       return true;
 
@@ -1768,11 +1800,11 @@
     // postfix-expression suffix, followed by the (optional)
     // right-hand side of the binary expression. We have an
     // instance method.
-    OwningExprResult Receiver = ParseCXXTypeConstructExpression(DS);
+    ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
     if (!Receiver.isInvalid())
-      Receiver = ParsePostfixExpressionSuffix(move(Receiver));
+      Receiver = ParsePostfixExpressionSuffix(Receiver.take());
     if (!Receiver.isInvalid())
-      Receiver = ParseRHSOfBinaryExpression(move(Receiver), prec::Comma);
+      Receiver = ParseRHSOfBinaryExpression(Receiver.take(), prec::Comma);
     if (Receiver.isInvalid())
       return true;
 
@@ -1785,15 +1817,27 @@
   // 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);
+  TypeResult Type = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
   if (Type.isInvalid())
     return true;
 
   IsExpr = false;
-  TypeOrExpr = Type.get();
+  TypeOrExpr = Type.get().getAsOpaquePtr();
   return false;
 }
 
+/// \brief Determine whether the parser is currently referring to a an
+/// Objective-C message send, using a simplified heuristic to avoid overhead.
+///
+/// This routine will only return true for a subset of valid message-send
+/// expressions.
+bool Parser::isSimpleObjCMessageExpression() {
+  assert(Tok.is(tok::l_square) && getLang().ObjC1 &&
+         "Incorrect start for isSimpleObjCMessageExpression");
+  return GetLookAheadToken(1).is(tok::identifier) &&
+         GetLookAheadToken(2).is(tok::identifier);
+}
+
 ///   objc-message-expr:
 ///     '[' objc-receiver objc-message-args ']'
 ///
@@ -1803,10 +1847,17 @@
 ///     class-name
 ///     type-name
 ///
-Parser::OwningExprResult Parser::ParseObjCMessageExpression() {
+ExprResult Parser::ParseObjCMessageExpression() {
   assert(Tok.is(tok::l_square) && "'[' expected");
   SourceLocation LBracLoc = ConsumeBracket(); // consume '['
 
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteObjCMessageReceiver(getCurScope());
+    ConsumeCodeCompletionToken();
+    SkipUntil(tok::r_square);
+    return ExprError();
+  }
+  
   if (getLang().CPlusPlus) {
     // We completely separate the C and C++ cases because C++ requires
     // more complicated (read: slower) parsing. 
@@ -1815,9 +1866,9 @@
     // 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));
+        NextToken().isNot(tok::period) && getCurScope()->isInObjcMethodScope())
+      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(),
+                                            ParsedType(), 0);
 
     // Parse the receiver, which is either a type or an expression.
     bool IsExpr;
@@ -1828,24 +1879,28 @@
     }
 
     if (IsExpr)
-      return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0,
-                                         OwningExprResult(Actions, TypeOrExpr));
+      return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
+                                            ParsedType(),
+                                            static_cast<Expr*>(TypeOrExpr));
 
     return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 
-                                          TypeOrExpr, ExprArg(Actions));
-  } else if (Tok.is(tok::identifier)) {
+                              ParsedType::getFromOpaquePtr(TypeOrExpr),
+                                          0);
+  }
+  
+  if (Tok.is(tok::identifier)) {
     IdentifierInfo *Name = Tok.getIdentifierInfo();
     SourceLocation NameLoc = Tok.getLocation();
-    TypeTy *ReceiverType;
-    switch (Actions.getObjCMessageKind(CurScope, Name, NameLoc,
+    ParsedType ReceiverType;
+    switch (Actions.getObjCMessageKind(getCurScope(), Name, NameLoc,
                                        Name == Ident_super,
                                        NextToken().is(tok::period),
                                        ReceiverType)) {
-    case Action::ObjCSuperMessage:
-      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), 0,
-                                            ExprArg(Actions));
+    case Sema::ObjCSuperMessage:
+      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(),
+                                            ParsedType(), 0);
 
-    case Action::ObjCClassMessage:
+    case Sema::ObjCClassMessage:
       if (!ReceiverType) {
         SkipUntil(tok::r_square);
         return ExprError();
@@ -1854,24 +1909,23 @@
       ConsumeToken(); // the type name
 
       return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 
-                                            ReceiverType,
-                                            ExprArg(Actions));
+                                            ReceiverType, 0);
         
-    case Action::ObjCInstanceMessage:
+    case Sema::ObjCInstanceMessage:
       // Fall through to parse an expression.
       break;
     }
   }
   
   // Otherwise, an arbitrary expression can be the receiver of a send.
-  OwningExprResult Res(ParseExpression());
+  ExprResult Res(ParseExpression());
   if (Res.isInvalid()) {
     SkipUntil(tok::r_square);
     return move(Res);
   }
 
-  return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0, 
-                                        move(Res));
+  return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
+                                        ParsedType(), Res.take());
 }
 
 /// \brief Parse the remainder of an Objective-C message following the
@@ -1912,20 +1966,20 @@
 ///     assignment-expression
 ///     nonempty-expr-list , assignment-expression
 ///
-Parser::OwningExprResult
+ExprResult
 Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
                                        SourceLocation SuperLoc,
-                                       TypeTy *ReceiverType,
+                                       ParsedType ReceiverType,
                                        ExprArg ReceiverExpr) {
   if (Tok.is(tok::code_completion)) {
     if (SuperLoc.isValid())
-      Actions.CodeCompleteObjCSuperMessage(CurScope, SuperLoc, 0, 0);
+      Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, 0, 0);
     else if (ReceiverType)
-      Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverType, 0, 0);
+      Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType, 0, 0);
     else
-      Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get(), 
+      Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
                                               0, 0);
-    ConsumeToken();
+    ConsumeCodeCompletionToken();
   }
   
   // Parse objc-selector
@@ -1953,7 +2007,7 @@
 
       ConsumeToken(); // Eat the ':'.
       ///  Parse the expression after ':'
-      OwningExprResult Res(ParseAssignmentExpression());
+      ExprResult 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
@@ -1968,18 +2022,18 @@
       // Code completion after each argument.
       if (Tok.is(tok::code_completion)) {
         if (SuperLoc.isValid())
-          Actions.CodeCompleteObjCSuperMessage(CurScope, SuperLoc, 
+          Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, 
                                                KeyIdents.data(), 
                                                KeyIdents.size());
         else if (ReceiverType)
-          Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverType,
+          Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType,
                                                KeyIdents.data(), 
                                                KeyIdents.size());
         else
-          Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get(),
+          Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
                                                   KeyIdents.data(), 
                                                   KeyIdents.size());
-        ConsumeToken();
+        ConsumeCodeCompletionToken();
       }
             
       // Check for another keyword selector.
@@ -1992,7 +2046,7 @@
     while (Tok.is(tok::comma)) {
       ConsumeToken(); // Eat the ','.
       ///  Parse the expression after ','
-      OwningExprResult Res(ParseAssignmentExpression());
+      ExprResult 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
@@ -2034,26 +2088,26 @@
   Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
 
   if (SuperLoc.isValid())
-    return Actions.ActOnSuperMessage(CurScope, SuperLoc, Sel,
+    return Actions.ActOnSuperMessage(getCurScope(), SuperLoc, Sel,
                                      LBracLoc, SelectorLoc, RBracLoc,
-                                     Action::MultiExprArg(Actions, 
-                                                          KeyExprs.take(),
-                                                          KeyExprs.size()));
+                                     MultiExprArg(Actions, 
+                                                  KeyExprs.take(),
+                                                  KeyExprs.size()));
   else if (ReceiverType)
-    return Actions.ActOnClassMessage(CurScope, ReceiverType, Sel,
+    return Actions.ActOnClassMessage(getCurScope(), ReceiverType, Sel,
                                      LBracLoc, SelectorLoc, RBracLoc,
-                                     Action::MultiExprArg(Actions, 
-                                                          KeyExprs.take(), 
-                                                          KeyExprs.size()));
-  return Actions.ActOnInstanceMessage(CurScope, move(ReceiverExpr), Sel,
+                                     MultiExprArg(Actions, 
+                                                  KeyExprs.take(), 
+                                                  KeyExprs.size()));
+  return Actions.ActOnInstanceMessage(getCurScope(), ReceiverExpr, Sel,
                                       LBracLoc, SelectorLoc, RBracLoc,
-                                      Action::MultiExprArg(Actions, 
-                                                           KeyExprs.take(), 
-                                                           KeyExprs.size()));
+                                      MultiExprArg(Actions, 
+                                                   KeyExprs.take(), 
+                                                   KeyExprs.size()));
 }
 
-Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
-  OwningExprResult Res(ParseStringLiteralExpression());
+ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
+  ExprResult Res(ParseStringLiteralExpression());
   if (Res.isInvalid()) return move(Res);
 
   // @"foo" @"bar" is a valid concatenated string.  Eat any subsequent string
@@ -2071,7 +2125,7 @@
     if (!isTokenStringLiteral())
       return ExprError(Diag(Tok, diag::err_objc_concat_string));
 
-    OwningExprResult Lit(ParseStringLiteralExpression());
+    ExprResult Lit(ParseStringLiteralExpression());
     if (Lit.isInvalid())
       return move(Lit);
 
@@ -2084,7 +2138,7 @@
 
 ///    objc-encode-expression:
 ///      @encode ( type-name )
-Parser::OwningExprResult
+ExprResult
 Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
   assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!");
 
@@ -2108,7 +2162,7 @@
 
 ///     objc-protocol-expression
 ///       @protocol ( protocol-name )
-Parser::OwningExprResult
+ExprResult
 Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
   SourceLocation ProtoLoc = ConsumeToken();
 
@@ -2131,8 +2185,7 @@
 
 ///     objc-selector-expression
 ///       @selector '(' objc-keyword-selector ')'
-Parser::OwningExprResult
-Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
+ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
   SourceLocation SelectorLoc = ConsumeToken();
 
   if (Tok.isNot(tok::l_paren))
@@ -2141,21 +2194,43 @@
   llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
   SourceLocation LParenLoc = ConsumeParen();
   SourceLocation sLoc;
+  
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents.data(),
+                                     KeyIdents.size());
+    ConsumeCodeCompletionToken();
+    MatchRHSPunctuation(tok::r_paren, LParenLoc);
+    return ExprError();
+  }
+  
   IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
-  if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name.
+  if (!SelIdent &&  // missing selector name.
+      Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
     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))
+      if (Tok.is(tok::coloncolon)) { // Handle :: in C++.
+        ++nColons;
+        KeyIdents.push_back(0);
+      } else if (Tok.isNot(tok::colon))
         return ExprError(Diag(Tok, diag::err_expected_colon));
 
-      nColons++;
+      ++nColons;
       ConsumeToken(); // Eat the ':'.
       if (Tok.is(tok::r_paren))
         break;
+      
+      if (Tok.is(tok::code_completion)) {
+        Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents.data(),
+                                         KeyIdents.size());
+        ConsumeCodeCompletionToken();
+        MatchRHSPunctuation(tok::r_paren, LParenLoc);
+        return ExprError();
+      }
+
       // Check for another keyword selector.
       SourceLocation Loc;
       SelIdent = ParseObjCSelectorPiece(Loc);
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index 812d8e2..ddba09a 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -13,17 +13,68 @@
 
 #include "ParsePragma.h"
 #include "clang/Parse/ParseDiagnostic.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/Action.h"
 #include "clang/Parse/Parser.h"
+#include "clang/Lex/Preprocessor.h"
 using namespace clang;
 
+
+// #pragma GCC visibility comes in two variants:
+//   'push' '(' [visibility] ')'
+//   'pop'
+void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, Token &VisTok) {
+  SourceLocation VisLoc = VisTok.getLocation();
+
+  Token Tok;
+  PP.Lex(Tok);
+
+  const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
+
+  bool IsPush;
+  const IdentifierInfo *VisType;
+  if (PushPop && PushPop->isStr("pop")) {
+    IsPush = false;
+    VisType = 0;
+  } else if (PushPop && PushPop->isStr("push")) {
+    IsPush = true;
+    PP.Lex(Tok);
+    if (Tok.isNot(tok::l_paren)) {
+      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
+        << "visibility";
+      return;
+    }
+    PP.Lex(Tok);
+    VisType = Tok.getIdentifierInfo();
+    if (!VisType) {
+      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
+        << "visibility";
+      return;
+    }
+    PP.Lex(Tok);
+    if (Tok.isNot(tok::r_paren)) {
+      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
+        << "visibility";
+      return;
+    }
+  } else {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
+      << "visibility";
+    return;
+  }
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::eom)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+      << "visibility";
+    return;
+  }
+
+  Actions.ActOnPragmaVisibility(IsPush, VisType, VisLoc);
+}
+
 // #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;
@@ -33,9 +84,9 @@
     return;
   }
 
-  Action::PragmaPackKind Kind = Action::PPK_Default;
+  Sema::PragmaPackKind Kind = Sema::PPK_Default;
   IdentifierInfo *Name = 0;
-  Action::OwningExprResult Alignment(Actions);
+  ExprResult Alignment;
   SourceLocation LParenLoc = Tok.getLocation();
   PP.Lex(Tok);
   if (Tok.is(tok::numeric_constant)) {
@@ -47,13 +98,13 @@
   } else if (Tok.is(tok::identifier)) {
     const IdentifierInfo *II = Tok.getIdentifierInfo();
     if (II->isStr("show")) {
-      Kind = Action::PPK_Show;
+      Kind = Sema::PPK_Show;
       PP.Lex(Tok);
     } else {
       if (II->isStr("push")) {
-        Kind = Action::PPK_Push;
+        Kind = Sema::PPK_Push;
       } else if (II->isStr("pop")) {
-        Kind = Action::PPK_Pop;
+        Kind = Sema::PPK_Pop;
       } else {
         PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action);
         return;
@@ -100,17 +151,85 @@
     return;
   }
 
+  SourceLocation RParenLoc = Tok.getLocation();
   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 'align' '=' {'native','natural','mac68k','power','reset'}
+// #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
+static void ParseAlignPragma(Sema &Actions, Preprocessor &PP, Token &FirstTok,
+                             bool IsOptions) {
+  Token Tok;
+
+  if (IsOptions) {
+    PP.Lex(Tok);
+    if (Tok.isNot(tok::identifier) ||
+        !Tok.getIdentifierInfo()->isStr("align")) {
+      PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
+      return;
+    }
+  }
+
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::equal)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
+      << IsOptions;
+    return;
+  }
+
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::identifier)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
+      << (IsOptions ? "options" : "align");
+    return;
+  }
+
+  Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
+  const IdentifierInfo *II = Tok.getIdentifierInfo();
+  if (II->isStr("native"))
+    Kind = Sema::POAK_Native;
+  else if (II->isStr("natural"))
+    Kind = Sema::POAK_Natural;
+  else if (II->isStr("packed"))
+    Kind = Sema::POAK_Packed;
+  else if (II->isStr("power"))
+    Kind = Sema::POAK_Power;
+  else if (II->isStr("mac68k"))
+    Kind = Sema::POAK_Mac68k;
+  else if (II->isStr("reset"))
+    Kind = Sema::POAK_Reset;
+  else {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
+      << IsOptions;
+    return;
+  }
+
+  SourceLocation KindLoc = Tok.getLocation();
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::eom)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+      << (IsOptions ? "options" : "align");
+    return;
+  }
+
+  Actions.ActOnPragmaOptionsAlign(Kind, FirstTok.getLocation(), KindLoc);
+}
+
+void PragmaAlignHandler::HandlePragma(Preprocessor &PP, Token &AlignTok) {
+  ParseAlignPragma(Actions, PP, AlignTok, /*IsOptions=*/false);
+}
+
+void PragmaOptionsHandler::HandlePragma(Preprocessor &PP, Token &OptionsTok) {
+  ParseAlignPragma(Actions, PP, OptionsTok, /*IsOptions=*/true);
+}
+
 // #pragma unused(identifier)
 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, Token &UnusedTok) {
   // FIXME: Should we be expanding macros here? My guess is no.
@@ -174,7 +293,7 @@
 
   // Perform the action to handle the pragma.
   Actions.ActOnPragmaUnused(Identifiers.data(), Identifiers.size(),
-                            parser.CurScope, UnusedLoc, LParenLoc, RParenLoc);
+                            parser.getCurScope(), UnusedLoc, LParenLoc, RParenLoc);
 }
 
 // #pragma weak identifier
diff --git a/lib/Parse/ParsePragma.h b/lib/Parse/ParsePragma.h
index db385c6..0feaa99 100644
--- a/lib/Parse/ParsePragma.h
+++ b/lib/Parse/ParsePragma.h
@@ -17,33 +17,59 @@
 #include "clang/Lex/Pragma.h"
 
 namespace clang {
-  class Action;
+  class Sema;
   class Parser;
 
-class PragmaPackHandler : public PragmaHandler {
-  Action &Actions;
+class PragmaAlignHandler : public PragmaHandler {
+  Sema &Actions;
 public:
-  PragmaPackHandler(const IdentifierInfo *N, Action &A) : PragmaHandler(N),
-                                                          Actions(A) {}
+  explicit PragmaAlignHandler(Sema &A) : PragmaHandler("align"), Actions(A) {}
+
+  virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
+};
+
+class PragmaGCCVisibilityHandler : public PragmaHandler {
+  Sema &Actions;
+public:
+  explicit PragmaGCCVisibilityHandler(Sema &A) : PragmaHandler("visibility"),
+                                                 Actions(A) {}
+
+  virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
+};
+
+class PragmaOptionsHandler : public PragmaHandler {
+  Sema &Actions;
+public:
+  explicit PragmaOptionsHandler(Sema &A) : PragmaHandler("options"),
+                                           Actions(A) {}
+
+  virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
+};
+
+class PragmaPackHandler : public PragmaHandler {
+  Sema &Actions;
+public:
+  explicit PragmaPackHandler(Sema &A) : PragmaHandler("pack"),
+                                        Actions(A) {}
 
   virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
 };
 
 class PragmaUnusedHandler : public PragmaHandler {
-  Action &Actions;
+  Sema &Actions;
   Parser &parser;
 public:
-  PragmaUnusedHandler(const IdentifierInfo *N, Action &A, Parser& p)
-    : PragmaHandler(N), Actions(A), parser(p) {}
+  PragmaUnusedHandler(Sema &A, Parser& p)
+    : PragmaHandler("unused"), Actions(A), parser(p) {}
 
   virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
 };
 
 class PragmaWeakHandler : public PragmaHandler {
-  Action &Actions;
+  Sema &Actions;
 public:
-  PragmaWeakHandler(const IdentifierInfo *N, Action &A)
-    : PragmaHandler(N), Actions(A) {}
+  explicit PragmaWeakHandler(Sema &A)
+    : PragmaHandler("weak"), Actions(A) {}
 
   virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
 };
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 9b22270..af92728 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -14,8 +14,9 @@
 
 #include "clang/Parse/Parser.h"
 #include "RAIIObjectsForParser.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/PrettyDeclStackTrace.h"
+#include "clang/Sema/Scope.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
@@ -73,10 +74,12 @@
 /// [OBC]   '@' 'throw' expression ';'
 /// [OBC]   '@' 'throw' ';'
 ///
-Parser::OwningStmtResult
+StmtResult
 Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
   const char *SemiError = 0;
-  OwningStmtResult Res(Actions);
+  StmtResult Res;
+  
+  ParenBraceBracketBalancer BalancerRAIIObj(*this);
 
   CXX0XAttributeList Attr;
   if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
@@ -96,8 +99,8 @@
     }
 
   case tok::code_completion:
-    Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Statement);
-    ConsumeToken();
+    Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Statement);
+    ConsumeCodeCompletionToken();
     return ParseStatementOrDeclaration(OnlyStatement);
       
   case tok::identifier:
@@ -123,7 +126,7 @@
 
     // FIXME: Use the attributes
     // expression[opt] ';'
-    OwningExprResult Expr(ParseExpression());
+    ExprResult 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
@@ -135,7 +138,7 @@
     }
     // Otherwise, eat the semicolon.
     ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
-    return Actions.ActOnExprStmt(Actions.MakeFullExpr(Expr));
+    return Actions.ActOnExprStmt(Actions.MakeFullExpr(Expr.get()));
   }
 
   case tok::kw_case:                // C99 6.8.1: labeled-statement
@@ -215,7 +218,7 @@
 ///         identifier ':' statement
 /// [GNU]   identifier ':' attributes[opt] statement
 ///
-Parser::OwningStmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
+StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
   assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
          "Not an identifier!");
 
@@ -232,7 +235,7 @@
   if (Tok.is(tok::kw___attribute))
     AttrList.reset(addAttributeLists(AttrList.take(), ParseGNUAttributes()));
 
-  OwningStmtResult SubStmt(ParseStatement());
+  StmtResult SubStmt(ParseStatement());
 
   // Broken substmt shouldn't prevent the label from being added to the AST.
   if (SubStmt.isInvalid())
@@ -241,7 +244,7 @@
   // FIXME: use attributes?
   return Actions.ActOnLabelStmt(IdentTok.getLocation(),
                                 IdentTok.getIdentifierInfo(),
-                                ColonLoc, move(SubStmt));
+                                ColonLoc, SubStmt.get());
 }
 
 /// ParseCaseStatement
@@ -249,7 +252,7 @@
 ///         'case' constant-expression ':' statement
 /// [GNU]   'case' constant-expression '...' constant-expression ':' statement
 ///
-Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) {
+StmtResult Parser::ParseCaseStatement(AttributeList *Attr) {
   assert(Tok.is(tok::kw_case) && "Not a case stmt!");
   // FIXME: Use attributes?
   delete Attr;
@@ -270,7 +273,7 @@
 
   // TopLevelCase - This is the highest level we have parsed.  'case 1' in the
   // example above.
-  OwningStmtResult TopLevelCase(Actions, true);
+  StmtResult TopLevelCase(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
@@ -282,8 +285,8 @@
     SourceLocation CaseLoc = ConsumeToken();  // eat the 'case'.
 
     if (Tok.is(tok::code_completion)) {
-      Actions.CodeCompleteCase(CurScope);
-      ConsumeToken();
+      Actions.CodeCompleteCase(getCurScope());
+      ConsumeCodeCompletionToken();
     }
     
     /// We don't want to treat 'case x : y' as a potential typo for 'case x::y'.
@@ -291,7 +294,7 @@
     /// expression.
     ColonProtectionRAIIObject ColonProtection(*this);
     
-    OwningExprResult LHS(ParseConstantExpression());
+    ExprResult LHS(ParseConstantExpression());
     if (LHS.isInvalid()) {
       SkipUntil(tok::colon);
       return StmtError();
@@ -299,7 +302,7 @@
 
     // GNU case range extension.
     SourceLocation DotDotDotLoc;
-    OwningExprResult RHS(Actions);
+    ExprResult RHS;
     if (Tok.is(tok::ellipsis)) {
       Diag(Tok, diag::ext_gnu_case_range);
       DotDotDotLoc = ConsumeToken();
@@ -321,9 +324,9 @@
 
     SourceLocation ColonLoc = ConsumeToken();
 
-    OwningStmtResult Case =
-      Actions.ActOnCaseStmt(CaseLoc, move(LHS), DotDotDotLoc,
-                            move(RHS), ColonLoc);
+    StmtResult Case =
+      Actions.ActOnCaseStmt(CaseLoc, LHS.get(), DotDotDotLoc,
+                            RHS.get(), ColonLoc);
 
     // If we had a sema error parsing this case, then just ignore it and
     // continue parsing the sub-stmt.
@@ -334,11 +337,11 @@
     } 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();
+      Stmt *NextDeepest = Case.get();
       if (TopLevelCase.isInvalid())
         TopLevelCase = move(Case);
       else
-        Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, move(Case));
+        Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get());
       DeepestParsedCaseStmt = NextDeepest;
     }
 
@@ -348,7 +351,7 @@
   assert(!TopLevelCase.isInvalid() && "Should have parsed at least one case!");
 
   // If we found a non-case statement, start by parsing it.
-  OwningStmtResult SubStmt(Actions);
+  StmtResult SubStmt;
 
   if (Tok.isNot(tok::r_brace)) {
     SubStmt = ParseStatement();
@@ -365,7 +368,7 @@
     SubStmt = Actions.ActOnNullStmt(SourceLocation());
 
   // Install the body into the most deeply-nested case.
-  Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, move(SubStmt));
+  Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get());
 
   // Return the top level parsed statement tree.
   return move(TopLevelCase);
@@ -376,7 +379,7 @@
 ///         'default' ':' statement
 /// Note that this does not parse the 'statement' at the end.
 ///
-Parser::OwningStmtResult Parser::ParseDefaultStatement(AttributeList *Attr) {
+StmtResult Parser::ParseDefaultStatement(AttributeList *Attr) {
   //FIXME: Use attributes?
   delete Attr;
 
@@ -397,12 +400,12 @@
     return StmtError();
   }
 
-  OwningStmtResult SubStmt(ParseStatement());
+  StmtResult SubStmt(ParseStatement());
   if (SubStmt.isInvalid())
     return StmtError();
 
   return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
-                                  move(SubStmt), CurScope);
+                                  SubStmt.get(), getCurScope());
 }
 
 
@@ -433,7 +436,7 @@
 /// [OMP]   barrier-directive
 /// [OMP]   flush-directive
 ///
-Parser::OwningStmtResult Parser::ParseCompoundStatement(AttributeList *Attr,
+StmtResult Parser::ParseCompoundStatement(AttributeList *Attr,
                                                         bool isStmtExpr) {
   //FIXME: Use attributes?
   delete Attr;
@@ -453,7 +456,7 @@
 /// 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) {
+StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
   PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
                                 Tok.getLocation(),
                                 "in compound statement ('{}')");
@@ -466,7 +469,7 @@
   typedef StmtVector StmtsTy;
   StmtsTy Stmts(Actions);
   while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
-    OwningStmtResult R(Actions);
+    StmtResult R;
     if (Tok.isNot(tok::kw___extension__)) {
       R = ParseStatementOrDeclaration(false);
     } else {
@@ -494,7 +497,7 @@
         R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
       } else {
         // Otherwise this was a unary __extension__ marker.
-        OwningExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
+        ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
 
         if (Res.isInvalid()) {
           SkipUntil(tok::semi);
@@ -505,7 +508,7 @@
         // 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));
+        R = Actions.ActOnExprStmt(Actions.MakeFullExpr(Res.get()));
       }
     }
 
@@ -535,22 +538,30 @@
 /// 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 Parser::ParseParenExprOrCondition(ExprResult &ExprResult,
+                                       Decl *&DeclResult,
+                                       SourceLocation Loc,
+                                       bool ConvertToBoolean) {
   bool ParseError = false;
   
   SourceLocation LParenLoc = ConsumeParen();
   if (getLang().CPlusPlus) 
-    ParseError = ParseCXXCondition(ExprResult, DeclResult);
+    ParseError = ParseCXXCondition(ExprResult, DeclResult, Loc, 
+                                   ConvertToBoolean);
   else {
     ExprResult = ParseExpression();
-    DeclResult = DeclPtrTy();
+    DeclResult = 0;
+    
+    // If required, convert to a boolean value.
+    if (!ExprResult.isInvalid() && ConvertToBoolean)
+      ExprResult
+        = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprResult.get());
   }
 
   // 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)) {
+  if (ExprResult.isInvalid() && !DeclResult && 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.
@@ -571,7 +582,7 @@
 /// [C++]   'if' '(' condition ')' statement
 /// [C++]   'if' '(' condition ')' statement 'else' statement
 ///
-Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) {
+StmtResult Parser::ParseIfStatement(AttributeList *Attr) {
   // FIXME: Use attributes?
   delete Attr;
 
@@ -601,12 +612,12 @@
   ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX);
 
   // Parse the condition.
-  OwningExprResult CondExp(Actions);
-  DeclPtrTy CondVar;
-  if (ParseParenExprOrCondition(CondExp, CondVar))
+  ExprResult CondExp;
+  Decl *CondVar = 0;
+  if (ParseParenExprOrCondition(CondExp, CondVar, IfLoc, true))
     return StmtError();
 
-  FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp));
+  FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp.get()));
 
   // 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
@@ -631,7 +642,7 @@
 
   // Read the 'then' stmt.
   SourceLocation ThenStmtLoc = Tok.getLocation();
-  OwningStmtResult ThenStmt(ParseStatement());
+  StmtResult ThenStmt(ParseStatement());
 
   // Pop the 'if' scope if needed.
   InnerScope.Exit();
@@ -639,7 +650,7 @@
   // If it has an else, parse it.
   SourceLocation ElseLoc;
   SourceLocation ElseStmtLoc;
-  OwningStmtResult ElseStmt(Actions);
+  StmtResult ElseStmt;
 
   if (Tok.is(tok::kw_else)) {
     ElseLoc = ConsumeToken();
@@ -657,13 +668,7 @@
     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();
@@ -673,7 +678,7 @@
 
   // 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())
+  if (CondExp.isInvalid() && !CondVar)
     return StmtError();
 
   // If the then or else stmt is invalid and the other is valid (and present),
@@ -692,15 +697,15 @@
   if (ElseStmt.isInvalid())
     ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
 
-  return Actions.ActOnIfStmt(IfLoc, FullCondExp, CondVar, move(ThenStmt),
-                             ElseLoc, move(ElseStmt));
+  return Actions.ActOnIfStmt(IfLoc, FullCondExp, CondVar, ThenStmt.get(),
+                             ElseLoc, ElseStmt.get());
 }
 
 /// ParseSwitchStatement
 ///       switch-statement:
 ///         'switch' '(' expression ')' statement
 /// [C++]   'switch' '(' condition ')' statement
-Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) {
+StmtResult Parser::ParseSwitchStatement(AttributeList *Attr) {
   // FIXME: Use attributes?
   delete Attr;
 
@@ -733,15 +738,27 @@
   ParseScope SwitchScope(this, ScopeFlags);
 
   // Parse the condition.
-  OwningExprResult Cond(Actions);
-  DeclPtrTy CondVar;
-  if (ParseParenExprOrCondition(Cond, CondVar))
+  ExprResult Cond;
+  Decl *CondVar = 0;
+  if (ParseParenExprOrCondition(Cond, CondVar, SwitchLoc, false))
     return StmtError();
 
-  FullExprArg FullCond(Actions.MakeFullExpr(Cond));
-  
-  OwningStmtResult Switch = Actions.ActOnStartOfSwitchStmt(FullCond, CondVar);
+  StmtResult Switch
+    = Actions.ActOnStartOfSwitchStmt(SwitchLoc, Cond.get(), CondVar);
 
+  if (Switch.isInvalid()) {
+    // Skip the switch body. 
+    // FIXME: This is not optimal recovery, but parsing the body is more
+    // dangerous due to the presence of case and default statements, which
+    // will have no place to connect back with the switch.
+    if (Tok.is(tok::l_brace)) {
+      ConsumeBrace();
+      SkipUntil(tok::r_brace, false, false);
+    } else
+      SkipUntil(tok::semi);
+    return move(Switch);
+  }
+  
   // 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.
@@ -757,29 +774,24 @@
                         C99orCXX && Tok.isNot(tok::l_brace));
 
   // Read the body statement.
-  OwningStmtResult Body(ParseStatement());
+  StmtResult 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));
+  return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.get(), Body.get());
 }
 
 /// ParseWhileStatement
 ///       while-statement: [C99 6.8.5.1]
 ///         'while' '(' expression ')' statement
 /// [C++]   'while' '(' condition ')' statement
-Parser::OwningStmtResult Parser::ParseWhileStatement(AttributeList *Attr) {
+StmtResult Parser::ParseWhileStatement(AttributeList *Attr) {
   // FIXME: Use attributes?
   delete Attr;
 
@@ -816,12 +828,12 @@
   ParseScope WhileScope(this, ScopeFlags);
 
   // Parse the condition.
-  OwningExprResult Cond(Actions);
-  DeclPtrTy CondVar;
-  if (ParseParenExprOrCondition(Cond, CondVar))
+  ExprResult Cond;
+  Decl *CondVar = 0;
+  if (ParseParenExprOrCondition(Cond, CondVar, WhileLoc, true))
     return StmtError();
 
-  FullExprArg FullCond(Actions.MakeFullExpr(Cond));
+  FullExprArg FullCond(Actions.MakeFullExpr(Cond.get()));
 
   // 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
@@ -838,23 +850,23 @@
                         C99orCXX && Tok.isNot(tok::l_brace));
 
   // Read the body statement.
-  OwningStmtResult Body(ParseStatement());
+  StmtResult Body(ParseStatement());
 
   // Pop the body scope if needed.
   InnerScope.Exit();
   WhileScope.Exit();
 
-  if ((Cond.isInvalid() && !CondVar.get()) || Body.isInvalid())
+  if ((Cond.isInvalid() && !CondVar) || Body.isInvalid())
     return StmtError();
 
-  return Actions.ActOnWhileStmt(WhileLoc, FullCond, CondVar, move(Body));
+  return Actions.ActOnWhileStmt(WhileLoc, FullCond, CondVar, Body.get());
 }
 
 /// 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) {
+StmtResult Parser::ParseDoStatement(AttributeList *Attr) {
   // FIXME: Use attributes?
   delete Attr;
 
@@ -884,7 +896,7 @@
                         Tok.isNot(tok::l_brace));
 
   // Read the body statement.
-  OwningStmtResult Body(ParseStatement());
+  StmtResult Body(ParseStatement());
 
   // Pop the body scope if needed.
   InnerScope.Exit();
@@ -907,15 +919,15 @@
 
   // Parse the parenthesized condition.
   SourceLocation LPLoc = ConsumeParen();
-  OwningExprResult Cond = ParseExpression();
+  ExprResult 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);
+  return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc, LPLoc,
+                             Cond.get(), RPLoc);
 }
 
 /// ParseForStatement
@@ -931,7 +943,7 @@
 /// [C++]   expression-statement
 /// [C++]   simple-declaration
 ///
-Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) {
+StmtResult Parser::ParseForStatement(AttributeList *Attr) {
   // FIXME: Use attributes?
   delete Attr;
 
@@ -971,18 +983,21 @@
   ParseScope ForScope(this, ScopeFlags);
 
   SourceLocation LParenLoc = ConsumeParen();
-  OwningExprResult Value(Actions);
+  ExprResult Value;
 
   bool ForEach = false;
-  OwningStmtResult FirstPart(Actions);
-  OwningExprResult SecondPart(Actions), ThirdPart(Actions);
-  DeclPtrTy SecondVar;
+  StmtResult FirstPart;
+  bool SecondPartIsInvalid = false;
+  FullExprArg SecondPart(Actions);
+  ExprResult Collection;
+  FullExprArg ThirdPart(Actions);
+  Decl *SecondVar = 0;
   
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteOrdinaryName(CurScope, 
-                                     C99orCXXorObjC? Action::CCC_ForInit
-                                                   : Action::CCC_Expression);
-    ConsumeToken();
+    Actions.CodeCompleteOrdinaryName(getCurScope(), 
+                                     C99orCXXorObjC? Sema::PCC_ForInit
+                                                   : Sema::PCC_Expression);
+    ConsumeCodeCompletionToken();
   }
   
   // Parse the first part of the for specifier.
@@ -1009,7 +1024,12 @@
       Actions.ActOnForEachDeclStmt(DG);
       // ObjC: for (id x in expr)
       ConsumeToken(); // consume 'in'
-      SecondPart = ParseExpression();
+      
+      if (Tok.is(tok::code_completion)) {
+        Actions.CodeCompleteObjCForCollection(getCurScope(), DG);
+        ConsumeCodeCompletionToken();
+      }
+      Collection = ParseExpression();
     } else {
       Diag(Tok, diag::err_expected_semi_for);
       SkipUntil(tok::semi);
@@ -1019,13 +1039,18 @@
 
     // Turn the expression into a stmt.
     if (!Value.isInvalid())
-      FirstPart = Actions.ActOnExprStmt(Actions.MakeFullExpr(Value));
+      FirstPart = Actions.ActOnExprStmt(Actions.MakeFullExpr(Value.get()));
 
     if (Tok.is(tok::semi)) {
       ConsumeToken();
     } else if ((ForEach = isTokIdentifier_in())) {
       ConsumeToken(); // consume 'in'
-      SecondPart = ParseExpression();
+      
+      if (Tok.is(tok::code_completion)) {
+        Actions.CodeCompleteObjCForCollection(getCurScope(), DeclGroupPtrTy());
+        ConsumeCodeCompletionToken();
+      }
+      Collection = ParseExpression();
     } else {
       if (!Value.isInvalid()) Diag(Tok, diag::err_expected_semi_for);
       SkipUntil(tok::semi);
@@ -1037,23 +1062,32 @@
     if (Tok.is(tok::semi)) {  // for (...;;
       // no second part.
     } else {
+      ExprResult Second;
       if (getLang().CPlusPlus)
-        ParseCXXCondition(SecondPart, SecondVar);
-      else
-        SecondPart = ParseExpression();
+        ParseCXXCondition(Second, SecondVar, ForLoc, true);
+      else {
+        Second = ParseExpression();
+        if (!Second.isInvalid())
+          Second = Actions.ActOnBooleanCondition(getCurScope(), ForLoc, 
+                                                 Second.get());
+      }
+      SecondPartIsInvalid = Second.isInvalid();
+      SecondPart = Actions.MakeFullExpr(Second.get());
     }
 
     if (Tok.is(tok::semi)) {
       ConsumeToken();
     } else {
-      if (!SecondPart.isInvalid() || SecondVar.get()) 
+      if (!SecondPartIsInvalid || SecondVar) 
         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();
+    if (Tok.isNot(tok::r_paren)) {   // for (...;...;)
+      ExprResult Third = ParseExpression();
+      ThirdPart = Actions.MakeFullExpr(Third.take());
+    }
   }
   // Match the ')'.
   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
@@ -1073,7 +1107,7 @@
                         C99orCXXorObjC && Tok.isNot(tok::l_brace));
 
   // Read the body statement.
-  OwningStmtResult Body(ParseStatement());
+  StmtResult Body(ParseStatement());
 
   // Pop the body scope if needed.
   InnerScope.Exit();
@@ -1085,15 +1119,14 @@
     return StmtError();
 
   if (!ForEach)
-    return Actions.ActOnForStmt(ForLoc, LParenLoc, move(FirstPart),
-                                Actions.MakeFullExpr(SecondPart), SecondVar,
-                                Actions.MakeFullExpr(ThirdPart), RParenLoc, 
-                                move(Body));
+    return Actions.ActOnForStmt(ForLoc, LParenLoc, FirstPart.take(), SecondPart,
+                                SecondVar, ThirdPart, RParenLoc, Body.take());
 
-  return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
-                                            move(FirstPart),
-                                            move(SecondPart),
-                                            RParenLoc, move(Body));
+  // FIXME: It isn't clear how to communicate the late destruction of 
+  // C++ temporaries used to create the collection.
+  return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc, FirstPart.take(), 
+                                            Collection.take(), RParenLoc, 
+                                            Body.take());
 }
 
 /// ParseGotoStatement
@@ -1103,14 +1136,14 @@
 ///
 /// Note: this lets the caller parse the end ';'.
 ///
-Parser::OwningStmtResult Parser::ParseGotoStatement(AttributeList *Attr) {
+StmtResult 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);
+  StmtResult Res;
   if (Tok.is(tok::identifier)) {
     Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(),
                                 Tok.getIdentifierInfo());
@@ -1119,12 +1152,12 @@
     // GNU indirect goto extension.
     Diag(Tok, diag::ext_gnu_indirect_goto);
     SourceLocation StarLoc = ConsumeToken();
-    OwningExprResult R(ParseExpression());
+    ExprResult 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));
+    Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.take());
   } else {
     Diag(Tok, diag::err_expected_ident);
     return StmtError();
@@ -1139,12 +1172,12 @@
 ///
 /// Note: this lets the caller parse the end ';'.
 ///
-Parser::OwningStmtResult Parser::ParseContinueStatement(AttributeList *Attr) {
+StmtResult Parser::ParseContinueStatement(AttributeList *Attr) {
   // FIXME: Use attributes?
   delete Attr;
 
   SourceLocation ContinueLoc = ConsumeToken();  // eat the 'continue'.
-  return Actions.ActOnContinueStmt(ContinueLoc, CurScope);
+  return Actions.ActOnContinueStmt(ContinueLoc, getCurScope());
 }
 
 /// ParseBreakStatement
@@ -1153,38 +1186,45 @@
 ///
 /// Note: this lets the caller parse the end ';'.
 ///
-Parser::OwningStmtResult Parser::ParseBreakStatement(AttributeList *Attr) {
+StmtResult Parser::ParseBreakStatement(AttributeList *Attr) {
   // FIXME: Use attributes?
   delete Attr;
 
   SourceLocation BreakLoc = ConsumeToken();  // eat the 'break'.
-  return Actions.ActOnBreakStmt(BreakLoc, CurScope);
+  return Actions.ActOnBreakStmt(BreakLoc, getCurScope());
 }
 
 /// ParseReturnStatement
 ///       jump-statement:
 ///         'return' expression[opt] ';'
-Parser::OwningStmtResult Parser::ParseReturnStatement(AttributeList *Attr) {
+StmtResult 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);
+  ExprResult R;
   if (Tok.isNot(tok::semi)) {
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteReturn(getCurScope());
+      ConsumeCodeCompletionToken();
+      SkipUntil(tok::semi, false, true);
+      return StmtError();
+    }
+        
     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));
+  return Actions.ActOnReturnStmt(ReturnLoc, R.take());
 }
 
 /// FuzzyParseMicrosoftAsmStatement. When -fms-extensions is enabled, this
 /// routine is called to skip/ignore tokens that comprise the MS asm statement.
-Parser::OwningStmtResult Parser::FuzzyParseMicrosoftAsmStatement() {
+StmtResult Parser::FuzzyParseMicrosoftAsmStatement() {
   if (Tok.is(tok::l_brace)) {
     unsigned short savedBraceCount = BraceCount;
     do {
@@ -1205,16 +1245,16 @@
   }
   Token t;
   t.setKind(tok::string_literal);
-  t.setLiteralData("\"FIXME: not done\"");
+  t.setLiteralData("\"/*FIXME: not done*/\"");
   t.clearFlag(Token::NeedsCleaning);
-  t.setLength(17);
-  OwningExprResult AsmString(Actions.ActOnStringLiteral(&t, 1));
+  t.setLength(21);
+  ExprResult 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),
+                              AsmString.take(), move_arg(Clobbers),
                               Tok.getLocation(), true);
 }
 
@@ -1245,7 +1285,7 @@
 ///         assembly-instruction ';'[opt]
 ///         assembly-instruction-list ';' assembly-instruction ';'[opt]
 ///
-Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) {
+StmtResult Parser::ParseAsmStatement(bool &msAsm) {
   assert(Tok.is(tok::kw_asm) && "Not an asm stmt");
   SourceLocation AsmLoc = ConsumeToken();
 
@@ -1272,7 +1312,7 @@
   }
   Loc = ConsumeParen();
 
-  OwningExprResult AsmString(ParseAsmStringLiteral());
+  ExprResult AsmString(ParseAsmStringLiteral());
   if (AsmString.isInvalid())
     return StmtError();
 
@@ -1287,7 +1327,7 @@
     return Actions.ActOnAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile,
                                 /*NumOutputs*/ 0, /*NumInputs*/ 0, 0, 
                                 move_arg(Constraints), move_arg(Exprs),
-                                move(AsmString), move_arg(Clobbers),
+                                AsmString.take(), move_arg(Clobbers),
                                 RParenLoc);
   }
 
@@ -1332,17 +1372,19 @@
     if (!AteExtraColon)
       ConsumeToken();
 
-    // Parse the asm-string list for clobbers.
-    while (1) {
-      OwningExprResult Clobber(ParseAsmStringLiteral());
+    // Parse the asm-string list for clobbers if present.
+    if (Tok.isNot(tok::r_paren)) {
+      while (1) {
+        ExprResult Clobber(ParseAsmStringLiteral());
 
-      if (Clobber.isInvalid())
-        break;
+        if (Clobber.isInvalid())
+          break;
 
-      Clobbers.push_back(Clobber.release());
+        Clobbers.push_back(Clobber.release());
 
-      if (Tok.isNot(tok::comma)) break;
-      ConsumeToken();
+        if (Tok.isNot(tok::comma)) break;
+        ConsumeToken();
+      }
     }
   }
 
@@ -1350,7 +1392,7 @@
   return Actions.ActOnAsmStmt(AsmLoc, false, isVolatile,
                               NumOutputs, NumInputs, Names.data(),
                               move_arg(Constraints), move_arg(Exprs),
-                              move(AsmString), move_arg(Clobbers),
+                              AsmString.take(), move_arg(Clobbers),
                               RParenLoc);
 }
 
@@ -1393,7 +1435,7 @@
     } else
       Names.push_back(0);
 
-    OwningExprResult Constraint(ParseAsmStringLiteral());
+    ExprResult Constraint(ParseAsmStringLiteral());
     if (Constraint.isInvalid()) {
         SkipUntil(tok::r_paren);
         return true;
@@ -1408,7 +1450,7 @@
 
     // Read the parenthesized expression.
     SourceLocation OpenLoc = ConsumeParen();
-    OwningExprResult Res(ParseExpression());
+    ExprResult Res(ParseExpression());
     MatchRHSPunctuation(tok::r_paren, OpenLoc);
     if (Res.isInvalid()) {
       SkipUntil(tok::r_paren);
@@ -1423,25 +1465,24 @@
   return true;
 }
 
-Parser::DeclPtrTy Parser::ParseFunctionStatementBody(DeclPtrTy Decl) {
+Decl *Parser::ParseFunctionStatementBody(Decl *Decl) {
   assert(Tok.is(tok::l_brace));
   SourceLocation LBraceLoc = Tok.getLocation();
 
-  PrettyStackTraceActionsDecl CrashInfo(Decl, LBraceLoc, Actions,
-                                        PP.getSourceManager(),
-                                        "parsing function body");
+  PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, LBraceLoc,
+                                      "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());
+  StmtResult 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));
+  return Actions.ActOnFinishFunctionBody(Decl, FnBody.take());
 }
 
 /// ParseFunctionTryBlock - Parse a C++ function-try-block.
@@ -1449,27 +1490,26 @@
 ///       function-try-block:
 ///         'try' ctor-initializer[opt] compound-statement handler-seq
 ///
-Parser::DeclPtrTy Parser::ParseFunctionTryBlock(DeclPtrTy Decl) {
+Decl *Parser::ParseFunctionTryBlock(Decl *Decl) {
   assert(Tok.is(tok::kw_try) && "Expected 'try'");
   SourceLocation TryLoc = ConsumeToken();
 
-  PrettyStackTraceActionsDecl CrashInfo(Decl, TryLoc, Actions,
-                                        PP.getSourceManager(),
-                                        "parsing function try block");
+  PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, TryLoc,
+                                      "parsing function try block");
 
   // Constructor initializer list?
   if (Tok.is(tok::colon))
     ParseConstructorInitializer(Decl);
 
   SourceLocation LBraceLoc = Tok.getLocation();
-  OwningStmtResult FnBody(ParseCXXTryBlockCommon(TryLoc));
+  StmtResult 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));
+  return Actions.ActOnFinishFunctionBody(Decl, FnBody.take());
 }
 
 /// ParseCXXTryBlock - Parse a C++ try-block.
@@ -1477,7 +1517,7 @@
 ///       try-block:
 ///         'try' compound-statement handler-seq
 ///
-Parser::OwningStmtResult Parser::ParseCXXTryBlock(AttributeList* Attr) {
+StmtResult Parser::ParseCXXTryBlock(AttributeList* Attr) {
   // FIXME: Add attributes?
   delete Attr;
 
@@ -1499,11 +1539,11 @@
 ///       handler-seq:
 ///         handler handler-seq[opt]
 ///
-Parser::OwningStmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) {
+StmtResult 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));
+  StmtResult TryBlock(ParseCompoundStatement(0));
   if (TryBlock.isInvalid())
     return move(TryBlock);
 
@@ -1516,7 +1556,7 @@
   if (Tok.isNot(tok::kw_catch))
     return StmtError(Diag(Tok, diag::err_expected_catch));
   while (Tok.is(tok::kw_catch)) {
-    OwningStmtResult Handler(ParseCXXCatchBlock());
+    StmtResult Handler(ParseCXXCatchBlock());
     if (!Handler.isInvalid())
       Handlers.push_back(Handler.release());
   }
@@ -1525,7 +1565,7 @@
   if (Handlers.empty())
     return StmtError();
 
-  return Actions.ActOnCXXTryBlock(TryLoc, move(TryBlock), move_arg(Handlers));
+  return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.take(), move_arg(Handlers));
 }
 
 /// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the standard
@@ -1539,7 +1579,7 @@
 ///         type-specifier-seq
 ///         '...'
 ///
-Parser::OwningStmtResult Parser::ParseCXXCatchBlock() {
+StmtResult Parser::ParseCXXCatchBlock() {
   assert(Tok.is(tok::kw_catch) && "Expected 'catch'");
 
   SourceLocation CatchLoc = ConsumeToken();
@@ -1555,14 +1595,14 @@
 
   // exception-declaration is equivalent to '...' or a parameter-declaration
   // without default arguments.
-  DeclPtrTy ExceptionDecl;
+  Decl *ExceptionDecl = 0;
   if (Tok.isNot(tok::ellipsis)) {
     DeclSpec DS;
     if (ParseCXXTypeSpecifierSeq(DS))
       return StmtError();
     Declarator ExDecl(DS, Declarator::CXXCatchContext);
     ParseDeclarator(ExDecl);
-    ExceptionDecl = Actions.ActOnExceptionDeclarator(CurScope, ExDecl);
+    ExceptionDecl = Actions.ActOnExceptionDeclarator(getCurScope(), ExDecl);
   } else
     ConsumeToken();
 
@@ -1573,9 +1613,9 @@
     return StmtError(Diag(Tok, diag::err_expected_lbrace));
 
   // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
-  OwningStmtResult Block(ParseCompoundStatement(0));
+  StmtResult Block(ParseCompoundStatement(0));
   if (Block.isInvalid())
     return move(Block);
 
-  return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, move(Block));
+  return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.take());
 }
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index ff69953..dfb4785 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -13,15 +13,15 @@
 
 #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 "clang/Sema/DeclSpec.h"
+#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Sema/Scope.h"
 #include "RAIIObjectsForParser.h"
 using namespace clang;
 
 /// \brief Parse a template declaration, explicit instantiation, or
 /// explicit specialization.
-Parser::DeclPtrTy
+Decl *
 Parser::ParseDeclarationStartingWithTemplate(unsigned Context,
                                              SourceLocation &DeclEnd,
                                              AccessSpecifier AS) {
@@ -70,7 +70,7 @@
 ///
 ///       explicit-specialization: [ C++ temp.expl.spec]
 ///         'template' '<' '>' declaration
-Parser::DeclPtrTy
+Decl *
 Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
                                                  SourceLocation &DeclEnd,
                                                  AccessSpecifier AS) {
@@ -80,6 +80,10 @@
   // Enter template-parameter scope.
   ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
 
+  // Tell the action that names should be checked in the context of
+  // the declaration to come.
+  ParsingDeclRAIIObject ParsingTemplateParams(*this);
+
   // Parse multiple levels of template headers within this template
   // parameter scope, e.g.,
   //
@@ -118,19 +122,19 @@
       TemplateLoc = ConsumeToken();
     } else {
       Diag(Tok.getLocation(), diag::err_expected_template);
-      return DeclPtrTy();
+      return 0;
     }
 
     // Parse the '<' template-parameter-list '>'
     SourceLocation LAngleLoc, RAngleLoc;
-    TemplateParameterList TemplateParams;
+    llvm::SmallVector<Decl*, 4> 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();
+      return 0;
     }
 
     ParamLists.push_back(
@@ -152,6 +156,7 @@
                                              ParsedTemplateInfo(&ParamLists,
                                                              isSpecialization,
                                                          LastParamListWasEmpty),
+                                             ParsingTemplateParams,
                                              DeclEnd, AS);
 }
 
@@ -175,10 +180,11 @@
 /// declaration. Will be AS_none for namespace-scope declarations.
 ///
 /// \returns the new declaration.
-Parser::DeclPtrTy
+Decl *
 Parser::ParseSingleDeclarationAfterTemplate(
                                        unsigned Context,
                                        const ParsedTemplateInfo &TemplateInfo,
+                                       ParsingDeclRAIIObject &DiagsFromTParams,
                                        SourceLocation &DeclEnd,
                                        AccessSpecifier AS) {
   assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
@@ -186,12 +192,13 @@
 
   if (Context == Declarator::MemberContext) {
     // We are parsing a member template.
-    ParseCXXClassMemberDeclaration(AS, TemplateInfo);
-    return DeclPtrTy::make((void*)0);
+    ParseCXXClassMemberDeclaration(AS, TemplateInfo, &DiagsFromTParams);
+    return 0;
   }
 
-  // Parse the declaration specifiers.
-  ParsingDeclSpec DS(*this);
+  // Parse the declaration specifiers, stealing the accumulated
+  // diagnostics from the template parameters.
+  ParsingDeclSpec DS(DiagsFromTParams);
 
   if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
     DS.AddAttributes(ParseCXX0XAttributes().AttrList);
@@ -201,7 +208,7 @@
 
   if (Tok.is(tok::semi)) {
     DeclEnd = ConsumeToken();
-    DeclPtrTy Decl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
+    Decl *Decl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS);
     DS.complete(Decl);
     return Decl;
   }
@@ -215,14 +222,14 @@
     SkipUntil(tok::r_brace, true, true);
     if (Tok.is(tok::semi))
       ConsumeToken();
-    return DeclPtrTy();
+    return 0;
   }
 
   // If we have a declaration or declarator list, handle it.
   if (isDeclarationAfterDeclarator()) {
     // Parse this declaration.
-    DeclPtrTy ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo,
-                                                         TemplateInfo);
+    Decl *ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo,
+                                                     TemplateInfo);
 
     if (Tok.is(tok::comma)) {
       Diag(Tok, diag::err_multiple_template_declarators)
@@ -238,7 +245,7 @@
   }
 
   if (DeclaratorInfo.isFunctionDeclarator() &&
-      isStartOfFunctionDefinition()) {
+      isStartOfFunctionDefinition(DeclaratorInfo)) {
     if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
       Diag(Tok, diag::err_function_declared_typedef);
 
@@ -251,7 +258,7 @@
       } else {
         SkipUntil(tok::semi);
       }
-      return DeclPtrTy();
+      return 0;
     }
     return ParseFunctionDefinition(DeclaratorInfo, TemplateInfo);
   }
@@ -261,7 +268,7 @@
   else
     Diag(Tok, diag::err_invalid_token_after_toplevel_declarator);
   SkipUntil(tok::semi);
-  return DeclPtrTy();
+  return 0;
 }
 
 /// ParseTemplateParameters - Parses a template-parameter-list enclosed in
@@ -274,7 +281,7 @@
 ///
 /// \returns true if an error occurred, false otherwise.
 bool Parser::ParseTemplateParameters(unsigned Depth,
-                                     TemplateParameterList &TemplateParams,
+                               llvm::SmallVectorImpl<Decl*> &TemplateParams,
                                      SourceLocation &LAngleLoc,
                                      SourceLocation &RAngleLoc) {
   // Get the template parameter list.
@@ -307,9 +314,9 @@
 ///         template-parameter-list ',' template-parameter
 bool
 Parser::ParseTemplateParameterList(unsigned Depth,
-                                   TemplateParameterList &TemplateParams) {
+                             llvm::SmallVectorImpl<Decl*> &TemplateParams) {
   while (1) {
-    if (DeclPtrTy TmpParam
+    if (Decl *TmpParam
           = ParseTemplateParameter(Depth, TemplateParams.size())) {
       TemplateParams.push_back(TmpParam);
     } else {
@@ -341,8 +348,37 @@
 /// \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.is(tok::kw_class)) {
+    // "class" may be the start of an elaborated-type-specifier or a
+    // type-parameter. Per C++ [temp.param]p3, we prefer the type-parameter.
+    switch (NextToken().getKind()) {
+    case tok::equal:
+    case tok::comma:
+    case tok::greater:
+    case tok::greatergreater:
+    case tok::ellipsis:
+      return true;
+        
+    case tok::identifier:
+      // This may be either a type-parameter or an elaborated-type-specifier. 
+      // We have to look further.
+      break;
+        
+    default:
+      return false;
+    }
+    
+    switch (GetLookAheadToken(2).getKind()) {
+    case tok::equal:
+    case tok::comma:
+    case tok::greater:
+    case tok::greatergreater:
+      return true;
+      
+    default:
+      return false;
+    }
+  }
 
   if (Tok.isNot(tok::kw_typename))
     return false;
@@ -385,8 +421,7 @@
 ///         '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) {
+Decl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
   if (isStartOfTemplateTypeParameter())
     return ParseTypeParameter(Depth, Position);
 
@@ -408,7 +443,7 @@
 ///         'class' identifier[opt] '=' type-id
 ///         'typename' ...[opt][C++0x] identifier[opt]
 ///         'typename' identifier[opt] '=' type-id
-Parser::DeclPtrTy Parser::ParseTypeParameter(unsigned Depth, unsigned Position){
+Decl *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'");
 
@@ -439,25 +474,22 @@
     // don't consume this token.
   } else {
     Diag(Tok.getLocation(), diag::err_expected_ident);
-    return DeclPtrTy();
+    return 0;
   }
 
-  DeclPtrTy TypeParam = Actions.ActOnTypeParameter(CurScope, TypenameKeyword,
-                                                   Ellipsis, EllipsisLoc,
-                                                   KeyLoc, ParamName, NameLoc,
-                                                   Depth, Position);
-
-  // Grab a default type id (if given).
+  // Grab a default argument (if available).
+  // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
+  // we introduce the type parameter into the local scope.
+  SourceLocation EqualLoc;
+  ParsedType DefaultArg;
   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());
+    EqualLoc = ConsumeToken();
+    DefaultArg = ParseTypeName().get();
   }
-
-  return TypeParam;
+  
+  return Actions.ActOnTypeParameter(getCurScope(), TypenameKeyword, Ellipsis, 
+                                    EllipsisLoc, KeyLoc, ParamName, NameLoc,
+                                    Depth, Position, EqualLoc, DefaultArg);
 }
 
 /// ParseTemplateTemplateParameter - Handle the parsing of template
@@ -466,19 +498,19 @@
 ///       type-parameter:    [C++ temp.param]
 ///         'template' '<' template-parameter-list '>' 'class' identifier[opt]
 ///         'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression
-Parser::DeclPtrTy
+Decl *
 Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
   assert(Tok.is(tok::kw_template) && "Expected 'template' keyword");
 
   // Handle the template <...> part.
   SourceLocation TemplateLoc = ConsumeToken();
-  TemplateParameterList TemplateParams;
+  llvm::SmallVector<Decl*,8> TemplateParams;
   SourceLocation LAngleLoc, RAngleLoc;
   {
     ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
     if (ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc,
                                RAngleLoc)) {
-      return DeclPtrTy();
+      return 0;
     }
   }
 
@@ -487,7 +519,7 @@
   if (!Tok.is(tok::kw_class)) {
     Diag(Tok.getLocation(), diag::err_expected_class_before)
       << PP.getSpelling(Tok);
-    return DeclPtrTy();
+    return 0;
   }
   SourceLocation ClassLoc = ConsumeToken();
 
@@ -502,7 +534,7 @@
     // don't consume this token.
   } else {
     Diag(Tok.getLocation(), diag::err_expected_ident);
-    return DeclPtrTy();
+    return 0;
   }
 
   TemplateParamsTy *ParamList =
@@ -512,28 +544,28 @@
                                        TemplateParams.size(),
                                        RAngleLoc);
 
-  Parser::DeclPtrTy Param
-    = Actions.ActOnTemplateTemplateParameter(CurScope, TemplateLoc,
-                                             ParamList, ParamName,
-                                             NameLoc, Depth, Position);
-
-  // Get the a default value, if given.
+  // Grab a default argument (if available).
+  // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
+  // we introduce the template parameter into the local scope.
+  SourceLocation EqualLoc;
+  ParsedTemplateArgument DefaultArg;
   if (Tok.is(tok::equal)) {
-    SourceLocation EqualLoc = ConsumeToken();
-    ParsedTemplateArgument Default = ParseTemplateTemplateArgument();
-    if (Default.isInvalid()) {
+    EqualLoc = ConsumeToken();
+    DefaultArg = ParseTemplateTemplateArgument();
+    if (DefaultArg.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;
+  
+  return Actions.ActOnTemplateTemplateParameter(getCurScope(), TemplateLoc,
+                                                ParamList, ParamName,
+                                                NameLoc, Depth, Position,
+                                                EqualLoc, DefaultArg);
 }
 
 /// ParseNonTypeTemplateParameter - Handle the parsing of non-type
@@ -542,14 +574,7 @@
 ///       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
+Decl *
 Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
   SourceLocation StartLoc = Tok.getLocation();
 
@@ -562,23 +587,23 @@
   // Parse this as a typename.
   Declarator ParamDecl(DS, Declarator::TemplateParamContext);
   ParseDeclarator(ParamDecl);
-  if (DS.getTypeSpecType() == DeclSpec::TST_unspecified && !DS.getTypeRep()) {
+  if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) {
     // 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();
+    return 0;
   }
 
-  // Create the parameter.
-  DeclPtrTy Param = Actions.ActOnNonTypeTemplateParameter(CurScope, ParamDecl,
-                                                          Depth, Position);
-
   // If there is a default value, parse it.
+  // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
+  // we introduce the template parameter into the local scope.
+  SourceLocation EqualLoc;
+  ExprResult DefaultArg;
   if (Tok.is(tok::equal)) {
-    SourceLocation EqualLoc = ConsumeToken();
+    EqualLoc = ConsumeToken();
 
     // C++ [temp.param]p15:
     //   When parsing a default template-argument for a non-type
@@ -587,15 +612,15 @@
     //   operator.
     GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
 
-    OwningExprResult DefaultArg = ParseAssignmentExpression();
+    DefaultArg = ParseAssignmentExpression();
     if (DefaultArg.isInvalid())
       SkipUntil(tok::comma, tok::greater, true, true);
-    else if (Param)
-      Actions.ActOnNonTypeTemplateParameterDefault(Param, EqualLoc,
-                                                   move(DefaultArg));
   }
 
-  return Param;
+  // Create the parameter.
+  return Actions.ActOnNonTypeTemplateParameter(getCurScope(), ParamDecl, 
+                                               Depth, Position, EqualLoc, 
+                                               DefaultArg.take());
 }
 
 /// \brief Parses a template-id that after the template name has
@@ -747,7 +772,7 @@
 
   // Build the annotation token.
   if (TNK == TNK_Type_template && AllowTypeAnnotation) {
-    Action::TypeResult Type
+    TypeResult Type
       = Actions.ActOnTemplateIdType(Template, TemplateNameLoc,
                                     LAngleLoc, TemplateArgsPtr,
                                     RAngleLoc);
@@ -760,7 +785,7 @@
     }
 
     Tok.setKind(tok::annot_typename);
-    Tok.setAnnotationValue(Type.get());
+    setTypeAnnotation(Tok, Type.get());
     if (SS && SS->isNotEmpty())
       Tok.setLocation(SS->getBeginLoc());
     else if (TemplateKWLoc.isValid())
@@ -781,7 +806,7 @@
       TemplateId->Name = 0;
       TemplateId->Operator = TemplateName.OperatorFunctionId.Operator;
     }
-    TemplateId->Template = Template.getAs<void*>();
+    TemplateId->Template = Template;
     TemplateId->Kind = TNK;
     TemplateId->LAngleLoc = LAngleLoc;
     TemplateId->RAngleLoc = RAngleLoc;
@@ -825,15 +850,15 @@
                                      TemplateId->getTemplateArgs(),
                                      TemplateId->NumArgs);
 
-  Action::TypeResult Type
-    = Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+  TypeResult Type
+    = Actions.ActOnTemplateIdType(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());
+  setTypeAnnotation(Tok, Type.isInvalid() ? ParsedType() : Type.get());
   if (SS && SS->isNotEmpty()) // it was a C++ qualified type name.
     Tok.setLocation(SS->getBeginLoc());
   // End location stays the same
@@ -868,7 +893,7 @@
   // 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, 
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
                                  /*EnteringContext=*/false);
   
   if (SS.isSet() && Tok.is(tok::kw_template)) {
@@ -885,15 +910,15 @@
       // 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);
-      }
-    } 
+      TemplateTy Template;
+      if (isEndOfTemplateArgument(Tok) &&
+          Actions.ActOnDependentTemplateName(getCurScope(), TemplateLoc,
+                                             SS, Name, 
+                                             /*ObjectType=*/ ParsedType(),
+                                             /*EnteringContext=*/false,
+                                             Template))
+        return ParsedTemplateArgument(SS, Template, Name.StartLocation);
+    }
   } else if (Tok.is(tok::identifier)) {
     // We may have a (non-dependent) template name.
     TemplateTy Template;
@@ -902,10 +927,14 @@
     ConsumeToken(); // the identifier
     
     if (isEndOfTemplateArgument(Tok)) {
-      TemplateNameKind TNK = Actions.isTemplateName(CurScope, SS, Name, 
-                                                    /*ObjectType=*/0, 
+      bool MemberOfUnknownSpecialization;
+      TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS,
+                                               /*hasTemplateKeyword=*/false,
+                                                    Name,
+                                               /*ObjectType=*/ ParsedType(), 
                                                     /*EnteringContext=*/false, 
-                                                    Template);
+                                                    Template,
+                                                MemberOfUnknownSpecialization);
       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. 
@@ -937,7 +966,8 @@
     if (TypeArg.isInvalid())
       return ParsedTemplateArgument();
     
-    return ParsedTemplateArgument(ParsedTemplateArgument::Type, TypeArg.get(), 
+    return ParsedTemplateArgument(ParsedTemplateArgument::Type,
+                                  TypeArg.get().getAsOpaquePtr(), 
                                   Loc);
   }
   
@@ -958,7 +988,7 @@
   
   // Parse a non-type template argument. 
   SourceLocation Loc = Tok.getLocation();
-  OwningExprResult ExprArg = ParseConstantExpression();
+  ExprResult ExprArg = ParseConstantExpression();
   if (ExprArg.isInvalid() || !ExprArg.get())
     return ParsedTemplateArgument();
 
@@ -966,6 +996,37 @@
                                 ExprArg.release(), Loc);
 }
 
+/// \brief Determine whether the current tokens can only be parsed as a 
+/// template argument list (starting with the '<') and never as a '<' 
+/// expression.
+bool Parser::IsTemplateArgumentList(unsigned Skip) {
+  struct AlwaysRevertAction : TentativeParsingAction {
+    AlwaysRevertAction(Parser &P) : TentativeParsingAction(P) { }
+    ~AlwaysRevertAction() { Revert(); }
+  } Tentative(*this);
+  
+  while (Skip) {
+    ConsumeToken();
+    --Skip;
+  }
+  
+  // '<'
+  if (!Tok.is(tok::less))
+    return false;
+  ConsumeToken();
+
+  // An empty template argument list.
+  if (Tok.is(tok::greater))
+    return true;
+  
+  // See whether we have declaration specifiers, which indicate a type.
+  while (isCXXDeclarationSpecifier() == TPResult::True())
+    ConsumeToken();
+  
+  // If we have a '>' or a ',' then this is a template argument list.
+  return Tok.is(tok::greater) || Tok.is(tok::comma);
+}
+
 /// ParseTemplateArgumentList - Parse a C++ template-argument-list
 /// (C++ [temp.names]). Returns true if there was an error.
 ///
@@ -1002,12 +1063,15 @@
 ///         '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) {
+Decl *Parser::ParseExplicitInstantiation(SourceLocation ExternLoc,
+                                         SourceLocation TemplateLoc,
+                                         SourceLocation &DeclEnd) {
+  // This isn't really required here.
+  ParsingDeclRAIIObject ParsingTemplateParams(*this);
+
   return ParseSingleDeclarationAfterTemplate(Declarator::FileContext,
                                              ParsedTemplateInfo(ExternLoc,
                                                                 TemplateLoc),
+                                             ParsingTemplateParams,
                                              DeclEnd, AS_none);
 }
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index 516a9a6..dcf1d40 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -14,6 +14,7 @@
 
 #include "clang/Parse/Parser.h"
 #include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Sema/ParsedTemplate.h"
 using namespace clang;
 
 /// isCXXDeclarationStatement - C++-specialized function that disambiguates
@@ -171,14 +172,6 @@
 ///   '{' '}'
 ///
 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*/);
@@ -196,14 +189,15 @@
       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.
+      // MSVC and g++ won't examine the rest of declarators if '=' is 
+      // encountered; they just conclude that we have a declaration.
+      // EDG parses the initializer completely, which is the proper behavior
+      // for this case.
       //
-      // Parse through the initializer-clause.
-      SkipUntil(tok::comma, true/*StopAtSemi*/, true/*DontConsume*/);
+      // At present, Clang follows MSVC and g++, since the parser does not have
+      // the ability to parse an expression fully without recording the
+      // results of that parse.
+      return TPResult::True();
     }
 
     if (Tok.isNot(tok::comma))
@@ -752,6 +746,7 @@
   case tok::kw___cdecl:
   case tok::kw___stdcall:
   case tok::kw___fastcall:
+  case tok::kw___thiscall:
   case tok::kw___w64:
   case tok::kw___ptr64:
   case tok::kw___forceinline:
@@ -761,6 +756,17 @@
   case tok::kw___vector:
     return TPResult::True();
 
+  case tok::annot_template_id: {
+    TemplateIdAnnotation *TemplateId
+      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+    if (TemplateId->Kind != TNK_Type_template)
+      return TPResult::False();
+    CXXScopeSpec SS;
+    AnnotateTemplateIdTokenAsType(&SS);
+    assert(Tok.is(tok::annot_typename));
+    goto case_typename;
+  }
+
   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())
@@ -801,6 +807,7 @@
   case tok::kw_double:
   case tok::kw_void:
   case tok::annot_typename:
+  case_typename:
     if (NextToken().is(tok::l_paren))
       return TPResult::Ambiguous();
 
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 6dbb99e..5405343 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -13,38 +13,45 @@
 
 #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 "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ParsedTemplate.h"
 #include "llvm/Support/raw_ostream.h"
 #include "RAIIObjectsForParser.h"
 #include "ParsePragma.h"
 using namespace clang;
 
-Parser::Parser(Preprocessor &pp, Action &actions)
+Parser::Parser(Preprocessor &pp, Sema &actions)
   : CrashInfo(*this), PP(pp), Actions(actions), Diags(PP.getDiagnostics()),
     GreaterThanIsOperator(true), ColonIsSacred(false),
     TemplateParameterDepth(0) {
   Tok.setKind(tok::eof);
-  CurScope = 0;
+  Actions.CurScope = 0;
   NumCachedScopes = 0;
   ParenCount = BracketCount = BraceCount = 0;
-  ObjCImpDecl = DeclPtrTy();
+  ObjCImpDecl = 0;
 
   // 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());
+  AlignHandler.reset(new PragmaAlignHandler(actions));
+  PP.AddPragmaHandler(AlignHandler.get());
 
-  UnusedHandler.reset(new
-          PragmaUnusedHandler(&PP.getIdentifierTable().get("unused"), actions,
-                              *this));
-  PP.AddPragmaHandler(0, UnusedHandler.get());
+  GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler(actions));
+  PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
 
-  WeakHandler.reset(new
-          PragmaWeakHandler(&PP.getIdentifierTable().get("weak"), actions));
-  PP.AddPragmaHandler(0, WeakHandler.get());
+  OptionsHandler.reset(new PragmaOptionsHandler(actions));
+  PP.AddPragmaHandler(OptionsHandler.get());
+
+  PackHandler.reset(new PragmaPackHandler(actions));
+  PP.AddPragmaHandler(PackHandler.get());
+
+  UnusedHandler.reset(new PragmaUnusedHandler(actions, *this));
+  PP.AddPragmaHandler(UnusedHandler.get());
+
+  WeakHandler.reset(new PragmaWeakHandler(actions));
+  PP.AddPragmaHandler(WeakHandler.get());
+      
+  PP.setCodeCompletionHandler(*this);
 }
 
 /// If a crash happens while the parser is active, print out a line indicating
@@ -134,7 +141,7 @@
 /// returned.
 bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
                               const char *Msg, tok::TokenKind SkipToTok) {
-  if (Tok.is(ExpectedTok)) {
+  if (Tok.is(ExpectedTok) || Tok.is(tok::code_completion)) {
     ConsumeAnyToken();
     return false;
   }
@@ -189,7 +196,11 @@
     case tok::eof:
       // Ran out of tokens.
       return false;
-
+        
+    case tok::code_completion:
+      ConsumeToken();
+      return false;
+        
     case tok::l_paren:
       // Recursively skip properly-nested parens.
       ConsumeParen();
@@ -252,25 +263,25 @@
 void Parser::EnterScope(unsigned ScopeFlags) {
   if (NumCachedScopes) {
     Scope *N = ScopeCache[--NumCachedScopes];
-    N->Init(CurScope, ScopeFlags);
-    CurScope = N;
+    N->Init(getCurScope(), ScopeFlags);
+    Actions.CurScope = N;
   } else {
-    CurScope = new Scope(CurScope, ScopeFlags);
+    Actions.CurScope = new Scope(getCurScope(), ScopeFlags);
   }
-  CurScope->setNumErrorsAtStart(Diags.getNumErrors());
+  getCurScope()->setNumErrorsAtStart(Diags.getNumErrors());
 }
 
 /// ExitScope - Pop a scope off the scope stack.
 void Parser::ExitScope() {
-  assert(CurScope && "Scope imbalance!");
+  assert(getCurScope() && "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);
+  if (!getCurScope()->decl_empty())
+    Actions.ActOnPopScope(Tok.getLocation(), getCurScope());
 
-  Scope *OldScope = CurScope;
-  CurScope = OldScope->getParent();
+  Scope *OldScope = getCurScope();
+  Actions.CurScope = OldScope->getParent();
 
   if (NumCachedScopes == ScopeCacheSize)
     delete OldScope;
@@ -287,32 +298,40 @@
 
 Parser::~Parser() {
   // If we still have scopes active, delete the scope tree.
-  delete CurScope;
-
+  delete getCurScope();
+  Actions.CurScope = 0;
+  
   // 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());
+  PP.RemovePragmaHandler(AlignHandler.get());
+  AlignHandler.reset();
+  PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
+  GCCVisibilityHandler.reset();
+  PP.RemovePragmaHandler(OptionsHandler.get());
+  OptionsHandler.reset();
+  PP.RemovePragmaHandler(PackHandler.get());
   PackHandler.reset();
-  PP.RemovePragmaHandler(0, UnusedHandler.get());
+  PP.RemovePragmaHandler(UnusedHandler.get());
   UnusedHandler.reset();
-  PP.RemovePragmaHandler(0, WeakHandler.get());
+  PP.RemovePragmaHandler(WeakHandler.get());
   WeakHandler.reset();
+  PP.clearCodeCompletionHandler();
 }
 
 /// Initialize - Warm up the parser.
 ///
 void Parser::Initialize() {
+  // Create the translation unit scope.  Install it as the current scope.
+  assert(getCurScope() == 0 && "A scope is already active?");
+  EnterScope(Scope::DeclScope);
+  Actions.ActOnTranslationUnitScope(getCurScope());
+
   // 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);
@@ -364,7 +383,7 @@
     /*parse them all*/;
 
   ExitScope();
-  assert(CurScope == 0 && "Scope imbalance!");
+  assert(getCurScope() == 0 && "Scope imbalance!");
 }
 
 /// ParseExternalDeclaration:
@@ -389,8 +408,11 @@
 ///           ';'
 ///
 /// [C++0x/GNU] 'extern' 'template' declaration
-Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr) {
-  DeclPtrTy SingleDecl;
+Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
+                                                        ParsingDeclSpec *DS) {
+  ParenBraceBracketBalancer BalancerRAIIObj(*this);
+  
+  Decl *SingleDecl = 0;
   switch (Tok.getKind()) {
   case tok::semi:
     if (!getLang().CPlusPlus0x)
@@ -418,14 +440,14 @@
       Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
         << Attr.Range;
 
-    OwningExprResult Result(ParseSimpleAsm());
+    ExprResult 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));
+    SingleDecl = Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), Result.get());
     break;
   }
   case tok::at:
@@ -444,10 +466,10 @@
     SingleDecl = ParseObjCMethodDefinition();
     break;
   case tok::code_completion:
-      Actions.CodeCompleteOrdinaryName(CurScope, 
-                                   ObjCImpDecl? Action::CCC_ObjCImplementation
-                                              : Action::CCC_Namespace);
-    ConsumeToken();
+      Actions.CodeCompleteOrdinaryName(getCurScope(), 
+                                   ObjCImpDecl? Sema::PCC_ObjCImplementation
+                                              : Sema::PCC_Namespace);
+    ConsumeCodeCompletionToken();
     return ParseExternalDeclaration(Attr);
   case tok::kw_using:
   case tok::kw_namespace:
@@ -460,6 +482,15 @@
       SourceLocation DeclEnd;
       return ParseDeclaration(Declarator::FileContext, DeclEnd, Attr);
     }
+
+  case tok::kw_inline:
+    if (getLang().CPlusPlus0x && NextToken().is(tok::kw_namespace)) {
+      // Inline namespaces
+      SourceLocation DeclEnd;
+      return ParseDeclaration(Declarator::FileContext, DeclEnd, Attr);
+    }
+    goto dont_know;
+
   case tok::kw_extern:
     if (getLang().CPlusPlus && NextToken().is(tok::kw_template)) {
       // Extern templates
@@ -469,14 +500,16 @@
       return Actions.ConvertDeclToDeclGroup(
                   ParseExplicitInstantiation(ExternLoc, TemplateLoc, DeclEnd));
     }
-
     // FIXME: Detect C++ linkage specifications here?
-
-    // Fall through to handle other declarations or function definitions.
+    goto dont_know;
 
   default:
+  dont_know:
     // We can't tell whether this is a function-definition or declaration yet.
-    return ParseDeclarationOrFunctionDefinition(Attr.AttrList);
+    if (DS)
+      return ParseDeclarationOrFunctionDefinition(*DS, Attr.AttrList);
+    else
+      return ParseDeclarationOrFunctionDefinition(Attr.AttrList);
   }
 
   // This routine returns a DeclGroup, if the thing we parsed only contains a
@@ -486,7 +519,7 @@
 
 /// \brief Determine whether the current token, if it occurs after a
 /// declarator, continues a declaration or declaration list.
-bool Parser::isDeclarationAfterDeclarator() {
+bool Parser::isDeclarationAfterDeclarator() const {
   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
@@ -498,12 +531,17 @@
 
 /// \brief Determine whether the current token, if it occurs after a
 /// declarator, indicates the start of a function definition.
-bool Parser::isStartOfFunctionDefinition() {
+bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) {
+  assert(Declarator.getTypeObject(0).Kind == DeclaratorChunk::Function &&
+         "Isn't a function declarator");
   if (Tok.is(tok::l_brace))   // int X() {}
     return true;
   
-  if (!getLang().CPlusPlus)
-    return isDeclarationSpecifier();   // int X(f) int f; {}
+  // Handle K&R C argument lists: int X(f) int f; {}
+  if (!getLang().CPlusPlus &&
+      Declarator.getTypeObject(0).Fun.isKNRPrototype()) 
+    return isDeclarationSpecifier();
+  
   return Tok.is(tok::colon) ||         // X() : Base() {} (used for ctors)
          Tok.is(tok::kw_try);          // X() try { ... }
 }
@@ -538,7 +576,7 @@
   // declaration-specifiers init-declarator-list[opt] ';'
   if (Tok.is(tok::semi)) {
     ConsumeToken();
-    DeclPtrTy TheDecl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
+    Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS);
     DS.complete(TheDecl);
     return Actions.ConvertDeclToDeclGroup(TheDecl);
   }
@@ -562,7 +600,7 @@
     if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec, DiagID))
       Diag(AtLoc, DiagID) << PrevSpec;
 
-    DeclPtrTy TheDecl;
+    Decl *TheDecl = 0;
     if (Tok.isObjCAtKeyword(tok::objc_protocol))
       TheDecl = ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());
     else
@@ -576,7 +614,7 @@
   if (Tok.is(tok::string_literal) && getLang().CPlusPlus &&
       DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
       DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) {
-    DeclPtrTy TheDecl = ParseLinkage(DS, Declarator::FileContext);
+    Decl *TheDecl = ParseLinkage(DS, Declarator::FileContext);
     return Actions.ConvertDeclToDeclGroup(TheDecl);
   }
 
@@ -604,7 +642,7 @@
 /// [C++] function-definition: [C++ 8.4]
 ///         decl-specifier-seq[opt] declarator function-try-block
 ///
-Parser::DeclPtrTy Parser::ParseFunctionDefinition(ParsingDeclarator &D,
+Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
                                      const ParsedTemplateInfo &TemplateInfo) {
   const DeclaratorChunk &FnTypeInfo = D.getTypeObject(0);
   assert(FnTypeInfo.Kind == DeclaratorChunk::Function &&
@@ -626,7 +664,7 @@
   // 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)
+  if (FTI.isKNRPrototype())
     ParseKNRParamDeclarations(D);
 
   // We should have either an opening brace or, in a C++ constructor,
@@ -640,7 +678,7 @@
 
     // If we didn't find the '{', bail out.
     if (Tok.isNot(tok::l_brace))
-      return DeclPtrTy();
+      return 0;
   }
 
   // Enter a scope for the function body.
@@ -648,13 +686,13 @@
 
   // 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,
+  Decl *Res = TemplateInfo.TemplateParams?
+      Actions.ActOnStartOfFunctionTemplateDef(getCurScope(),
+                              MultiTemplateParamsArg(Actions,
                                           TemplateInfo.TemplateParams->data(),
                                          TemplateInfo.TemplateParams->size()),
                                               D)
-    : Actions.ActOnStartOfFunctionDef(CurScope, D);
+    : Actions.ActOnStartOfFunctionDef(getCurScope(), D);
 
   // Break out of the ParsingDeclarator context before we parse the body.
   D.complete(Res);
@@ -673,7 +711,7 @@
 
     // Recover from error.
     if (!Tok.is(tok::l_brace)) {
-      Actions.ActOnFinishFunctionBody(Res, Action::StmtArg(Actions));
+      Actions.ActOnFinishFunctionBody(Res, 0);
       return Res;
     }
   } else
@@ -739,8 +777,8 @@
       }
 
       // Ask the actions module to compute the type for this declarator.
-      Action::DeclPtrTy Param =
-        Actions.ActOnParamDeclarator(CurScope, ParmDeclarator);
+      Decl *Param =
+        Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator);
 
       if (Param &&
           // A missing identifier has already been diagnosed.
@@ -796,7 +834,7 @@
   }
 
   // The actions module must verify that all arguments were declared.
-  Actions.ActOnFinishKNRParamDeclarations(CurScope, D, Tok.getLocation());
+  Actions.ActOnFinishKNRParamDeclarations(getCurScope(), D, Tok.getLocation());
 }
 
 
@@ -806,13 +844,13 @@
 /// [GNU] asm-string-literal:
 ///         string-literal
 ///
-Parser::OwningExprResult Parser::ParseAsmStringLiteral() {
+Parser::ExprResult Parser::ParseAsmStringLiteral() {
   if (!isTokenStringLiteral()) {
     Diag(Tok, diag::err_expected_string_literal);
     return ExprError();
   }
 
-  OwningExprResult Res(ParseStringLiteralExpression());
+  ExprResult Res(ParseStringLiteralExpression());
   if (Res.isInvalid()) return move(Res);
 
   // TODO: Diagnose: wide string literal in 'asm'
@@ -825,7 +863,7 @@
 /// [GNU] simple-asm-expr:
 ///         'asm' '(' asm-string-literal ')'
 ///
-Parser::OwningExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) {
+Parser::ExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) {
   assert(Tok.is(tok::kw_asm) && "Not an asm!");
   SourceLocation Loc = ConsumeToken();
 
@@ -846,7 +884,7 @@
 
   Loc = ConsumeParen();
 
-  OwningExprResult Result(ParseAsmStringLiteral());
+  ExprResult Result(ParseAsmStringLiteral());
 
   if (Result.isInvalid()) {
     SkipUntil(tok::r_paren, true, true);
@@ -898,7 +936,7 @@
     //            simple-template-id
     SourceLocation TypenameLoc = ConsumeToken();
     CXXScopeSpec SS;
-    if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false))
+    if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/ParsedType(), false))
       return true;
     if (!SS.isSet()) {
       Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);
@@ -908,7 +946,8 @@
     TypeResult Ty;
     if (Tok.is(tok::identifier)) {
       // FIXME: check whether the next token is '<', first!
-      Ty = Actions.ActOnTypenameType(TypenameLoc, SS, *Tok.getIdentifierInfo(),
+      Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS, 
+                                     *Tok.getIdentifierInfo(),
                                      Tok.getLocation());
     } else if (Tok.is(tok::annot_template_id)) {
       TemplateIdAnnotation *TemplateId
@@ -923,8 +962,9 @@
       assert(Tok.is(tok::annot_typename) &&
              "AnnotateTemplateIdTokenAsType isn't working properly");
       if (Tok.getAnnotationValue())
-        Ty = Actions.ActOnTypenameType(TypenameLoc, SS, SourceLocation(),
-                                       Tok.getAnnotationValue());
+        Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS, 
+                                       SourceLocation(),
+                                       getTypeAnnotation(Tok));
       else
         Ty = true;
     } else {
@@ -935,7 +975,7 @@
 
     SourceLocation EndLoc = Tok.getLastLoc();
     Tok.setKind(tok::annot_typename);
-    Tok.setAnnotationValue(Ty.isInvalid()? 0 : Ty.get());
+    setTypeAnnotation(Tok, Ty.isInvalid() ? ParsedType() : Ty.get());
     Tok.setAnnotationEndLoc(EndLoc);
     Tok.setLocation(TypenameLoc);
     PP.AnnotateCachedTokens(Tok);
@@ -947,17 +987,18 @@
 
   CXXScopeSpec SS;
   if (getLang().CPlusPlus)
-    if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext))
+    if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 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)) {
+    if (ParsedType Ty = Actions.getTypeName(*Tok.getIdentifierInfo(),
+                                            Tok.getLocation(), getCurScope(),
+                                            &SS)) {
       // This is a typename. Replace the current token in-place with an
       // annotation type token.
       Tok.setKind(tok::annot_typename);
-      Tok.setAnnotationValue(Ty);
+      setTypeAnnotation(Tok, Ty);
       Tok.setAnnotationEndLoc(Tok.getLocation());
       if (SS.isNotEmpty()) // it was a C++ qualified type name.
         Tok.setLocation(SS.getBeginLoc());
@@ -980,10 +1021,13 @@
       TemplateTy Template;
       UnqualifiedId TemplateName;
       TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
+      bool MemberOfUnknownSpecialization;
       if (TemplateNameKind TNK
-            = Actions.isTemplateName(CurScope, SS, TemplateName, 
-                                     /*ObjectType=*/0, EnteringContext,
-                                     Template)) {
+          = Actions.isTemplateName(getCurScope(), SS,
+                                   /*hasTemplateKeyword=*/false, TemplateName,
+                                   /*ObjectType=*/ ParsedType(),
+                                   EnteringContext,
+                                   Template, MemberOfUnknownSpecialization)) {
         // Consume the identifier.
         ConsumeToken();
         if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName)) {
@@ -1050,7 +1094,7 @@
          "Cannot be a type or scope token!");
 
   CXXScopeSpec SS;
-  if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext))
+  if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext))
     return true;
   if (SS.isEmpty())
     return false;
@@ -1071,9 +1115,54 @@
   return false;
 }
 
+void Parser::CodeCompletionRecovery() {
+  for (Scope *S = getCurScope(); S; S = S->getParent()) {
+    if (S->getFlags() & Scope::FnScope) {
+      Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_RecoveryInFunction);
+      return;
+    }
+    
+    if (S->getFlags() & Scope::ClassScope) {
+      Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Class);
+      return;
+    }
+  }
+  
+  Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Namespace);
+}
+
 // 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() {
 }
+
+// Code-completion pass-through functions
+
+void Parser::CodeCompleteDirective(bool InConditional) {
+  Actions.CodeCompletePreprocessorDirective(InConditional);
+}
+
+void Parser::CodeCompleteInConditionalExclusion() {
+  Actions.CodeCompleteInPreprocessorConditionalExclusion(getCurScope());
+}
+
+void Parser::CodeCompleteMacroName(bool IsDefinition) {
+  Actions.CodeCompletePreprocessorMacroName(IsDefinition);
+}
+
+void Parser::CodeCompletePreprocessorExpression() { 
+  Actions.CodeCompletePreprocessorExpression();
+}
+
+void Parser::CodeCompleteMacroArgument(IdentifierInfo *Macro,
+                                       MacroInfo *MacroInfo,
+                                       unsigned ArgumentIndex) {
+  Actions.CodeCompletePreprocessorMacroArgument(getCurScope(), Macro, MacroInfo, 
+                                                ArgumentIndex);
+}
+
+void Parser::CodeCompleteNaturalLanguage() {
+  Actions.CodeCompleteNaturalLanguage();
+}
diff --git a/lib/Parse/RAIIObjectsForParser.h b/lib/Parse/RAIIObjectsForParser.h
index 06bbbc2..addc795 100644
--- a/lib/Parse/RAIIObjectsForParser.h
+++ b/lib/Parse/RAIIObjectsForParser.h
@@ -80,6 +80,23 @@
     }
   };
   
+  /// \brief RAII object that makes sure paren/bracket/brace count is correct
+  /// after declaration/statement parsing, even when there's a parsing error.
+  class ParenBraceBracketBalancer {
+    Parser &P;
+    unsigned short ParenCount, BracketCount, BraceCount;
+  public:
+    ParenBraceBracketBalancer(Parser &p)
+      : P(p), ParenCount(p.ParenCount), BracketCount(p.BracketCount),
+        BraceCount(p.BraceCount) { }
+    
+    ~ParenBraceBracketBalancer() {
+      P.ParenCount = ParenCount;
+      P.BracketCount = BracketCount;
+      P.BraceCount = BraceCount;
+    }
+  };
+  
 } // end namespace clang
 
 #endif
diff --git a/lib/Rewrite/CMakeLists.txt b/lib/Rewrite/CMakeLists.txt
index ce9e1ed..ce728af 100644
--- a/lib/Rewrite/CMakeLists.txt
+++ b/lib/Rewrite/CMakeLists.txt
@@ -2,8 +2,14 @@
 
 add_clang_library(clangRewrite
   DeltaTree.cpp
+  FixItRewriter.cpp
+  FrontendActions.cpp
+  HTMLPrint.cpp
   HTMLRewrite.cpp
+  RewriteMacros.cpp
+  RewriteObjC.cpp
   RewriteRope.cpp
+  RewriteTest.cpp
   Rewriter.cpp
   TokenRewriter.cpp
   )
diff --git a/lib/Rewrite/FixItRewriter.cpp b/lib/Rewrite/FixItRewriter.cpp
new file mode 100644
index 0000000..5820969
--- /dev/null
+++ b/lib/Rewrite/FixItRewriter.cpp
@@ -0,0 +1,156 @@
+//===--- 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/Rewrite/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,
+                             FixItOptions *FixItOpts)
+  : Diags(Diags),
+    Rewrite(SourceMgr, LangOpts),
+    FixItOpts(FixItOpts),
+    NumFailures(0) {
+  Client = Diags.takeClient();
+  Diags.setClient(this);
+}
+
+FixItRewriter::~FixItRewriter() {
+  Diags.takeClient();
+  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 && !FixItOpts->FixWhatYouCan) {
+    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 = FixItOpts->RewriteFilename(Entry->getName());
+    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 (!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.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.takeClient();
+  Diags.setClient(Client);
+  Diags.Clear();
+  Diags.Report(Loc, DiagID);
+  Diags.takeClient();
+  Diags.setClient(this);
+}
+
+FixItOptions::~FixItOptions() {}
diff --git a/lib/Rewrite/FrontendActions.cpp b/lib/Rewrite/FrontendActions.cpp
new file mode 100644
index 0000000..977e0cf
--- /dev/null
+++ b/lib/Rewrite/FrontendActions.cpp
@@ -0,0 +1,115 @@
+//===--- 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/Rewrite/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/CompilerInstance.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/Utils.h"
+#include "clang/Rewrite/ASTConsumers.h"
+#include "clang/Rewrite/FixItRewriter.h"
+#include "clang/Rewrite/Rewriters.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+ASTConsumer *HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI,
+                                                llvm::StringRef InFile) {
+  if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
+    return CreateHTMLPrinter(OS, CI.getPreprocessor());
+  return 0;
+}
+
+FixItAction::FixItAction() {}
+FixItAction::~FixItAction() {}
+
+ASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI,
+                                            llvm::StringRef InFile) {
+  return new ASTConsumer();
+}
+
+class FixItRewriteInPlace : public FixItOptions {
+public:
+  std::string RewriteFilename(const std::string &Filename) { return Filename; }
+};
+
+class FixItActionSuffixInserter : public FixItOptions {
+  std::string NewSuffix;
+
+public:
+  FixItActionSuffixInserter(std::string NewSuffix, bool FixWhatYouCan)
+    : NewSuffix(NewSuffix) {
+      this->FixWhatYouCan = FixWhatYouCan;
+  }
+
+  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()) {
+    FixItOpts.reset(new FixItActionSuffixInserter(FEOpts.FixItSuffix,
+                                                  FEOpts.FixWhatYouCan));
+  } else {
+    FixItOpts.reset(new FixItRewriteInPlace);
+    FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan;
+  }
+  Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(),
+                                   CI.getLangOpts(), FixItOpts.get()));
+  return true;
+}
+
+void FixItAction::EndSourceFileAction() {
+  // Otherwise rewrite all files.
+  Rewriter->WriteFixedFiles();
+}
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Actions
+//===----------------------------------------------------------------------===//
+
+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;
+}
+
+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/Rewrite/HTMLPrint.cpp b/lib/Rewrite/HTMLPrint.cpp
new file mode 100644
index 0000000..f66bfcb
--- /dev/null
+++ b/lib/Rewrite/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/Rewrite/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/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp
index 5fe0649..b461df4 100644
--- a/lib/Rewrite/HTMLRewrite.cpp
+++ b/lib/Rewrite/HTMLRewrite.cpp
@@ -486,8 +486,7 @@
 
   // Temporarily change the diagnostics object so that we ignore any generated
   // diagnostics from this pass.
-  IgnoringDiagClient TmpDC;
-  Diagnostic TmpDiags(&TmpDC);
+  Diagnostic TmpDiags(new IgnoringDiagClient);
 
   // 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
diff --git a/lib/Rewrite/Makefile b/lib/Rewrite/Makefile
index 04c3530..5fef9b2 100644
--- a/lib/Rewrite/Makefile
+++ b/lib/Rewrite/Makefile
@@ -11,11 +11,8 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
+CLANG_LEVEL := ../..
 LIBRARYNAME := clangRewrite
-BUILD_ARCHIVE = 1
 
-CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
 
diff --git a/lib/Rewrite/RewriteMacros.cpp b/lib/Rewrite/RewriteMacros.cpp
new file mode 100644
index 0000000..910fa6b
--- /dev/null
+++ b/lib/Rewrite/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/Rewrite/Rewriters.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/Rewrite/RewriteObjC.cpp b/lib/Rewrite/RewriteObjC.cpp
new file mode 100644
index 0000000..4a7de4b
--- /dev/null
+++ b/lib/Rewrite/RewriteObjC.cpp
@@ -0,0 +1,5734 @@
+//===--- 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/Rewrite/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 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 RewriteInclude();
+    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 RewriteBlockPointerType(std::string& Str, QualType Type);
+    void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD);
+    void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
+    void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
+    void RewriteTypeOfDecl(VarDecl *VD);
+    void RewriteObjCQualifiedInterfaceTypes(Expr *E);
+    bool needToScanForQualifiers(QualType T);
+    QualType getSuperStructType();
+    QualType getConstantStringStructType();
+    QualType convertFunctionTypeOfBlocks(const FunctionType *FT);
+    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 *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,
+                                    llvm::StringRef prefix,
+                                    llvm::StringRef ClassName,
+                                    std::string &Result);
+
+    void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
+                                     llvm::StringRef prefix,
+                                     llvm::StringRef ClassName,
+                                     std::string &Result);
+    void RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Prots,
+                                         llvm::StringRef prefix,
+                                         llvm::StringRef 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 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,
+                                      llvm::StringRef funcName, std::string Tag);
+    std::string SynthesizeBlockFunc(BlockExpr *CE, int i,
+                                      llvm::StringRef 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, llvm::StringRef funcName,
+                                          unsigned hasCopy);
+    Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp);
+    void SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                 llvm::StringRef 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);
+    }
+
+    /// convertBlockPointerToFunctionPointer - Converts a block-pointer type
+    /// to a function pointer type and upon success, returns true; false
+    /// otherwise.
+    bool convertBlockPointerToFunctionPointer(QualType &T) {
+      if (isTopLevelBlockPointerType(T)) {
+        const BlockPointerType *BPT = T->getAs<BlockPointerType>();
+        T = Context->getPointerType(BPT->getPointeeType());
+        return true;
+      }
+      return false;
+    }
+    
+    // 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(llvm::StringRef 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,
+                                           CastKind Kind, Expr *E) {
+    TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
+    return CStyleCastExpr::Create(*Ctx, Ty, Kind, E, 0, 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 (FVD->getName() == "_NSConstantStringClassReference") {
+      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;
+      }
+    }
+  }
+}
+
+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(
+            Context->PrintingPolicy);
+          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->getName();
+    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->getName();
+  }
+  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(), 
+              strlen("@end"), "/* @end */");
+}
+
+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, strlen("@end"), "/* @end */");
+
+  // 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(
+        Context->PrintingPolicy);
+      ResultStr += "(*";
+    }
+  } else
+    ResultStr += T.getAsString(Context->PrintingPolicy);
+}
+
+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(
+      Context->PrintingPolicy);
+
+  ResultStr += " self, ";
+  ResultStr += Context->getObjCSelType().getAsString(Context->PrintingPolicy);
+  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();
+      QualType QT = PDecl->getType();
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      if (convertBlockPointerToFunctionPointer(QT))
+        QT.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(
+          Context->PrintingPolicy);
+        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(), strlen("@end"), 
+              "/* @end */");
+}
+
+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, TTK_Struct, TUDecl,
+                                          SourceLocation(), II);
+      assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT,
+                                                    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, TTK_Struct, TUDecl,
+                                          SourceLocation(), II);
+      assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT,
+                                                    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);
+  llvm::StringRef 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(Context->PrintingPolicy);
+    buf += elementTypeAsString;
+    buf += " ";
+    elementName = D->getName();
+    buf += elementName;
+    buf += ";\n\t";
+  }
+  else {
+    DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
+    elementName = DR->getDecl()->getName();
+    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(Context->PrintingPolicy);
+  }
+
+  // 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(),
+                                            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 (const ObjCObjectPointerType *Ptr =
+                   t->getAs<ObjCObjectPointerType>()) {
+        // Should be a pointer to a class.
+        ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
+        if (IDecl) {
+          buf += "objc_exception_match((struct objc_class *)objc_getClass(\"";
+          buf += IDecl->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;
+}
+
+// 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 = 
+    ImplicitCastExpr::Create(*Context, pToFunc, CK_Unknown,
+                             DRE, 0, VK_RValue);
+
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+
+  CallExpr *Exp =  
+    new (Context) CallExpr(*Context, ICE, args, nargs, 
+                           FT->getCallResultType(*Context), 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(Context->PrintingPolicy));
+  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,
+                                           SC_Extern,
+                                           SC_None, false);
+}
+
+void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
+  // declared in <objc/objc.h>
+  if (FD->getIdentifier() &&
+      FD->getName() == "sel_registerName") {
+    SelGetUidFunctionDecl = FD;
+    return;
+  }
+  RewriteObjCQualifiedInterfaceTypes(FD);
+}
+
+void RewriteObjC::RewriteBlockPointerType(std::string& Str, QualType Type) {
+  std::string TypeString(Type.getAsString(Context->PrintingPolicy));
+  const char *argPtr = TypeString.c_str();
+  if (!strchr(argPtr, '^')) {
+    Str += TypeString;
+    return;
+  }
+  while (*argPtr) {
+    Str += (*argPtr == '^' ? '*' : *argPtr);
+    argPtr++;
+  }
+}
+
+// FIXME. Consolidate this routine with RewriteBlockPointerType.
+void RewriteObjC::RewriteBlockPointerTypeVariable(std::string& Str,
+                                                  ValueDecl *VD) {
+  QualType Type = VD->getType();
+  std::string TypeString(Type.getAsString(Context->PrintingPolicy));
+  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(Context->PrintingPolicy);
+  FdStr += " ";
+  FdStr += FD->getName();
+  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,
+                                         SC_Extern,
+                                         SC_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,
+                                         SC_Extern,
+                                         SC_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, TTK_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,
+                                              SC_Extern,
+                                              SC_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,
+                                         SC_Extern,
+                                         SC_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, TTK_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,
+                                              SC_Extern,
+                                              SC_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,
+                                              SC_Extern,
+                                              SC_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,
+                                          SC_Extern,
+                                          SC_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,
+                                                   SC_Extern,
+                                                   SC_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,
+                                              SC_Extern,
+                                              SC_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,
+                                    SC_Static, SC_None);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, SourceLocation());
+  Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
+                                 Context->getPointerType(DRE->getType()),
+                                 SourceLocation());
+  // cast to NSConstantString *
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
+                                            CK_Unknown, Unop);
+  ReplaceStmt(Exp, cast);
+  // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
+  return cast;
+}
+
+// struct objc_super { struct objc_object *receiver; struct objc_class *super; };
+QualType RewriteObjC::getSuperStructType() {
+  if (!SuperStructDecl) {
+    SuperStructDecl = RecordDecl::Create(*Context, TTK_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, TTK_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(),
+                               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(),
+                                             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(),
+                                                 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, UO_AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                                          Context->getPointerType(superType),
+                                          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, UO_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<ObjCObjectType>()->getInterface();
+    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(),
+                               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(),
+                                                 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(),
+                               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, UO_AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                               Context->getPointerType(superType),
+                               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(),
+                                       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();
+      // Make sure we convert "type (^)(...)" to "type (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(type);
+      userExpr = NoTypeInfoCStyleCastExpr(Context, type, 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(),
+                                            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 (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(t);
+      ArgTypes.push_back(t);
+    }
+    returnType = OMD->getResultType()->isObjCQualifiedIdType()
+                   ? Context->getObjCIdType() : OMD->getResultType();
+    (void)convertBlockPointerToFunctionPointer(returnType);
+  } 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),
+                                  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, 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),
+                                    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, 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 = IntegerLiteral::Create(*Context,
+                                                   llvm::APInt(IntSize, 8),
+                                                   Context->IntTy,
+                                                   SourceLocation());
+    BinaryOperator *lessThanExpr = new (Context) BinaryOperator(sizeofExpr, limit,
+                                                      BO_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,
+                                SC_Extern, SC_None);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), SourceLocation());
+  Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf,
+                             Context->getPointerType(DRE->getType()),
+                             SourceLocation());
+  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(),
+                                                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->getName() != "" &&
+         "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,
+                                             llvm::StringRef prefix,
+                                             llvm::StringRef 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, llvm::StringRef prefix,
+                            llvm::StringRef 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();
+      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();
+      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,
+                                llvm::StringRef prefix, llvm::StringRef 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, 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->getName(), Result);
+
+  // Build _objc_method_list for class's class methods if needed
+  RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
+                             false, "", IDecl->getName(), Result);
+
+  // Protocols referenced in class declaration?
+  RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(),
+                                  "CLASS", CDecl->getName(), 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,
+                                                   llvm::StringRef funcName,
+                                                   std::string Tag) {
+  const FunctionType *AFT = CE->getFunctionType();
+  QualType RT = AFT->getResultType();
+  std::string StructRef = "struct " + Tag;
+  std::string S = "static " + RT.getAsString(Context->PrintingPolicy) + " __" +
+                  funcName.str() + "_" + "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();
+      QualType QT = (*AI)->getType();
+      if (convertBlockPointerToFunctionPointer(QT))
+        QT.getAsStringInternal(ParamStr, Context->PrintingPolicy);
+      else
+        QT.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,
+                                                   llvm::StringRef 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)";
+    // Initialize all "by copy" arguments.
+    bool firsTime = true;
+    for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+        if (firsTime) {
+          Constructor += " : ";
+          firsTime = false;
+        }
+        else
+          Constructor += ", ";
+        if (isTopLevelBlockPointerType((*I)->getType()))
+          Constructor += Name + "((struct __block_impl *)_" + Name + ")";
+        else
+          Constructor += Name + "(_" + Name + ")";
+    }
+    // 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();
+      if (firsTime) {
+        Constructor += " : ";
+        firsTime = false;
+      }
+      else
+        Constructor += ", ";
+      if (isTopLevelBlockPointerType((*I)->getType()))
+        Constructor += Name + "((struct __block_impl *)_" 
+                        + Name + "->__forwarding)";
+      else
+        Constructor += Name + "(_" + Name + "->__forwarding)";
+    }
+    
+    Constructor += " {\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";
+  } 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,
+                                                   llvm::StringRef 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 += ", __" + FunName.str() + "_block_copy_" + utostr(i);
+    S += ", __" + FunName.str() + "_block_dispose_" + utostr(i);
+  }
+  S += "};\n";
+  return S;
+}
+
+void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                          llvm::StringRef 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() == SC_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 = "__" + FunName.str() + "_block_impl_" + utostr(i);
+    std::string DescTag = "__" + FunName.str() + "_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() == SC_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();
+  llvm::StringRef FuncName = FD->getName();
+
+  SynthesizeBlockLiterals(FunLocStart, FuncName);
+}
+
+static void BuildUniqueMethodName(std::string &Name,
+                                  ObjCMethodDecl *MD) {
+  ObjCInterfaceDecl *IFace = MD->getClassInterface();
+  Name = IFace->getName();
+  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);
+}
+
+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;
+}
+
+/// convertFunctionTypeOfBlocks - This routine converts a function type
+/// whose result type may be a block pointer or whose argument type(s)
+/// might be block pointers to an equivalent funtion type replacing
+/// all block pointers to function pointers.
+QualType RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) {
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
+  // FTP will be null for closures that don't take arguments.
+  // Generate a funky cast.
+  llvm::SmallVector<QualType, 8> ArgTypes;
+  QualType Res = FT->getResultType();
+  bool HasBlockType = convertBlockPointerToFunctionPointer(Res);
+  
+  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 (convertBlockPointerToFunctionPointer(t))
+        HasBlockType = true;
+      ArgTypes.push_back(t);
+    }
+  }
+  QualType FuncType;
+  // FIXME. Does this work if block takes no argument but has a return type
+  // which is of block type?
+  if (HasBlockType)
+    FuncType = Context->getFunctionType(Res,
+                        &ArgTypes[0], ArgTypes.size(), false/*no variadic*/, 0,
+                        false, false, 0, 0, FunctionType::ExtInfo());
+  else FuncType = QualType(FT, 0);
+  return FuncType;
+}
+
+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, TTK_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 (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(t);
+      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,
+                                               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,
+                                                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;
+}
+
+// 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());
+
+  llvm::StringRef Name = VD->getName();
+  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, UO_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 *startInitializerBuf = SM->getCharacterData(startLoc);
+    const char *semiBuf = strchr(startInitializerBuf, ';');
+    assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'");
+    SourceLocation semiLoc =
+      startLoc.getFileLocWithOffset(semiBuf-startInitializerBuf);
+
+    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(llvm::StringRef name) {
+  IdentifierInfo *ID = &Context->Idents.get(name);
+  QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
+  return FunctionDecl::Create(*Context, TUDecl,SourceLocation(),
+                              ID, FType, 0, SC_Extern,
+                              SC_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 BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
+  QualType FType = Context->getPointerType(BFT);
+
+  FunctionDecl *FD;
+  Expr *NewRep;
+
+  // Simulate a contructor call...
+  FD = SynthBlockInitFunctionDecl(Tag);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, FType, SourceLocation());
+
+  llvm::SmallVector<Expr*, 4> InitExprs;
+
+  // Initialize the block function.
+  FD = SynthBlockInitFunctionDecl(Func);
+  DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, FD->getType(),
+                                               SourceLocation());
+  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
+                                                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,
+                                    SC_Static, SC_None);
+  UnaryOperator *DescRefExpr = new (Context) UnaryOperator(
+                                  new (Context) DeclRefExpr(NewVD, 
+                                    Context->VoidPtrTy, SourceLocation()), 
+                                  UO_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)->getName());
+        Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
+        if (HasLocalVariableExternalStorage(*I)) {
+          QualType QT = (*I)->getType();
+          QT = Context->getPointerType(QT);
+          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT,
+                                            SourceLocation());
+        }
+      } else if (isTopLevelBlockPointerType((*I)->getType())) {
+        FD = SynthBlockInitFunctionDecl((*I)->getName());
+        Arg = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
+        Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
+                                       CK_Unknown, Arg);
+      } else {
+        FD = SynthBlockInitFunctionDecl((*I)->getName());
+        Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
+        if (HasLocalVariableExternalStorage(*I)) {
+          QualType QT = (*I)->getType();
+          QT = Context->getPointerType(QT);
+          Exp = new (Context) UnaryOperator(Exp, UO_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, TTK_Struct, TUDecl,
+                                          SourceLocation(), II);
+      assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      
+      FD = SynthBlockInitFunctionDecl((*I)->getName());
+      Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
+      Exp = new (Context) UnaryOperator(Exp, UO_AddrOf,
+                              Context->getPointerType(Exp->getType()),
+                              SourceLocation());
+      Exp = NoTypeInfoCStyleCastExpr(Context, castT, 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 = IntegerLiteral::Create(*Context, 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, UO_AddrOf,
+                             Context->getPointerType(NewRep->getType()),
+                             SourceLocation());
+  NewRep = NoTypeInfoCStyleCastExpr(Context, FType, 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 = dyn_cast_or_null<CompoundStmt>(FD->getBody())) {
+      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->getName());
+      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/Rewrite/RewriteRope.cpp b/lib/Rewrite/RewriteRope.cpp
index fdb6fc3..e290921 100644
--- a/lib/Rewrite/RewriteRope.cpp
+++ b/lib/Rewrite/RewriteRope.cpp
@@ -532,7 +532,7 @@
               (getNumChildren()-i-1)*sizeof(Children[0]));
     Children[i+1] = RHS;
     ++NumChildren;
-    return false;
+    return 0;
   }
 
   // Okay, this node is full.  Split it in half, moving WidthFactor children to
diff --git a/lib/Rewrite/RewriteTest.cpp b/lib/Rewrite/RewriteTest.cpp
new file mode 100644
index 0000000..3620700
--- /dev/null
+++ b/lib/Rewrite/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/Rewrite/Rewriters.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/Rewrite/Rewriter.cpp b/lib/Rewrite/Rewriter.cpp
index 376678a..92e2b03 100644
--- a/lib/Rewrite/Rewriter.cpp
+++ b/lib/Rewrite/Rewriter.cpp
@@ -40,7 +40,7 @@
   AddReplaceDelta(OrigOffset, -Size);
 }
 
-void RewriteBuffer::InsertText(unsigned OrigOffset, const llvm::StringRef &Str,
+void RewriteBuffer::InsertText(unsigned OrigOffset, llvm::StringRef Str,
                                bool InsertAfter) {
 
   // Nothing to insert, exit early.
@@ -57,7 +57,7 @@
 /// buffer with a new string.  This is effectively a combined "remove+insert"
 /// operation.
 void RewriteBuffer::ReplaceText(unsigned OrigOffset, unsigned OrigLength,
-                                const llvm::StringRef &NewStr) {
+                                llvm::StringRef NewStr) {
   unsigned RealOffset = getMappedOffset(OrigOffset, true);
   Buffer.erase(RealOffset, OrigLength);
   Buffer.insert(RealOffset, NewStr.begin(), NewStr.end());
@@ -72,7 +72,7 @@
 
 /// 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 {
+int Rewriter::getRangeSize(const CharSourceRange &Range) const {
   if (!isRewritable(Range.getBegin()) ||
       !isRewritable(Range.getEnd())) return -1;
 
@@ -97,12 +97,18 @@
 
 
   // 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);
+  // start of the last token if this is a token range.
+  if (Range.isTokenRange())
+    EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
 
   return EndOff-StartOff;
 }
 
+int Rewriter::getRangeSize(SourceRange Range) const {
+  return getRangeSize(CharSourceRange::getTokenRange(Range));
+}
+
+
 /// 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.
@@ -179,7 +185,7 @@
 
 /// InsertText - Insert the specified string at the specified location in the
 /// original buffer.
-bool Rewriter::InsertText(SourceLocation Loc, const llvm::StringRef &Str,
+bool Rewriter::InsertText(SourceLocation Loc, llvm::StringRef Str,
                           bool InsertAfter) {
   if (!isRewritable(Loc)) return true;
   FileID FID;
@@ -201,7 +207,7 @@
 /// buffer with a new string.  This is effectively a combined "remove/insert"
 /// operation.
 bool Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength,
-                           const llvm::StringRef &NewStr) {
+                           llvm::StringRef NewStr) {
   if (!isRewritable(Start)) return true;
   FileID StartFileID;
   unsigned StartOffs = getLocationOffsetAndFileID(Start, StartFileID);
diff --git a/lib/Runtime/Makefile b/lib/Runtime/Makefile
deleted file mode 100644
index 9a3c347..0000000
--- a/lib/Runtime/Makefile
+++ /dev/null
@@ -1,99 +0,0 @@
-##===- 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
index 7c1d8cb..cfebed6 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -13,9 +13,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "AnalysisBasedWarnings.h"
+#include "clang/Sema/AnalysisBasedWarnings.h"
+#include "clang/Sema/SemaInternal.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/StmtObjC.h"
@@ -54,8 +56,13 @@
 // Check for missing return value.
 //===----------------------------------------------------------------------===//
 
-enum ControlFlowKind { NeverFallThrough = 0, MaybeFallThrough = 1,
-  AlwaysFallThrough = 2, NeverFallThroughOrReturn = 3 };
+enum ControlFlowKind {
+  UnknownFallThrough,
+  NeverFallThrough,
+  MaybeFallThrough,
+  AlwaysFallThrough,
+  NeverFallThroughOrReturn
+};
 
 /// CheckFallThrough - Check that we don't fall off the end of a
 /// Statement that should return a value.
@@ -68,9 +75,7 @@
 /// will return.
 static ControlFlowKind CheckFallThrough(AnalysisContext &AC) {
   CFG *cfg = AC.getCFG();
-  if (cfg == 0)
-    // FIXME: This should be NeverFallThrough
-    return NeverFallThroughOrReturn;
+  if (cfg == 0) return UnknownFallThrough;
 
   // 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.
@@ -147,7 +152,8 @@
 
     bool NoReturnEdge = false;
     if (CallExpr *C = dyn_cast<CallExpr>(S)) {
-      if (B.succ_begin()[0] != &cfg->getExit()) {
+      if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit())
+            == B.succ_end()) {
         HasAbnormalEdge = true;
         continue;
       }
@@ -163,6 +169,19 @@
         }
       }
     }
+    // FIXME: Remove this hack once temporaries and their destructors are
+    // modeled correctly by the CFG.
+    if (CXXExprWithTemporaries *E = dyn_cast<CXXExprWithTemporaries>(S)) {
+      for (unsigned I = 0, N = E->getNumTemporaries(); I != N; ++I) {
+        const FunctionDecl *FD = E->getTemporary(I)->getDestructor();
+        if (FD->hasAttr<NoReturnAttr>() ||
+            FD->getType()->getAs<FunctionType>()->getNoReturnAttr()) {
+          NoReturnEdge = true;
+          HasFakeEdge = true;
+          break;
+        }
+      }
+    }
     // FIXME: Add noreturn message sends.
     if (NoReturnEdge == false)
       HasPlainEdge = true;
@@ -180,6 +199,8 @@
   return AlwaysFallThrough;
 }
 
+namespace {
+
 struct CheckFallThroughDiagnostics {
   unsigned diag_MaybeFallThrough_HasNoReturn;
   unsigned diag_MaybeFallThrough_ReturnsNonVoid;
@@ -249,6 +270,8 @@
   }
 };
 
+}
+
 /// 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
@@ -289,6 +312,9 @@
   // FIXME: Function try block
   if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) {
     switch (CheckFallThrough(AC)) {
+      case UnknownFallThrough:
+        break;
+
       case MaybeFallThrough:
         if (HasNoReturn)
           S.Diag(Compound->getRBracLoc(),
@@ -344,28 +370,27 @@
   //     don't bother trying.
   // (2) The code already has problems; running the analysis just takes more
   //     time.
-  if (S.getDiagnostics().hasErrorOccurred())
+  Diagnostic &Diags = S.getDiagnostics();
+
+  if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred())
     return;
 
   // Do not do any analysis for declarations in system headers if we are
   // going to just ignore them.
-  if (S.getDiagnostics().getSuppressSystemWarnings() &&
+  if (Diags.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;
-  }
+  // For code in dependent contexts, we'll do this at instantiation time.
+  if (cast<DeclContext>(D)->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);
+  AnalysisContext AC(D, 0, false);
 
   // Warning: check missing 'return'
   if (P.enableCheckFallThrough) {
@@ -379,3 +404,21 @@
   if (P.enableCheckUnreachable)
     CheckUnreachable(S, AC);
 }
+
+void clang::sema::
+AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
+                                     const BlockExpr *E) {
+  return IssueWarnings(P, E->getBlockDecl(), E->getType());
+}
+
+void clang::sema::
+AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
+                                     const ObjCMethodDecl *D) {
+  return IssueWarnings(P, D, QualType());
+}
+
+void clang::sema::
+AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
+                                     const FunctionDecl *D) {
+  return IssueWarnings(P, D, QualType());
+}
diff --git a/lib/Sema/AnalysisBasedWarnings.h b/lib/Sema/AnalysisBasedWarnings.h
deleted file mode 100644
index dea19ba..0000000
--- a/lib/Sema/AnalysisBasedWarnings.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//=- 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
index 60f292e..03f742b 100644
--- a/lib/Sema/Android.mk
+++ b/lib/Sema/Android.mk
@@ -6,17 +6,23 @@
 include $(CLEAR_TBLGEN_VARS)
 
 TBLGEN_TABLES :=    \
+	AttrList.inc	\
+	Attrs.inc	\
+	DeclNodes.inc	\
 	DiagnosticASTKinds.inc	\
 	DiagnosticSemaKinds.inc	\
 	DiagnosticParseKinds.inc	\
-    DiagnosticCommonKinds.inc
+	DiagnosticCommonKinds.inc	\
+	StmtNodes.inc	\
+	arm_neon.inc
 
 clang_sema_SRC_FILES :=	\
 	AnalysisBasedWarnings.cpp	\
+	AttributeList.cpp	\
 	CodeCompleteConsumer.cpp	\
+	DeclSpec.cpp	\
 	IdentifierResolver.cpp	\
 	JumpDiagnostics.cpp	\
-	ParseAST.cpp	\
 	Sema.cpp	\
 	SemaAccess.cpp	\
 	SemaAttr.cpp	\
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp
new file mode 100644
index 0000000..3f34aa6
--- /dev/null
+++ b/lib/Sema/AttributeList.cpp
@@ -0,0 +1,134 @@
+//===--- 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/Sema/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,
+                             Expr **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), Invalid(false) {
+
+  if (numArgs == 0)
+    Args = 0;
+  else {
+    Args = new Expr*[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("iboutletcollection", AT_IBOutletCollection)
+    .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("vecreturn", AT_vecreturn)
+    .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("ownership_returns", AT_ownership_returns)
+    .Case("ownership_holds", AT_ownership_holds)
+    .Case("ownership_takes", AT_ownership_takes)
+    .Case("reqd_work_group_size", AT_reqd_wg_size)
+    .Case("init_priority", AT_init_priority)
+    .Case("no_instrument_function", AT_no_instrument_function)
+    .Case("thiscall", AT_thiscall)
+    .Case("__cdecl", AT_cdecl)
+    .Case("__stdcall", AT_stdcall)
+    .Case("__fastcall", AT_fastcall)
+    .Case("__thiscall", AT_thiscall)
+    .Default(UnknownAttribute);
+}
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt
index ac0dfd6..e65bb22 100644
--- a/lib/Sema/CMakeLists.txt
+++ b/lib/Sema/CMakeLists.txt
@@ -2,10 +2,11 @@
 
 add_clang_library(clangSema
   AnalysisBasedWarnings.cpp
+  AttributeList.cpp
   CodeCompleteConsumer.cpp
+  DeclSpec.cpp
   IdentifierResolver.cpp
   JumpDiagnostics.cpp
-  ParseAST.cpp
   Sema.cpp
   SemaAccess.cpp
   SemaAttr.cpp
@@ -34,4 +35,5 @@
   TargetAttributesSema.cpp
   )
 
-add_dependencies(clangSema ClangDiagnosticSema)
+add_dependencies(clangSema ClangARMNeon ClangAttrClasses ClangAttrList 
+                 ClangDiagnosticSema ClangDeclNodes ClangStmtNodes)
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp
index 0ef9a15..c4e7bb4 100644
--- a/lib/Sema/CodeCompleteConsumer.cpp
+++ b/lib/Sema/CodeCompleteConsumer.cpp
@@ -11,11 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 #include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/Sema.h"
 #include "clang/AST/DeclCXX.h"
-#include "clang/Parse/Scope.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.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>
@@ -210,9 +212,10 @@
   }
 }
 
-CodeCompletionString::~CodeCompletionString() {
+void CodeCompletionString::clear() {
   std::for_each(Chunks.begin(), Chunks.end(), 
                 std::mem_fun_ref(&Chunk::Destroy));
+  Chunks.clear();
 }
 
 std::string CodeCompletionString::getAsString() const {
@@ -233,8 +236,7 @@
     default: OS << C->Text; break;
     }
   }
-  OS.flush();
-  return Result;
+  return OS.str();
 }
 
 const char *CodeCompletionString::getTypedText() const {
@@ -245,8 +247,10 @@
   return 0;
 }
 
-CodeCompletionString *CodeCompletionString::Clone() const {
-  CodeCompletionString *Result = new CodeCompletionString;
+CodeCompletionString *
+CodeCompletionString::Clone(CodeCompletionString *Result) const {
+  if (!Result)
+    Result = new CodeCompletionString;
   for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
     Result->AddChunk(C->Clone());
   return Result;
@@ -310,15 +314,13 @@
   }
 }
 
-CodeCompletionString *CodeCompletionString::Deserialize(const char *&Str,
-                                                        const char *StrEnd) {
+bool CodeCompletionString::Deserialize(const char *&Str, const char *StrEnd) {
   if (Str == StrEnd || *Str == 0)
-    return 0;
+    return false;
 
-  CodeCompletionString *Result = new CodeCompletionString;
   unsigned NumBlocks;
   if (ReadUnsigned(Str, StrEnd, NumBlocks))
-    return Result;
+    return false;
 
   for (unsigned I = 0; I != NumBlocks; ++I) {
     if (Str + 1 >= StrEnd)
@@ -327,7 +329,7 @@
     // Parse the next kind.
     unsigned KindValue;
     if (ReadUnsigned(Str, StrEnd, KindValue))
-      return Result;
+      return false;
 
     switch (ChunkKind Kind = (ChunkKind)KindValue) {
     case CK_TypedText:
@@ -338,16 +340,17 @@
     case CK_CurrentParameter: {
       unsigned StrLen;
       if (ReadUnsigned(Str, StrEnd, StrLen) || (Str + StrLen > StrEnd))
-        return Result;
+        return false;
 
-      Result->AddChunk(Chunk(Kind, StringRef(Str, StrLen)));
+      AddChunk(Chunk(Kind, StringRef(Str, StrLen)));
       Str += StrLen;
       break;
     }
 
     case CK_Optional: {
-      std::auto_ptr<CodeCompletionString> Optional(Deserialize(Str, StrEnd));
-      Result->AddOptionalChunk(Optional);
+      std::auto_ptr<CodeCompletionString> Optional(new CodeCompletionString());
+      if (Optional->Deserialize(Str, StrEnd))
+        AddOptionalChunk(Optional);
       break;
     }
 
@@ -365,21 +368,40 @@
     case CK_Equal:
     case CK_HorizontalSpace:
     case CK_VerticalSpace:
-      Result->AddChunk(Chunk(Kind));
+      AddChunk(Chunk(Kind));
       break;      
     }
   };
   
-  return Result;
+  return true;
 }
 
-void CodeCompleteConsumer::Result::Destroy() {
+void CodeCompletionResult::Destroy() {
   if (Kind == RK_Pattern) {
     delete Pattern;
     Pattern = 0;
   }
 }
 
+unsigned CodeCompletionResult::getPriorityFromDecl(NamedDecl *ND) {
+  if (!ND)
+    return CCP_Unlikely;
+  
+  // Context-based decisions.
+  DeclContext *DC = ND->getDeclContext()->getLookupContext();
+  if (DC->isFunctionOrMethod() || isa<BlockDecl>(DC))
+    return CCP_LocalDeclaration;
+  if (DC->isRecord() || isa<ObjCContainerDecl>(DC))
+    return CCP_MemberDeclaration;
+  
+  // Content-based decisions.
+  if (isa<EnumConstantDecl>(ND))
+    return CCP_Constant;
+  if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
+    return CCP_Type;
+  return CCP_Declaration;
+}
+
 //===----------------------------------------------------------------------===//
 // Code completion overload candidate implementation
 //===----------------------------------------------------------------------===//
@@ -418,13 +440,16 @@
 
 void 
 PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
-                                                         Result *Results, 
+                                                 CodeCompletionContext Context,
+                                                 CodeCompletionResult *Results,
                                                          unsigned NumResults) {
+  std::stable_sort(Results, Results + NumResults);
+  
   // Print the results.
   for (unsigned I = 0; I != NumResults; ++I) {
     OS << "COMPLETION: ";
     switch (Results[I].Kind) {
-    case Result::RK_Declaration:
+    case CodeCompletionResult::RK_Declaration:
       OS << Results[I].Declaration;
       if (Results[I].Hidden)
         OS << " (Hidden)";
@@ -437,11 +462,11 @@
       OS << '\n';
       break;
       
-    case Result::RK_Keyword:
+    case CodeCompletionResult::RK_Keyword:
       OS << Results[I].Keyword << '\n';
       break;
         
-    case Result::RK_Macro: {
+    case CodeCompletionResult::RK_Macro: {
       OS << Results[I].Macro->getName();
       if (CodeCompletionString *CCS 
             = Results[I].CreateCodeCompletionString(SemaRef)) {
@@ -452,18 +477,13 @@
       break;
     }
         
-    case Result::RK_Pattern: {
+    case CodeCompletionResult::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 
@@ -478,132 +498,201 @@
       delete CCS;
     }
   }
+}
 
-  // Once we've printed the code-completion results, suppress remaining
-  // diagnostics.
-  // FIXME: Move this somewhere else!
-  SemaRef.PP.getDiagnostics().setSuppressAllDiagnostics();
+void CodeCompletionResult::computeCursorKindAndAvailability() {
+  switch (Kind) {
+  case RK_Declaration:
+    // Set the availability based on attributes.
+    Availability = CXAvailability_Available;      
+    if (Declaration->getAttr<UnavailableAttr>())
+      Availability = CXAvailability_NotAvailable;
+    else if (Declaration->getAttr<DeprecatedAttr>())
+      Availability = CXAvailability_Deprecated;
+      
+    switch (Declaration->getKind()) {
+    case Decl::Record:
+    case Decl::CXXRecord:
+    case Decl::ClassTemplateSpecialization: {
+      RecordDecl *Record = cast<RecordDecl>(Declaration);
+      if (Record->isStruct())
+        CursorKind = CXCursor_StructDecl;
+      else if (Record->isUnion())
+        CursorKind = CXCursor_UnionDecl;
+      else
+        CursorKind = CXCursor_ClassDecl;
+      break;
+    }
+      
+    case Decl::ObjCMethod: {
+      ObjCMethodDecl *Method = cast<ObjCMethodDecl>(Declaration);
+      if (Method->isInstanceMethod())
+          CursorKind = CXCursor_ObjCInstanceMethodDecl;
+      else
+        CursorKind = CXCursor_ObjCClassMethodDecl;
+      break;
+    }
+      
+    case Decl::Typedef:
+      CursorKind = CXCursor_TypedefDecl;
+      break;
+        
+    case Decl::Enum:
+      CursorKind = CXCursor_EnumDecl;
+      break;
+        
+    case Decl::Field:
+      CursorKind = CXCursor_FieldDecl;
+      break;
+        
+    case Decl::EnumConstant:
+      CursorKind = CXCursor_EnumConstantDecl;
+      break;      
+        
+    case Decl::Function:
+    case Decl::CXXMethod:
+    case Decl::CXXConstructor:
+    case Decl::CXXDestructor:
+    case Decl::CXXConversion:
+      CursorKind = CXCursor_FunctionDecl;
+      if (cast<FunctionDecl>(Declaration)->isDeleted())
+        Availability = CXAvailability_NotAvailable;
+      break;
+        
+    case Decl::Var:
+      CursorKind = CXCursor_VarDecl;
+      break;
+        
+    case Decl::ParmVar:
+      CursorKind = CXCursor_ParmDecl;
+      break;
+        
+    case Decl::ObjCInterface:
+      CursorKind = CXCursor_ObjCInterfaceDecl;
+      break;
+        
+    case Decl::ObjCCategory:
+      CursorKind = CXCursor_ObjCCategoryDecl;
+      break;
+        
+    case Decl::ObjCProtocol:
+      CursorKind = CXCursor_ObjCProtocolDecl;
+      break;
+
+    case Decl::ObjCProperty:
+      CursorKind = CXCursor_ObjCPropertyDecl;
+      break;
+        
+    case Decl::ObjCIvar:
+      CursorKind = CXCursor_ObjCIvarDecl;
+      break;
+        
+    case Decl::ObjCImplementation:
+      CursorKind = CXCursor_ObjCImplementationDecl;
+      break;
+        
+    case Decl::ObjCCategoryImpl:
+      CursorKind = CXCursor_ObjCCategoryImplDecl;
+      break;
+        
+    default:
+      CursorKind = CXCursor_NotImplemented;
+      break;
+    }
+    break;
+
+  case RK_Macro:
+    Availability = CXAvailability_Available;      
+    CursorKind = CXCursor_MacroDefinition;
+    break;
+      
+  case RK_Keyword:
+    Availability = CXAvailability_Available;      
+    CursorKind = CXCursor_NotImplemented;
+    break;
+      
+  case RK_Pattern:
+    // Do nothing: Patterns can come with cursor kinds!
+    break;
+  }
+}
+
+/// \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 CodeCompletionResult &R,
+                                    std::string &Saved) {
+  switch (R.Kind) {
+    case CodeCompletionResult::RK_Keyword:
+      return R.Keyword;
+      
+    case CodeCompletionResult::RK_Pattern:
+      return R.Pattern->getTypedText();
+      
+    case CodeCompletionResult::RK_Macro:
+      return R.Macro->getName();
+      
+    case CodeCompletionResult::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 clang::operator<(const CodeCompletionResult &X, 
+                      const CodeCompletionResult &Y) {
+  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;
+  
+  // If case-insensitive comparison fails, try case-sensitive comparison.
+  cmp = XStr.compare(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;
 }
 
 void 
 CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
-                                                       Result *Results, 
+                                                 CodeCompletionContext Context,
+                                                 CodeCompletionResult *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);
+    WriteUnsigned(OS, Results[I].CursorKind);
+    WriteUnsigned(OS, Results[I].Priority);
+    WriteUnsigned(OS, Results[I].Availability);
     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 
@@ -613,15 +702,12 @@
                                                        unsigned NumCandidates) {
   for (unsigned I = 0; I != NumCandidates; ++I) {
     WriteUnsigned(OS, CXCursor_NotImplemented);
+    WriteUnsigned(OS, /*Priority=*/I);
+    WriteUnsigned(OS, /*Availability=*/CXAvailability_Available);
     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/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
new file mode 100644
index 0000000..b46e8af
--- /dev/null
+++ b/lib/Sema/DeclSpec.cpp
@@ -0,0 +1,667 @@
+//===--- 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/ParseDiagnostic.h" // FIXME: remove this back-dependency!
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/ParsedTemplate.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,
+                                             ParsedType *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) {
+    // Changing storage class is allowed only if the previous one
+    // was the 'extern' that is part of a linkage specification and
+    // the new storage class is 'typedef'.
+    if (!(SCS_extern_in_linkage_spec &&
+          StorageClassSpec == SCS_extern &&
+          S == SCS_typedef))
+      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 && !TypeAltiVecBool &&
+      ((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,
+                               ParsedType Rep) {
+  assert(isTypeRep(T) && "T does not store a type");
+  assert(Rep && "no type provided!");
+  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 = false;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+                               const char *&PrevSpec,
+                               unsigned &DiagID,
+                               Expr *Rep) {
+  assert(isExprRep(T) && "T does not store an expr");
+  assert(Rep && "no expression provided!");
+  if (TypeSpecType != TST_unspecified) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_decl_spec_combination;
+    return true;
+  }
+  TypeSpecType = T;
+  ExprRep = Rep;
+  TSTLoc = Loc;
+  TypeSpecOwned = false;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+                               const char *&PrevSpec,
+                               unsigned &DiagID,
+                               Decl *Rep, bool Owned) {
+  assert(isDeclRep(T) && "T does not store a decl");
+  // Unlike the other cases, we don't assert that we actually get a decl.
+
+  if (TypeSpecType != TST_unspecified) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_decl_spec_combination;
+    return true;
+  }
+  TypeSpecType = T;
+  DeclRep = Rep;
+  TSTLoc = Loc;
+  TypeSpecOwned = Owned;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+                               const char *&PrevSpec,
+                               unsigned &DiagID) {
+  assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&
+         "rep required for these type-spec kinds!");
+  if (TypeSpecType != TST_unspecified) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_decl_spec_combination;
+    return true;
+  }
+  if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) {
+    TypeAltiVecBool = true;
+    TSTLoc = Loc;
+    return false;
+  }
+  TypeSpecType = T;
+  TSTLoc = Loc;
+  TypeSpecOwned = false;
+  if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_vector_decl_spec;
+    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 || TypeAltiVecPixel ||
+      (TypeSpecType != TST_unspecified)) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_pixel_decl_spec_combination;
+    return true;
+  }
+  TypeAltiVecPixel = isAltiVecPixel;
+  TSTLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecError() {
+  TypeSpecType = TST_error;
+  TypeSpecOwned = false;
+  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(Decl * const *Protos,
+                                     unsigned NP,
+                                     SourceLocation *ProtoLocs,
+                                     SourceLocation LAngleLoc) {
+  if (NP == 0) return;
+  ProtocolQualifiers = new Decl*[NP];
+  ProtocolLocs = new SourceLocation[NP];
+  memcpy((void*)ProtocolQualifiers, Protos, sizeof(Decl*)*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();
+  }
+}
+
+void DeclSpec::SaveStorageSpecifierAsWritten() {
+  if (SCS_extern_in_linkage_spec && StorageClassSpec == SCS_extern)
+    // If 'extern' is part of a linkage specification,
+    // then it is not a storage class "as written".
+    StorageClassSpecAsWritten = SCS_unspecified;
+  else
+    StorageClassSpecAsWritten = StorageClassSpec;
+}
+
+/// 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();
+
+  // Validate and finalize AltiVec vector declspec.
+  if (TypeAltiVecVector) {
+    if (TypeAltiVecBool) {
+      // Sign specifiers are not allowed with vector bool. (PIM 2.1)
+      if (TypeSpecSign != TSS_unspecified) {
+        Diag(D, TSSLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+          << getSpecifierName((TSS)TypeSpecSign);
+      }
+
+      // Only char/int are valid with vector bool. (PIM 2.1)
+      if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&
+           (TypeSpecType != TST_int)) || TypeAltiVecPixel) {
+        Diag(D, TSTLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+          << (TypeAltiVecPixel ? "__pixel" :
+                                 getSpecifierName((TST)TypeSpecType));
+      }
+
+      // Only 'short' is valid with vector bool. (PIM 2.1)
+      if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short))
+        Diag(D, TSWLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+          << getSpecifierName((TSW)TypeSpecWidth);
+
+      // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
+      if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
+          (TypeSpecWidth != TSW_unspecified))
+        TypeSpecSign = TSS_unsigned;
+    }
+
+    if (TypeAltiVecPixel) {
+      //TODO: perform validation
+      TypeSpecType = TST_int;
+      TypeSpecSign = TSS_unsigned;
+      TypeSpecWidth = TSW_short;
+      TypeSpecOwned = false;
+    }
+  }
+
+  // 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;
+      TypeSpecOwned = false;
+    }
+    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;
+      TypeSpecOwned = false;
+    }
+    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();
+  }
+
+  assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));
+
+  // 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 isDeclRep(tst) && getRepAsDecl() != 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/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp
index b09526e..384fbec 100644
--- a/lib/Sema/IdentifierResolver.cpp
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -12,7 +12,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "IdentifierResolver.h"
+#include "clang/Sema/IdentifierResolver.h"
+#include "clang/Sema/Scope.h"
+#include "clang/AST/Decl.h"
 #include "clang/Basic/LangOptions.h"
 
 using namespace clang;
@@ -111,7 +113,7 @@
            ((DeclContext *)S->getEntity())->isTransparentContext())
       S = S->getParent();
 
-    if (S->isDeclScope(Action::DeclPtrTy::make(D)))
+    if (S->isDeclScope(D))
       return true;
     if (LangOpt.CPlusPlus) {
       // C++ 3.3.2p3:
@@ -128,7 +130,7 @@
       //
       assert(S->getParent() && "No TUScope?");
       if (S->getParent()->getFlags() & Scope::ControlScope)
-        return S->getParent()->isDeclScope(Action::DeclPtrTy::make(D));
+        return S->getParent()->isDeclScope(D);
     }
     return false;
   }
@@ -139,6 +141,9 @@
 /// AddDecl - Link the decl to its shadowed decl chain.
 void IdentifierResolver::AddDecl(NamedDecl *D) {
   DeclarationName Name = D->getDeclName();
+  if (IdentifierInfo *II = Name.getAsIdentifierInfo())
+    II->setIsFromAST(false);
+
   void *Ptr = Name.getFETokenInfo<void>();
 
   if (!Ptr) {
@@ -164,6 +169,9 @@
 void IdentifierResolver::RemoveDecl(NamedDecl *D) {
   assert(D && "null param passed");
   DeclarationName Name = D->getDeclName();
+  if (IdentifierInfo *II = Name.getAsIdentifierInfo())
+    II->setIsFromAST(false);
+
   void *Ptr = Name.getFETokenInfo<void>();
 
   assert(Ptr && "Didn't find this decl on its identifier's chain!");
@@ -182,6 +190,9 @@
          "Cannot replace a decl with another decl of a different name");
 
   DeclarationName Name = Old->getDeclName();
+  if (IdentifierInfo *II = Name.getAsIdentifierInfo())
+    II->setIsFromAST(false);
+
   void *Ptr = Name.getFETokenInfo<void>();
 
   if (!Ptr)
@@ -218,6 +229,7 @@
 
 void IdentifierResolver::AddDeclToIdentifierChain(IdentifierInfo *II,
                                                   NamedDecl *D) {
+  II->setIsFromAST(false);
   void *Ptr = II->getFETokenInfo<void>();
 
   if (!Ptr) {
@@ -261,3 +273,16 @@
   ++CurIndex;
   return *IDI;
 }
+
+void IdentifierResolver::iterator::incrementSlowCase() {
+  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();
+}
diff --git a/lib/Sema/IdentifierResolver.h b/lib/Sema/IdentifierResolver.h
deleted file mode 100644
index 59bd834..0000000
--- a/lib/Sema/IdentifierResolver.h
+++ /dev/null
@@ -1,203 +0,0 @@
-//===- 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
index 0694294..b23f615 100644
--- a/lib/Sema/JumpDiagnostics.cpp
+++ b/lib/Sema/JumpDiagnostics.cpp
@@ -12,10 +12,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtCXX.h"
+#include "llvm/ADT/BitVector.h"
 using namespace clang;
 
 namespace {
@@ -39,33 +41,48 @@
     /// the parent scope is the function body.
     unsigned ParentScope;
 
-    /// Diag - The diagnostic to emit if there is a jump into this scope.
-    unsigned Diag;
+    /// InDiag - The diagnostic to emit if there is a jump into this scope.
+    unsigned InDiag;
+
+    /// OutDiag - The diagnostic to emit if there is an indirect jump out
+    /// of this scope.  Direct jumps always clean up their current scope
+    /// in an orderly way.
+    unsigned OutDiag;
 
     /// Loc - Location to emit the diagnostic.
     SourceLocation Loc;
 
-    GotoScope(unsigned parentScope, unsigned diag, SourceLocation L)
-    : ParentScope(parentScope), Diag(diag), Loc(L) {}
+    GotoScope(unsigned parentScope, unsigned InDiag, unsigned OutDiag,
+              SourceLocation L)
+      : ParentScope(parentScope), InDiag(InDiag), OutDiag(OutDiag), Loc(L) {}
   };
 
   llvm::SmallVector<GotoScope, 48> Scopes;
   llvm::DenseMap<Stmt*, unsigned> LabelAndGotoScopes;
   llvm::SmallVector<Stmt*, 16> Jumps;
+
+  llvm::SmallVector<IndirectGotoStmt*, 4> IndirectJumps;
+  llvm::SmallVector<LabelStmt*, 4> IndirectJumpTargets;
 public:
   JumpScopeChecker(Stmt *Body, Sema &S);
 private:
+  void BuildScopeInformation(Decl *D, unsigned &ParentScope);
   void BuildScopeInformation(Stmt *S, unsigned ParentScope);
   void VerifyJumps();
+  void VerifyIndirectJumps();
+  void DiagnoseIndirectJump(IndirectGotoStmt *IG, unsigned IGScope,
+                            LabelStmt *Target, unsigned TargetScope);
   void CheckJump(Stmt *From, Stmt *To,
                  SourceLocation DiagLoc, unsigned JumpDiag);
+
+  unsigned GetDeepestCommonScope(unsigned A, unsigned B);
 };
 } // 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()));
+  Scopes.push_back(GotoScope(~0U, ~0U, ~0U, SourceLocation()));
 
   // Build information for the top level compound statement, so that we have a
   // defined scope record for every "goto" and label.
@@ -73,55 +90,153 @@
 
   // Check that all jumps we saw are kosher.
   VerifyJumps();
+  VerifyIndirectJumps();
+}
+
+/// GetDeepestCommonScope - Finds the innermost scope enclosing the
+/// two scopes.
+unsigned JumpScopeChecker::GetDeepestCommonScope(unsigned A, unsigned B) {
+  while (A != B) {
+    // Inner scopes are created after outer scopes and therefore have
+    // higher indices.
+    if (A < B) {
+      assert(Scopes[B].ParentScope < B);
+      B = Scopes[B].ParentScope;
+    } else {
+      assert(Scopes[A].ParentScope < A);
+      A = Scopes[A].ParentScope;
+    }
+  }
+  return A;
 }
 
 /// 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) {
+static std::pair<unsigned,unsigned>
+    GetDiagForGotoScopeDecl(const Decl *D, bool isCPlusPlus) {
   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    unsigned InDiag = 0, OutDiag = 0;
     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;
+      InDiag = diag::note_protected_by_vla;
+
+    if (VD->hasAttr<BlocksAttr>()) {
+      InDiag = diag::note_protected_by___block;
+      OutDiag = diag::note_exits___block;
+    } else if (VD->hasAttr<CleanupAttr>()) {
+      InDiag = diag::note_protected_by_cleanup;
+      OutDiag = diag::note_exits_cleanup;
+    } else if (isCPlusPlus) {
+      // FIXME: In C++0x, we have to check more conditions than "did we
+      // just give it an initializer?". See 6.7p3.
+      if (VD->hasLocalStorage() && VD->hasInit())
+        InDiag = diag::note_protected_by_variable_init;
+
+      CanQualType T = VD->getType()->getCanonicalTypeUnqualified();
+      if (!T->isDependentType()) {
+        while (CanQual<ArrayType> AT = T->getAs<ArrayType>())
+          T = AT->getElementType();
+        if (CanQual<RecordType> RT = T->getAs<RecordType>())
+          if (!cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor())
+            OutDiag = diag::note_exits_dtor;
+      }
+    }
     
-  } else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
-    if (TD->getUnderlyingType()->isVariablyModifiedType())
-      return diag::note_protected_by_vla_typedef;
+    return std::make_pair(InDiag, OutDiag);    
   }
 
-  return 0;
+  if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+    if (TD->getUnderlyingType()->isVariablyModifiedType())
+      return std::make_pair((unsigned) diag::note_protected_by_vla_typedef, 0);
+  }
+
+  return std::make_pair(0U, 0U);
 }
 
+/// \brief Build scope information for a declaration that is part of a DeclStmt.
+void JumpScopeChecker::BuildScopeInformation(Decl *D, unsigned &ParentScope) {
+  bool isCPlusPlus = this->S.getLangOptions().CPlusPlus;
+  
+  // If this decl causes a new scope, push and switch to it.
+  std::pair<unsigned,unsigned> Diags
+    = GetDiagForGotoScopeDecl(D, isCPlusPlus);
+  if (Diags.first || Diags.second) {
+    Scopes.push_back(GotoScope(ParentScope, Diags.first, Diags.second,
+                               D->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>(D))
+    if (Expr *Init = VD->getInit())
+      BuildScopeInformation(Init, ParentScope);
+}
 
 /// 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) {
-
+  bool SkipFirstSubStmt = false;
+  
   // If we found a label, remember that it is in ParentScope scope.
-  if (isa<LabelStmt>(S) || isa<DefaultStmt>(S) || isa<CaseStmt>(S)) {
+  switch (S->getStmtClass()) {
+  case Stmt::AddrLabelExprClass:
+    IndirectJumpTargets.push_back(cast<AddrLabelExpr>(S)->getLabel());
+    break;
+
+  case Stmt::IndirectGotoStmtClass:
     LabelAndGotoScopes[S] = ParentScope;
-  } else if (isa<GotoStmt>(S) || isa<SwitchStmt>(S) ||
-             isa<IndirectGotoStmt>(S) || isa<AddrLabelExpr>(S)) {
+    IndirectJumps.push_back(cast<IndirectGotoStmt>(S));
+    break;
+
+  case Stmt::SwitchStmtClass:
+    // Evaluate the condition variable before entering the scope of the switch
+    // statement.
+    if (VarDecl *Var = cast<SwitchStmt>(S)->getConditionVariable()) {
+      BuildScopeInformation(Var, ParentScope);
+      SkipFirstSubStmt = true;
+    }
+    // Fall through
+      
+  case Stmt::GotoStmtClass:
     // 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);
+    break;
+
+  default:
+    break;
   }
 
   for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end(); CI != E;
        ++CI) {
+    if (SkipFirstSubStmt) {
+      SkipFirstSubStmt = false;
+      continue;
+    }
+    
     Stmt *SubStmt = *CI;
     if (SubStmt == 0) continue;
 
-    bool isCPlusPlus = this->S.getLangOptions().CPlusPlus;
+    // Cases, labels, and defaults aren't "scope parents".  It's also
+    // important to handle these iteratively instead of recursively in
+    // order to avoid blowing out the stack.
+    while (true) {
+      Stmt *Next;
+      if (isa<CaseStmt>(SubStmt))
+        Next = cast<CaseStmt>(SubStmt)->getSubStmt();
+      else if (isa<DefaultStmt>(SubStmt))
+        Next = cast<DefaultStmt>(SubStmt)->getSubStmt();
+      else if (isa<LabelStmt>(SubStmt))
+        Next = cast<LabelStmt>(SubStmt)->getSubStmt();
+      else
+        break;
+
+      LabelAndGotoScopes[SubStmt] = ParentScope;
+      SubStmt = Next;
+    }
 
     // If this is a declstmt with a VLA definition, it defines a scope from here
     // to the end of the containing context.
@@ -129,19 +244,8 @@
       // 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);
-      }
+           I != E; ++I)
+        BuildScopeInformation(*I, ParentScope);
       continue;
     }
 
@@ -149,7 +253,9 @@
     // 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,
+      Scopes.push_back(GotoScope(ParentScope,
+                                 diag::note_protected_by_objc_try,
+                                 diag::note_exits_objc_try,
                                  AT->getAtTryLoc()));
       if (Stmt *TryPart = AT->getTryBody())
         BuildScopeInformation(TryPart, Scopes.size()-1);
@@ -159,6 +265,7 @@
         ObjCAtCatchStmt *AC = AT->getCatchStmt(I);
         Scopes.push_back(GotoScope(ParentScope,
                                    diag::note_protected_by_objc_catch,
+                                   diag::note_exits_objc_catch,
                                    AC->getAtCatchLoc()));
         // @catches are nested and it isn't
         BuildScopeInformation(AC->getCatchBody(), Scopes.size()-1);
@@ -168,6 +275,7 @@
       if (ObjCAtFinallyStmt *AF = AT->getFinallyStmt()) {
         Scopes.push_back(GotoScope(ParentScope,
                                    diag::note_protected_by_objc_finally,
+                                   diag::note_exits_objc_finally,
                                    AF->getAtFinallyLoc()));
         BuildScopeInformation(AF, Scopes.size()-1);
       }
@@ -186,6 +294,7 @@
       // scope.
       Scopes.push_back(GotoScope(ParentScope,
                                  diag::note_protected_by_objc_synchronized,
+                                 diag::note_exits_objc_synchronized,
                                  AS->getAtSynchronizedLoc()));
       BuildScopeInformation(AS->getSynchBody(), Scopes.size()-1);
       continue;
@@ -194,7 +303,9 @@
     // 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,
+      Scopes.push_back(GotoScope(ParentScope,
+                                 diag::note_protected_by_cxx_try,
+                                 diag::note_exits_cxx_try,
                                  TS->getSourceRange().getBegin()));
       if (Stmt *TryBlock = TS->getTryBlock())
         BuildScopeInformation(TryBlock, Scopes.size()-1);
@@ -204,6 +315,7 @@
         CXXCatchStmt *CS = TS->getHandler(I);
         Scopes.push_back(GotoScope(ParentScope,
                                    diag::note_protected_by_cxx_catch,
+                                   diag::note_exits_cxx_catch,
                                    CS->getSourceRange().getBegin()));
         BuildScopeInformation(CS->getHandlerBlock(), Scopes.size()-1);
       }
@@ -229,54 +341,178 @@
       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;
+    SwitchStmt *SS = 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);
     }
   }
 }
 
+/// VerifyIndirectJumps - Verify whether any possible indirect jump
+/// might cross a protection boundary.  Unlike direct jumps, indirect
+/// jumps count cleanups as protection boundaries:  since there's no
+/// way to know where the jump is going, we can't implicitly run the
+/// right cleanups the way we can with direct jumps.
+///
+/// Thus, an indirect jump is "trivial" if it bypasses no
+/// initializations and no teardowns.  More formally, an indirect jump
+/// from A to B is trivial if the path out from A to DCA(A,B) is
+/// trivial and the path in from DCA(A,B) to B is trivial, where
+/// DCA(A,B) is the deepest common ancestor of A and B.
+/// Jump-triviality is transitive but asymmetric.
+///
+/// A path in is trivial if none of the entered scopes have an InDiag.
+/// A path out is trivial is none of the exited scopes have an OutDiag.
+///
+/// Under these definitions, this function checks that the indirect
+/// jump between A and B is trivial for every indirect goto statement A
+/// and every label B whose address was taken in the function.
+void JumpScopeChecker::VerifyIndirectJumps() {
+  if (IndirectJumps.empty()) return;
+
+  // If there aren't any address-of-label expressions in this function,
+  // complain about the first indirect goto.
+  if (IndirectJumpTargets.empty()) {
+    S.Diag(IndirectJumps[0]->getGotoLoc(),
+           diag::err_indirect_goto_without_addrlabel);
+    return;
+  }
+
+  // Collect a single representative of every scope containing an
+  // indirect goto.  For most code bases, this substantially cuts
+  // down on the number of jump sites we'll have to consider later.
+  typedef std::pair<unsigned, IndirectGotoStmt*> JumpScope;
+  llvm::SmallVector<JumpScope, 32> JumpScopes;
+  {
+    llvm::DenseMap<unsigned, IndirectGotoStmt*> JumpScopesMap;
+    for (llvm::SmallVectorImpl<IndirectGotoStmt*>::iterator
+           I = IndirectJumps.begin(), E = IndirectJumps.end(); I != E; ++I) {
+      IndirectGotoStmt *IG = *I;
+      assert(LabelAndGotoScopes.count(IG) &&
+             "indirect jump didn't get added to scopes?");
+      unsigned IGScope = LabelAndGotoScopes[IG];
+      IndirectGotoStmt *&Entry = JumpScopesMap[IGScope];
+      if (!Entry) Entry = IG;
+    }
+    JumpScopes.reserve(JumpScopesMap.size());
+    for (llvm::DenseMap<unsigned, IndirectGotoStmt*>::iterator
+           I = JumpScopesMap.begin(), E = JumpScopesMap.end(); I != E; ++I)
+      JumpScopes.push_back(*I);
+  }
+
+  // Collect a single representative of every scope containing a
+  // label whose address was taken somewhere in the function.
+  // For most code bases, there will be only one such scope.
+  llvm::DenseMap<unsigned, LabelStmt*> TargetScopes;
+  for (llvm::SmallVectorImpl<LabelStmt*>::iterator
+         I = IndirectJumpTargets.begin(), E = IndirectJumpTargets.end();
+       I != E; ++I) {
+    LabelStmt *TheLabel = *I;
+    assert(LabelAndGotoScopes.count(TheLabel) &&
+           "Referenced label didn't get added to scopes?");
+    unsigned LabelScope = LabelAndGotoScopes[TheLabel];
+    LabelStmt *&Target = TargetScopes[LabelScope];
+    if (!Target) Target = TheLabel;
+  }
+
+  // For each target scope, make sure it's trivially reachable from
+  // every scope containing a jump site.
+  //
+  // A path between scopes always consists of exitting zero or more
+  // scopes, then entering zero or more scopes.  We build a set of
+  // of scopes S from which the target scope can be trivially
+  // entered, then verify that every jump scope can be trivially
+  // exitted to reach a scope in S.
+  llvm::BitVector Reachable(Scopes.size(), false);
+  for (llvm::DenseMap<unsigned,LabelStmt*>::iterator
+         TI = TargetScopes.begin(), TE = TargetScopes.end(); TI != TE; ++TI) {
+    unsigned TargetScope = TI->first;
+    LabelStmt *TargetLabel = TI->second;
+
+    Reachable.reset();
+
+    // Mark all the enclosing scopes from which you can safely jump
+    // into the target scope.  'Min' will end up being the index of
+    // the shallowest such scope.
+    unsigned Min = TargetScope;
+    while (true) {
+      Reachable.set(Min);
+
+      // Don't go beyond the outermost scope.
+      if (Min == 0) break;
+
+      // Stop if we can't trivially enter the current scope.
+      if (Scopes[Min].InDiag) break;
+
+      Min = Scopes[Min].ParentScope;
+    }
+
+    // Walk through all the jump sites, checking that they can trivially
+    // reach this label scope.
+    for (llvm::SmallVectorImpl<JumpScope>::iterator
+           I = JumpScopes.begin(), E = JumpScopes.end(); I != E; ++I) {
+      unsigned Scope = I->first;
+
+      // Walk out the "scope chain" for this scope, looking for a scope
+      // we've marked reachable.  For well-formed code this amortizes
+      // to O(JumpScopes.size() / Scopes.size()):  we only iterate
+      // when we see something unmarked, and in well-formed code we
+      // mark everything we iterate past.
+      bool IsReachable = false;
+      while (true) {
+        if (Reachable.test(Scope)) {
+          // If we find something reachable, mark all the scopes we just
+          // walked through as reachable.
+          for (unsigned S = I->first; S != Scope; S = Scopes[S].ParentScope)
+            Reachable.set(S);
+          IsReachable = true;
+          break;
+        }
+
+        // Don't walk out if we've reached the top-level scope or we've
+        // gotten shallower than the shallowest reachable scope.
+        if (Scope == 0 || Scope < Min) break;
+
+        // Don't walk out through an out-diagnostic.
+        if (Scopes[Scope].OutDiag) break;
+
+        Scope = Scopes[Scope].ParentScope;
+      }
+
+      // Only diagnose if we didn't find something.
+      if (IsReachable) continue;
+
+      DiagnoseIndirectJump(I->second, I->first, TargetLabel, TargetScope);
+    }
+  }
+}
+
+/// Diagnose an indirect jump which is known to cross scopes.
+void JumpScopeChecker::DiagnoseIndirectJump(IndirectGotoStmt *Jump,
+                                            unsigned JumpScope,
+                                            LabelStmt *Target,
+                                            unsigned TargetScope) {
+  assert(JumpScope != TargetScope);
+
+  S.Diag(Jump->getGotoLoc(), diag::warn_indirect_goto_in_protected_scope);
+  S.Diag(Target->getIdentLoc(), diag::note_indirect_goto_target);
+
+  unsigned Common = GetDeepestCommonScope(JumpScope, TargetScope);
+
+  // Walk out the scope chain until we reach the common ancestor.
+  for (unsigned I = JumpScope; I != Common; I = Scopes[I].ParentScope)
+    if (Scopes[I].OutDiag)
+      S.Diag(Scopes[I].Loc, Scopes[I].OutDiag);
+
+  // Now walk into the scopes containing the label whose address was taken.
+  for (unsigned I = TargetScope; I != Common; I = Scopes[I].ParentScope)
+    if (Scopes[I].InDiag)
+      S.Diag(Scopes[I].Loc, Scopes[I].InDiag);
+}
+
 /// 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,
@@ -290,42 +526,25 @@
   // 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;
+  unsigned CommonScope = GetDeepestCommonScope(FromScope, ToScope);
 
-    // Otherwise, scan up the hierarchy.
-    TestScope = Scopes[TestScope].ParentScope;
-  }
+  // It's okay to jump out from a nested scope.
+  if (CommonScope == ToScope) return;
 
-  // 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.
+  // Pull out (and reverse) any scopes we might need to diagnose skipping.
+  llvm::SmallVector<unsigned, 10> ToScopes;
+  for (unsigned I = ToScope; I != CommonScope; I = Scopes[I].ParentScope)
+    if (Scopes[I].InDiag)
+      ToScopes.push_back(I);
+
+  // If the only scopes present are cleanup scopes, we're okay.
+  if (ToScopes.empty()) return;
+
   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);
+    S.Diag(Scopes[ToScopes[i]].Loc, Scopes[ToScopes[i]].InDiag);
 }
 
 void Sema::DiagnoseInvalidJumps(Stmt *Body) {
diff --git a/lib/Sema/Lookup.h b/lib/Sema/Lookup.h
deleted file mode 100644
index 0961299..0000000
--- a/lib/Sema/Lookup.h
+++ /dev/null
@@ -1,649 +0,0 @@
-//===--- 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
index 3a5a99a..2c02739 100644
--- a/lib/Sema/Makefile
+++ b/lib/Sema/Makefile
@@ -12,11 +12,8 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ../../../..
+CLANG_LEVEL := ../..
 LIBRARYNAME := clangSema
-BUILD_ARCHIVE = 1
 
-CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
 
diff --git a/lib/Sema/ParseAST.cpp b/lib/Sema/ParseAST.cpp
deleted file mode 100644
index bb0bd9e..0000000
--- a/lib/Sema/ParseAST.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-//===--- 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
index 755af84..60e308a 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -12,48 +12,52 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/DelayedDiagnostic.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/Sema/CXXFieldCollector.h"
+#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/Sema/PrettyDeclStackTrace.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/DeclCXX.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;
+using namespace sema;
 
 FunctionScopeInfo::~FunctionScopeInfo() { }
 
 void FunctionScopeInfo::Clear(unsigned NumErrors) {
-  NeedsScopeChecking = false;
+  HasBranchProtectedScope = false;
+  HasBranchIntoScope = false;
+  HasIndirectGoto = false;
+  
   LabelMap.clear();
   SwitchStack.clear();
+  Returns.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) {
+void Sema::ActOnTranslationUnitScope(Scope *S) {
   TUScope = S;
   PushDeclContext(S, Context.getTranslationUnitDecl());
 
-  if (PP.getTargetInfo().getPointerWidth(0) >= 64) {
+  VAListTagName = PP.getIdentifierInfo("__va_list_tag");
+
+  if (!Context.isInt128Installed() && // May be set by ASTReader.
+      PP.getTargetInfo().getPointerWidth(0) >= 64) {
     TypeSourceInfo *TInfo;
 
     // Install [u]int128_t for 64-bit targets.
@@ -68,12 +72,13 @@
                                           SourceLocation(),
                                           &Context.Idents.get("__uint128_t"),
                                           TInfo), TUScope);
+    Context.setInt128Installed();
   }
 
 
   if (!PP.getLangOptions().ObjC1) return;
 
-  // Built-in ObjC types may already be set by PCHReader (hence isNull checks).
+  // Built-in ObjC types may already be set by ASTReader (hence isNull checks).
   if (Context.getObjCSelType().isNull()) {
     // Create the built-in typedef for 'SEL'.
     QualType SelT = Context.getPointerType(Context.ObjCBuiltinSelTy);
@@ -97,8 +102,9 @@
   }
   // Create the built-in typedef for 'id'.
   if (Context.getObjCIdType().isNull()) {
-    QualType IdT = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy);
-    TypeSourceInfo *IdInfo = Context.getTrivialTypeSourceInfo(IdT);
+    QualType T = Context.getObjCObjectType(Context.ObjCBuiltinIdTy, 0, 0);
+    T = Context.getObjCObjectPointerType(T);
+    TypeSourceInfo *IdInfo = Context.getTrivialTypeSourceInfo(T);
     TypedefDecl *IdTypedef
       = TypedefDecl::Create(Context, CurContext, SourceLocation(),
                             &Context.Idents.get("id"), IdInfo);
@@ -108,16 +114,16 @@
   }
   // Create the built-in typedef for 'Class'.
   if (Context.getObjCClassType().isNull()) {
-    QualType ClassType
-      = Context.getObjCObjectPointerType(Context.ObjCBuiltinClassTy);
-    TypeSourceInfo *ClassInfo = Context.getTrivialTypeSourceInfo(ClassType);
+    QualType T = Context.getObjCObjectType(Context.ObjCBuiltinClassTy, 0, 0);
+    T = Context.getObjCObjectPointerType(T);
+    TypeSourceInfo *ClassInfo = Context.getTrivialTypeSourceInfo(T);
     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,
@@ -127,12 +133,11 @@
     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), 
+    PackContext(0), VisContext(0), ParsingDeclDepth(0),
+    IdResolver(pp.getLangOptions()), GlobalNewDeleteDeclared(false), 
     CompleteTranslationUnit(CompleteTranslationUnit),
-    NumSFINAEErrors(0), NonInstantiationEntries(0), 
-    CurrentInstantiationScope(0), TyposCorrected(0),
+    NumSFINAEErrors(0), SuppressAccessChecking(false),
+    NonInstantiationEntries(0), CurrentInstantiationScope(0), TyposCorrected(0),
     AnalysisWarnings(*this)
 {
   TUScope = 0;
@@ -144,22 +149,52 @@
                                        &Context);
 
   ExprEvalContexts.push_back(
-                  ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0));
+                  ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0));  
+
+  FunctionScopes.push_back(new FunctionScopeInfo(Diags.getNumErrors()));
+}
+
+void Sema::Initialize() {
+  // Tell the AST consumer about this Sema object.
+  Consumer.Initialize(Context);
+  
+  // FIXME: Isn't this redundant with the initialization above?
+  if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
+    SC->InitializeSema(*this);
+  
+  // Tell the external Sema source about this Sema object.
+  if (ExternalSemaSource *ExternalSema
+      = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))
+    ExternalSema->InitializeSema(*this);
 }
 
 Sema::~Sema() {
   if (PackContext) FreePackedContext();
+  if (VisContext) FreeVisContext();
   delete TheTargetAttributesSema;
-  while (!FunctionScopes.empty())
-    PopFunctionOrBlockScope();
+
+  // Kill all the active scopes.
+  for (unsigned I = 1, E = FunctionScopes.size(); I != E; ++I)
+    delete FunctionScopes[I];
+  if (FunctionScopes.size() == 1)
+    delete FunctionScopes[0];
+  
+  // Tell the SemaConsumer to forget about us; we're going out of scope.
+  if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
+    SC->ForgetSema();
+
+  // Detach from the external Sema source.
+  if (ExternalSemaSource *ExternalSema
+        = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))
+    ExternalSema->ForgetSema();
 }
 
 /// 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.
+/// The result is of the given category.
 void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
-                             CastExpr::CastKind Kind, 
-                             bool isLvalue, CXXBaseSpecifierArray BasePath) {
+                             CastKind Kind, ExprValueKind VK,
+                             const CXXCastPath *BasePath) {
   QualType ExprTy = Context.getCanonicalType(Expr->getType());
   QualType TypeTy = Context.getCanonicalType(Ty);
 
@@ -175,55 +210,114 @@
     }
   }
 
-  CheckImplicitConversion(Expr, Ty);
+  // If this is a derived-to-base cast to a through a virtual base, we
+  // need a vtable.
+  if (Kind == CK_DerivedToBase && 
+      BasePathInvolvesVirtualBase(*BasePath)) {
+    QualType T = Expr->getType();
+    if (const PointerType *Pointer = T->getAs<PointerType>())
+      T = Pointer->getPointeeType();
+    if (const RecordType *RecordTy = T->getAs<RecordType>())
+      MarkVTableUsed(Expr->getLocStart(), 
+                     cast<CXXRecordDecl>(RecordTy->getDecl()));
+  }
 
   if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr)) {
-    if (ImpCast->getCastKind() == Kind && BasePath.empty()) {
+    if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
       ImpCast->setType(Ty);
-      ImpCast->setLvalueCast(isLvalue);
+      ImpCast->setValueKind(VK);
       return;
     }
   }
 
-  Expr = new (Context) ImplicitCastExpr(Ty, Kind, Expr, BasePath, isLvalue);
+  Expr = ImplicitCastExpr::Create(Context, Ty, Kind, Expr, BasePath, VK);
+}
+
+ExprValueKind Sema::CastCategory(Expr *E) {
+  Expr::Classification Classification = E->Classify(Context);
+  return Classification.isRValue() ? VK_RValue :
+      (Classification.isLValue() ? VK_LValue : VK_XValue);
 }
 
 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);
+}
+
+/// \brief Used to prune the decls of Sema's UnusedFileScopedDecls vector.
+static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
+  if (D->isUsed())
+    return true;
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    // UnusedFileScopedDecls stores the first declaration.
+    // The declaration may have become definition so check again.
+    const FunctionDecl *DeclToCheck;
+    if (FD->hasBody(DeclToCheck))
+      return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
+
+    // Later redecls may add new information resulting in not having to warn,
+    // so check again.
+    DeclToCheck = FD->getMostRecentDeclaration();
+    if (DeclToCheck != FD)
+      return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
+  }
+
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    // UnusedFileScopedDecls stores the first declaration.
+    // The declaration may have become definition so check again.
+    const VarDecl *DeclToCheck = VD->getDefinition(); 
+    if (DeclToCheck)
+      return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
+
+    // Later redecls may add new information resulting in not having to warn,
+    // so check again.
+    DeclToCheck = VD->getMostRecentDeclaration();
+    if (DeclToCheck != VD)
+      return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
+  }
+
+  return false;
 }
 
 /// 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;
-  }
+void Sema::ActOnEndOfTranslationUnit() {
+  // At PCH writing, implicit instantiations and VTable handling info are
+  // stored and performed when the PCH is included.
+  if (CompleteTranslationUnit)
+    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.
+      PerformPendingInstantiations();
+
+      /// If DefinedUsedVTables ends up marking any virtual member
+      /// functions it might lead to more pending template
+      /// instantiations, which is why we need to loop here.
+      if (!DefineUsedVTables())
+        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());
+  // Remove file scoped decls that turned out to be used.
+  UnusedFileScopedDecls.erase(std::remove_if(UnusedFileScopedDecls.begin(),
+                                             UnusedFileScopedDecls.end(),
+                              std::bind1st(std::ptr_fun(ShouldRemoveFromUnused),
+                                           this)),
+                              UnusedFileScopedDecls.end());
+
+  if (!CompleteTranslationUnit) {
+    TUScope = 0;
+    return;
+  }
 
   // Check for #pragma weak identifiers that were never declared
   // FIXME: This will cause diagnostics to be emitted in a non-determinstic
@@ -237,9 +331,6 @@
       << 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
@@ -286,14 +377,28 @@
 
   }
   
-  // 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();
-  
+  // Output warning for unused file scoped decls.
+  for (llvm::SmallVectorImpl<const DeclaratorDecl*>::iterator
+         I = UnusedFileScopedDecls.begin(),
+         E = UnusedFileScopedDecls.end(); I != E; ++I) {
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
+      const FunctionDecl *DiagD;
+      if (!FD->hasBody(DiagD))
+        DiagD = FD;
+      Diag(DiagD->getLocation(),
+           isa<CXXMethodDecl>(DiagD) ? diag::warn_unused_member_function
+                                     : diag::warn_unused_function)
+            << DiagD->getDeclName();
+    } else {
+      const VarDecl *DiagD = cast<VarDecl>(*I)->getDefinition();
+      if (!DiagD)
+        DiagD = cast<VarDecl>(*I);
+      Diag(DiagD->getLocation(), diag::warn_unused_variable)
+            << DiagD->getDeclName();
+    }
+  }
+
+  TUScope = 0;
 }
 
 
@@ -304,7 +409,7 @@
 DeclContext *Sema::getFunctionLevelDeclContext() {
   DeclContext *DC = CurContext;
 
-  while (isa<BlockDecl>(DC))
+  while (isa<BlockDecl>(DC) || isa<EnumDecl>(DC))
     DC = DC->getParent();
 
   return DC;
@@ -380,14 +485,42 @@
   return Builder;
 }
 
+/// \brief Determines the active Scope associated with the given declaration
+/// context.
+///
+/// This routine maps a declaration context to the active Scope object that
+/// represents that declaration context in the parser. It is typically used
+/// from "scope-less" code (e.g., template instantiation, lazy creation of
+/// declarations) that injects a name for name-lookup purposes and, therefore,
+/// must update the Scope.
+///
+/// \returns The scope corresponding to the given declaraion context, or NULL
+/// if no such scope is open.
+Scope *Sema::getScopeForContext(DeclContext *Ctx) {
+  
+  if (!Ctx)
+    return 0;
+  
+  Ctx = Ctx->getPrimaryContext();
+  for (Scope *S = getCurScope(); S; S = S->getParent()) {
+    // Ignore scopes that cannot have declarations. This is important for
+    // out-of-line definitions of static class members.
+    if (S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope))
+      if (DeclContext *Entity = static_cast<DeclContext *> (S->getEntity()))
+        if (Ctx == Entity->getPrimaryContext())
+          return S;
+  }
+  
+  return 0;
+}
 
 /// \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);
+  if (FunctionScopes.size() == 1) {
+    // Use the "top" function scope rather than having to allocate
+    // memory for a new scope.
+    FunctionScopes.back()->Clear(getDiagnostics().getNumErrors());
+    FunctionScopes.push_back(FunctionScopes.back());
     return;
   }
   
@@ -401,21 +534,17 @@
 }
 
 void Sema::PopFunctionOrBlockScope() {
-  if (FunctionScopes.back() != &TopFunctionScope)
-    delete FunctionScopes.back();
-  else
-    TopFunctionScope.Clear(getDiagnostics().getNumErrors());
-  
-  FunctionScopes.pop_back();
+  FunctionScopeInfo *Scope = FunctionScopes.pop_back_val();
+  assert(!FunctionScopes.empty() && "mismatched push/pop!");
+  if (FunctionScopes.back() != Scope)
+    delete Scope;
 }
 
 /// \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();
+  return getCurFunction()->NumErrorsAtStartOfFunction
+             != getDiagnostics().getNumErrors();
 }
 
 BlockScopeInfo *Sema::getCurBlock() {
@@ -424,3 +553,24 @@
   
   return dyn_cast<BlockScopeInfo>(FunctionScopes.back());  
 }
+
+// Pin this vtable to this file.
+ExternalSemaSource::~ExternalSemaSource() {}
+
+void PrettyDeclStackTraceEntry::print(llvm::raw_ostream &OS) const {
+  SourceLocation Loc = this->Loc;
+  if (!Loc.isValid() && TheDecl) Loc = TheDecl->getLocation();
+  if (Loc.isValid()) {
+    Loc.print(OS, S.getSourceManager());
+    OS << ": ";
+  }
+  OS << Message;
+
+  if (TheDecl && isa<NamedDecl>(TheDecl)) {
+    std::string Name = cast<NamedDecl>(TheDecl)->getNameAsString();
+    if (!Name.empty())
+      OS << " '" << Name << '\'';
+  }
+
+  OS << '\n';
+}
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
deleted file mode 100644
index 212a36f..0000000
--- a/lib/Sema/Sema.h
+++ /dev/null
@@ -1,4463 +0,0 @@
-//===--- 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
index 30c53ed..4625cb1 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -11,9 +11,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/DelayedDiagnostic.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclCXX.h"
@@ -22,6 +23,7 @@
 #include "clang/AST/ExprCXX.h"
 
 using namespace clang;
+using namespace sema;
 
 /// A copy of Sema's enum without AR_delayed.
 enum AccessResult {
@@ -132,10 +134,10 @@
   bool Dependent;
 };
 
-/// Like Sema's AccessedEntity, but kindly lets us scribble all over
+/// Like sema:;AccessedEntity, but kindly lets us scribble all over
 /// it.
-struct AccessTarget : public Sema::AccessedEntity {
-  AccessTarget(const Sema::AccessedEntity &Entity)
+struct AccessTarget : public AccessedEntity {
+  AccessTarget(const AccessedEntity &Entity)
     : AccessedEntity(Entity) {
     initialize();
   }
@@ -222,6 +224,22 @@
 
 }
 
+/// Checks whether one class might instantiate to the other.
+static bool MightInstantiateTo(const CXXRecordDecl *From,
+                               const CXXRecordDecl *To) {
+  // Declaration names are always preserved by instantiation.
+  if (From->getDeclName() != To->getDeclName())
+    return false;
+
+  const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext();
+  const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext();
+  if (FromDC == ToDC) return true;
+  if (FromDC->isFileContext() || ToDC->isFileContext()) return false;
+
+  // Be conservative.
+  return true;
+}
+
 /// Checks whether one class is derived from another, inclusively.
 /// Properly indicates when it couldn't be determined due to
 /// dependence.
@@ -234,6 +252,10 @@
 
   if (Derived == Target) return AR_accessible;
 
+  bool CheckDependent = Derived->isDependentContext();
+  if (CheckDependent && MightInstantiateTo(Derived, Target))
+    return AR_dependent;
+
   AccessResult OnFailure = AR_inaccessible;
   llvm::SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
 
@@ -246,10 +268,10 @@
       QualType T = I->getType();
       if (const RecordType *RT = T->getAs<RecordType>()) {
         RD = cast<CXXRecordDecl>(RT->getDecl());
+      } else if (const InjectedClassNameType *IT
+                   = T->getAs<InjectedClassNameType>()) {
+        RD = IT->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;
@@ -257,6 +279,9 @@
 
       RD = RD->getCanonicalDecl();
       if (RD == Target) return AR_accessible;
+      if (CheckDependent && MightInstantiateTo(RD, Target))
+        OnFailure = AR_dependent;
+
       Queue.push_back(RD);
     }
 
@@ -539,6 +564,130 @@
   return OnFailure;
 }
 
+namespace {
+
+/// A helper class for checking for a friend which will grant access
+/// to a protected instance member.
+struct ProtectedFriendContext {
+  Sema &S;
+  const EffectiveContext &EC;
+  const CXXRecordDecl *NamingClass;
+  bool CheckDependent;
+  bool EverDependent;
+
+  /// The path down to the current base class.
+  llvm::SmallVector<const CXXRecordDecl*, 20> CurPath;
+
+  ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
+                         const CXXRecordDecl *InstanceContext,
+                         const CXXRecordDecl *NamingClass)
+    : S(S), EC(EC), NamingClass(NamingClass),
+      CheckDependent(InstanceContext->isDependentContext() ||
+                     NamingClass->isDependentContext()),
+      EverDependent(false) {}
+
+  /// Check classes in the current path for friendship, starting at
+  /// the given index.
+  bool checkFriendshipAlongPath(unsigned I) {
+    assert(I < CurPath.size());
+    for (unsigned E = CurPath.size(); I != E; ++I) {
+      switch (GetFriendKind(S, EC, CurPath[I])) {
+      case AR_accessible:   return true;
+      case AR_inaccessible: continue;
+      case AR_dependent:    EverDependent = true; continue;
+      }
+    }
+    return false;
+  }
+
+  /// Perform a search starting at the given class.
+  ///
+  /// PrivateDepth is the index of the last (least derived) class
+  /// along the current path such that a notional public member of
+  /// the final class in the path would have access in that class.
+  bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {
+    // If we ever reach the naming class, check the current path for
+    // friendship.  We can also stop recursing because we obviously
+    // won't find the naming class there again.
+    if (Cur == NamingClass)
+      return checkFriendshipAlongPath(PrivateDepth);
+
+    if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
+      EverDependent = true;
+
+    // Recurse into the base classes.
+    for (CXXRecordDecl::base_class_const_iterator
+           I = Cur->bases_begin(), E = Cur->bases_end(); I != E; ++I) {
+
+      // If this is private inheritance, then a public member of the
+      // base will not have any access in classes derived from Cur.
+      unsigned BasePrivateDepth = PrivateDepth;
+      if (I->getAccessSpecifier() == AS_private)
+        BasePrivateDepth = CurPath.size() - 1;
+
+      const CXXRecordDecl *RD;
+
+      QualType T = I->getType();
+      if (const RecordType *RT = T->getAs<RecordType>()) {
+        RD = cast<CXXRecordDecl>(RT->getDecl());
+      } else if (const InjectedClassNameType *IT
+                   = T->getAs<InjectedClassNameType>()) {
+        RD = IT->getDecl();
+      } else {
+        assert(T->isDependentType() && "non-dependent base wasn't a record?");
+        EverDependent = true;
+        continue;
+      }
+
+      // Recurse.  We don't need to clean up if this returns true.
+      CurPath.push_back(RD);
+      if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))
+        return true;
+      CurPath.pop_back();
+    }
+
+    return false;
+  }
+
+  bool findFriendship(const CXXRecordDecl *Cur) {
+    assert(CurPath.empty());
+    CurPath.push_back(Cur);
+    return findFriendship(Cur, 0);
+  }
+};
+}
+
+/// Search for a class P that EC is a friend of, under the constraint
+///   InstanceContext <= P <= NamingClass
+/// and with the additional restriction that a protected member of
+/// NamingClass would have some natural access in P.
+///
+/// That second condition isn't actually quite right: the condition in
+/// the standard is whether the target would have some natural access
+/// in P.  The difference is that the target might be more accessible
+/// along some path not passing through NamingClass.  Allowing that
+/// introduces two problems:
+///   - It breaks encapsulation because you can suddenly access a
+///     forbidden base class's members by subclassing it elsewhere.
+///   - It makes access substantially harder to compute because it
+///     breaks the hill-climbing algorithm: knowing that the target is
+///     accessible in some base class would no longer let you change
+///     the question solely to whether the base class is accessible,
+///     because the original target might have been more accessible
+///     because of crazy subclassing.
+/// So we don't implement that.
+static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC,
+                                           const CXXRecordDecl *InstanceContext,
+                                           const CXXRecordDecl *NamingClass) {
+  assert(InstanceContext->getCanonicalDecl() == InstanceContext);
+  assert(NamingClass->getCanonicalDecl() == NamingClass);
+
+  ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
+  if (PRC.findFriendship(InstanceContext)) return AR_accessible;
+  if (PRC.EverDependent) return AR_dependent;
+  return AR_inaccessible;
+}
+
 static AccessResult HasAccess(Sema &S,
                               const EffectiveContext &EC,
                               const CXXRecordDecl *NamingClass,
@@ -563,6 +712,9 @@
       if (ECRecord == NamingClass)
         return AR_accessible;
 
+      if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass))
+        OnFailure = AR_dependent;
+
     // [B3] and [M3]
     } else {
       assert(Access == AS_protected);
@@ -603,20 +755,25 @@
     }
   }
 
-  if (!NamingClass->hasFriends())
-    return OnFailure;
-
-  // Don't consider friends if we're under the [class.protected]
-  // restriction, above.
+  // [M3] and [B3] say that, if the target is protected in N, we grant
+  // access if the access occurs in a friend or member of some class P
+  // that's a subclass of N and where the target has some natural
+  // access in P.  The 'member' aspect is easy to handle because P
+  // would necessarily be one of the effective-context records, and we
+  // address that above.  The 'friend' aspect is completely ridiculous
+  // to implement because there are no restrictions at all on P
+  // *unless* the [class.protected] restriction applies.  If it does,
+  // however, we should ignore whether the naming class is a friend,
+  // and instead rely on whether any potential P is a friend.
   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;
+    switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) {
+    case AR_accessible: return AR_accessible;
     case AR_inaccessible: return OnFailure;
     case AR_dependent: return AR_dependent;
     }
+    llvm_unreachable("impossible friendship kind");
   }
 
   switch (GetFriendKind(S, EC, NamingClass)) {
@@ -844,6 +1001,10 @@
         << BS->getSourceRange()
         << (BaseAccess == AS_protected)
         << (BS->getAccessSpecifierAsWritten() == AS_none);
+      
+      if (D)
+        S.Diag(D->getLocation(), diag::note_field_decl);
+      
       return;
     }
   }
@@ -994,13 +1155,16 @@
   if (Entity.getAccess() == AS_public)
     return Sema::AR_accessible;
 
+  if (S.SuppressAccessChecking)
+    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));
+        DelayedDiagnostic::makeAccess(Loc, Entity));
     return Sema::AR_delayed;
   }
 
@@ -1127,9 +1291,10 @@
 
 /// Checks access to a constructor.
 Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
-                                  CXXConstructorDecl *Constructor,
-                                  const InitializedEntity &Entity,
-                                  AccessSpecifier Access) {
+                                                CXXConstructorDecl *Constructor,
+                                                const InitializedEntity &Entity,
+                                                AccessSpecifier Access,
+                                                bool IsCopyBindingRefToTemp) {
   if (!getLangOptions().AccessControl ||
       Access == AS_public)
     return AR_accessible;
@@ -1140,7 +1305,9 @@
                             QualType());
   switch (Entity.getKind()) {
   default:
-    AccessEntity.setDiag(diag::err_access_ctor);
+    AccessEntity.setDiag(IsCopyBindingRefToTemp
+                         ? diag::ext_rvalue_to_reference_access_ctor
+                         : diag::err_access_ctor);
     break;
 
   case InitializedEntity::EK_Base:
@@ -1230,7 +1397,7 @@
       Found.getAccess() == AS_public)
     return AR_accessible;
 
-  OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).getPointer();
+  OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression;
   CXXRecordDecl *NamingClass = Ovl->getNamingClass();
 
   AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
@@ -1301,3 +1468,15 @@
     }
   }
 }
+
+void Sema::ActOnStartSuppressingAccessChecks() {
+  assert(!SuppressAccessChecking &&
+         "Tried to start access check suppression when already started.");
+  SuppressAccessChecking = true;
+}
+
+void Sema::ActOnStopSuppressingAccessChecks() {
+  assert(SuppressAccessChecking &&
+         "Tried to stop access check suprression when already stopped.");
+  SuppressAccessChecking = false;
+}
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index 095f537..0921156 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -12,20 +12,32 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Expr.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/Preprocessor.h"
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
-// Pragma Packed
+// Pragma 'pack' and 'options align'
 //===----------------------------------------------------------------------===//
 
 namespace {
+  struct PackStackEntry {
+    // We just use a sentinel to represent when the stack is set to mac68k
+    // alignment.
+    static const unsigned kMac68kAlignmentSentinel = ~0U;
+
+    unsigned Alignment;
+    IdentifierInfo *Name;
+  };
+
   /// PragmaPackStack - Simple class to wrap the stack used by #pragma
   /// pack.
   class PragmaPackStack {
-    typedef std::vector< std::pair<unsigned, IdentifierInfo*> > stack_ty;
+    typedef std::vector<PackStackEntry> stack_ty;
 
     /// Alignment - The current user specified alignment.
     unsigned Alignment;
@@ -43,34 +55,47 @@
     /// 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));
+      PackStackEntry PSE = { Alignment, Name };
+      Stack.push_back(PSE);
     }
 
     /// 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);
+    bool pop(IdentifierInfo *Name, bool IsReset);
   };
 }  // end anonymous namespace.
 
-bool PragmaPackStack::pop(IdentifierInfo *Name) {
-  if (Stack.empty())
-    return false;
-
+bool PragmaPackStack::pop(IdentifierInfo *Name, bool IsReset) {
   // If name is empty just pop top.
   if (!Name) {
-    Alignment = Stack.back().first;
-    Stack.pop_back();
+    // An empty stack is a special case...
+    if (Stack.empty()) {
+      // If this isn't a reset, it is always an error.
+      if (!IsReset)
+        return false;
+
+      // Otherwise, it is an error only if some alignment has been set.
+      if (!Alignment)
+        return false;
+
+      // Otherwise, reset to the default alignment.
+      Alignment = 0;
+    } else {
+      Alignment = Stack.back().Alignment;
+      Stack.pop_back();
+    }
+
     return true;
   }
 
   // Otherwise, find the named record.
   for (unsigned i = Stack.size(); i != 0; ) {
     --i;
-    if (Stack[i].second == Name) {
+    if (Stack[i].Name == Name) {
       // Found it, pop up to and including this record.
-      Alignment = Stack[i].first;
+      Alignment = Stack[i].Alignment;
       Stack.erase(Stack.begin() + i, Stack.end());
       return true;
     }
@@ -86,12 +111,75 @@
   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::AddAlignmentAttributesForRecord(RecordDecl *RD) {
+  // If there is no pack context, we don't need any attributes.
+  if (!PackContext)
+    return;
+
+  PragmaPackStack *Stack = static_cast<PragmaPackStack*>(PackContext);
+
+  // Otherwise, check to see if we need a max field alignment attribute.
+  if (unsigned Alignment = Stack->getAlignment()) {
+    if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
+      RD->addAttr(::new (Context) AlignMac68kAttr(SourceLocation(), Context));
+    else
+      RD->addAttr(::new (Context) MaxFieldAlignmentAttr(SourceLocation(),
+                                                        Context,
+                                                        Alignment * 8));
+  }
+}
+
+void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
+                                   SourceLocation PragmaLoc,
+                                   SourceLocation KindLoc) {
+  if (PackContext == 0)
+    PackContext = new PragmaPackStack();
+
+  PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
+
+  // Reset just pops the top of the stack, or resets the current alignment to
+  // default.
+  if (Kind == Sema::POAK_Reset) {
+    if (!Context->pop(0, /*IsReset=*/true)) {
+      Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
+        << "stack empty";
+    }
+    return;
+  }
+
+  switch (Kind) {
+    // For all targets we support native and natural are the same.
+    //
+    // FIXME: This is not true on Darwin/PPC.
+  case POAK_Native:
+  case POAK_Power:
+  case POAK_Natural:
+    Context->push(0);
+    Context->setAlignment(0);
+    break;
+
+    // Note that '#pragma options align=packed' is not equivalent to attribute
+    // packed, it has a different precedence relative to attribute aligned.
+  case POAK_Packed:
+    Context->push(0);
+    Context->setAlignment(1);
+    break;
+
+  case POAK_Mac68k:
+    // Check if the target supports this.
+    if (!PP.getTargetInfo().hasAlignMac68kSupport()) {
+      Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported);
+      return;
+    }
+    Context->push(0);
+    Context->setAlignment(PackStackEntry::kMac68kAlignmentSentinel);
+    break;
+
+  default:
+    Diag(PragmaLoc, diag::warn_pragma_options_align_unsupported_option)
+      << KindLoc;
+    break;
+  }
 }
 
 void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
@@ -106,11 +194,12 @@
 
     // pack(0) is like pack(), which just works out since that is what
     // we use 0 for in PackAttr.
-    if (!Alignment->isIntegerConstantExpr(Val, Context) ||
+    if (Alignment->isTypeDependent() ||
+        Alignment->isValueDependent() ||
+        !Alignment->isIntegerConstantExpr(Val, Context) ||
         !(Val == 0 || Val.isPowerOf2()) ||
         Val.getZExtValue() > 16) {
       Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
-      Alignment->Destroy(Context);
       return; // Ignore
     }
 
@@ -123,35 +212,38 @@
   PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
 
   switch (Kind) {
-  case Action::PPK_Default: // pack([n])
+  case Sema::PPK_Default: // pack([n])
     Context->setAlignment(AlignmentVal);
     break;
 
-  case Action::PPK_Show: // pack(show)
+  case Sema::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;
+    if (AlignmentVal == PackStackEntry::kMac68kAlignmentSentinel)
+      Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k";
+    else
+      Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
     break;
 
-  case Action::PPK_Push: // pack(push [, id] [, [n])
+  case Sema::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])
+  case Sema::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 (!Context->pop(Name, /*IsReset=*/false)) {
       // If a name was specified then failure indicates the name
       // wasn't found. Otherwise failure indicates the stack was
       // empty.
@@ -196,6 +288,80 @@
       continue;
     }
 
-    VD->addAttr(::new (Context) UnusedAttr());
+    VD->addAttr(::new (Context) UnusedAttr(Tok.getLocation(), Context));
   }
 }
+
+typedef std::vector<std::pair<VisibilityAttr::VisibilityType,
+                              SourceLocation> > VisStack;
+
+void Sema::AddPushedVisibilityAttribute(Decl *D) {
+  if (!VisContext)
+    return;
+
+  if (D->hasAttr<VisibilityAttr>())
+    return;
+
+  VisStack *Stack = static_cast<VisStack*>(VisContext);
+  VisibilityAttr::VisibilityType type = Stack->back().first;
+  SourceLocation loc = Stack->back().second;
+
+  D->addAttr(::new (Context) VisibilityAttr(loc, Context, type));
+}
+
+/// FreeVisContext - Deallocate and null out VisContext.
+void Sema::FreeVisContext() {
+  delete static_cast<VisStack*>(VisContext);
+  VisContext = 0;
+}
+
+static void PushPragmaVisibility(Sema &S, VisibilityAttr::VisibilityType type,
+                                 SourceLocation loc) {
+  // Put visibility on stack.
+  if (!S.VisContext)
+    S.VisContext = new VisStack;
+
+  VisStack *Stack = static_cast<VisStack*>(S.VisContext);
+  Stack->push_back(std::make_pair(type, loc));
+}
+
+void Sema::ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType,
+                                 SourceLocation PragmaLoc) {
+  if (IsPush) {
+    // Compute visibility to use.
+    VisibilityAttr::VisibilityType type;
+    if (VisType->isStr("default"))
+      type = VisibilityAttr::Default;
+    else if (VisType->isStr("hidden"))
+      type = VisibilityAttr::Hidden;
+    else if (VisType->isStr("internal"))
+      type = VisibilityAttr::Hidden; // FIXME
+    else if (VisType->isStr("protected"))
+      type = VisibilityAttr::Protected;
+    else {
+      Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) <<
+        VisType->getName();
+      return;
+    }
+    PushPragmaVisibility(*this, type, PragmaLoc);
+  } else {
+    PopPragmaVisibility();
+  }
+}
+
+void Sema::PushVisibilityAttr(const VisibilityAttr *Attr) {
+  PushPragmaVisibility(*this, Attr->getVisibility(), Attr->getLocation());
+}
+
+void Sema::PopPragmaVisibility() {
+  // Pop visibility from stack, if there is one on the stack.
+  if (VisContext) {
+    VisStack *Stack = static_cast<VisStack*>(VisContext);
+
+    Stack->pop_back();
+    // To simplify the implementation, never keep around an empty stack.
+    if (Stack->empty())
+      FreeVisContext();
+  }
+  // FIXME: Add diag for pop without push.
+}
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index ba7e1ff..21b1a73 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -11,8 +11,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Initialization.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
@@ -43,16 +43,16 @@
 static void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                                  const SourceRange &OpRange,
                                  const SourceRange &DestRange,
-                                 CastExpr::CastKind &Kind);
+                                 CastKind &Kind);
 static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                             const SourceRange &OpRange,
-                            CastExpr::CastKind &Kind,
-                            CXXBaseSpecifierArray &BasePath);
+                            CastKind &Kind,
+                            CXXCastPath &BasePath);
 static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                              const SourceRange &OpRange,
                              const SourceRange &DestRange,
-                             CastExpr::CastKind &Kind,
-                             CXXBaseSpecifierArray &BasePath);
+                             CastKind &Kind,
+                             CXXCastPath &BasePath);
 
 static bool CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType);
 
@@ -73,54 +73,54 @@
                                                QualType DestType, bool CStyle,
                                                const SourceRange &OpRange,
                                                unsigned &msg,
-                                               CastExpr::CastKind &Kind,
-                                               CXXBaseSpecifierArray &BasePath);
+                                               CastKind &Kind,
+                                               CXXCastPath &BasePath);
 static TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType,
                                               QualType DestType, bool CStyle,
                                               const SourceRange &OpRange,
                                               unsigned &msg,
-                                              CastExpr::CastKind &Kind,
-                                              CXXBaseSpecifierArray &BasePath);
+                                              CastKind &Kind,
+                                              CXXCastPath &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);
+                                       CastKind &Kind,
+                                       CXXCastPath &BasePath);
 static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr,
                                                QualType SrcType,
                                                QualType DestType,bool CStyle,
                                                const SourceRange &OpRange,
                                                unsigned &msg,
-                                               CastExpr::CastKind &Kind,
-                                               CXXBaseSpecifierArray &BasePath);
+                                               CastKind &Kind,
+                                               CXXCastPath &BasePath);
 
 static TryCastResult TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr,
                                            QualType DestType, bool CStyle,
                                            const SourceRange &OpRange,
                                            unsigned &msg,
-                                           CastExpr::CastKind &Kind);
+                                           CastKind &Kind);
 static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
                                    QualType DestType, bool CStyle,
                                    const SourceRange &OpRange,
                                    unsigned &msg,
-                                   CastExpr::CastKind &Kind,
-                                   CXXBaseSpecifierArray &BasePath);
+                                   CastKind &Kind,
+                                   CXXCastPath &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);
+                                        CastKind &Kind);
 
 /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
-Action::OwningExprResult
+ExprResult
 Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
-                        SourceLocation LAngleBracketLoc, TypeTy *Ty,
+                        SourceLocation LAngleBracketLoc, ParsedType Ty,
                         SourceLocation RAngleBracketLoc,
-                        SourceLocation LParenLoc, ExprArg E,
+                        SourceLocation LParenLoc, Expr *E,
                         SourceLocation RParenLoc) {
   
   TypeSourceInfo *DestTInfo;
@@ -133,11 +133,10 @@
                            SourceRange(LParenLoc, RParenLoc));
 }
 
-Action::OwningExprResult
+ExprResult
 Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
-                        TypeSourceInfo *DestTInfo, ExprArg E,
+                        TypeSourceInfo *DestTInfo, Expr *Ex,
                         SourceRange AngleBrackets, SourceRange Parens) {
-  Expr *Ex = E.takeAs<Expr>();
   QualType DestType = DestTInfo->getType();
 
   SourceRange OpRange(OpLoc, Parens.getEnd());
@@ -153,36 +152,39 @@
   case tok::kw_const_cast:
     if (!TypeDependent)
       CheckConstCast(*this, Ex, DestType, OpRange, DestRange);
-    return Owned(new (Context) CXXConstCastExpr(DestType.getNonReferenceType(),
-                                                Ex, DestTInfo, OpLoc));
+    return Owned(CXXConstCastExpr::Create(Context,
+                                        DestType.getNonLValueExprType(Context),
+                                          Ex, DestTInfo, OpLoc));
 
   case tok::kw_dynamic_cast: {
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CastKind Kind = CK_Unknown;
+    CXXCastPath BasePath;
     if (!TypeDependent)
       CheckDynamicCast(*this, Ex, DestType, OpRange, DestRange, Kind, BasePath);
-    return Owned(new (Context)CXXDynamicCastExpr(DestType.getNonReferenceType(),
-                                                 Kind, Ex, BasePath, DestTInfo,
-                                                 OpLoc));
+    return Owned(CXXDynamicCastExpr::Create(Context,
+                                          DestType.getNonLValueExprType(Context),
+                                            Kind, Ex, &BasePath, DestTInfo,
+                                            OpLoc));
   }
   case tok::kw_reinterpret_cast: {
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+    CastKind Kind = CK_Unknown;
     if (!TypeDependent)
       CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange, Kind);
-    return Owned(new (Context) CXXReinterpretCastExpr(
-                                  DestType.getNonReferenceType(),
-                                  Kind, Ex, CXXBaseSpecifierArray(), 
+    return Owned(CXXReinterpretCastExpr::Create(Context,
+                                  DestType.getNonLValueExprType(Context),
+                                  Kind, Ex, 0,
                                   DestTInfo, OpLoc));
   }
   case tok::kw_static_cast: {
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CastKind Kind = CK_Unknown;
+    CXXCastPath BasePath;
     if (!TypeDependent)
       CheckStaticCast(*this, Ex, DestType, OpRange, Kind, BasePath);
     
-    return Owned(new (Context) CXXStaticCastExpr(DestType.getNonReferenceType(),
-                                                 Kind, Ex, BasePath,
-                                                 DestTInfo, OpLoc));
+    return Owned(CXXStaticCastExpr::Create(Context,
+                                         DestType.getNonLValueExprType(Context),
+                                           Kind, Ex, &BasePath,
+                                           DestTInfo, OpLoc));
   }
   }
 
@@ -194,7 +196,7 @@
 /// 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) {
+static bool UnwrapDissimilarPointerTypes(QualType& T1, QualType& T2) {
   const PointerType *T1PtrType = T1->getAs<PointerType>(),
                     *T2PtrType = T2->getAs<PointerType>();
   if (T1PtrType && T2PtrType) {
@@ -233,6 +235,15 @@
     T2 = T2MPType->getPointeeType();
     return true;
   }
+  
+  const BlockPointerType *T1BPType = T1->getAs<BlockPointerType>(),
+                         *T2BPType = T2->getAs<BlockPointerType>();
+  if (T1BPType && T2BPType) {
+    T1 = T1BPType->getPointeeType();
+    T2 = T2BPType->getPointeeType();
+    return true;
+  }
+  
   return false;
 }
 
@@ -246,9 +257,11 @@
   // 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()) &&
+  assert((SrcType->isAnyPointerType() || SrcType->isMemberPointerType() ||
+          SrcType->isBlockPointerType()) &&
          "Source type is not pointer or pointer to member.");
-  assert((DestType->isAnyPointerType() || DestType->isMemberPointerType()) &&
+  assert((DestType->isAnyPointerType() || DestType->isMemberPointerType() ||
+          DestType->isBlockPointerType()) &&
          "Destination type is not pointer or pointer to member.");
 
   QualType UnwrappedSrcType = Self.Context.getCanonicalType(SrcType), 
@@ -257,10 +270,16 @@
 
   // Find the qualifications.
   while (UnwrapDissimilarPointerTypes(UnwrappedSrcType, UnwrappedDestType)) {
-    cv1.push_back(UnwrappedSrcType.getQualifiers());
-    cv2.push_back(UnwrappedDestType.getQualifiers());
+    Qualifiers SrcQuals;
+    Self.Context.getUnqualifiedArrayType(UnwrappedSrcType, SrcQuals);
+    cv1.push_back(SrcQuals);
+    
+    Qualifiers DestQuals;
+    Self.Context.getUnqualifiedArrayType(UnwrappedDestType, DestQuals);
+    cv2.push_back(DestQuals);
   }
-  assert(cv1.size() > 0 && "Must have at least one pointer level.");
+  if (cv1.empty())
+    return false;
 
   // Construct void pointers with those qualifiers (in reverse order of
   // unwrapping, of course).
@@ -287,8 +306,8 @@
 static void
 CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                  const SourceRange &OpRange,
-                 const SourceRange &DestRange, CastExpr::CastKind &Kind,
-                 CXXBaseSpecifierArray &BasePath) {
+                 const SourceRange &DestRange, CastKind &Kind,
+                 CXXCastPath &BasePath) {
   QualType OrigDestType = DestType, OrigSrcType = SrcExpr->getType();
   DestType = Self.Context.getCanonicalType(DestType);
 
@@ -376,6 +395,7 @@
   // C++ 5.2.7p3: If the type of v is the same as the required result type,
   //   [except for cv].
   if (DestRecord == SrcRecord) {
+    Kind = CK_NoOp;
     return;
   }
 
@@ -387,7 +407,13 @@
                                            &BasePath))
         return;
         
-    Kind = CastExpr::CK_DerivedToBase;
+    Kind = CK_DerivedToBase;
+
+    // If we are casting to or through a virtual base class, we need a
+    // vtable.
+    if (Self.BasePathInvolvesVirtualBase(BasePath))
+      Self.MarkVTableUsed(OpRange.getBegin(), 
+                          cast<CXXRecordDecl>(SrcRecord->getDecl()));
     return;
   }
 
@@ -398,9 +424,11 @@
     Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
       << SrcPointee.getUnqualifiedType() << SrcExpr->getSourceRange();
   }
+  Self.MarkVTableUsed(OpRange.getBegin(), 
+                      cast<CXXRecordDecl>(SrcRecord->getDecl()));
 
   // Done. Everything else is run-time checks.
-  Kind = CastExpr::CK_Dynamic;
+  Kind = CK_Dynamic;
 }
 
 /// CheckConstCast - Check that a const_cast\<DestType\>(SrcExpr) is valid.
@@ -429,7 +457,7 @@
 void
 CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                      const SourceRange &OpRange, const SourceRange &DestRange,
-                     CastExpr::CastKind &Kind) {
+                     CastKind &Kind) {
   if (!DestType->isLValueReferenceType())
     Self.DefaultFunctionArrayLvalueConversion(SrcExpr);
 
@@ -447,13 +475,13 @@
 /// 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) {
+                const SourceRange &OpRange, CastKind &Kind,
+                CXXCastPath &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;
+    Kind = CK_ToVoid;
     return;
   }
 
@@ -465,6 +493,8 @@
                     Kind, BasePath) != TC_Success && msg != 0)
     Self.Diag(OpRange.getBegin(), msg) << CT_Static
       << SrcExpr->getType() << DestType << OpRange;
+  else if (Kind == CK_Unknown || Kind == CK_BitCast)
+    Self.CheckCastAlign(SrcExpr, DestType, OpRange);
 }
 
 /// TryStaticCast - Check if a static cast can be performed, and do so if
@@ -473,8 +503,8 @@
 static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
                                    QualType DestType, bool CStyle,
                                    const SourceRange &OpRange, unsigned &msg,
-                                   CastExpr::CastKind &Kind,
-                                   CXXBaseSpecifierArray &BasePath) {
+                                   CastKind &Kind,
+                                   CXXCastPath &BasePath) {
   // The order the tests is not entirely arbitrary. There is one conversion
   // that can be handled in two different ways. Given:
   // struct A {};
@@ -504,7 +534,7 @@
   //   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;
+    Kind = CK_NoOp;
     return tcr;
   }
 
@@ -539,7 +569,7 @@
     if (SrcType->isComplexType() || SrcType->isVectorType()) {
       // Fall through - these cannot be converted.
     } else if (SrcType->isArithmeticType() || SrcType->isEnumeralType()) {
-      Kind = CastExpr::CK_IntegralCast;
+      Kind = CK_IntegralCast;
       return TC_Success;
     }
   }
@@ -574,23 +604,28 @@
             msg = diag::err_bad_cxx_cast_const_away;
             return TC_Failed;
           }
-          Kind = CastExpr::CK_BitCast;
+          Kind = 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;
+      else if (DestType->isObjCObjectPointerType()) {
+        // allow both c-style cast and static_cast of objective-c pointers as 
+        // they are pervasive.
+        Kind = CK_AnyPointerToObjCPointerCast;
         return TC_Success;
       }
       else if (CStyle && DestType->isBlockPointerType()) {
         // allow c-style cast of void * to block pointers.
-        Kind = CastExpr::CK_AnyPointerToBlockPointerCast;
+        Kind = CK_AnyPointerToBlockPointerCast;
         return TC_Success;
       }
     }
   }
-
+  // Allow arbitray objective-c pointer conversion with static casts.
+  if (SrcType->isObjCObjectPointerType() &&
+      DestType->isObjCObjectPointerType())
+    return TC_Success;
+  
   // We tried everything. Everything! Nothing works! :-(
   return TC_NotApplicable;
 }
@@ -612,9 +647,10 @@
   // 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;
+  bool ObjCConversion;
   if (Self.CompareReferenceRelationship(SrcExpr->getLocStart(),
                                         SrcExpr->getType(), R->getPointeeType(),
-                                        DerivedToBase) <
+                                        DerivedToBase, ObjCConversion) <
         Sema::Ref_Compatible_With_Added_Qualification) {
     msg = diag::err_bad_lvalue_to_rvalue_cast;
     return TC_Failed;
@@ -629,8 +665,8 @@
 TryCastResult
 TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType,
                            bool CStyle, const SourceRange &OpRange,
-                           unsigned &msg, CastExpr::CastKind &Kind,
-                           CXXBaseSpecifierArray &BasePath) {
+                           unsigned &msg, CastKind &Kind,
+                           CXXCastPath &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"
@@ -664,8 +700,8 @@
 TryCastResult
 TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType,
                          bool CStyle, const SourceRange &OpRange,
-                         unsigned &msg, CastExpr::CastKind &Kind,
-                         CXXBaseSpecifierArray &BasePath) {
+                         unsigned &msg, CastKind &Kind,
+                         CXXCastPath &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
@@ -699,7 +735,7 @@
 TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType,
                   bool CStyle, const SourceRange &OpRange, QualType OrigSrcType,
                   QualType OrigDestType, unsigned &msg, 
-                  CastExpr::CastKind &Kind, CXXBaseSpecifierArray &BasePath) {
+                  CastKind &Kind, CXXCastPath &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)))
@@ -791,7 +827,7 @@
   }
 
   Self.BuildBasePathArray(Paths, BasePath);
-  Kind = CastExpr::CK_BaseToDerived;
+  Kind = CK_BaseToDerived;
   return TC_Success;
 }
 
@@ -806,8 +842,8 @@
 TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType, 
                              QualType DestType, bool CStyle, 
                              const SourceRange &OpRange,
-                             unsigned &msg, CastExpr::CastKind &Kind,
-                             CXXBaseSpecifierArray &BasePath) {
+                             unsigned &msg, CastKind &Kind,
+                             CXXCastPath &BasePath) {
   const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>();
   if (!DestMemPtr)
     return TC_NotApplicable;
@@ -846,7 +882,7 @@
   }
 
   // B is a base of D. But is it an allowed base? If not, it's a hard error.
-  if (Paths.isAmbiguous(DestClass)) {
+  if (Paths.isAmbiguous(Self.Context.getCanonicalType(DestClass))) {
     Paths.clear();
     Paths.setRecordingPaths(true);
     bool StillOkay = Self.IsDerivedFrom(SrcClass, DestClass, Paths);
@@ -867,7 +903,7 @@
   }
 
   if (!CStyle && Self.CheckBaseClassAccess(OpRange.getBegin(),
-                                           DestType, SrcType,
+                                           DestClass, SrcClass,
                                            Paths.front(),
                                      diag::err_upcast_to_inaccessible_base)) {
     msg = 0;
@@ -894,7 +930,7 @@
   }
 
   Self.BuildBasePathArray(Paths, BasePath);
-  Kind = CastExpr::CK_DerivedToBaseMemberPointer;
+  Kind = CK_DerivedToBaseMemberPointer;
   return TC_Success;
 }
 
@@ -906,7 +942,7 @@
 TryCastResult
 TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                       bool CStyle, const SourceRange &OpRange, unsigned &msg,
-                      CastExpr::CastKind &Kind) {
+                      CastKind &Kind) {
   if (DestType->isRecordType()) {
     if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
                                  diag::err_bad_dynamic_cast_incomplete)) {
@@ -928,18 +964,17 @@
       (CStyle || !DestType->isReferenceType()))
     return TC_NotApplicable;
     
-  Sema::OwningExprResult Result
-    = InitSeq.Perform(Self, Entity, InitKind,
-                      Action::MultiExprArg(Self, (void**)&SrcExpr, 1));
+  ExprResult Result
+    = InitSeq.Perform(Self, Entity, InitKind, MultiExprArg(Self, &SrcExpr, 1));
   if (Result.isInvalid()) {
     msg = 0;
     return TC_Failed;
   }
   
   if (InitSeq.isConstructorInitialization())
-    Kind = CastExpr::CK_ConstructorConversion;
+    Kind = CK_ConstructorConversion;
   else
-    Kind = CastExpr::CK_NoOp;
+    Kind = CK_NoOp;
   
   SrcExpr = Result.takeAs<Expr>();
   return TC_Success;
@@ -970,7 +1005,9 @@
   // 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()) {
+  if (!DestType->isPointerType() &&
+      !DestType->isMemberPointerType() &&
+      !DestType->isObjCObjectPointerType()) {
     // 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
@@ -999,7 +1036,7 @@
   // 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)) {
+         Self.Context.UnwrapSimilarPointerTypes(SrcType, DestType)) {
     Qualifiers Quals;
     SrcType = Self.Context.getUnqualifiedArrayType(SrcType, Quals);
     DestType = Self.Context.getUnqualifiedArrayType(DestType, Quals);
@@ -1016,7 +1053,9 @@
                                         QualType DestType, bool CStyle,
                                         const SourceRange &OpRange,
                                         unsigned &msg,
-                                        CastExpr::CastKind &Kind) {
+                                        CastKind &Kind) {
+  bool IsLValueCast = false;
+  
   DestType = Self.Context.getCanonicalType(DestType);
   QualType SrcType = SrcExpr->getType();
   if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) {
@@ -1034,6 +1073,7 @@
     // This code does this transformation for the checked types.
     DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType());
     SrcType = Self.Context.getPointerType(SrcType);
+    IsLValueCast = true;
   }
 
   // Canonicalize source for comparison.
@@ -1059,14 +1099,20 @@
       return TC_Failed;
     }
 
+    // Don't allow casting between member pointers of different sizes.
+    if (Self.Context.getTypeSize(DestMemPtr) !=
+        Self.Context.getTypeSize(SrcMemPtr)) {
+      msg = diag::err_bad_cxx_cast_member_pointer_size;
+      return TC_Failed;
+    }
+
     // A valid member pointer cast.
-    Kind = CastExpr::CK_BitCast;
+    Kind = IsLValueCast? CK_LValueBitCast : CK_BitCast;
     return TC_Success;
   }
 
   // See below for the enumeral issue.
-  if (SrcType->isNullPtrType() && DestType->isIntegralType() &&
-      !DestType->isEnumeralType()) {
+  if (SrcType->isNullPtrType() && DestType->isIntegralType(Self.Context)) {
     // 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
@@ -1076,16 +1122,16 @@
       msg = diag::err_bad_reinterpret_cast_small_int;
       return TC_Failed;
     }
-    Kind = CastExpr::CK_PointerToIntegral;
+    Kind = 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();
+    // FIXME: Should this also apply to floating point types?
+    bool srcIsScalar = SrcType->isIntegralType(Self.Context);
+    bool destIsScalar = DestType->isIntegralType(Self.Context);
     
     // Check if this is a cast between a vector and something else.
     if (!(srcIsScalar && destIsVector) && !(srcIsVector && destIsScalar) &&
@@ -1095,7 +1141,7 @@
     // If both types have the same size, we can successfully cast.
     if (Self.Context.getTypeSize(SrcType)
           == Self.Context.getTypeSize(DestType)) {
-      Kind = CastExpr::CK_BitCast;
+      Kind = CK_BitCast;
       return TC_Success;
     }
     
@@ -1109,8 +1155,10 @@
     return TC_Failed;
   }
   
-  bool destIsPtr = DestType->isAnyPointerType();
-  bool srcIsPtr = SrcType->isAnyPointerType();
+  bool destIsPtr = DestType->isAnyPointerType() ||
+                   DestType->isBlockPointerType();
+  bool srcIsPtr = SrcType->isAnyPointerType() ||
+                  SrcType->isBlockPointerType();
   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.
@@ -1124,13 +1172,11 @@
     // 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;
+    Kind = 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()) {
+  if (DestType->isIntegralType(Self.Context)) {
     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.
@@ -1139,15 +1185,15 @@
       msg = diag::err_bad_reinterpret_cast_small_int;
       return TC_Failed;
     }
-    Kind = CastExpr::CK_PointerToIntegral;
+    Kind = CK_PointerToIntegral;
     return TC_Success;
   }
 
-  if (SrcType->isIntegralType() || SrcType->isEnumeralType()) {
+  if (SrcType->isIntegralOrEnumerationType()) {
     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;
+    Kind = CK_IntegralToPointer;
     return TC_Success;
   }
 
@@ -1163,14 +1209,22 @@
     msg = diag::err_bad_cxx_cast_const_away;
     return TC_Failed;
   }
+  
+  // Cannot convert between block pointers and Objective-C object pointers.
+  if ((SrcType->isBlockPointerType() && DestType->isObjCObjectPointerType()) ||
+      (DestType->isBlockPointerType() && SrcType->isObjCObjectPointerType()))
+    return TC_NotApplicable;
+
+  // Any pointer can be cast to an Objective-C pointer type with a C-style
+  // cast.
   if (CStyle && DestType->isObjCObjectPointerType()) {
-    Kind = CastExpr::CK_AnyPointerToObjCPointerCast;
+    Kind = CK_AnyPointerToObjCPointerCast;
     return TC_Success;
   }
-  
+    
   // Not casting away constness, so the only remaining check is for compatible
   // pointer categories.
-  Kind = CastExpr::CK_BitCast;
+  Kind = IsLValueCast? CK_LValueBitCast : CK_BitCast;
 
   if (SrcType->isFunctionPointerType()) {
     if (DestType->isFunctionPointerType()) {
@@ -1196,7 +1250,7 @@
       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.
@@ -1207,14 +1261,14 @@
 
 bool 
 Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
-                         CastExpr::CastKind &Kind, 
-                         CXXBaseSpecifierArray &BasePath,
+                         CastKind &Kind, 
+                         CXXCastPath &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;
+    Kind = CK_ToVoid;
     return false;
   }
 
@@ -1240,7 +1294,7 @@
   TryCastResult tcr = TryConstCast(*this, CastExpr, CastTy, /*CStyle*/true,
                                    msg);
   if (tcr == TC_Success)
-    Kind = CastExpr::CK_NoOp;
+    Kind = CK_NoOp;
 
   if (tcr == TC_NotApplicable) {
     // ... or if that is not possible, a static_cast, ignoring const, ...
@@ -1256,6 +1310,8 @@
   if (tcr != TC_Success && msg != 0)
     Diag(R.getBegin(), msg) << (FunctionalStyle ? CT_Functional : CT_CStyle)
       << CastExpr->getType() << CastTy << R;
+  else if (Kind == CK_Unknown || Kind == CK_BitCast)
+    CheckCastAlign(CastExpr, CastTy, R);
 
   return tcr != TC_Success;
 }
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 10adc67..d7ef793 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -11,14 +11,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/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 "clang/Sema/DeclSpec.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
@@ -96,7 +96,7 @@
           // injected class name of the named class template, we're entering
           // into that class template definition.
           QualType Injected
-            = ClassTemplate->getInjectedClassNameSpecialization(Context);
+            = ClassTemplate->getInjectedClassNameSpecialization();
           if (Context.hasSameType(Injected, ContextType))
             return ClassTemplate->getTemplatedDecl();
 
@@ -186,21 +186,10 @@
 /// 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;
+bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS,
+                                      DeclContext *DC) {
+  assert(DC != 0 && "given null context");
 
-  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())
@@ -216,7 +205,7 @@
     if (RequireCompleteType(SS.getRange().getBegin(),
                             Context.getTypeDeclType(Tag),
                             PDiag(diag::err_incomplete_nested_name_spec)
-                            << SS.getRange())) {
+                              << SS.getRange())) {
       SS.setScopeRep(0);  // Mark the ScopeSpec invalid.
       return true;
     }
@@ -294,7 +283,7 @@
 bool Sema::isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
                                         SourceLocation IdLoc,
                                         IdentifierInfo &II,
-                                        TypeTy *ObjectTypePtr) {
+                                        ParsedType ObjectTypePtr) {
   QualType ObjectType = GetTypeFromParser(ObjectTypePtr);
   LookupResult Found(*this, &II, IdLoc, LookupNestedNameSpecifierName);
   
@@ -322,7 +311,8 @@
     // nested-name-specifier.
     
     // The declaration context must be complete.
-    if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(SS))
+    if (!LookupCtx->isDependentContext() &&
+        RequireCompleteDeclContext(SS, LookupCtx))
       return false;
     
     LookupQualifiedName(Found, LookupCtx);
@@ -392,7 +382,8 @@
     // nested-name-specifier.
 
     // The declaration context must be complete.
-    if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(SS))
+    if (!LookupCtx->isDependentContext() &&
+        RequireCompleteDeclContext(SS, LookupCtx))
       return 0;
 
     LookupQualifiedName(Found, LookupCtx);
@@ -425,7 +416,17 @@
 
       ObjectTypeSearchedInScope = true;
     }
-  } else if (isDependent) {
+  } else if (!isDependent) {
+    // Perform unqualified name lookup in the current scope.
+    LookupName(Found, S);
+  }
+
+  // If we performed lookup into a dependent context and did not find anything,
+  // that's fine: just build a dependent nested-name-specifier.
+  if (Found.empty() && isDependent &&
+      !(LookupCtx && LookupCtx->isRecord() &&
+        (!cast<CXXRecordDecl>(LookupCtx)->hasDefinition() ||
+         !cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases()))) {
     // Don't speculate if we're just trying to improve error recovery.
     if (ErrorRecoveryLookup)
       return 0;
@@ -438,11 +439,8 @@
       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) {
@@ -467,8 +465,10 @@
       if (NamedDecl *ND = Found.getAsSingle<NamedDecl>())
         Diag(ND->getLocation(), diag::note_previous_decl)
           << ND->getDeclName();
-    } else
+    } else {
       Found.clear();
+      Found.setLookupName(&II);
+    }
   }
 
   NamedDecl *SD = Found.getAsSingle<NamedDecl>();
@@ -567,10 +567,10 @@
                                                     SourceLocation IdLoc,
                                                     SourceLocation CCLoc,
                                                     IdentifierInfo &II,
-                                                    TypeTy *ObjectTypePtr,
+                                                    ParsedType ObjectTypePtr,
                                                     bool EnteringContext) {
   return BuildCXXNestedNameSpecifier(S, SS, IdLoc, CCLoc, II,
-                                     QualType::getFromOpaquePtr(ObjectTypePtr),
+                                     GetTypeFromParser(ObjectTypePtr),
                                      /*ScopeLookupResult=*/0, EnteringContext,
                                      false);
 }
@@ -582,21 +582,20 @@
 ///
 /// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
 bool Sema::IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS,
-                                     IdentifierInfo &II, TypeTy *ObjectType,
+                                     IdentifierInfo &II, ParsedType ObjectType,
                                      bool EnteringContext) {
   return BuildCXXNestedNameSpecifier(S, SS, SourceLocation(), SourceLocation(),
-                                     II, QualType::getFromOpaquePtr(ObjectType),
+                                     II, GetTypeFromParser(ObjectType),
                                      /*ScopeLookupResult=*/0, EnteringContext,
                                      true);
 }
 
 Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
                                                     const CXXScopeSpec &SS,
-                                                    TypeTy *Ty,
+                                                    ParsedType Ty,
                                                     SourceRange TypeRange,
                                                     SourceLocation CCLoc) {
-  NestedNameSpecifier *Prefix
-    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  NestedNameSpecifier *Prefix = SS.getScopeRep();
   QualType T = GetTypeFromParser(Ty);
   return NestedNameSpecifier::Create(Context, Prefix, /*FIXME:*/false,
                                      T.getTypePtr());
@@ -656,7 +655,7 @@
 
   // Before we enter a declarator's context, we need to make sure that
   // it is a complete declaration context.
-  if (!DC->isDependentContext() && RequireCompleteDeclContext(SS))
+  if (!DC->isDependentContext() && RequireCompleteDeclContext(SS, DC))
     return true;
     
   EnterDeclaratorContext(S, DC);
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 0373ca8..caef9fb 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -12,10 +12,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "clang/Analysis/Analyses/PrintfFormatString.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Analysis/Analyses/FormatString.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
@@ -26,9 +29,12 @@
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/raw_ostream.h"
 #include "clang/Basic/TargetBuiltins.h"
+#include "clang/Basic/TargetInfo.h"
 #include <limits>
 using namespace clang;
+using namespace sema;
 
 /// getLocationOfStringLiteralByte - Return a source location that points to the
 /// specified byte of the specified string literal.
@@ -75,14 +81,15 @@
     TheLexer.LexFromRawLexer(TheTok);
 
     // Use the StringLiteralParser to compute the length of the string in bytes.
-    StringLiteralParser SLP(&TheTok, 1, PP);
+    StringLiteralParser SLP(&TheTok, 1, PP, /*Complain=*/false);
     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);
+        StringLiteralParser::getOffsetOfStringByte(TheTok, ByteNo, PP,
+                                                   /*Complain=*/false);
 
       // Now that we know the offset of the token in the spelling, use the
       // preprocessor to get the offset in the original source.
@@ -118,9 +125,9 @@
   return false;
 }
 
-Action::OwningExprResult
+ExprResult
 Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
-  OwningExprResult TheCallResult(Owned(TheCall));
+  ExprResult TheCallResult(Owned(TheCall));
 
   switch (BuiltinID) {
   case Builtin::BI__builtin___CFStringMakeConstantString:
@@ -198,21 +205,123 @@
   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.
+    return SemaBuiltinAtomicOverloaded(move(TheCallResult));
+  }
+  
+  // Since the target specific builtins for each arch overlap, only check those
+  // of the arch we are compiling for.
+  if (BuiltinID >= Builtin::FirstTSBuiltin) {
+    switch (Context.Target.getTriple().getArch()) {
+      case llvm::Triple::arm:
+      case llvm::Triple::thumb:
+        if (CheckARMBuiltinFunctionCall(BuiltinID, TheCall))
+          return ExprError();
+        break;
+      case llvm::Triple::x86:
+      case llvm::Triple::x86_64:
+        if (CheckX86BuiltinFunctionCall(BuiltinID, TheCall))
+          return ExprError();
+        break;
+      default:
+        break;
+    }
+  }
+
+  return move(TheCallResult);
+}
+
+bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  switch (BuiltinID) {
   case X86::BI__builtin_ia32_palignr128:
   case X86::BI__builtin_ia32_palignr: {
     llvm::APSInt Result;
     if (SemaBuiltinConstantArg(TheCall, 2, Result))
-      return ExprError();
+      return true;
     break;
   }
   }
+  return false;
+}
 
-  return move(TheCallResult);
+// Get the valid immediate range for the specified NEON type code.
+static unsigned RFT(unsigned t, bool shift = false) {
+  bool quad = t & 0x10;
+  
+  switch (t & 0x7) {
+    case 0: // i8
+      return shift ? 7 : (8 << (int)quad) - 1;
+    case 1: // i16
+      return shift ? 15 : (4 << (int)quad) - 1;
+    case 2: // i32
+      return shift ? 31 : (2 << (int)quad) - 1;
+    case 3: // i64
+      return shift ? 63 : (1 << (int)quad) - 1;
+    case 4: // f32
+      assert(!shift && "cannot shift float types!");
+      return (2 << (int)quad) - 1;
+    case 5: // poly8
+      assert(!shift && "cannot shift polynomial types!");
+      return (8 << (int)quad) - 1;
+    case 6: // poly16
+      assert(!shift && "cannot shift polynomial types!");
+      return (4 << (int)quad) - 1;
+    case 7: // float16
+      assert(!shift && "cannot shift float types!");
+      return (4 << (int)quad) - 1;
+  }
+  return 0;
+}
+
+bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  llvm::APSInt Result;
+
+  unsigned mask = 0;
+  unsigned TV = 0;
+  switch (BuiltinID) {
+#define GET_NEON_OVERLOAD_CHECK
+#include "clang/Basic/arm_neon.inc"
+#undef GET_NEON_OVERLOAD_CHECK
+  }
+  
+  // For NEON intrinsics which are overloaded on vector element type, validate
+  // the immediate which specifies which variant to emit.
+  if (mask) {
+    unsigned ArgNo = TheCall->getNumArgs()-1;
+    if (SemaBuiltinConstantArg(TheCall, ArgNo, Result))
+      return true;
+    
+    TV = Result.getLimitedValue(32);
+    if ((TV > 31) || (mask & (1 << TV)) == 0)
+      return Diag(TheCall->getLocStart(), diag::err_invalid_neon_type_code)
+        << TheCall->getArg(ArgNo)->getSourceRange();
+  }
+  
+  // For NEON intrinsics which take an immediate value as part of the 
+  // instruction, range check them here.
+  unsigned i = 0, l = 0, u = 0;
+  switch (BuiltinID) {
+  default: return false;
+  case ARM::BI__builtin_arm_ssat: i = 1; l = 1; u = 31; break;
+  case ARM::BI__builtin_arm_usat: i = 1; u = 31; break;
+  case ARM::BI__builtin_arm_vcvtr_f:
+  case ARM::BI__builtin_arm_vcvtr_d: i = 1; u = 1; break;
+#define GET_NEON_IMMEDIATE_CHECK
+#include "clang/Basic/arm_neon.inc"
+#undef GET_NEON_IMMEDIATE_CHECK
+  };
+
+  // Check that the immediate argument is actually a constant.
+  if (SemaBuiltinConstantArg(TheCall, i, Result))
+    return true;
+
+  // Range check against the upper/lower values for this isntruction.
+  unsigned Val = Result.getZExtValue();
+  if (Val < l || Val > (u + l))
+    return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
+      << l << u+l << TheCall->getArg(i)->getSourceRange();
+
+  // FIXME: VFP Intrinsics should error if VFP not present.
+  return false;
 }
 
 /// CheckFunctionCall - Check a direct function call for various correctness
@@ -232,16 +341,22 @@
 
   // Printf checking.
   if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) {
-    if (CheckablePrintfAttr(Format, TheCall)) {
+    const bool b = Format->getType() == "scanf";
+    if (b || CheckablePrintfAttr(Format, TheCall)) {
       bool HasVAListArg = Format->getFirstArg() == 0;
-      CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1,
-                           HasVAListArg ? 0 : Format->getFirstArg() - 1);
+      CheckPrintfScanfArguments(TheCall, HasVAListArg,
+                                Format->getFormatIdx() - 1,
+                                HasVAListArg ? 0 : Format->getFirstArg() - 1,
+                                !b);
     }
   }
 
-  for (const NonNullAttr *NonNull = FDecl->getAttr<NonNullAttr>(); NonNull;
-       NonNull = NonNull->getNext<NonNullAttr>())
-    CheckNonNullArguments(NonNull, TheCall);
+  specific_attr_iterator<NonNullAttr>
+    i = FDecl->specific_attr_begin<NonNullAttr>(),
+    e = FDecl->specific_attr_end<NonNullAttr>();
+
+  for (; i != e; ++i)
+    CheckNonNullArguments(*i, TheCall);
 
   return false;
 }
@@ -260,12 +375,13 @@
   if (!Ty->isBlockPointerType())
     return false;
 
-  if (!CheckablePrintfAttr(Format, TheCall))
+  const bool b = Format->getType() == "scanf";
+  if (!b && !CheckablePrintfAttr(Format, TheCall))
     return false;
 
   bool HasVAListArg = Format->getFirstArg() == 0;
-  CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1,
-                       HasVAListArg ? 0 : Format->getFirstArg() - 1);
+  CheckPrintfScanfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1,
+                            HasVAListArg ? 0 : Format->getFirstArg() - 1, !b);
 
   return false;
 }
@@ -278,32 +394,44 @@
 ///
 /// This function goes through and does final semantic checking for these
 /// builtins,
-bool Sema::SemaBuiltinAtomicOverloaded(CallExpr *TheCall) {
+ExprResult
+Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
+  CallExpr *TheCall = (CallExpr *)TheCallResult.get();
   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();
+  if (TheCall->getNumArgs() < 1) {
+    Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args_at_least)
+      << 0 << 1 << TheCall->getNumArgs()
+      << TheCall->getCallee()->getSourceRange();
+    return ExprError();
+  }
 
   // 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.
+  // FIXME: We don't allow floating point scalars as input.
   Expr *FirstArg = TheCall->getArg(0);
-  if (!FirstArg->getType()->isPointerType())
-    return Diag(DRE->getLocStart(), diag::err_atomic_builtin_must_be_pointer)
-             << FirstArg->getType() << FirstArg->getSourceRange();
+  if (!FirstArg->getType()->isPointerType()) {
+    Diag(DRE->getLocStart(), diag::err_atomic_builtin_must_be_pointer)
+      << FirstArg->getType() << FirstArg->getSourceRange();
+    return ExprError();
+  }
 
-  QualType ValType = FirstArg->getType()->getAs<PointerType>()->getPointeeType();
+  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();
+      !ValType->isBlockPointerType()) {
+    Diag(DRE->getLocStart(), diag::err_atomic_builtin_must_be_pointer_intptr)
+      << FirstArg->getType() << FirstArg->getSourceRange();
+    return ExprError();
+  }
+
+  // The majority of builtins return a value, but a few have special return
+  // types, so allow them to override appropriately below.
+  QualType ResultType = ValType;
 
   // We need to figure out which concrete builtin this maps onto.  For example,
   // __sync_fetch_and_add with a 2 byte object turns into
@@ -341,8 +469,9 @@
   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();
+    Diag(DRE->getLocStart(), diag::err_atomic_builtin_pointer_size)
+      << FirstArg->getType() << FirstArg->getSourceRange();
+    return ExprError();
   }
 
   // Each of these builtins has one pointer argument, followed by some number of
@@ -372,22 +501,24 @@
   case Builtin::BI__sync_bool_compare_and_swap:
     BuiltinIndex = 11;
     NumFixed = 2;
+    ResultType = Context.BoolTy;
     break;
   case Builtin::BI__sync_lock_test_and_set: BuiltinIndex = 12; break;
   case Builtin::BI__sync_lock_release:
     BuiltinIndex = 13;
     NumFixed = 0;
+    ResultType = Context.VoidTy;
     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();
-
+  if (TheCall->getNumArgs() < 1+NumFixed) {
+    Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args_at_least)
+      << 0 << 1+NumFixed << TheCall->getNumArgs()
+      << TheCall->getCallee()->getSourceRange();
+    return ExprError();
+  }
 
   // Get the decl for the concrete builtin from this, we can tell what the
   // concrete integer type we should convert to is.
@@ -397,17 +528,10 @@
   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.
+  // The first argument --- the pointer --- has a fixed type; we
+  // deduce the types of the rest of the arguments accordingly.  Walk
+  // the remaining arguments, converting them to the deduced value type.
   for (unsigned i = 0; i != NumFixed; ++i) {
     Expr *Arg = TheCall->getArg(i+1);
 
@@ -416,16 +540,15 @@
     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;
+    CastKind Kind = CK_Unknown;
+    CXXCastPath BasePath;
     if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, BasePath))
-      return true;
+      return ExprError();
 
     // 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
@@ -433,7 +556,7 @@
     // 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);
+    ImpCastExprToType(Arg, ValType, Kind, VK_RValue, &BasePath);
     TheCall->setArg(i+1, Arg);
   }
 
@@ -447,10 +570,12 @@
   UsualUnaryConversions(PromotedCall);
   TheCall->setCallee(PromotedCall);
 
+  // Change the result type of the call to match the original value type. This
+  // is arbitrary, but the codegen for these builtins ins design to handle it
+  // gracefully.
+  TheCall->setType(ResultType);
 
-  // Change the result type of the call to match the result type of the decl.
-  TheCall->setType(NewBuiltinDecl->getResultType());
-  return false;
+  return move(TheCallResult);
 }
 
 
@@ -471,16 +596,11 @@
     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;
-    }
+  size_t NulPos = Literal->getString().find('\0');
+  if (NulPos != llvm::StringRef::npos) {
+    Diag(getLocationOfStringLiteralByte(Literal, NulPos),
+         diag::warn_cfstring_literal_contains_nul_character)
+      << Arg->getSourceRange();
   }
 
   return false;
@@ -510,16 +630,11 @@
   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 = CurBlock->TheDecl->isVariadic();
+  else if (FunctionDecl *FD = getCurFunctionDecl())
+    isVariadic = FD->isVariadic();
+  else
     isVariadic = getCurMethodDecl()->isVariadic();
-  }
 
   if (!isVariadic) {
     Diag(Fn->getLocStart(), diag::err_va_start_used_in_non_variadic_function);
@@ -612,57 +727,78 @@
   if (OrigArg->isTypeDependent())
     return false;
 
-  // This operation requires a floating-point number
+  // This operation requires a non-_Complex floating-point number.
   if (!OrigArg->getType()->isRealFloatingType())
     return Diag(OrigArg->getLocStart(),
                 diag::err_typecheck_call_invalid_unary_fp)
       << OrigArg->getType() << OrigArg->getSourceRange();
 
+  // If this is an implicit conversion from float -> double, remove it.
+  if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) {
+    Expr *CastArg = Cast->getSubExpr();
+    if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) {
+      assert(Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) &&
+             "promotion from float to double is the only expected cast here");
+      Cast->setSubExpr(0);
+      TheCall->setArg(NumArgs-1, CastArg);
+      OrigArg = CastArg;
+    }
+  }
+  
   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)
+ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
+  if (TheCall->getNumArgs() < 2)
     return ExprError(Diag(TheCall->getLocEnd(),
                           diag::err_typecheck_call_too_few_args_at_least)
-      << 0 /*function call*/ << 3 << TheCall->getNumArgs()
+      << 0 /*function call*/ << 2 << TheCall->getNumArgs()
       << TheCall->getSourceRange());
 
-  unsigned numElements = std::numeric_limits<unsigned>::max();
+  // Determine which of the following types of shufflevector we're checking:
+  // 1) unary, vector mask: (lhs, mask)
+  // 2) binary, vector mask: (lhs, rhs, mask)
+  // 3) binary, scalar mask: (lhs, rhs, index, ..., index)
+  QualType resType = TheCall->getArg(0)->getType();
+  unsigned numElements = 0;
+  
   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()) {
+    QualType LHSType = TheCall->getArg(0)->getType();
+    QualType RHSType = TheCall->getArg(1)->getType();
+    
+    if (!LHSType->isVectorType() || !RHSType->isVectorType()) {
       Diag(TheCall->getLocStart(), diag::err_shufflevector_non_vector)
         << SourceRange(TheCall->getArg(0)->getLocStart(),
                        TheCall->getArg(1)->getLocEnd());
       return ExprError();
     }
+    
+    numElements = LHSType->getAs<VectorType>()->getNumElements();
+    unsigned numResElements = TheCall->getNumArgs() - 2;
 
-    if (!Context.hasSameUnqualifiedType(FAType, SAType)) {
+    // Check to see if we have a call with 2 vector arguments, the unary shuffle
+    // with mask.  If so, verify that RHS is an integer vector type with the
+    // same number of elts as lhs.
+    if (TheCall->getNumArgs() == 2) {
+      if (!RHSType->hasIntegerRepresentation() || 
+          RHSType->getAs<VectorType>()->getNumElements() != numElements)
+        Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector)
+          << SourceRange(TheCall->getArg(1)->getLocStart(),
+                         TheCall->getArg(1)->getLocEnd());
+      numResElements = numElements;
+    }
+    else if (!Context.hasSameUnqualifiedType(LHSType, RHSType)) {
       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());
+    } else if (numElements != numResElements) {
+      QualType eltType = LHSType->getAs<VectorType>()->getElementType();
+      resType = Context.getVectorType(eltType, numResElements,
+                                      VectorType::NotAltiVec);
     }
   }
 
@@ -671,9 +807,11 @@
         TheCall->getArg(i)->isValueDependent())
       continue;
 
-    llvm::APSInt Result;
-    if (SemaBuiltinConstantArg(TheCall, i, Result))
-      return ExprError();
+    llvm::APSInt Result(32);
+    if (!TheCall->getArg(i)->isIntegerConstantExpr(Result, Context))
+      return ExprError(Diag(TheCall->getLocStart(),
+                  diag::err_shufflevector_nonconstant_argument)
+                << TheCall->getArg(i)->getSourceRange());
 
     if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2)
       return ExprError(Diag(TheCall->getLocStart(),
@@ -689,7 +827,7 @@
   }
 
   return Owned(new (Context) ShuffleVectorExpr(Context, exprs.begin(),
-                                            exprs.size(), exprs[0]->getType(),
+                                            exprs.size(), resType,
                                             TheCall->getCallee()->getLocStart(),
                                             TheCall->getRParenLoc()));
 }
@@ -789,29 +927,31 @@
 // Handle i > 1 ? "x" : "y", recursivelly
 bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
                                   bool HasVAListArg,
-                                  unsigned format_idx, unsigned firstDataArg) {
+                                  unsigned format_idx, unsigned firstDataArg,
+                                  bool isPrintf) {
+
   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);
+    return SemaCheckStringLiteral(C->getTrueExpr(), TheCall, HasVAListArg,
+                                  format_idx, firstDataArg, isPrintf)
+        && SemaCheckStringLiteral(C->getRHS(), TheCall, HasVAListArg,
+                                  format_idx, firstDataArg, isPrintf);
   }
 
   case Stmt::ImplicitCastExprClass: {
     const ImplicitCastExpr *Expr = cast<ImplicitCastExpr>(E);
     return SemaCheckStringLiteral(Expr->getSubExpr(), TheCall, HasVAListArg,
-                                  format_idx, firstDataArg);
+                                  format_idx, firstDataArg, isPrintf);
   }
 
   case Stmt::ParenExprClass: {
     const ParenExpr *Expr = cast<ParenExpr>(E);
     return SemaCheckStringLiteral(Expr->getSubExpr(), TheCall, HasVAListArg,
-                                  format_idx, firstDataArg);
+                                  format_idx, firstDataArg, isPrintf);
   }
 
   case Stmt::DeclRefExprClass: {
@@ -833,7 +973,8 @@
       if (isConstant) {
         if (const Expr *Init = VD->getAnyInitializer())
           return SemaCheckStringLiteral(Init, TheCall,
-                                        HasVAListArg, format_idx, firstDataArg);
+                                        HasVAListArg, format_idx, firstDataArg,
+                                        isPrintf);
       }
 
       // For vprintf* functions (i.e., HasVAListArg==true), we add a
@@ -873,7 +1014,7 @@
             const Expr *Arg = CE->getArg(ArgIndex - 1);
 
             return SemaCheckStringLiteral(Arg, TheCall, HasVAListArg,
-                                          format_idx, firstDataArg);
+                                          format_idx, firstDataArg, isPrintf);
           }
         }
       }
@@ -891,8 +1032,8 @@
       StrE = cast<StringLiteral>(E);
 
     if (StrE) {
-      CheckPrintfString(StrE, E, TheCall, HasVAListArg, format_idx,
-                        firstDataArg);
+      CheckFormatString(StrE, E, TheCall, HasVAListArg, format_idx,
+                        firstDataArg, isPrintf);
       return true;
     }
 
@@ -907,7 +1048,8 @@
 void
 Sema::CheckNonNullArguments(const NonNullAttr *NonNull,
                             const CallExpr *TheCall) {
-  for (NonNullAttr::iterator i = NonNull->begin(), e = NonNull->end();
+  for (NonNullAttr::args_iterator i = NonNull->args_begin(),
+                                  e = NonNull->args_end();
        i != e; ++i) {
     const Expr *ArgExpr = TheCall->getArg(*i);
     if (ArgExpr->isNullPointerConstant(Context,
@@ -917,55 +1059,13 @@
   }
 }
 
-/// 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.
-///
+/// CheckPrintfScanfArguments - Check calls to printf and scanf (and similar
+/// functions) for correct use of format strings.
 void
-Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
-                           unsigned format_idx, unsigned firstDataArg) {
+Sema::CheckPrintfScanfArguments(const CallExpr *TheCall, bool HasVAListArg,
+                                unsigned format_idx, unsigned firstDataArg,
+                                bool isPrintf) {
+
   const Expr *Fn = TheCall->getCallee();
 
   // The way the format attribute works in GCC, the implicit this argument
@@ -980,9 +1080,9 @@
       --firstDataArg;
   }
 
-  // CHECK: printf-like function is called with no format string.
+  // CHECK: printf/scanf-like function is called with no format string.
   if (format_idx >= TheCall->getNumArgs()) {
-    Diag(TheCall->getRParenLoc(), diag::warn_printf_missing_format_string)
+    Diag(TheCall->getRParenLoc(), diag::warn_missing_format_string)
       << Fn->getSourceRange();
     return;
   }
@@ -1002,23 +1102,24 @@
   // 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))
+                             firstDataArg, isPrintf))
     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)
+         diag::warn_format_nonliteral_noargs)
       << OrigFormatExpr->getSourceRange();
   else
     Diag(TheCall->getArg(format_idx)->getLocStart(),
-         diag::warn_printf_nonliteral)
+         diag::warn_format_nonliteral)
            << OrigFormatExpr->getSourceRange();
 }
 
 namespace {
-class CheckPrintfHandler : public analyze_printf::FormatStringHandler {
+class CheckFormatHandler : public analyze_format_string::FormatStringHandler {
+protected:
   Sema &S;
   const StringLiteral *FExpr;
   const Expr *OrigFormatExpr;
@@ -1033,7 +1134,7 @@
   bool usesPositionalArgs;
   bool atFirstArg;
 public:
-  CheckPrintfHandler(Sema &s, const StringLiteral *fexpr,
+  CheckFormatHandler(Sema &s, const StringLiteral *fexpr,
                      const Expr *origFormatExpr, unsigned firstDataArg,
                      unsigned numDataArgs, bool isObjCLiteral,
                      const char *beg, bool hasVAListArg,
@@ -1051,84 +1152,113 @@
 
   void DoneProcessing();
 
-  void HandleIncompleteFormatSpecifier(const char *startSpecifier,
-                                       unsigned specifierLen);
-
-  bool
-  HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
-                                   const char *startSpecifier,
-                                   unsigned specifierLen);
-
+  void HandleIncompleteSpecifier(const char *startSpecifier,
+                                 unsigned specifierLen);
+    
   virtual void HandleInvalidPosition(const char *startSpecifier,
                                      unsigned specifierLen,
-                                     analyze_printf::PositionContext p);
+                                     analyze_format_string::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:
+protected:
+  bool HandleInvalidConversionSpecifier(unsigned argIndex, SourceLocation Loc,
+                                        const char *startSpec,
+                                        unsigned specifierLen,
+                                        const char *csStart, unsigned csLen);
+  
   SourceRange getFormatStringRange();
-  SourceRange getFormatSpecifierRange(const char *startSpecifier,
-                                      unsigned specifierLen);
+  CharSourceRange getSpecifierRange(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;
+  
+  bool CheckNumArgs(const analyze_format_string::FormatSpecifier &FS,
+                    const analyze_format_string::ConversionSpecifier &CS,
+                    const char *startSpecifier, unsigned specifierLen,
+                    unsigned argIndex);
 };
 }
 
-SourceRange CheckPrintfHandler::getFormatStringRange() {
+SourceRange CheckFormatHandler::getFormatStringRange() {
   return OrigFormatExpr->getSourceRange();
 }
 
-SourceRange CheckPrintfHandler::
-getFormatSpecifierRange(const char *startSpecifier, unsigned specifierLen) {
-  return SourceRange(getLocationOfByte(startSpecifier),
-                     getLocationOfByte(startSpecifier+specifierLen-1));
+CharSourceRange CheckFormatHandler::
+getSpecifierRange(const char *startSpecifier, unsigned specifierLen) {
+  SourceLocation Start = getLocationOfByte(startSpecifier);
+  SourceLocation End   = getLocationOfByte(startSpecifier + specifierLen - 1);
+
+  // Advance the end SourceLocation by one due to half-open ranges.
+  End = End.getFileLocWithOffset(1);
+
+  return CharSourceRange::getCharRange(Start, End);
 }
 
-SourceLocation CheckPrintfHandler::getLocationOfByte(const char *x) {
+SourceLocation CheckFormatHandler::getLocationOfByte(const char *x) {
   return S.getLocationOfStringLiteralByte(FExpr, x - Beg);
 }
 
-void CheckPrintfHandler::
-HandleIncompleteFormatSpecifier(const char *startSpecifier,
-                                unsigned specifierLen) {
+void CheckFormatHandler::HandleIncompleteSpecifier(const char *startSpecifier,
+                                                   unsigned specifierLen){
   SourceLocation Loc = getLocationOfByte(startSpecifier);
   S.Diag(Loc, diag::warn_printf_incomplete_specifier)
-    << getFormatSpecifierRange(startSpecifier, specifierLen);
+    << getSpecifierRange(startSpecifier, specifierLen);
 }
 
 void
-CheckPrintfHandler::HandleInvalidPosition(const char *startPos, unsigned posLen,
-                                          analyze_printf::PositionContext p) {
+CheckFormatHandler::HandleInvalidPosition(const char *startPos, unsigned posLen,
+                                     analyze_format_string::PositionContext p) {
   SourceLocation Loc = getLocationOfByte(startPos);
-  S.Diag(Loc, diag::warn_printf_invalid_positional_specifier)
-    << (unsigned) p << getFormatSpecifierRange(startPos, posLen);
+  S.Diag(Loc, diag::warn_format_invalid_positional_specifier)
+    << (unsigned) p << getSpecifierRange(startPos, posLen);
 }
 
-void CheckPrintfHandler::HandleZeroPosition(const char *startPos,
+void CheckFormatHandler::HandleZeroPosition(const char *startPos,
                                             unsigned posLen) {
   SourceLocation Loc = getLocationOfByte(startPos);
-  S.Diag(Loc, diag::warn_printf_zero_positional_specifier)
-    << getFormatSpecifierRange(startPos, posLen);
+  S.Diag(Loc, diag::warn_format_zero_positional_specifier)
+    << getSpecifierRange(startPos, posLen);
 }
 
-bool CheckPrintfHandler::
-HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
-                                 const char *startSpecifier,
-                                 unsigned specifierLen) {
+void CheckFormatHandler::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();
+}
 
-  unsigned argIndex = FS.getArgIndex();
+const Expr *CheckFormatHandler::getDataArg(unsigned i) const {
+  return TheCall->getArg(FirstDataArg + i);
+}
+
+void CheckFormatHandler::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();
+    }
+  }
+}
+
+bool
+CheckFormatHandler::HandleInvalidConversionSpecifier(unsigned argIndex,
+                                                     SourceLocation Loc,
+                                                     const char *startSpec,
+                                                     unsigned specifierLen,
+                                                     const char *csStart,
+                                                     unsigned csLen) {
+  
   bool keepGoing = true;
   if (argIndex < NumDataArgs) {
     // Consider the argument coverered, even though the specifier doesn't
@@ -1143,42 +1273,95 @@
     // 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);
-
+  
+  S.Diag(Loc, diag::warn_format_invalid_conversion)
+    << llvm::StringRef(csStart, csLen)
+    << getSpecifierRange(startSpec, 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) {
+CheckFormatHandler::CheckNumArgs(
+  const analyze_format_string::FormatSpecifier &FS,
+  const analyze_format_string::ConversionSpecifier &CS,
+  const char *startSpecifier, unsigned specifierLen, unsigned argIndex) {
+
+  if (argIndex >= NumDataArgs) {
+    if (FS.usesPositionalArg())  {
+      S.Diag(getLocationOfByte(CS.getStart()),
+             diag::warn_printf_positional_arg_exceeds_data_args)
+      << (argIndex+1) << NumDataArgs
+      << getSpecifierRange(startSpecifier, specifierLen);
+    }
+    else {
+      S.Diag(getLocationOfByte(CS.getStart()),
+             diag::warn_printf_insufficient_data_args)
+      << getSpecifierRange(startSpecifier, specifierLen);
+    }
+    
+    return false;
+  }
+  return true;
+}
+
+//===--- CHECK: Printf format string checking ------------------------------===//
+
+namespace {
+class CheckPrintfHandler : public CheckFormatHandler {
+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)
+  : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg,
+                       numDataArgs, isObjCLiteral, beg, hasVAListArg,
+                       theCall, formatIdx) {}
+  
+  
+  bool HandleInvalidPrintfConversionSpecifier(
+                                      const analyze_printf::PrintfSpecifier &FS,
+                                      const char *startSpecifier,
+                                      unsigned specifierLen);
+  
+  bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,
+                             const char *startSpecifier,
+                             unsigned specifierLen);
+  
+  bool HandleAmount(const analyze_format_string::OptionalAmount &Amt, unsigned k,
+                    const char *startSpecifier, unsigned specifierLen);
+  void HandleInvalidAmount(const analyze_printf::PrintfSpecifier &FS,
+                           const analyze_printf::OptionalAmount &Amt,
+                           unsigned type,
+                           const char *startSpecifier, unsigned specifierLen);
+  void HandleFlag(const analyze_printf::PrintfSpecifier &FS,
+                  const analyze_printf::OptionalFlag &flag,
+                  const char *startSpecifier, unsigned specifierLen);
+  void HandleIgnoredFlag(const analyze_printf::PrintfSpecifier &FS,
+                         const analyze_printf::OptionalFlag &ignoredFlag,
+                         const analyze_printf::OptionalFlag &flag,
+                         const char *startSpecifier, unsigned specifierLen);
+};  
+}
+
+bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
+                                      const analyze_printf::PrintfSpecifier &FS,
+                                      const char *startSpecifier,
+                                      unsigned specifierLen) {
+  const analyze_printf::PrintfConversionSpecifier &CS =
+    FS.getConversionSpecifier();
+  
+  return HandleInvalidConversionSpecifier(FS.getArgIndex(),
+                                          getLocationOfByte(CS.getStart()),
+                                          startSpecifier, specifierLen,
+                                          CS.getStart(), CS.getLength());
+}
+
+bool CheckPrintfHandler::HandleAmount(
+                               const analyze_format_string::OptionalAmount &Amt,
+                               unsigned k, const char *startSpecifier,
+                               unsigned specifierLen) {
 
   if (Amt.hasDataArgument()) {
     if (!HasVAListArg) {
@@ -1186,7 +1369,7 @@
       if (argIndex >= NumDataArgs) {
         S.Diag(getLocationOfByte(Amt.getStart()),
                diag::warn_printf_asterisk_missing_arg)
-          << k << getFormatSpecifierRange(startSpecifier, specifierLen);
+          << k << getSpecifierRange(startSpecifier, specifierLen);
         // Don't do any more checking.  We will just emit
         // spurious errors.
         return false;
@@ -1208,7 +1391,7 @@
                diag::warn_printf_asterisk_wrong_type)
           << k
           << ATR.getRepresentativeType(S.Context) << T
-          << getFormatSpecifierRange(startSpecifier, specifierLen)
+          << getSpecifierRange(startSpecifier, specifierLen)
           << Arg->getSourceRange();
         // Don't do any more checking.  We will just emit
         // spurious errors.
@@ -1219,25 +1402,86 @@
   return true;
 }
 
+void CheckPrintfHandler::HandleInvalidAmount(
+                                      const analyze_printf::PrintfSpecifier &FS,
+                                      const analyze_printf::OptionalAmount &Amt,
+                                      unsigned type,
+                                      const char *startSpecifier,
+                                      unsigned specifierLen) {
+  const analyze_printf::PrintfConversionSpecifier &CS =
+    FS.getConversionSpecifier();
+  switch (Amt.getHowSpecified()) {
+  case analyze_printf::OptionalAmount::Constant:
+    S.Diag(getLocationOfByte(Amt.getStart()),
+        diag::warn_printf_nonsensical_optional_amount)
+      << type
+      << CS.toString()
+      << getSpecifierRange(startSpecifier, specifierLen)
+      << FixItHint::CreateRemoval(getSpecifierRange(Amt.getStart(),
+          Amt.getConstantLength()));
+    break;
+
+  default:
+    S.Diag(getLocationOfByte(Amt.getStart()),
+        diag::warn_printf_nonsensical_optional_amount)
+      << type
+      << CS.toString()
+      << getSpecifierRange(startSpecifier, specifierLen);
+    break;
+  }
+}
+
+void CheckPrintfHandler::HandleFlag(const analyze_printf::PrintfSpecifier &FS,
+                                    const analyze_printf::OptionalFlag &flag,
+                                    const char *startSpecifier,
+                                    unsigned specifierLen) {
+  // Warn about pointless flag with a fixit removal.
+  const analyze_printf::PrintfConversionSpecifier &CS =
+    FS.getConversionSpecifier();
+  S.Diag(getLocationOfByte(flag.getPosition()),
+      diag::warn_printf_nonsensical_flag)
+    << flag.toString() << CS.toString()
+    << getSpecifierRange(startSpecifier, specifierLen)
+    << FixItHint::CreateRemoval(getSpecifierRange(flag.getPosition(), 1));
+}
+
+void CheckPrintfHandler::HandleIgnoredFlag(
+                                const analyze_printf::PrintfSpecifier &FS,
+                                const analyze_printf::OptionalFlag &ignoredFlag,
+                                const analyze_printf::OptionalFlag &flag,
+                                const char *startSpecifier,
+                                unsigned specifierLen) {
+  // Warn about ignored flag with a fixit removal.
+  S.Diag(getLocationOfByte(ignoredFlag.getPosition()),
+      diag::warn_printf_ignored_flag)
+    << ignoredFlag.toString() << flag.toString()
+    << getSpecifierRange(startSpecifier, specifierLen)
+    << FixItHint::CreateRemoval(getSpecifierRange(
+        ignoredFlag.getPosition(), 1));
+}
+
 bool
-CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
+CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier
                                             &FS,
                                           const char *startSpecifier,
                                           unsigned specifierLen) {
 
+  using namespace analyze_format_string;
   using namespace analyze_printf;  
-  const ConversionSpecifier &CS = FS.getConversionSpecifier();
+  const PrintfConversionSpecifier &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;
+  if (FS.consumesDataArgument()) {
+    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_format_mix_positional_nonpositional_args)
+        << getSpecifierRange(startSpecifier, specifierLen);
+      return false;
+    }
   }
 
   // First check if the field width, precision, and conversion specifier
@@ -1270,57 +1514,67 @@
   // Check for using an Objective-C specific conversion specifier
   // in a non-ObjC literal.
   if (!IsObjCLiteral && CS.isObjCArg()) {
-    return HandleInvalidConversionSpecifier(FS, startSpecifier, specifierLen);
+    return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
+                                                  specifierLen);
   }
 
-  // Are we using '%n'?  Issue a warning about this being
-  // a possible security issue.
-  if (CS.getKind() == ConversionSpecifier::OutIntPtrArg) {
+  // Check for invalid use of field width
+  if (!FS.hasValidFieldWidth()) {
+    HandleInvalidAmount(FS, FS.getFieldWidth(), /* field width */ 0,
+        startSpecifier, specifierLen);
+  }
+
+  // Check for invalid use of precision
+  if (!FS.hasValidPrecision()) {
+    HandleInvalidAmount(FS, FS.getPrecision(), /* precision */ 1,
+        startSpecifier, specifierLen);
+  }
+
+  // Check each flag does not conflict with any other component.
+  if (!FS.hasValidLeadingZeros())
+    HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen);
+  if (!FS.hasValidPlusPrefix())
+    HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen);
+  if (!FS.hasValidSpacePrefix())
+    HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen);
+  if (!FS.hasValidAlternativeForm())
+    HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen);
+  if (!FS.hasValidLeftJustified())
+    HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen);
+
+  // Check that flags are not ignored by another flag
+  if (FS.hasSpacePrefix() && FS.hasPlusPrefix()) // ' ' ignored by '+'
+    HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(),
+        startSpecifier, specifierLen);
+  if (FS.hasLeadingZeros() && FS.isLeftJustified()) // '0' ignored by '-'
+    HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(),
+            startSpecifier, specifierLen);
+
+  // Check the length modifier is valid with the given conversion specifier.
+  const LengthModifier &LM = FS.getLengthModifier();
+  if (!FS.hasValidLengthModifier())
+    S.Diag(getLocationOfByte(LM.getStart()),
+        diag::warn_format_nonsensical_length)
+      << LM.toString() << CS.toString()
+      << getSpecifierRange(startSpecifier, specifierLen)
+      << FixItHint::CreateRemoval(getSpecifierRange(LM.getStart(),
+          LM.getLength()));
+
+  // Are we using '%n'?
+  if (CS.getKind() == ConversionSpecifier::nArg) {
+    // Issue a warning about this being a possible security issue.
     S.Diag(getLocationOfByte(CS.getStart()), diag::warn_printf_write_back)
-      << getFormatSpecifierRange(startSpecifier, specifierLen);
+      << getSpecifierRange(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.
+  if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
     return false;
-  }
 
   // Now type check the data expression that matches the
   // format specifier.
@@ -1335,64 +1589,207 @@
         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();
+    // We may be able to offer a FixItHint if it is a supported type.
+    PrintfSpecifier fixedFS = FS;
+    bool success = fixedFS.fixType(Ex->getType());
+
+    if (success) {
+      // Get the fix string from the fixed format specifier
+      llvm::SmallString<128> buf;
+      llvm::raw_svector_ostream os(buf);
+      fixedFS.toString(os);
+
+      // FIXME: getRepresentativeType() perhaps should return a string
+      // instead of a QualType to better handle when the representative
+      // type is 'wint_t' (which is defined in the system headers).
+      S.Diag(getLocationOfByte(CS.getStart()),
+          diag::warn_printf_conversion_argument_type_mismatch)
+        << ATR.getRepresentativeType(S.Context) << Ex->getType()
+        << getSpecifierRange(startSpecifier, specifierLen)
+        << Ex->getSourceRange()
+        << FixItHint::CreateReplacement(
+            getSpecifierRange(startSpecifier, specifierLen),
+            os.str());
+    }
+    else {
+      S.Diag(getLocationOfByte(CS.getStart()),
+             diag::warn_printf_conversion_argument_type_mismatch)
+        << ATR.getRepresentativeType(S.Context) << Ex->getType()
+        << getSpecifierRange(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();
-    }
-  }
+//===--- CHECK: Scanf format string checking ------------------------------===//
+
+namespace {  
+class CheckScanfHandler : public CheckFormatHandler {
+public:
+  CheckScanfHandler(Sema &s, const StringLiteral *fexpr,
+                    const Expr *origFormatExpr, unsigned firstDataArg,
+                    unsigned numDataArgs, bool isObjCLiteral,
+                    const char *beg, bool hasVAListArg,
+                    const CallExpr *theCall, unsigned formatIdx)
+  : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg,
+                       numDataArgs, isObjCLiteral, beg, hasVAListArg,
+                       theCall, formatIdx) {}
+  
+  bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS,
+                            const char *startSpecifier,
+                            unsigned specifierLen);
+  
+  bool HandleInvalidScanfConversionSpecifier(
+          const analyze_scanf::ScanfSpecifier &FS,
+          const char *startSpecifier,
+          unsigned specifierLen);
+
+  void HandleIncompleteScanList(const char *start, const char *end);
+};
 }
 
-void Sema::CheckPrintfString(const StringLiteral *FExpr,
+void CheckScanfHandler::HandleIncompleteScanList(const char *start,
+                                                 const char *end) {
+  S.Diag(getLocationOfByte(end), diag::warn_scanf_scanlist_incomplete)
+    << getSpecifierRange(start, end - start);
+}
+
+bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
+                                        const analyze_scanf::ScanfSpecifier &FS,
+                                        const char *startSpecifier,
+                                        unsigned specifierLen) {
+
+  const analyze_scanf::ScanfConversionSpecifier &CS =
+    FS.getConversionSpecifier();
+
+  return HandleInvalidConversionSpecifier(FS.getArgIndex(),
+                                          getLocationOfByte(CS.getStart()),
+                                          startSpecifier, specifierLen,
+                                          CS.getStart(), CS.getLength());
+}
+
+bool CheckScanfHandler::HandleScanfSpecifier(
+                                       const analyze_scanf::ScanfSpecifier &FS,
+                                       const char *startSpecifier,
+                                       unsigned specifierLen) {
+  
+  using namespace analyze_scanf;
+  using namespace analyze_format_string;  
+
+  const ScanfConversionSpecifier &CS = FS.getConversionSpecifier();
+
+  // Handle case where '%' and '*' don't consume an argument.  These shouldn't
+  // be used to decide if we are using positional arguments consistently.
+  if (FS.consumesDataArgument()) {
+    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_format_mix_positional_nonpositional_args)
+        << getSpecifierRange(startSpecifier, specifierLen);
+      return false;
+    }
+  }
+  
+  // Check if the field with is non-zero.
+  const OptionalAmount &Amt = FS.getFieldWidth();
+  if (Amt.getHowSpecified() == OptionalAmount::Constant) {
+    if (Amt.getConstantAmount() == 0) {
+      const CharSourceRange &R = getSpecifierRange(Amt.getStart(),
+                                                   Amt.getConstantLength());
+      S.Diag(getLocationOfByte(Amt.getStart()),
+             diag::warn_scanf_nonzero_width)
+        << R << FixItHint::CreateRemoval(R);
+    }
+  }
+  
+  if (!FS.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 the length modifier is valid with the given conversion specifier.
+  const LengthModifier &LM = FS.getLengthModifier();
+  if (!FS.hasValidLengthModifier()) {
+    S.Diag(getLocationOfByte(LM.getStart()),
+           diag::warn_format_nonsensical_length)
+      << LM.toString() << CS.toString()
+      << getSpecifierRange(startSpecifier, specifierLen)
+      << FixItHint::CreateRemoval(getSpecifierRange(LM.getStart(),
+                                                    LM.getLength()));
+  }
+
+  // The remaining checks depend on the data arguments.
+  if (HasVAListArg)
+    return true;
+  
+  if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
+    return false;
+  
+  // FIXME: Check that the argument type matches the format specifier.
+  
+  return true;
+}
+
+void Sema::CheckFormatString(const StringLiteral *FExpr,
                              const Expr *OrigFormatExpr,
                              const CallExpr *TheCall, bool HasVAListArg,
-                             unsigned format_idx, unsigned firstDataArg) {
-
+                             unsigned format_idx, unsigned firstDataArg,
+                             bool isPrintf) {
+  
   // CHECK: is the format string a wide literal?
   if (FExpr->isWide()) {
     Diag(FExpr->getLocStart(),
-         diag::warn_printf_format_string_is_wide_literal)
+         diag::warn_format_string_is_wide_literal)
     << OrigFormatExpr->getSourceRange();
     return;
   }
-
+  
   // Str - The format string.  NOTE: this is NOT null-terminated!
-  const char *Str = FExpr->getStrData();
-
+  llvm::StringRef StrRef = FExpr->getString();
+  const char *Str = StrRef.data();
+  unsigned StrLen = StrRef.size();
+  
   // CHECK: empty format string?
-  unsigned StrLen = FExpr->getByteLength();
-
   if (StrLen == 0) {
-    Diag(FExpr->getLocStart(), diag::warn_printf_empty_format_string)
+    Diag(FExpr->getLocStart(), diag::warn_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();
+  
+  if (isPrintf) {
+    CheckPrintfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg,
+                         TheCall->getNumArgs() - firstDataArg,
+                         isa<ObjCStringLiteral>(OrigFormatExpr), Str,
+                         HasVAListArg, TheCall, format_idx);
+  
+    if (!analyze_format_string::ParsePrintfString(H, Str, Str + StrLen))
+      H.DoneProcessing();
+  }
+  else {
+    CheckScanfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg,
+                        TheCall->getNumArgs() - firstDataArg,
+                        isa<ObjCStringLiteral>(OrigFormatExpr), Str,
+                        HasVAListArg, TheCall, format_idx);
+    
+    if (!analyze_format_string::ParseScanfString(H, Str, Str + StrLen))
+      H.DoneProcessing();
+  }
 }
 
 //===--- CHECK: Return Address of Stack Variable --------------------------===//
@@ -1474,7 +1871,7 @@
     // is AddrOf.  All others don't make sense as pointers.
     UnaryOperator *U = cast<UnaryOperator>(E);
 
-    if (U->getOpcode() == UnaryOperator::AddrOf)
+    if (U->getOpcode() == UO_AddrOf)
       return EvalVal(U->getSubExpr());
     else
       return NULL;
@@ -1484,9 +1881,9 @@
     // Handle pointer arithmetic.  All other binary operators are not valid
     // in this context.
     BinaryOperator *B = cast<BinaryOperator>(E);
-    BinaryOperator::Opcode op = B->getOpcode();
+    BinaryOperatorKind op = B->getOpcode();
 
-    if (op != BinaryOperator::Add && op != BinaryOperator::Sub)
+    if (op != BO_Add && op != BO_Sub)
       return NULL;
 
     Expr *Base = B->getLHS();
@@ -1559,7 +1956,7 @@
 ///  EvalVal - This function is complements EvalAddr in the mutual recursion.
 ///   See the comments for EvalAddr for more details.
 static DeclRefExpr* EvalVal(Expr *E) {
-
+do {
   // 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).
@@ -1568,6 +1965,15 @@
   // viewed AST node.  We then recursively traverse the AST by calling
   // EvalAddr and EvalVal appropriately.
   switch (E->getStmtClass()) {
+  case Stmt::ImplicitCastExprClass: {
+    ImplicitCastExpr *IE = cast<ImplicitCastExpr>(E);
+    if (IE->getValueKind() == VK_LValue) {
+      E = IE->getSubExpr();
+      continue;
+    }
+    return NULL;
+  }
+
   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
@@ -1580,9 +1986,11 @@
     return NULL;
   }
 
-  case Stmt::ParenExprClass:
+  case Stmt::ParenExprClass: {
     // Ignore parentheses.
-    return EvalVal(cast<ParenExpr>(E)->getSubExpr());
+    E = cast<ParenExpr>(E)->getSubExpr();
+    continue;
+  }
 
   case Stmt::UnaryOperatorClass: {
     // The only unary operator that make sense to handle here
@@ -1590,7 +1998,7 @@
     // handling all sorts of rvalues passed to a unary operator.
     UnaryOperator *U = cast<UnaryOperator>(E);
 
-    if (U->getOpcode() == UnaryOperator::Deref)
+    if (U->getOpcode() == UO_Deref)
       return EvalAddr(U->getSubExpr());
 
     return NULL;
@@ -1631,6 +2039,7 @@
   default:
     return NULL;
   }
+} while (true);
 }
 
 //===--- CHECK: Floating-Point comparisons (-Wfloat-equal) ---------------===//
@@ -1699,7 +2108,6 @@
   /// True if the int is known not to have negative values.
   bool NonNegative;
 
-  IntRange() {}
   IntRange(unsigned Width, bool NonNegative)
     : Width(Width), NonNegative(NonNegative)
   {}
@@ -1723,8 +2131,14 @@
       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();
+
+    if (const EnumType *ET = dyn_cast<EnumType>(T)) {
+      EnumDecl *Enum = ET->getDecl();
+      unsigned NumPositive = Enum->getNumPositiveBits();
+      unsigned NumNegative = Enum->getNumNegativeBits();
+
+      return IntRange(std::max(NumPositive, NumNegative), NumNegative == 0);
+    }
 
     const BuiltinType *BT = cast<BuiltinType>(T);
     assert(BT->isInteger());
@@ -1802,13 +2216,13 @@
   // 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)
+    if (CE->getCastKind() == 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)
+    bool isIntegerCast = (CE->getCastKind() == CK_IntegralCast);
+    if (!isIntegerCast && CE->getCastKind() == CK_Unknown)
       isIntegerCast = CE->getSubExpr()->getType()->isIntegerType();
 
     // Assume that non-integer casts can span the full range of the type.
@@ -1847,38 +2261,38 @@
     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:
+    case BO_LAnd:
+    case BO_LOr:
+    case BO_LT:
+    case BO_GT:
+    case BO_LE:
+    case BO_GE:
+    case BO_EQ:
+    case BO_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:
+    case BO_MulAssign:
+    case BO_DivAssign:
+    case BO_RemAssign:
+    case BO_AddAssign:
+    case BO_SubAssign:
       return IntRange::forType(C, E->getType());
 
     // Operations with opaque sources are black-listed.
-    case BinaryOperator::PtrMemD:
-    case BinaryOperator::PtrMemI:
+    case BO_PtrMemD:
+    case BO_PtrMemI:
       return IntRange::forType(C, E->getType());
 
     // Bitwise-and uses the *infinum* of the two source ranges.
-    case BinaryOperator::And:
-    case BinaryOperator::AndAssign:
+    case BO_And:
+    case BO_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:
+    case BO_Shl:
       // ...except that we want to treat '1 << (blah)' as logically
       // positive.  It's an important idiom.
       if (IntegerLiteral *I
@@ -1890,12 +2304,12 @@
       }
       // fallthrough
 
-    case BinaryOperator::ShlAssign:
+    case BO_ShlAssign:
       return IntRange::forType(C, E->getType());
 
     // Right shift by a constant can narrow its left argument.
-    case BinaryOperator::Shr:
-    case BinaryOperator::ShrAssign: {
+    case BO_Shr:
+    case BO_ShrAssign: {
       IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth);
 
       // If the shift amount is a positive constant, drop the width by
@@ -1914,11 +2328,11 @@
     }
 
     // Comma acts as its right operand.
-    case BinaryOperator::Comma:
+    case BO_Comma:
       return GetExprRange(C, BO->getRHS(), MaxWidth);
 
     // Black-list pointer subtractions.
-    case BinaryOperator::Sub:
+    case BO_Sub:
       if (BO->getLHS()->getType()->isPointerType())
         return IntRange::forType(C, E->getType());
       // fallthrough
@@ -1937,19 +2351,22 @@
   if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
     switch (UO->getOpcode()) {
     // Boolean-valued operations are white-listed.
-    case UnaryOperator::LNot:
+    case UO_LNot:
       return IntRange::forBoolType();
 
     // Operations with opaque sources are black-listed.
-    case UnaryOperator::Deref:
-    case UnaryOperator::AddrOf: // should be impossible
-    case UnaryOperator::OffsetOf:
+    case UO_Deref:
+    case UO_AddrOf: // should be impossible
       return IntRange::forType(C, E->getType());
 
     default:
       return GetExprRange(C, UO->getSubExpr(), MaxWidth);
     }
   }
+  
+  if (dyn_cast<OffsetOfExpr>(E)) {
+    IntRange::forType(C, E->getType());
+  }
 
   FieldDecl *BitField = E->getBitField();
   if (BitField) {
@@ -1962,6 +2379,10 @@
   return IntRange::forType(C, E->getType());
 }
 
+IntRange GetExprRange(ASTContext &C, Expr *E) {
+  return GetExprRange(C, E, C.getIntWidth(E->getType()));
+}
+
 /// Checks whether the given value, which currently has the given
 /// source semantics, has the same value when coerced through the
 /// target semantics.
@@ -2000,7 +2421,40 @@
           IsSameFloatAfterCast(value.getComplexFloatImag(), Src, Tgt));
 }
 
-} // end anonymous namespace
+void AnalyzeImplicitConversions(Sema &S, Expr *E);
+
+bool IsZero(Sema &S, Expr *E) {
+  llvm::APSInt Value;
+  return E->isIntegerConstantExpr(Value, S.Context) && Value == 0;
+}
+
+void CheckTrivialUnsignedComparison(Sema &S, BinaryOperator *E) {
+  BinaryOperatorKind op = E->getOpcode();
+  if (op == BO_LT && IsZero(S, E->getRHS())) {
+    S.Diag(E->getOperatorLoc(), diag::warn_lunsigned_always_true_comparison)
+      << "< 0" << "false"
+      << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
+  } else if (op == BO_GE && IsZero(S, E->getRHS())) {
+    S.Diag(E->getOperatorLoc(), diag::warn_lunsigned_always_true_comparison)
+      << ">= 0" << "true"
+      << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
+  } else if (op == BO_GT && IsZero(S, E->getLHS())) {
+    S.Diag(E->getOperatorLoc(), diag::warn_runsigned_always_true_comparison)
+      << "0 >" << "false" 
+      << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
+  } else if (op == BO_LE && IsZero(S, E->getLHS())) {
+    S.Diag(E->getOperatorLoc(), diag::warn_runsigned_always_true_comparison)
+      << "0 <=" << "true" 
+      << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
+  }
+}
+
+/// Analyze the operands of the given comparison.  Implements the
+/// fallback case from AnalyzeComparison.
+void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E) {
+  AnalyzeImplicitConversions(S, E->getLHS());
+  AnalyzeImplicitConversions(S, E->getRHS());
+}
 
 /// \brief Implements -Wsign-compare.
 ///
@@ -2008,138 +2462,85 @@
 /// \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;
+void AnalyzeComparison(Sema &S, BinaryOperator *E) {
+  // The type the comparison is being performed in.
+  QualType T = E->getLHS()->getType();
+  assert(S.Context.hasSameUnqualifiedType(T, E->getRHS()->getType())
+         && "comparison with mismatched types");
 
-  // If either expression is value-dependent, don't warn. We'll get another
-  // chance at instantiation time.
-  if (lex->isValueDependent() || rex->isValueDependent())
-    return;
+  // We don't do anything special if this isn't an unsigned integral
+  // comparison:  we're only interested in integral comparisons, and
+  // signed comparisons only happen in cases we don't care to warn about.
+  if (!T->hasUnsignedIntegerRepresentation())
+    return AnalyzeImpConvsInComparison(S, E);
 
-  QualType lt = lex->getType(), rt = rex->getType();
+  Expr *lex = E->getLHS()->IgnoreParenImpCasts();
+  Expr *rex = E->getRHS()->IgnoreParenImpCasts();
 
-  // 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;
+  // Check to see if one of the (unmodified) operands is of different
+  // signedness.
+  Expr *signedOperand, *unsignedOperand;
+  if (lex->getType()->hasSignedIntegerRepresentation()) {
+    assert(!rex->getType()->hasSignedIntegerRepresentation() &&
+           "unsigned comparison between two signed integer expressions?");
+    signedOperand = lex;
+    unsignedOperand = rex;
+  } else if (rex->getType()->hasSignedIntegerRepresentation()) {
+    signedOperand = rex;
+    unsignedOperand = lex;
   } else {
-    if (!rt->isSignedIntegerType()) return;
-    std::swap(signedOperand, unsignedOperand);
-    std::swap(signedType, unsignedType);
+    CheckTrivialUnsignedComparison(S, E);
+    return AnalyzeImpConvsInComparison(S, E);
   }
 
-  unsigned unsignedWidth = Context.getIntWidth(unsignedType);
-  unsigned signedWidth = Context.getIntWidth(signedType);
+  // Otherwise, calculate the effective range of the signed operand.
+  IntRange signedRange = GetExprRange(S.Context, signedOperand);
 
-  // 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;
+  // Go ahead and analyze implicit conversions in the operands.  Note
+  // that we skip the implicit conversions on both sides.
+  AnalyzeImplicitConversions(S, lex);
+  AnalyzeImplicitConversions(S, rex);
 
-  // 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;
-  }
+  // If the signed range is non-negative, -Wsign-compare won't fire,
+  // but we should still check for comparisons which are always true
+  // or false.
+  if (signedRange.NonNegative)
+    return CheckTrivialUnsignedComparison(S, E);
 
   // 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;
+  if (E->isEqualityOp()) {
+    unsigned comparisonWidth = S.Context.getIntWidth(T);
+    IntRange unsignedRange = GetExprRange(S.Context, unsignedOperand);
 
-  Diag(OpLoc, BinOpc ? diag::warn_mixed_sign_comparison
-                     : diag::warn_mixed_sign_conditional)
-    << lt << rt << lex->getSourceRange() << rex->getSourceRange();
+    // We should never be unable to prove that the unsigned operand is
+    // non-negative.
+    assert(unsignedRange.NonNegative && "unsigned range includes negative?");
+
+    if (unsignedRange.Width < comparisonWidth)
+      return;
+  }
+
+  S.Diag(E->getOperatorLoc(), diag::warn_mixed_sign_comparison)
+    << lex->getType() << rex->getType()
+    << lex->getSourceRange() << rex->getSourceRange();
 }
 
 /// Diagnose an implicit cast;  purely a helper for CheckImplicitConversion.
-static void DiagnoseImpCast(Sema &S, Expr *E, QualType T, unsigned diag) {
+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;
+void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
+                             bool *ICContext = 0) {
+  if (E->isTypeDependent() || E->isValueDependent()) 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();
+  const Type *Source = S.Context.getCanonicalType(E->getType()).getTypePtr();
+  const Type *Target = S.Context.getCanonicalType(T).getTypePtr();
+  if (Source == Target) return;
+  if (Target->isDependentType()) return;
 
   // Never diagnose implicit casts to bool.
   if (Target->isSpecificBuiltinType(BuiltinType::Bool))
@@ -2148,7 +2549,7 @@
   // Strip vector types.
   if (isa<VectorType>(Source)) {
     if (!isa<VectorType>(Target))
-      return DiagnoseImpCast(*this, E, T, diag::warn_impcast_vector_scalar);
+      return DiagnoseImpCast(S, E, T, diag::warn_impcast_vector_scalar);
 
     Source = cast<VectorType>(Source)->getElementType().getTypePtr();
     Target = cast<VectorType>(Target)->getElementType().getTypePtr();
@@ -2157,7 +2558,7 @@
   // Strip complex types.
   if (isa<ComplexType>(Source)) {
     if (!isa<ComplexType>(Target))
-      return DiagnoseImpCast(*this, E, T, diag::warn_impcast_complex_scalar);
+      return DiagnoseImpCast(S, E, T, diag::warn_impcast_complex_scalar);
 
     Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
     Target = cast<ComplexType>(Target)->getElementType().getTypePtr();
@@ -2177,15 +2578,15 @@
         // Don't warn about float constants that are precisely
         // representable in the target type.
         Expr::EvalResult result;
-        if (E->Evaluate(result, Context)) {
+        if (E->Evaluate(result, S.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))))
+                   S.Context.getFloatTypeSemantics(QualType(TargetBT, 0)),
+                   S.Context.getFloatTypeSemantics(QualType(SourceBT, 0))))
             return;
         }
 
-        DiagnoseImpCast(*this, E, T, diag::warn_impcast_float_precision);
+        DiagnoseImpCast(S, E, T, diag::warn_impcast_float_precision);
       }
       return;
     }
@@ -2193,7 +2594,7 @@
     // 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);
+      DiagnoseImpCast(S, E, T, diag::warn_impcast_float_integer);
 
     return;
   }
@@ -2201,22 +2602,158 @@
   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?
+  IntRange SourceRange = GetExprRange(S.Context, E);
+  IntRange TargetRange = IntRange::forCanonicalType(S.Context, Target);
 
   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 DiagnoseImpCast(S, E, T, diag::warn_impcast_integer_64_32);
+    return DiagnoseImpCast(S, E, T, diag::warn_impcast_integer_precision);
+  }
+
+  if ((TargetRange.NonNegative && !SourceRange.NonNegative) ||
+      (!TargetRange.NonNegative && SourceRange.NonNegative &&
+       SourceRange.Width == TargetRange.Width)) {
+    unsigned DiagID = diag::warn_impcast_integer_sign;
+
+    // Traditionally, gcc has warned about this under -Wsign-compare.
+    // We also want to warn about it in -Wconversion.
+    // So if -Wconversion is off, use a completely identical diagnostic
+    // in the sign-compare group.
+    // The conditional-checking code will 
+    if (ICContext) {
+      DiagID = diag::warn_impcast_integer_sign_conditional;
+      *ICContext = true;
+    }
+
+    return DiagnoseImpCast(S, E, T, DiagID);
   }
 
   return;
 }
 
+void CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T);
+
+void CheckConditionalOperand(Sema &S, Expr *E, QualType T,
+                             bool &ICContext) {
+  E = E->IgnoreParenImpCasts();
+
+  if (isa<ConditionalOperator>(E))
+    return CheckConditionalOperator(S, cast<ConditionalOperator>(E), T);
+
+  AnalyzeImplicitConversions(S, E);
+  if (E->getType() != T)
+    return CheckImplicitConversion(S, E, T, &ICContext);
+  return;
+}
+
+void CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T) {
+  AnalyzeImplicitConversions(S, E->getCond());
+
+  bool Suspicious = false;
+  CheckConditionalOperand(S, E->getTrueExpr(), T, Suspicious);
+  CheckConditionalOperand(S, E->getFalseExpr(), T, Suspicious);
+
+  // If -Wconversion would have warned about either of the candidates
+  // for a signedness conversion to the context type...
+  if (!Suspicious) return;
+
+  // ...but it's currently ignored...
+  if (S.Diags.getDiagnosticLevel(diag::warn_impcast_integer_sign_conditional))
+    return;
+
+  // ...and -Wsign-compare isn't...
+  if (!S.Diags.getDiagnosticLevel(diag::warn_mixed_sign_conditional))
+    return;
+
+  // ...then check whether it would have warned about either of the
+  // candidates for a signedness conversion to the condition type.
+  if (E->getType() != T) {
+    Suspicious = false;
+    CheckImplicitConversion(S, E->getTrueExpr()->IgnoreParenImpCasts(),
+                            E->getType(), &Suspicious);
+    if (!Suspicious)
+      CheckImplicitConversion(S, E->getFalseExpr()->IgnoreParenImpCasts(),
+                              E->getType(), &Suspicious);
+    if (!Suspicious)
+      return;
+  }
+
+  // If so, emit a diagnostic under -Wsign-compare.
+  Expr *lex = E->getTrueExpr()->IgnoreParenImpCasts();
+  Expr *rex = E->getFalseExpr()->IgnoreParenImpCasts();
+  S.Diag(E->getQuestionLoc(), diag::warn_mixed_sign_conditional)
+    << lex->getType() << rex->getType()
+    << lex->getSourceRange() << rex->getSourceRange();
+}
+
+/// AnalyzeImplicitConversions - Find and report any interesting
+/// implicit conversions in the given expression.  There are a couple
+/// of competing diagnostics here, -Wconversion and -Wsign-compare.
+void AnalyzeImplicitConversions(Sema &S, Expr *OrigE) {
+  QualType T = OrigE->getType();
+  Expr *E = OrigE->IgnoreParenImpCasts();
+
+  // For conditional operators, we analyze the arguments as if they
+  // were being fed directly into the output.
+  if (isa<ConditionalOperator>(E)) {
+    ConditionalOperator *CO = cast<ConditionalOperator>(E);
+    CheckConditionalOperator(S, CO, T);
+    return;
+  }
+
+  // Go ahead and check any implicit conversions we might have skipped.
+  // The non-canonical typecheck is just an optimization;
+  // CheckImplicitConversion will filter out dead implicit conversions.
+  if (E->getType() != T)
+    CheckImplicitConversion(S, E, T);
+
+  // Now continue drilling into this expression.
+
+  // Skip past explicit casts.
+  if (isa<ExplicitCastExpr>(E)) {
+    E = cast<ExplicitCastExpr>(E)->getSubExpr()->IgnoreParenImpCasts();
+    return AnalyzeImplicitConversions(S, E);
+  }
+
+  // Do a somewhat different check with comparison operators.
+  if (isa<BinaryOperator>(E) && cast<BinaryOperator>(E)->isComparisonOp())
+    return AnalyzeComparison(S, cast<BinaryOperator>(E));
+
+  // These break the otherwise-useful invariant below.  Fortunately,
+  // we don't really need to recurse into them, because any internal
+  // expressions should have been analyzed already when they were
+  // built into statements.
+  if (isa<StmtExpr>(E)) return;
+
+  // Don't descend into unevaluated contexts.
+  if (isa<SizeOfAlignOfExpr>(E)) return;
+
+  // Now just recurse over the expression's children.
+  for (Stmt::child_iterator I = E->child_begin(), IE = E->child_end();
+         I != IE; ++I)
+    AnalyzeImplicitConversions(S, cast<Expr>(*I));
+}
+
+} // end anonymous namespace
+
+/// Diagnoses "dangerous" implicit conversions within the given
+/// expression (which is a full expression).  Implements -Wconversion
+/// and -Wsign-compare.
+void Sema::CheckImplicitConversions(Expr *E) {
+  // Don't diagnose in unevaluated contexts.
+  if (ExprEvalContexts.back().Context == Sema::Unevaluated)
+    return;
+
+  // Don't diagnose for value- or type-dependent expressions.
+  if (E->isTypeDependent() || E->isValueDependent())
+    return;
+
+  AnalyzeImplicitConversions(*this, E);
+}
+
 /// 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
@@ -2263,3 +2800,48 @@
 
   return HasInvalidParm;
 }
+
+/// CheckCastAlign - Implements -Wcast-align, which warns when a
+/// pointer cast increases the alignment requirements.
+void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
+  // This is actually a lot of work to potentially be doing on every
+  // cast; don't do it if we're ignoring -Wcast_align (as is the default).
+  if (getDiagnostics().getDiagnosticLevel(diag::warn_cast_align)
+        == Diagnostic::Ignored)
+    return;
+
+  // Ignore dependent types.
+  if (T->isDependentType() || Op->getType()->isDependentType())
+    return;
+
+  // Require that the destination be a pointer type.
+  const PointerType *DestPtr = T->getAs<PointerType>();
+  if (!DestPtr) return;
+
+  // If the destination has alignment 1, we're done.
+  QualType DestPointee = DestPtr->getPointeeType();
+  if (DestPointee->isIncompleteType()) return;
+  CharUnits DestAlign = Context.getTypeAlignInChars(DestPointee);
+  if (DestAlign.isOne()) return;
+
+  // Require that the source be a pointer type.
+  const PointerType *SrcPtr = Op->getType()->getAs<PointerType>();
+  if (!SrcPtr) return;
+  QualType SrcPointee = SrcPtr->getPointeeType();
+
+  // Whitelist casts from cv void*.  We already implicitly
+  // whitelisted casts to cv void*, since they have alignment 1.
+  // Also whitelist casts involving incomplete types, which implicitly
+  // includes 'void'.
+  if (SrcPointee->isIncompleteType()) return;
+
+  CharUnits SrcAlign = Context.getTypeAlignInChars(SrcPointee);
+  if (SrcAlign >= DestAlign) return;
+
+  Diag(TRange.getBegin(), diag::warn_cast_align)
+    << Op->getType() << T
+    << static_cast<unsigned>(SrcAlign.getQuantity())
+    << static_cast<unsigned>(DestAlign.getQuantity())
+    << TRange << Op->getSourceRange();
+}
+
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 35bb697..d185181 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -10,10 +10,14 @@
 //  This file defines the code-completion semantic actions.
 //
 //===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Overload.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "clang/Sema/ExternalSemaSource.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/Lex/MacroInfo.h"
@@ -21,11 +25,13 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
 #include <list>
 #include <map>
 #include <vector>
 
 using namespace clang;
+using namespace sema;
 
 namespace {
   /// \brief A container of code-completion results.
@@ -37,7 +43,7 @@
     /// filtered out (returns false).
     typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
     
-    typedef CodeCompleteConsumer::Result Result;
+    typedef CodeCompletionResult Result;
     
   private:
     /// \brief The actual results we have found.
@@ -119,13 +125,40 @@
     /// nested-name-specifiers that would otherwise be filtered out.
     bool AllowNestedNameSpecifiers;
 
+    /// \brief If set, the type that we would prefer our resulting value
+    /// declarations to have.
+    ///
+    /// Closely matching the preferred type gives a boost to a result's 
+    /// priority.
+    CanQualType PreferredType;
+    
     /// \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;
     
+    /// \brief If we're potentially referring to a C++ member function, the set
+    /// of qualifiers applied to the object type.
+    Qualifiers ObjectTypeQualifiers;
+    
+    /// \brief Whether the \p ObjectTypeQualifiers field is active.
+    bool HasObjectTypeQualifiers;
+    
+    /// \brief The selector that we prefer.
+    Selector PreferredSelector;
+    
+    void AdjustResultPriorityForPreferredType(Result &R);
+
   public:
     explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
-      : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
+      : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false),
+        HasObjectTypeQualifiers(false) { }
+    
+    /// \brief Whether we should include code patterns in the completion
+    /// results.
+    bool includeCodePatterns() const {
+      return SemaRef.CodeCompleter && 
+             SemaRef.CodeCompleter->includeCodePatterns();
+    }
     
     /// \brief Set the filter used for code-completion results.
     void setFilter(LookupFilter Filter) {
@@ -140,6 +173,32 @@
     unsigned size() const { return Results.size(); }
     bool empty() const { return Results.empty(); }
     
+    /// \brief Specify the preferred type.
+    void setPreferredType(QualType T) { 
+      PreferredType = SemaRef.Context.getCanonicalType(T); 
+    }
+    
+    /// \brief Set the cv-qualifiers on the object type, for us in filtering
+    /// calls to member functions.
+    ///
+    /// When there are qualifiers in this set, they will be used to filter
+    /// out member functions that aren't available (because there will be a 
+    /// cv-qualifier mismatch) or prefer functions with an exact qualifier
+    /// match.
+    void setObjectTypeQualifiers(Qualifiers Quals) {
+      ObjectTypeQualifiers = Quals;
+      HasObjectTypeQualifiers = true;
+    }
+    
+    /// \brief Set the preferred selector.
+    ///
+    /// When an Objective-C method declaration result is added, and that
+    /// method's selector matches this preferred selector, we give that method
+    /// a slight priority boost.
+    void setPreferredSelector(Selector Sel) {
+      PreferredSelector = Sel;
+    }
+    
     /// \brief Specify whether nested-name-specifiers are allowed.
     void allowNestedNameSpecifiers(bool Allow = true) {
       AllowNestedNameSpecifiers = Allow;
@@ -205,6 +264,8 @@
     /// 
     //@{
     bool IsOrdinaryName(NamedDecl *ND) const;
+    bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
+    bool IsIntegralConstantValue(NamedDecl *ND) const;
     bool IsOrdinaryNonValueName(NamedDecl *ND) const;
     bool IsNestedNameSpecifier(NamedDecl *ND) const;
     bool IsEnum(NamedDecl *ND) const;
@@ -215,6 +276,8 @@
     bool IsType(NamedDecl *ND) const;
     bool IsMember(NamedDecl *ND) const;
     bool IsObjCIvar(NamedDecl *ND) const;
+    bool IsObjCMessageReceiver(NamedDecl *ND) const;
+    bool IsObjCCollection(NamedDecl *ND) const;
     //@}    
   };  
 }
@@ -342,14 +405,16 @@
     DeclContext *Parent = TargetParents.back();
     TargetParents.pop_back();
     
-    if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
+    if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
+      if (!Namespace->getIdentifier())
+        continue;
+
       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;
 }
@@ -386,13 +451,16 @@
       return false;
     
     // Filter out names reserved for the implementation (C99 7.1.3, 
-    // C++ [lib.global.names]). Users don't need to see those.
+    // C++ [lib.global.names]) if they come from a system header.
     //
     // 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')))
+          (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
+          (ND->getLocation().isInvalid() ||
+           SemaRef.SourceMgr.isInSystemHeader(
+                          SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
         return false;
     }
   }
@@ -401,6 +469,12 @@
   if (isa<CXXConstructorDecl>(ND))
     return false;
   
+  if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
+      ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
+       Filter != &ResultBuilder::IsNamespace &&
+       Filter != &ResultBuilder::IsNamespaceOrAlias))
+    AsNestedNameSpecifier = true;
+
   // Filter out any unwanted results.
   if (Filter && !(this->*Filter)(ND)) {
     // Check whether it is interesting as a nested-name-specifier.
@@ -414,11 +488,7 @@
     }
 
     return false;
-  }
-
-  if (Filter == &ResultBuilder::IsNestedNameSpecifier)
-    AsNestedNameSpecifier = true;
-  
+  }  
   // ... then it must be interesting!
   return true;
 }
@@ -451,6 +521,125 @@
   return false;
 }
 
+/// \brief A simplified classification of types used to determine whether two
+/// types are "similar enough" when adjusting priorities.
+SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
+  switch (T->getTypeClass()) {
+  case Type::Builtin:
+    switch (cast<BuiltinType>(T)->getKind()) {
+      case BuiltinType::Void:
+        return STC_Void;
+        
+      case BuiltinType::NullPtr:
+        return STC_Pointer;
+        
+      case BuiltinType::Overload:
+      case BuiltinType::Dependent:
+      case BuiltinType::UndeducedAuto:
+        return STC_Other;
+        
+      case BuiltinType::ObjCId:
+      case BuiltinType::ObjCClass:
+      case BuiltinType::ObjCSel:
+        return STC_ObjectiveC;
+        
+      default:
+        return STC_Arithmetic;
+    }
+    return STC_Other;
+    
+  case Type::Complex:
+    return STC_Arithmetic;
+    
+  case Type::Pointer:
+    return STC_Pointer;
+    
+  case Type::BlockPointer:
+    return STC_Block;
+    
+  case Type::LValueReference:
+  case Type::RValueReference:
+    return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
+    
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+  case Type::VariableArray:
+  case Type::DependentSizedArray:
+    return STC_Array;
+    
+  case Type::DependentSizedExtVector:
+  case Type::Vector:
+  case Type::ExtVector:
+    return STC_Arithmetic;
+    
+  case Type::FunctionProto:
+  case Type::FunctionNoProto:
+    return STC_Function;
+    
+  case Type::Record:
+    return STC_Record;
+    
+  case Type::Enum:
+    return STC_Arithmetic;
+    
+  case Type::ObjCObject:
+  case Type::ObjCInterface:
+  case Type::ObjCObjectPointer:
+    return STC_ObjectiveC;
+    
+  default:
+    return STC_Other;
+  }
+}
+
+/// \brief Get the type that a given expression will have if this declaration
+/// is used as an expression in its "typical" code-completion form.
+QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
+  ND = cast<NamedDecl>(ND->getUnderlyingDecl());
+  
+  if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
+    return C.getTypeDeclType(Type);
+  if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
+    return C.getObjCInterfaceType(Iface);
+  
+  QualType T;
+  if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
+    T = Function->getCallResultType();
+  else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
+    T = Method->getSendResultType();
+  else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
+    T = FunTmpl->getTemplatedDecl()->getCallResultType();
+  else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
+    T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
+  else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
+    T = Property->getType();
+  else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
+    T = Value->getType();
+  else
+    return QualType();
+  
+  return T.getNonReferenceType();
+}
+
+void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
+  QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
+  if (T.isNull())
+    return;
+  
+  CanQualType TC = SemaRef.Context.getCanonicalType(T);
+  // Check for exactly-matching types (modulo qualifiers).
+  if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC)) {
+    if (PreferredType->isVoidType())
+      R.Priority += CCD_VoidMatch;
+    else
+      R.Priority /= CCF_ExactTypeMatch;
+  } // Check for nearly-matching types, based on classification of each.
+  else if ((getSimplifiedTypeClass(PreferredType)
+                                               == getSimplifiedTypeClass(TC)) &&
+           !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
+    R.Priority /= CCF_SimilarTypeMatch;  
+}
+
 void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
   assert(!ShadowMaps.empty() && "Must enter into a results scope");
   
@@ -529,12 +718,22 @@
   // Make sure that any given declaration only shows up in the result set once.
   if (!AllDeclsFound.insert(CanonDecl))
     return;
-  
+
+  // If this is an Objective-C method declaration whose selector matches our
+  // preferred selector, give it a priority boost.
+  if (!PreferredSelector.isNull())
+    if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
+      if (PreferredSelector == Method->getSelector())
+        R.Priority += CCD_SelectorMatch;
+
   // If the filter is for nested-name-specifiers, then this result starts a
   // nested-name-specifier.
-  if (AsNestedNameSpecifier)
+  if (AsNestedNameSpecifier) {
     R.StartsNestedNameSpecifier = true;
-  
+    R.Priority = CCP_NestedNameSpecifier;
+  } else if (!PreferredType.isNull())
+      AdjustResultPriorityForPreferredType(R);
+      
   // If this result is supposed to have an informative qualifier, add one.
   if (R.QualifierIsInformative && !R.Qualifier &&
       !R.StartsNestedNameSpecifier) {
@@ -581,8 +780,10 @@
   
   // If the filter is for nested-name-specifiers, then this result starts a
   // nested-name-specifier.
-  if (AsNestedNameSpecifier)
+  if (AsNestedNameSpecifier) {
     R.StartsNestedNameSpecifier = true;
+    R.Priority = CCP_NestedNameSpecifier;
+  }
   else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
            isa<CXXRecordDecl>(R.Declaration->getDeclContext()
                                                   ->getLookupContext()))
@@ -601,6 +802,34 @@
       R.QualifierIsInformative = false;
   }
   
+  // Adjust the priority if this result comes from a base class.
+  if (InBaseClass)
+    R.Priority += CCD_InBaseClass;
+  
+  // If this is an Objective-C method declaration whose selector matches our
+  // preferred selector, give it a priority boost.
+  if (!PreferredSelector.isNull())
+    if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
+      if (PreferredSelector == Method->getSelector())
+        R.Priority += CCD_SelectorMatch;
+
+  if (!PreferredType.isNull())
+    AdjustResultPriorityForPreferredType(R);
+  
+  if (HasObjectTypeQualifiers)
+    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
+      if (Method->isInstance()) {
+        Qualifiers MethodQuals
+                        = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
+        if (ObjectTypeQualifiers == MethodQuals)
+          R.Priority += CCD_ObjectQualifierMatch;
+        else if (ObjectTypeQualifiers - MethodQuals) {
+          // The method cannot be invoked, because doing so would drop 
+          // qualifiers.
+          return;
+        }
+      }
+  
   // Insert this result into the set of results.
   Results.push_back(R);
 }
@@ -630,9 +859,11 @@
 /// \brief Determines whether this given declaration will be found by
 /// ordinary name lookup.
 bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
+  ND = cast<NamedDecl>(ND->getUnderlyingDecl());
+
   unsigned IDNS = Decl::IDNS_Ordinary;
   if (SemaRef.getLangOptions().CPlusPlus)
-    IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
+    IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
   else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
     return true;
 
@@ -640,14 +871,44 @@
 }
 
 /// \brief Determines whether this given declaration will be found by
+/// ordinary name lookup but is not a type name.
+bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
+  ND = cast<NamedDecl>(ND->getUnderlyingDecl());
+  if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
+    return false;
+  
+  unsigned IDNS = Decl::IDNS_Ordinary;
+  if (SemaRef.getLangOptions().CPlusPlus)
+    IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
+  else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
+    return true;
+  
+  return ND->getIdentifierNamespace() & IDNS;
+}
+
+bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
+  if (!IsOrdinaryNonTypeName(ND))
+    return 0;
+  
+  if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
+    if (VD->getType()->isIntegralOrEnumerationType())
+      return true;
+        
+  return false;
+}
+
+/// \brief Determines whether this given declaration will be found by
 /// ordinary name lookup.
 bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
+  ND = cast<NamedDecl>(ND->getUnderlyingDecl());
+
   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);
+    !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) && 
+    !isa<ObjCPropertyDecl>(ND);
 }
 
 /// \brief Determines whether the given declaration is suitable as the 
@@ -672,8 +933,8 @@
     ND = ClassTemplate->getTemplatedDecl();
   
   if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
-    return RD->getTagKind() == TagDecl::TK_class ||
-    RD->getTagKind() == TagDecl::TK_struct;
+    return RD->getTagKind() == TTK_Class ||
+    RD->getTagKind() == TTK_Struct;
   
   return false;
 }
@@ -685,7 +946,7 @@
     ND = ClassTemplate->getTemplatedDecl();
   
   if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
-    return RD->getTagKind() == TagDecl::TK_union;
+    return RD->getTagKind() == TTK_Union;
   
   return false;
 }
@@ -703,7 +964,10 @@
 
 /// \brief Determines whether the given declaration is a type.
 bool ResultBuilder::IsType(NamedDecl *ND) const {
-  return isa<TypeDecl>(ND);
+  if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
+    ND = Using->getTargetDecl();
+  
+  return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
 }
 
 /// \brief Determines which members of a class should be visible via
@@ -717,6 +981,63 @@
     isa<ObjCPropertyDecl>(ND);
 }
 
+static bool isObjCReceiverType(ASTContext &C, QualType T) {
+  T = C.getCanonicalType(T);
+  switch (T->getTypeClass()) {
+  case Type::ObjCObject: 
+  case Type::ObjCInterface:
+  case Type::ObjCObjectPointer:
+    return true;
+      
+  case Type::Builtin:
+    switch (cast<BuiltinType>(T)->getKind()) {
+    case BuiltinType::ObjCId:
+    case BuiltinType::ObjCClass:
+    case BuiltinType::ObjCSel:
+      return true;
+      
+    default:
+      break;
+    }
+    return false;
+      
+  default:
+    break;
+  }
+  
+  if (!C.getLangOptions().CPlusPlus)
+    return false;
+
+  // FIXME: We could perform more analysis here to determine whether a 
+  // particular class type has any conversions to Objective-C types. For now,
+  // just accept all class types.
+  return T->isDependentType() || T->isRecordType();
+}
+
+bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
+  QualType T = getDeclUsageType(SemaRef.Context, ND);
+  if (T.isNull())
+    return false;
+  
+  T = SemaRef.Context.getBaseElementType(T);
+  return isObjCReceiverType(SemaRef.Context, T);
+}
+
+bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
+  if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
+      (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
+    return false;
+  
+  QualType T = getDeclUsageType(SemaRef.Context, ND);
+  if (T.isNull())
+    return false;
+  
+  T = SemaRef.Context.getBaseElementType(T);
+  return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
+         T->isObjCIdType() || 
+         (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
+}
+
 /// \rief Determines whether the given declaration is an Objective-C
 /// instance variable.
 bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
@@ -743,48 +1064,56 @@
 /// \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"));
+  typedef CodeCompletionResult Result;
+  Results.AddResult(Result("short", CCP_Type));
+  Results.AddResult(Result("long", CCP_Type));
+  Results.AddResult(Result("signed", CCP_Type));
+  Results.AddResult(Result("unsigned", CCP_Type));
+  Results.AddResult(Result("void", CCP_Type));
+  Results.AddResult(Result("char", CCP_Type));
+  Results.AddResult(Result("int", CCP_Type));
+  Results.AddResult(Result("float", CCP_Type));
+  Results.AddResult(Result("double", CCP_Type));
+  Results.AddResult(Result("enum", CCP_Type));
+  Results.AddResult(Result("struct", CCP_Type));
+  Results.AddResult(Result("union", CCP_Type));
+  Results.AddResult(Result("const", CCP_Type));
+  Results.AddResult(Result("volatile", CCP_Type));
 
   if (LangOpts.C99) {
     // C99-specific
-    Results.AddResult(Result("_Complex"));
-    Results.AddResult(Result("_Imaginary"));
-    Results.AddResult(Result("_Bool"));
-    Results.AddResult(Result("restrict"));
+    Results.AddResult(Result("_Complex", CCP_Type));
+    Results.AddResult(Result("_Imaginary", CCP_Type));
+    Results.AddResult(Result("_Bool", CCP_Type));
+    Results.AddResult(Result("restrict", CCP_Type));
   }
   
   if (LangOpts.CPlusPlus) {
     // C++-specific
-    Results.AddResult(Result("bool"));
-    Results.AddResult(Result("class"));
-    Results.AddResult(Result("wchar_t"));
+    Results.AddResult(Result("bool", CCP_Type));
+    Results.AddResult(Result("class", CCP_Type));
+    Results.AddResult(Result("wchar_t", CCP_Type));
     
     // typename qualified-id
     CodeCompletionString *Pattern = new CodeCompletionString;
     Pattern->AddTypedTextChunk("typename");
     Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
-    Pattern->AddPlaceholderChunk("qualified-id");
+    Pattern->AddPlaceholderChunk("qualifier");
+    Pattern->AddTextChunk("::");
+    Pattern->AddPlaceholderChunk("name");
     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"));
+      Results.AddResult(Result("auto", CCP_Type));
+      Results.AddResult(Result("char16_t", CCP_Type));
+      Results.AddResult(Result("char32_t", CCP_Type));
+      
+      CodeCompletionString *Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk("decltype");
+      Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+      Pattern->AddPlaceholderChunk("expression");
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      Results.AddResult(Result(Pattern));
     }
   }
   
@@ -797,17 +1126,23 @@
     
     CodeCompletionString *Pattern = new CodeCompletionString;
     Pattern->AddTypedTextChunk("typeof");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddPlaceholderChunk("expression");
+    Results.AddResult(Result(Pattern));
+
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("typeof");
     Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
-    Pattern->AddPlaceholderChunk("expression-or-type");
+    Pattern->AddPlaceholderChunk("type");
     Pattern->AddChunk(CodeCompletionString::CK_RightParen);
     Results.AddResult(Result(Pattern));
   }
 }
 
-static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
+static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
                                  const LangOptions &LangOpts, 
                                  ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult 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.
@@ -815,13 +1150,13 @@
   Results.AddResult(Result("static"));
 }
 
-static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
+static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
                                   const LangOptions &LangOpts, 
                                   ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   switch (CCC) {
-  case Action::CCC_Class:
-  case Action::CCC_MemberTemplate:
+  case Sema::PCC_Class:
+  case Sema::PCC_MemberTemplate:
     if (LangOpts.CPlusPlus) {
       Results.AddResult(Result("explicit"));
       Results.AddResult(Result("friend"));
@@ -830,19 +1165,21 @@
     }    
     // Fall through
 
-  case Action::CCC_ObjCInterface:
-  case Action::CCC_ObjCImplementation:
-  case Action::CCC_Namespace:
-  case Action::CCC_Template:
+  case Sema::PCC_ObjCInterface:
+  case Sema::PCC_ObjCImplementation:
+  case Sema::PCC_Namespace:
+  case Sema::PCC_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:
+  case Sema::PCC_ObjCInstanceVariableList:
+  case Sema::PCC_Expression:
+  case Sema::PCC_Statement:
+  case Sema::PCC_ForInit:
+  case Sema::PCC_Condition:
+  case Sema::PCC_RecoveryInFunction:
+  case Sema::PCC_Type:
     break;
   }
 }
@@ -860,33 +1197,76 @@
                                     bool NeedAt);
 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
 
+static void AddTypedefResult(ResultBuilder &Results) {
+  CodeCompletionString *Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("typedef");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("type");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("name");
+  Results.AddResult(CodeCompletionResult(Pattern));        
+}
+
+static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
+                               const LangOptions &LangOpts) {
+  if (LangOpts.CPlusPlus)
+    return true;
+  
+  switch (CCC) {
+  case Sema::PCC_Namespace:
+  case Sema::PCC_Class:
+  case Sema::PCC_ObjCInstanceVariableList:
+  case Sema::PCC_Template:
+  case Sema::PCC_MemberTemplate:
+  case Sema::PCC_Statement:
+  case Sema::PCC_RecoveryInFunction:
+  case Sema::PCC_Type:
+    return true;
+    
+  case Sema::PCC_ObjCInterface:
+  case Sema::PCC_ObjCImplementation:
+  case Sema::PCC_Expression:
+  case Sema::PCC_Condition:
+    return false;
+    
+  case Sema::PCC_ForInit:
+    return LangOpts.ObjC1 || LangOpts.C99;
+  }
+  
+  return false;
+}
+
 /// \brief Add language constructs that show up for "ordinary" names.
-static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
+static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
                                    Scope *S,
                                    Sema &SemaRef,
                                    ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   switch (CCC) {
-  case Action::CCC_Namespace:
+  case Sema::PCC_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));
-
+      CodeCompletionString *Pattern = 0;
+      
+      if (Results.includeCodePatterns()) {
+        // namespace <identifier> { declarations }
+        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->AddPlaceholderChunk("name");
       Pattern->AddChunk(CodeCompletionString::CK_Equal);
-      Pattern->AddPlaceholderChunk("identifier");
+      Pattern->AddPlaceholderChunk("namespace");
       Results.AddResult(Result(Pattern));
 
       // Using directives
@@ -906,41 +1286,49 @@
       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 (Results.includeCodePatterns()) {
+        // 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);
       
+    AddTypedefResult(Results);
     // Fall through
 
-  case Action::CCC_Class:
-    Results.AddResult(Result("typedef"));
+  case Sema::PCC_Class:
     if (SemaRef.getLangOptions().CPlusPlus) {
       // Using declaration
       CodeCompletionString *Pattern = new CodeCompletionString;
       Pattern->AddTypedTextChunk("using");
       Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
-      Pattern->AddPlaceholderChunk("qualified-id");
+      Pattern->AddPlaceholderChunk("qualifier");
+      Pattern->AddTextChunk("::");
+      Pattern->AddPlaceholderChunk("name");
       Results.AddResult(Result(Pattern));
       
-      // using typename qualified-id; (only in a dependent context)
+      // using typename qualifier::name (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");
+        Pattern->AddPlaceholderChunk("qualifier");
+        Pattern->AddTextChunk("::");
+        Pattern->AddPlaceholderChunk("name");
         Results.AddResult(Result(Pattern));
       }
 
-      if (CCC == Action::CCC_Class) {
+      if (CCC == Sema::PCC_Class) {
+        AddTypedefResult(Results);
+
         // public:
         Pattern = new CodeCompletionString;
         Pattern->AddTypedTextChunk("public");
@@ -962,9 +1350,9 @@
     }
     // Fall through
 
-  case Action::CCC_Template:
-  case Action::CCC_MemberTemplate:
-    if (SemaRef.getLangOptions().CPlusPlus) {
+  case Sema::PCC_Template:
+  case Sema::PCC_MemberTemplate:
+    if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
       // template < parameters >
       CodeCompletionString *Pattern = new CodeCompletionString;
       Pattern->AddTypedTextChunk("template");
@@ -978,27 +1366,28 @@
     AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
     break;
 
-  case Action::CCC_ObjCInterface:
+  case Sema::PCC_ObjCInterface:
     AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
     AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
     AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
     break;
       
-  case Action::CCC_ObjCImplementation:
+  case Sema::PCC_ObjCImplementation:
     AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
     AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
     AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
     break;
       
-  case Action::CCC_ObjCInstanceVariableList:
+  case Sema::PCC_ObjCInstanceVariableList:
     AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
     break;
       
-  case Action::CCC_Statement: {
-    Results.AddResult(Result("typedef"));
+  case Sema::PCC_RecoveryInFunction:
+  case Sema::PCC_Statement: {
+    AddTypedefResult(Results);
 
     CodeCompletionString *Pattern = 0;
-    if (SemaRef.getLangOptions().CPlusPlus) {
+    if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
       Pattern = new CodeCompletionString;
       Pattern->AddTypedTextChunk("try");
       Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
@@ -1018,40 +1407,43 @@
     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));
+    if (Results.includeCodePatterns()) {
+      // 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 (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()) {
+    if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
       // case expression:
       Pattern = new CodeCompletionString;
       Pattern->AddTypedTextChunk("case");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
       Pattern->AddPlaceholderChunk("expression");
       Pattern->AddChunk(CodeCompletionString::CK_Colon);
       Results.AddResult(Result(Pattern));
@@ -1063,52 +1455,54 @@
       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
+    if (Results.includeCodePatterns()) {
+      /// 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);
-    Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
-    Pattern->AddPlaceholderChunk("statements");
-    Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
-    Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
-    Results.AddResult(Result(Pattern));
+      Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+      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));
+      // 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 ;
@@ -1147,7 +1541,7 @@
     Pattern = new CodeCompletionString;
     Pattern->AddTypedTextChunk("goto");
     Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
-    Pattern->AddPlaceholderChunk("identifier");
+    Pattern->AddPlaceholderChunk("label");
     Results.AddResult(Result(Pattern));    
 
     // Using directives
@@ -1161,12 +1555,12 @@
   }
 
   // Fall through (for statement expressions).
-  case Action::CCC_ForInit:
-  case Action::CCC_Condition:
+  case Sema::PCC_ForInit:
+  case Sema::PCC_Condition:
     AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
     // Fall through: conditions and statements can have expressions.
 
-  case Action::CCC_Expression: {
+  case Sema::PCC_Expression: {
     CodeCompletionString *Pattern = 0;
     if (SemaRef.getLangOptions().CPlusPlus) {
       // 'this', if we're in a non-static member function.
@@ -1182,7 +1576,7 @@
       Pattern = new CodeCompletionString;
       Pattern->AddTypedTextChunk("dynamic_cast");
       Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
-      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddPlaceholderChunk("type");
       Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
       Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
       Pattern->AddPlaceholderChunk("expression");
@@ -1193,7 +1587,7 @@
       Pattern = new CodeCompletionString;
       Pattern->AddTypedTextChunk("static_cast");
       Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
-      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddPlaceholderChunk("type");
       Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
       Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
       Pattern->AddPlaceholderChunk("expression");
@@ -1204,7 +1598,7 @@
       Pattern = new CodeCompletionString;
       Pattern->AddTypedTextChunk("reinterpret_cast");
       Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
-      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddPlaceholderChunk("type");
       Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
       Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
       Pattern->AddPlaceholderChunk("expression");
@@ -1215,7 +1609,7 @@
       Pattern = new CodeCompletionString;
       Pattern->AddTypedTextChunk("const_cast");
       Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
-      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddPlaceholderChunk("type");
       Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
       Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
       Pattern->AddPlaceholderChunk("expression");
@@ -1234,7 +1628,7 @@
       Pattern = new CodeCompletionString;
       Pattern->AddTypedTextChunk("new");
       Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
-      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddPlaceholderChunk("type");
       Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
       Pattern->AddPlaceholderChunk("expressions");
       Pattern->AddChunk(CodeCompletionString::CK_RightParen);
@@ -1244,7 +1638,7 @@
       Pattern = new CodeCompletionString;
       Pattern->AddTypedTextChunk("new");
       Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
-      Pattern->AddPlaceholderChunk("type-id");
+      Pattern->AddPlaceholderChunk("type");
       Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
       Pattern->AddPlaceholderChunk("size");
       Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
@@ -1263,6 +1657,7 @@
       // delete [] expression
       Pattern = new CodeCompletionString;
       Pattern->AddTypedTextChunk("delete");
+      Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
       Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
       Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
       Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
@@ -1275,14 +1670,19 @@
       Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
       Pattern->AddPlaceholderChunk("expression");
       Results.AddResult(Result(Pattern));
+      
+      // FIXME: Rethrow?
     }
 
     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"));
-      
+      if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
+        // The interface can be NULL.
+        if (ObjCInterfaceDecl *ID = Method->getClassInterface())
+          if (ID->getSuperClass())
+            Results.AddResult(Result("super"));
+      }
+
       AddObjCExpressionResults(Results, true);
     }
 
@@ -1295,11 +1695,15 @@
     Results.AddResult(Result(Pattern));
     break;
   }
+      
+  case Sema::PCC_Type:
+    break;
   }
 
-  AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
+  if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
+    AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
 
-  if (SemaRef.getLangOptions().CPlusPlus)
+  if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
     Results.AddResult(Result("operator"));
 }
 
@@ -1339,6 +1743,116 @@
   Result->AddResultTypeChunk(TypeStr);
 }
 
+static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
+                             CodeCompletionString *Result) {
+  if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
+    if (Sentinel->getSentinel() == 0) {
+      if (Context.getLangOptions().ObjC1 &&
+          Context.Idents.get("nil").hasMacroDefinition())
+        Result->AddTextChunk(", nil");
+      else if (Context.Idents.get("NULL").hasMacroDefinition())
+        Result->AddTextChunk(", NULL");
+      else
+        Result->AddTextChunk(", (void*)0");
+    }
+}
+
+static std::string FormatFunctionParameter(ASTContext &Context,
+                                           ParmVarDecl *Param) {
+  bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
+  if (Param->getType()->isDependentType() ||
+      !Param->getType()->isBlockPointerType()) {
+    // The argument for a dependent or non-block parameter is a placeholder 
+    // containing that parameter's type.
+    std::string Result;
+    
+    if (Param->getIdentifier() && !ObjCMethodParam)
+      Result = Param->getIdentifier()->getName();
+    
+    Param->getType().getAsStringInternal(Result, 
+                                         Context.PrintingPolicy);
+    
+    if (ObjCMethodParam) {
+      Result = "(" + Result;
+      Result += ")";
+      if (Param->getIdentifier())
+        Result += Param->getIdentifier()->getName();
+    }
+    return Result;
+  }
+  
+  // The argument for a block pointer parameter is a block literal with
+  // the appropriate type.
+  FunctionProtoTypeLoc *Block = 0;
+  TypeLoc TL;
+  if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
+    TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
+    while (true) {
+      // Look through typedefs.
+      if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
+        if (TypeSourceInfo *InnerTSInfo
+            = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
+          TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
+          continue;
+        }
+      }
+      
+      // Look through qualified types
+      if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
+        TL = QualifiedTL->getUnqualifiedLoc();
+        continue;
+      }
+      
+      // Try to get the function prototype behind the block pointer type,
+      // then we're done.
+      if (BlockPointerTypeLoc *BlockPtr
+          = dyn_cast<BlockPointerTypeLoc>(&TL)) {
+        TL = BlockPtr->getPointeeLoc();
+        Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
+      }
+      break;
+    }
+  }
+
+  if (!Block) {
+    // We were unable to find a FunctionProtoTypeLoc with parameter names
+    // for the block; just use the parameter type as a placeholder.
+    std::string Result;
+    Param->getType().getUnqualifiedType().
+                            getAsStringInternal(Result, Context.PrintingPolicy);
+    
+    if (ObjCMethodParam) {
+      Result = "(" + Result;
+      Result += ")";
+      if (Param->getIdentifier())
+        Result += Param->getIdentifier()->getName();
+    }
+      
+    return Result;
+  }
+  
+  // We have the function prototype behind the block pointer type, as it was
+  // written in the source.
+  std::string Result = "(^)(";
+  for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
+    if (I)
+      Result += ", ";
+    Result += FormatFunctionParameter(Context, Block->getArg(I));
+  }
+  if (Block->getTypePtr()->isVariadic()) {
+    if (Block->getNumArgs() > 0)
+      Result += ", ...";
+    else
+      Result += "...";
+  } else if (Block->getNumArgs() == 0 && !Context.getLangOptions().CPlusPlus)
+    Result += "void";
+             
+  Result += ")";
+  Block->getTypePtr()->getResultType().getAsStringInternal(Result, 
+                                                        Context.PrintingPolicy);
+  return Result;
+}
+
 /// \brief Add function parameter chunks to the given code completion string.
 static void AddFunctionParameterChunks(ASTContext &Context,
                                        FunctionDecl *Function,
@@ -1362,21 +1876,19 @@
       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);
-    
+    std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
+        
     // Add the placeholder string.
     CCStr->AddPlaceholderChunk(PlaceholderStr);
   }
   
   if (const FunctionProtoType *Proto 
         = Function->getType()->getAs<FunctionProtoType>())
-    if (Proto->isVariadic())
+    if (Proto->isVariadic()) {
       CCStr->AddPlaceholderChunk(", ...");
+
+      MaybeAddSentinel(Context, Function, CCStr);
+    }
 }
 
 /// \brief Add template parameter chunks to the given code completion string.
@@ -1493,13 +2005,15 @@
 /// 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) {
+CodeCompletionResult::CreateCodeCompletionString(Sema &S,
+                                               CodeCompletionString *Result) {
   typedef CodeCompletionString::Chunk Chunk;
   
   if (Kind == RK_Pattern)
-    return Pattern->Clone();
+    return Pattern->Clone(Result);
   
-  CodeCompletionString *Result = new CodeCompletionString;
+  if (!Result)
+    Result = new CodeCompletionString;
 
   if (Kind == RK_Keyword) {
     Result->AddTypedTextChunk(Keyword);
@@ -1543,7 +2057,7 @@
     return Result;
   }
   
-  assert(Kind == RK_Declaration && "Missed a macro kind?");
+  assert(Kind == RK_Declaration && "Missed a result kind?");
   NamedDecl *ND = Declaration;
   
   if (StartsNestedNameSpecifier) {
@@ -1659,9 +2173,9 @@
         if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
           Keyword += II->getName().str();
         Keyword += ":";
-        if (Idx < StartParameter || AllParametersAreInformative) {
+        if (Idx < StartParameter || AllParametersAreInformative)
           Result->AddInformativeChunk(Keyword);
-        } else if (Idx == StartParameter)
+        else if (Idx == StartParameter)
           Result->AddTypedTextChunk(Keyword);
         else
           Result->AddTextChunk(Keyword);
@@ -1672,21 +2186,33 @@
         continue;
 
       std::string Arg;
-      (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
-      Arg = "(" + Arg + ")";
-      if (IdentifierInfo *II = (*P)->getIdentifier())
-        Arg += II->getName().str();
-      if (AllParametersAreInformative)
+      
+      if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
+        Arg = FormatFunctionParameter(S.Context, *P);
+      else {
+        (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
+        Arg = "(" + Arg + ")";
+        if (IdentifierInfo *II = (*P)->getIdentifier())
+          Arg += II->getName().str();
+      }
+      
+      if (DeclaringEntity)
+        Result->AddTextChunk(Arg);
+      else if (AllParametersAreInformative)
         Result->AddInformativeChunk(Arg);
       else
         Result->AddPlaceholderChunk(Arg);
     }
 
     if (Method->isVariadic()) {
-      if (AllParametersAreInformative)
+      if (DeclaringEntity)
+        Result->AddTextChunk(", ...");
+      else if (AllParametersAreInformative)
         Result->AddInformativeChunk(", ...");
       else
         Result->AddPlaceholderChunk(", ...");
+      
+      MaybeAddSentinel(S.Context, Method, Result);
     }
     
     return Result;
@@ -1766,184 +2292,366 @@
   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;
-    }
-  };
+unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName, 
+                                      bool PreferredTypeIsPointer) {
+  unsigned Priority = CCP_Macro;
+  
+  // Treat the "nil" and "NULL" macros as null pointer constants.
+  if (MacroName.equals("nil") || MacroName.equals("NULL")) {
+    Priority = CCP_Constant;
+    if (PreferredTypeIsPointer)
+      Priority = Priority / CCF_SimilarTypeMatch;
+  }
+  
+  return Priority;
 }
 
-static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results) {
+static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
+                            bool TargetTypeIsPointer = false) {
+  typedef CodeCompletionResult Result;
+  
   Results.EnterNewScope();
   for (Preprocessor::macro_iterator M = PP.macro_begin(), 
                                  MEnd = PP.macro_end();
-       M != MEnd; ++M)
-    Results.AddResult(M->first);
+       M != MEnd; ++M) {
+    Results.AddResult(Result(M->first, 
+                             getMacroUsagePriority(M->first->getName(),
+                                                   TargetTypeIsPointer)));
+  }
+  Results.ExitScope();
+}
+
+static void AddPrettyFunctionResults(const LangOptions &LangOpts, 
+                                     ResultBuilder &Results) {
+  typedef CodeCompletionResult Result;
+  
+  Results.EnterNewScope();
+  Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
+  Results.AddResult(Result("__FUNCTION__", CCP_Constant));
+  if (LangOpts.C99 || LangOpts.CPlusPlus0x)
+    Results.AddResult(Result("__func__", CCP_Constant));
   Results.ExitScope();
 }
 
 static void HandleCodeCompleteResults(Sema *S,
                                       CodeCompleteConsumer *CodeCompleter,
-                                     CodeCompleteConsumer::Result *Results,
-                                     unsigned NumResults) {
-  std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
-
+                                      CodeCompletionContext Context,
+                                      CodeCompletionResult *Results,
+                                      unsigned NumResults) {
   if (CodeCompleter)
-    CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
+    CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
   
   for (unsigned I = 0; I != NumResults; ++I)
     Results[I].Destroy();
 }
 
+static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S, 
+                                            Sema::ParserCompletionContext PCC) {
+  switch (PCC) {
+  case Sema::PCC_Namespace:
+    return CodeCompletionContext::CCC_TopLevel;
+      
+  case Sema::PCC_Class:
+    return CodeCompletionContext::CCC_ClassStructUnion;
+
+  case Sema::PCC_ObjCInterface:
+    return CodeCompletionContext::CCC_ObjCInterface;
+      
+  case Sema::PCC_ObjCImplementation:
+    return CodeCompletionContext::CCC_ObjCImplementation;
+
+  case Sema::PCC_ObjCInstanceVariableList:
+    return CodeCompletionContext::CCC_ObjCIvarList;
+      
+  case Sema::PCC_Template:
+  case Sema::PCC_MemberTemplate:
+  case Sema::PCC_RecoveryInFunction:
+    return CodeCompletionContext::CCC_Other;
+      
+  case Sema::PCC_Expression:
+  case Sema::PCC_ForInit:
+  case Sema::PCC_Condition:
+    return CodeCompletionContext::CCC_Expression;
+      
+  case Sema::PCC_Statement:
+    return CodeCompletionContext::CCC_Statement;
+
+  case Sema::PCC_Type:
+    return CodeCompletionContext::CCC_Type;
+  }
+  
+  return CodeCompletionContext::CCC_Other;
+}
+
+/// \brief If we're in a C++ virtual member function, add completion results
+/// that invoke the functions we override, since it's common to invoke the 
+/// overridden function as well as adding new functionality.
+///
+/// \param S The semantic analysis object for which we are generating results.
+///
+/// \param InContext This context in which the nested-name-specifier preceding
+/// the code-completion point 
+static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
+                                  ResultBuilder &Results) {
+  // Look through blocks.
+  DeclContext *CurContext = S.CurContext;
+  while (isa<BlockDecl>(CurContext))
+    CurContext = CurContext->getParent();
+  
+  
+  CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
+  if (!Method || !Method->isVirtual())
+    return;
+  
+  // We need to have names for all of the parameters, if we're going to 
+  // generate a forwarding call.
+  for (CXXMethodDecl::param_iterator P = Method->param_begin(),
+                                  PEnd = Method->param_end();
+       P != PEnd;
+       ++P) {
+    if (!(*P)->getDeclName())
+      return;
+  }
+
+  for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
+                                   MEnd = Method->end_overridden_methods();
+       M != MEnd; ++M) {
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
+    if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
+      continue;
+        
+    // If we need a nested-name-specifier, add one now.
+    if (!InContext) {
+      NestedNameSpecifier *NNS
+        = getRequiredQualification(S.Context, CurContext,
+                                   Overridden->getDeclContext());
+      if (NNS) {
+        std::string Str;
+        llvm::raw_string_ostream OS(Str);
+        NNS->print(OS, S.Context.PrintingPolicy);
+        Pattern->AddTextChunk(OS.str());
+      }
+    } else if (!InContext->Equals(Overridden->getDeclContext()))
+      continue;
+    
+    Pattern->AddTypedTextChunk(Overridden->getNameAsString());
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    bool FirstParam = true;
+    for (CXXMethodDecl::param_iterator P = Method->param_begin(),
+                                    PEnd = Method->param_end();
+         P != PEnd; ++P) {
+      if (FirstParam)
+        FirstParam = false;
+      else
+        Pattern->AddChunk(CodeCompletionString::CK_Comma);
+
+      Pattern->AddPlaceholderChunk((*P)->getIdentifier()->getName());
+    }
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(CodeCompletionResult(Pattern,
+                                           CCP_SuperCompletion,
+                                           CXCursor_CXXMethod));
+    Results.Ignore(Overridden);
+  }
+}
+
 void Sema::CodeCompleteOrdinaryName(Scope *S, 
-                                    CodeCompletionContext CompletionContext) {
-  typedef CodeCompleteConsumer::Result Result;
-  ResultBuilder Results(*this);
+                                    ParserCompletionContext CompletionContext) {
+  typedef CodeCompletionResult Result;
+  ResultBuilder Results(*this);  
+  Results.EnterNewScope();
 
   // 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:
+  case PCC_Namespace:
+  case PCC_Class:
+  case PCC_ObjCInterface:
+  case PCC_ObjCImplementation:
+  case PCC_ObjCInstanceVariableList:
+  case PCC_Template:
+  case PCC_MemberTemplate:
+  case PCC_Type:
     Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
     break;
 
-  case CCC_Expression:
-  case CCC_Statement:
-  case CCC_ForInit:
-  case CCC_Condition:
-    Results.setFilter(&ResultBuilder::IsOrdinaryName);
+  case PCC_Statement:
+    // For statements that are expressions, we prefer to call 'void' functions 
+    // rather than functions that return a result, since then the result would
+    // be ignored.
+    Results.setPreferredType(Context.VoidTy);
+    // Fall through
+      
+  case PCC_Expression:
+  case PCC_ForInit:
+  case PCC_Condition:
+    if (WantTypesInContext(CompletionContext, getLangOptions()))
+      Results.setFilter(&ResultBuilder::IsOrdinaryName);
+    else
+      Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
+      
+    if (getLangOptions().CPlusPlus)
+      MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
+    break;
+      
+  case PCC_RecoveryInFunction:
+    // Unfiltered
     break;
   }
 
+  // If we are in a C++ non-static member function, check the qualifiers on
+  // the member function to filter/prioritize the results list.
+  if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
+    if (CurMethod->isInstance())
+      Results.setObjectTypeQualifiers(
+                      Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
+  
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
 
-  Results.EnterNewScope();
   AddOrdinaryNameResults(CompletionContext, S, *this, Results);
   Results.ExitScope();
 
+  switch (CompletionContext) {
+  case PCC_Expression:
+  case PCC_Statement:
+  case PCC_RecoveryInFunction:
+    if (S->getFnParent())
+      AddPrettyFunctionResults(PP.getLangOptions(), Results);        
+    break;
+    
+  case PCC_Namespace:
+  case PCC_Class:
+  case PCC_ObjCInterface:
+  case PCC_ObjCImplementation:
+  case PCC_ObjCInstanceVariableList:
+  case PCC_Template:
+  case PCC_MemberTemplate:
+  case PCC_ForInit:
+  case PCC_Condition:
+  case PCC_Type:
+    break;
+  }
+  
   if (CodeCompleter->includeMacros())
     AddMacroResults(PP, Results);
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  
+  HandleCodeCompleteResults(this, CodeCompleter,
+                            mapCodeCompletionContext(*this, CompletionContext),
+                            Results.data(),Results.size());
 }
 
+void Sema::CodeCompleteDeclarator(Scope *S,
+                                  bool AllowNonIdentifiers,
+                                  bool AllowNestedNameSpecifiers) {
+  typedef CodeCompletionResult Result;
+  ResultBuilder Results(*this);    
+  Results.EnterNewScope();
+  
+  // Type qualifiers can come after names.
+  Results.AddResult(Result("const"));
+  Results.AddResult(Result("volatile"));
+  if (getLangOptions().C99)
+    Results.AddResult(Result("restrict"));
+
+  if (getLangOptions().CPlusPlus) {
+    if (AllowNonIdentifiers) {
+      Results.AddResult(Result("operator")); 
+    }
+    
+    // Add nested-name-specifiers.
+    if (AllowNestedNameSpecifiers) {
+      Results.allowNestedNameSpecifiers();
+      CodeCompletionDeclConsumer Consumer(Results, CurContext);
+      LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
+                         CodeCompleter->includeGlobals());
+    }
+  }
+  Results.ExitScope();
+
+  // Note that we intentionally suppress macro results here, since we do not
+  // encourage using macros to produce the names of entities.
+
+  HandleCodeCompleteResults(this, CodeCompleter,
+                        AllowNestedNameSpecifiers
+                          ? CodeCompletionContext::CCC_PotentiallyQualifiedName
+                          : CodeCompletionContext::CCC_Name,
+                            Results.data(), Results.size());
+}
+
+struct Sema::CodeCompleteExpressionData {
+  CodeCompleteExpressionData(QualType PreferredType = QualType()) 
+    : PreferredType(PreferredType), IntegralConstantExpression(false),
+      ObjCCollection(false) { }
+  
+  QualType PreferredType;
+  bool IntegralConstantExpression;
+  bool ObjCCollection;
+  llvm::SmallVector<Decl *, 4> IgnoreDecls;
+};
+
+/// \brief Perform code-completion in an expression context when we know what
+/// type we're looking for.
+///
+/// \param IntegralConstantExpression Only permit integral constant 
+/// expressions.
+void Sema::CodeCompleteExpression(Scope *S, 
+                                  const CodeCompleteExpressionData &Data) {
+  typedef CodeCompletionResult Result;
+  ResultBuilder Results(*this);
+  
+  if (Data.ObjCCollection)
+    Results.setFilter(&ResultBuilder::IsObjCCollection);
+  else if (Data.IntegralConstantExpression)
+    Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
+  else if (WantTypesInContext(PCC_Expression, getLangOptions()))
+    Results.setFilter(&ResultBuilder::IsOrdinaryName);
+  else
+    Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
+
+  if (!Data.PreferredType.isNull())
+    Results.setPreferredType(Data.PreferredType.getNonReferenceType());
+  
+  // Ignore any declarations that we were told that we don't care about.
+  for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
+    Results.Ignore(Data.IgnoreDecls[I]);
+  
+  CodeCompletionDeclConsumer Consumer(Results, CurContext);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
+  
+  Results.EnterNewScope();
+  AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
+  Results.ExitScope();
+  
+  bool PreferredTypeIsPointer = false;
+  if (!Data.PreferredType.isNull())
+    PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
+      || Data.PreferredType->isMemberPointerType() 
+      || Data.PreferredType->isBlockPointerType();
+  
+  if (S->getFnParent() && 
+      !Data.ObjCCollection && 
+      !Data.IntegralConstantExpression)
+    AddPrettyFunctionResults(PP.getLangOptions(), Results);        
+
+  if (CodeCompleter->includeMacros())
+    AddMacroResults(PP, Results, PreferredTypeIsPointer);
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                CodeCompletionContext(CodeCompletionContext::CCC_Expression, 
+                                      Data.PreferredType),
+                            Results.data(),Results.size());
+}
+
+
 static void AddObjCProperties(ObjCContainerDecl *Container, 
                               bool AllowCategories,
                               DeclContext *CurContext,
                               ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
 
   // Add properties in this container.
   for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
@@ -1992,7 +2700,7 @@
   if (!BaseE || !CodeCompleter)
     return;
   
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   
   Expr *Base = static_cast<Expr *>(BaseE);
   QualType BaseType = Base->getType();
@@ -2001,7 +2709,7 @@
     if (const PointerType *Ptr = BaseType->getAs<PointerType>())
       BaseType = Ptr->getPointeeType();
     else if (BaseType->isObjCObjectPointerType())
-    /*Do nothing*/ ;
+      /*Do nothing*/ ;
     else
       return;
   }
@@ -2009,10 +2717,15 @@
   ResultBuilder Results(*this, &ResultBuilder::IsMember);
   Results.EnterNewScope();
   if (const RecordType *Record = BaseType->getAs<RecordType>()) {
+    // Indicate that we are performing a member access, and the cv-qualifiers
+    // for the base object type.
+    Results.setObjectTypeQualifiers(BaseType.getQualifiers());
+    
     // Access to a C/C++ class, struct, or union.
     Results.allowNestedNameSpecifiers();
     CodeCompletionDeclConsumer Consumer(Results, CurContext);
-    LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
+    LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
+                       CodeCompleter->includeGlobals());
 
     if (getLangOptions().CPlusPlus) {
       if (!Results.empty()) {
@@ -2047,20 +2760,21 @@
          I != E; ++I)
       AddObjCProperties(*I, true, CurContext, Results);
   } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
-             (!IsArrow && BaseType->isObjCInterfaceType())) {
+             (!IsArrow && BaseType->isObjCObjectType())) {
     // Objective-C instance variable access.
     ObjCInterfaceDecl *Class = 0;
     if (const ObjCObjectPointerType *ObjCPtr
                                     = BaseType->getAs<ObjCObjectPointerType>())
       Class = ObjCPtr->getInterfaceDecl();
     else
-      Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
+      Class = BaseType->getAs<ObjCObjectType>()->getInterface();
     
     // Add all ivars from this class and its superclasses.
     if (Class) {
       CodeCompletionDeclConsumer Consumer(Results, CurContext);
       Results.setFilter(&ResultBuilder::IsObjCIvar);
-      LookupVisibleDecls(Class, LookupMemberName, Consumer);
+      LookupVisibleDecls(Class, LookupMemberName, Consumer,
+                         CodeCompleter->includeGlobals());
     }
   }
   
@@ -2069,27 +2783,35 @@
   Results.ExitScope();
 
   // Hand off the results found for code completion.
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+            CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
+                                              BaseType),
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
   if (!CodeCompleter)
     return;
   
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   ResultBuilder::LookupFilter Filter = 0;
+  enum CodeCompletionContext::Kind ContextKind
+    = CodeCompletionContext::CCC_Other;
   switch ((DeclSpec::TST)TagSpec) {
   case DeclSpec::TST_enum:
     Filter = &ResultBuilder::IsEnum;
+    ContextKind = CodeCompletionContext::CCC_EnumTag;
     break;
     
   case DeclSpec::TST_union:
     Filter = &ResultBuilder::IsUnion;
+    ContextKind = CodeCompletionContext::CCC_UnionTag;
     break;
     
   case DeclSpec::TST_struct:
   case DeclSpec::TST_class:
     Filter = &ResultBuilder::IsClassOrStruct;
+    ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
     break;
     
   default:
@@ -2102,22 +2824,46 @@
 
   // First pass: look for tags.
   Results.setFilter(Filter);
-  LookupVisibleDecls(S, LookupTagName, Consumer);
+  LookupVisibleDecls(S, LookupTagName, Consumer,
+                     CodeCompleter->includeGlobals());
 
-  // Second pass: look for nested name specifiers.
-  Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
-  LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
+  if (CodeCompleter->includeGlobals()) {
+    // Second pass: look for nested name specifiers.
+    Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
+    LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
+  }
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
+                            Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
+    Results.AddResult("const");
+  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
+    Results.AddResult("volatile");
+  if (getLangOptions().C99 &&
+      !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
+    Results.AddResult("restrict");
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_TypeQualifiers,
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteCase(Scope *S) {
-  if (getSwitchStack().empty() || !CodeCompleter)
+  if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
     return;
   
-  SwitchStmt *Switch = getSwitchStack().back();
-  if (!Switch->getCond()->getType()->isEnumeralType())
+  SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
+  if (!Switch->getCond()->getType()->isEnumeralType()) {
+    CodeCompleteExpressionData Data(Switch->getCond()->getType());
+    Data.IntegralConstantExpression = true;
+    CodeCompleteExpression(S, Data);
     return;
+  }
   
   // Code-complete the cases of a switch statement over an enumeration type
   // by providing the list of 
@@ -2181,14 +2927,16 @@
     if (EnumeratorsSeen.count(*E))
       continue;
     
-    Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
+    Results.AddResult(CodeCompletionResult(*E, Qualifier),
                       CurContext, 0, false);
   }
   Results.ExitScope();
 
   if (CodeCompleter->includeMacros())
     AddMacroResults(PP, Results);
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Expression,
+                            Results.data(),Results.size());
 }
 
 namespace {
@@ -2202,11 +2950,22 @@
     
     bool 
     operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
-      return S.isBetterOverloadCandidate(X, Y, Loc);
+      return isBetterOverloadCandidate(S, X, Y, Loc);
     }
   };
 }
 
+static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
+  if (NumArgs && !Args)
+    return true;
+  
+  for (unsigned I = 0; I != NumArgs; ++I)
+    if (!Args[I])
+      return true;
+  
+  return false;
+}
+
 void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
                             ExprTy **ArgsIn, unsigned NumArgs) {
   if (!CodeCompleter)
@@ -2221,9 +2980,9 @@
   Expr **Args = (Expr **)ArgsIn;
 
   // Ignore type-dependent call expressions entirely.
-  if (Fn->isTypeDependent() || 
+  if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
       Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
-    CodeCompleteOrdinaryName(S, CCC_Expression);
+    CodeCompleteOrdinaryName(S, PCC_Expression);
     return;
   }
 
@@ -2245,7 +3004,8 @@
   else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
     FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
     if (FDecl) {
-      if (!FDecl->getType()->getAs<FunctionProtoType>())
+      if (!getLangOptions().CPlusPlus || 
+          !FDecl->getType()->getAs<FunctionProtoType>())
         Results.push_back(ResultCandidate(FDecl));
       else
         // FIXME: access?
@@ -2255,6 +3015,8 @@
     }
   }
   
+  QualType ParamType;
+  
   if (!CandidateSet.empty()) {
     // Sort the overload candidate set by placing the best overloads first.
     std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
@@ -2267,14 +3029,85 @@
       if (Cand->Viable)
         Results.push_back(ResultCandidate(Cand->Function));
     }
+
+    // From the viable candidates, try to determine the type of this parameter.
+    for (unsigned I = 0, N = Results.size(); I != N; ++I) {
+      if (const FunctionType *FType = Results[I].getFunctionType())
+        if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
+          if (NumArgs < Proto->getNumArgs()) {
+            if (ParamType.isNull())
+              ParamType = Proto->getArgType(NumArgs);
+            else if (!Context.hasSameUnqualifiedType(
+                                            ParamType.getNonReferenceType(),
+                           Proto->getArgType(NumArgs).getNonReferenceType())) {
+              ParamType = QualType();
+              break;
+            }
+          }
+    }
+  } else {
+    // Try to determine the parameter type from the type of the expression
+    // being called.
+    QualType FunctionType = Fn->getType();
+    if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
+      FunctionType = Ptr->getPointeeType();
+    else if (const BlockPointerType *BlockPtr
+                                    = FunctionType->getAs<BlockPointerType>())
+      FunctionType = BlockPtr->getPointeeType();
+    else if (const MemberPointerType *MemPtr
+                                    = FunctionType->getAs<MemberPointerType>())
+      FunctionType = MemPtr->getPointeeType();
+    
+    if (const FunctionProtoType *Proto
+                                  = FunctionType->getAs<FunctionProtoType>()) {
+      if (NumArgs < Proto->getNumArgs())
+        ParamType = Proto->getArgType(NumArgs);
+    }
   }
 
-  CodeCompleteOrdinaryName(S, CCC_Expression);
+  if (ParamType.isNull())
+    CodeCompleteOrdinaryName(S, PCC_Expression);
+  else
+    CodeCompleteExpression(S, ParamType);
+  
   if (!Results.empty())
     CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(), 
                                              Results.size());
 }
 
+void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
+  ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
+  if (!VD) {
+    CodeCompleteOrdinaryName(S, PCC_Expression);
+    return;
+  }
+  
+  CodeCompleteExpression(S, VD->getType());
+}
+
+void Sema::CodeCompleteReturn(Scope *S) {
+  QualType ResultType;
+  if (isa<BlockDecl>(CurContext)) {
+    if (BlockScopeInfo *BSI = getCurBlock())
+      ResultType = BSI->ReturnType;
+  } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
+    ResultType = Function->getResultType();
+  else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
+    ResultType = Method->getResultType();
+  
+  if (ResultType.isNull())
+    CodeCompleteOrdinaryName(S, PCC_Expression);
+  else
+    CodeCompleteExpression(S, ResultType);
+}
+
+void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
+  if (LHS)
+    CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
+  else
+    CodeCompleteOrdinaryName(S, PCC_Expression);
+}
+
 void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
                                    bool EnteringContext) {
   if (!SS.getScopeRep() || !CodeCompleter)
@@ -2286,20 +3119,33 @@
 
   // Try to instantiate any non-dependent declaration contexts before
   // we look in them.
-  if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS))
+  if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
     return;
 
   ResultBuilder Results(*this);
-  CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
   
+  Results.EnterNewScope();
   // 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");
+
+  // Add calls to overridden virtual functions, if there are any.
+  //
+  // FIXME: This isn't wonderful, because we don't know whether we're actually
+  // in a context that permits expressions. This is a general issue with
+  // qualified-id completions.
+  if (!EnteringContext)
+    MaybeAddOverrideCalls(*this, Ctx, Results);
+  Results.ExitScope();  
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  CodeCompletionDeclConsumer Consumer(Results, CurContext);
+  LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
+
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Name,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteUsing(Scope *S) {
@@ -2311,15 +3157,18 @@
   
   // If we aren't in class scope, we could see the "namespace" keyword.
   if (!S->isClassScope())
-    Results.AddResult(CodeCompleteConsumer::Result("namespace"));
+    Results.AddResult(CodeCompletionResult("namespace"));
   
   // After "using", we can see anything that would start a 
   // nested-name-specifier.
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
   Results.ExitScope();
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteUsingDirective(Scope *S) {
@@ -2331,9 +3180,12 @@
   ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
   Results.EnterNewScope();
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Namespace,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteNamespaceDecl(Scope *S)  {
@@ -2362,12 +3214,14 @@
     for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator 
          NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
          NS != NSEnd; ++NS)
-      Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
+      Results.AddResult(CodeCompletionResult(NS->second, 0),
                         CurContext, 0, false);
     Results.ExitScope();
   }
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteNamespaceAliasDecl(Scope *S)  {
@@ -2377,15 +3231,18 @@
   // 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());
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Namespace,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteOperatorName(Scope *S) {
   if (!CodeCompleter)
     return;
 
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, &ResultBuilder::IsType);
   Results.EnterNewScope();
   
@@ -2398,13 +3255,96 @@
   // Add any type names visible from the current scope
   Results.allowNestedNameSpecifiers();
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
   
   // Add any type specifiers
   AddTypeSpecifierResults(getLangOptions(), Results);
   Results.ExitScope();
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Type,
+                            Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
+                                    CXXBaseOrMemberInitializer** Initializers,
+                                              unsigned NumInitializers) {
+  CXXConstructorDecl *Constructor
+    = static_cast<CXXConstructorDecl *>(ConstructorD);
+  if (!Constructor)
+    return;
+  
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  
+  // Fill in any already-initialized fields or base classes.
+  llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
+  llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
+  for (unsigned I = 0; I != NumInitializers; ++I) {
+    if (Initializers[I]->isBaseInitializer())
+      InitializedBases.insert(
+        Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
+    else
+      InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
+  }
+  
+  // Add completions for base classes.
+  unsigned Priority = 1;
+  CXXRecordDecl *ClassDecl = Constructor->getParent();
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+                                       BaseEnd = ClassDecl->bases_end();
+       Base != BaseEnd; ++Base) {
+    if (!InitializedBases.insert(Context.getCanonicalType(Base->getType())))
+      continue;
+    
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk(
+                           Base->getType().getAsString(Context.PrintingPolicy));
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("args");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(CodeCompletionResult(Pattern, Priority++));
+  }
+  
+  // Add completions for virtual base classes.
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
+                                       BaseEnd = ClassDecl->vbases_end();
+       Base != BaseEnd; ++Base) {
+    if (!InitializedBases.insert(Context.getCanonicalType(Base->getType())))
+      continue;
+    
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk(
+                           Base->getType().getAsString(Context.PrintingPolicy));
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("args");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(CodeCompletionResult(Pattern, Priority++));
+  }
+  
+  // Add completions for members.
+  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+                                  FieldEnd = ClassDecl->field_end();
+       Field != FieldEnd; ++Field) {
+    if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl())))
+      continue;
+    
+    if (!Field->getDeclName())
+      continue;
+    
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("args");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(CodeCompletionResult(Pattern, Priority++));
+  }
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Name,
+                            Results.data(), Results.size());
 }
 
 // Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
@@ -2413,7 +3353,7 @@
 static void AddObjCImplementationResults(const LangOptions &LangOpts,
                                          ResultBuilder &Results,
                                          bool NeedAt) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   // Since we have an implementation, we can end it.
   Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
   
@@ -2438,7 +3378,7 @@
 static void AddObjCInterfaceResults(const LangOptions &LangOpts,
                                     ResultBuilder &Results,
                                     bool NeedAt) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   
   // Since we have an interface or protocol, we can end it.
   Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
@@ -2456,38 +3396,40 @@
 }
 
 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult 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");
+  Pattern->AddPlaceholderChunk("name");
   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));
+  if (Results.includeCodePatterns()) {
+    // @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));
+    // @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;
@@ -2499,9 +3441,9 @@
   Results.AddResult(Result(Pattern));
 }
 
-void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
+void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
                                        bool InInterface) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this);
   Results.EnterNewScope();
   if (ObjCImpDecl)
@@ -2511,11 +3453,13 @@
   else
     AddObjCTopLevelResults(Results, false);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   CodeCompletionString *Pattern = 0;
 
   // @encode ( type-name )
@@ -2544,28 +3488,30 @@
 }
 
 static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult 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));
+  if (Results.includeCodePatterns()) {
+    // @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;
@@ -2574,23 +3520,25 @@
   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));
+  if (Results.includeCodePatterns()) {
+    // @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;
+  typedef CodeCompletionResult 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)));
@@ -2603,7 +3551,9 @@
   Results.EnterNewScope();
   AddObjCVisibilityResults(getLangOptions(), Results, false);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteObjCAtStatement(Scope *S) {
@@ -2612,7 +3562,9 @@
   AddObjCStatementResults(Results, false);
   AddObjCExpressionResults(Results, false);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteObjCAtExpression(Scope *S) {
@@ -2620,7 +3572,9 @@
   Results.EnterNewScope();
   AddObjCExpressionResults(Results, false);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 /// \brief Determine whether the addition of the given flag to an Objective-C
@@ -2659,37 +3613,39 @@
   
   unsigned Attributes = ODS.getPropertyAttributes();
   
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this);
   Results.EnterNewScope();
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
-    Results.AddResult(CodeCompleteConsumer::Result("readonly"));
+    Results.AddResult(CodeCompletionResult("readonly"));
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
-    Results.AddResult(CodeCompleteConsumer::Result("assign"));
+    Results.AddResult(CodeCompletionResult("assign"));
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
-    Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
+    Results.AddResult(CodeCompletionResult("readwrite"));
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
-    Results.AddResult(CodeCompleteConsumer::Result("retain"));
+    Results.AddResult(CodeCompletionResult("retain"));
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
-    Results.AddResult(CodeCompleteConsumer::Result("copy"));
+    Results.AddResult(CodeCompletionResult("copy"));
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
-    Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
+    Results.AddResult(CodeCompletionResult("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));
+    Results.AddResult(CodeCompletionResult(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.AddResult(CodeCompletionResult(Getter));
   }
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 /// \brief Descripts the kind of Objective-C method that we want to find
@@ -2700,25 +3656,32 @@
   MK_OneArgSelector //< One-argument selector.
 };
 
+static bool isAcceptableObjCSelector(Selector Sel,
+                                     ObjCMethodKind WantKind,
+                                     IdentifierInfo **SelIdents,
+                                     unsigned NumSelIdents) {
+  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;
+}
+
 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;
+  return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
+                                  NumSelIdents);
 }
                                    
 /// \brief Add all of the Objective-C methods in the given Objective-C 
@@ -2744,8 +3707,9 @@
                            IdentifierInfo **SelIdents,
                            unsigned NumSelIdents,
                            DeclContext *CurContext,
-                           ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+                           ResultBuilder &Results,
+                           bool InOriginalClass = true) {
+  typedef CodeCompletionResult Result;
   for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
                                        MEnd = Container->meth_end();
        M != MEnd; ++M) {
@@ -2758,6 +3722,8 @@
       Result R = Result(*M, 0);
       R.StartParameter = NumSelIdents;
       R.AllParametersAreInformative = (WantKind != MK_Any);
+      if (!InOriginalClass)
+        R.Priority += CCD_InBaseClass;
       Results.MaybeAddResult(R, CurContext);
     }
   }
@@ -2772,13 +3738,13 @@
                                             E = Protocols.end(); 
        I != E; ++I)
     AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents, 
-                   CurContext, Results);
+                   CurContext, Results, false);
   
   // Add methods in categories.
   for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
        CatDecl = CatDecl->getNextClassCategory()) {
     AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents, 
-                   NumSelIdents, CurContext, Results);
+                   NumSelIdents, CurContext, Results, InOriginalClass);
     
     // Add a categories protocol methods.
     const ObjCList<ObjCProtocolDecl> &Protocols 
@@ -2787,37 +3753,36 @@
                                               E = Protocols.end();
          I != E; ++I)
       AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, 
-                     NumSelIdents, CurContext, Results);
+                     NumSelIdents, CurContext, Results, false);
     
     // Add methods in category implementations.
     if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
       AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, 
-                     NumSelIdents, CurContext, Results);
+                     NumSelIdents, CurContext, Results, InOriginalClass);
   }
   
   // Add methods in superclass.
   if (IFace->getSuperClass())
     AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind, 
-                   SelIdents, NumSelIdents, CurContext, Results);
+                   SelIdents, NumSelIdents, CurContext, Results, false);
 
   // Add methods in our implementation, if any.
   if (ObjCImplementationDecl *Impl = IFace->getImplementation())
     AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
-                   NumSelIdents, CurContext, Results);
+                   NumSelIdents, CurContext, Results, InOriginalClass);
 }
 
 
-void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
-                                          DeclPtrTy *Methods,
+void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
+                                          Decl **Methods,
                                           unsigned NumMethods) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
 
   // Try to find the interface where getters might live.
-  ObjCInterfaceDecl *Class
-    = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
+  ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
   if (!Class) {
     if (ObjCCategoryDecl *Category
-          = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
+          = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
       Class = Category->getClassInterface();
 
     if (!Class)
@@ -2832,7 +3797,7 @@
   // 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>()))
+            = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
       if (Method->isInstanceMethod() &&
           isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
         Result R = Result(Method, 0);
@@ -2843,20 +3808,22 @@
 
   AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter,
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
-void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
-                                          DeclPtrTy *Methods,
+void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
+                                          Decl **Methods,
                                           unsigned NumMethods) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
 
   // Try to find the interface where setters might live.
   ObjCInterfaceDecl *Class
-    = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
+    = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
   if (!Class) {
     if (ObjCCategoryDecl *Category
-          = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
+          = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
       Class = Category->getClassInterface();
 
     if (!Class)
@@ -2871,7 +3838,7 @@
   // 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>()))
+            = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
       if (Method->isInstanceMethod() &&
           isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
         Result R = Result(Method, 0);
@@ -2883,7 +3850,54 @@
   AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter,
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
+  typedef CodeCompletionResult Result;
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  
+  // Add context-sensitive, Objective-C parameter-passing keywords.
+  bool AddedInOut = false;
+  if ((DS.getObjCDeclQualifier() & 
+       (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
+    Results.AddResult("in");
+    Results.AddResult("inout");
+    AddedInOut = true;
+  }
+  if ((DS.getObjCDeclQualifier() & 
+       (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
+    Results.AddResult("out");
+    if (!AddedInOut)
+      Results.AddResult("inout");
+  }
+  if ((DS.getObjCDeclQualifier() & 
+       (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
+        ObjCDeclSpec::DQ_Oneway)) == 0) {
+     Results.AddResult("bycopy");
+     Results.AddResult("byref");
+     Results.AddResult("oneway");
+  }
+  
+  // Add various builtin type names and specifiers.
+  AddOrdinaryNameResults(PCC_Type, S, *this, Results);
+  Results.ExitScope();
+  
+  // Add the various type names
+  Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
+  CodeCompletionDeclConsumer Consumer(Results, CurContext);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
+  
+  if (CodeCompleter->includeMacros())
+    AddMacroResults(PP, Results);
+
+  HandleCodeCompleteResults(this, CodeCompleter,
+                            CodeCompletionContext::CCC_Type,
+                            Results.data(), Results.size());
 }
 
 /// \brief When we have an expression with type "id", we may assume
@@ -2911,9 +3925,9 @@
   ObjCInterfaceDecl *IFace = 0;
   switch (Msg->getReceiverKind()) {
   case ObjCMessageExpr::Class:
-    if (const ObjCInterfaceType *IFaceType
-                           = Msg->getClassReceiver()->getAs<ObjCInterfaceType>())
-      IFace = IFaceType->getDecl();
+    if (const ObjCObjectType *ObjType
+                           = Msg->getClassReceiver()->getAs<ObjCObjectType>())
+      IFace = ObjType->getInterface();
     break;
 
   case ObjCMessageExpr::Instance: {
@@ -2956,6 +3970,141 @@
     .Default(0);
 }
 
+// Add a special completion for a message send to "super", which fills in the
+// most likely case of forwarding all of our arguments to the superclass 
+// function.
+///
+/// \param S The semantic analysis object.
+///
+/// \param S NeedSuperKeyword Whether we need to prefix this completion with
+/// the "super" keyword. Otherwise, we just need to provide the arguments.
+///
+/// \param SelIdents The identifiers in the selector that have already been
+/// provided as arguments for a send to "super".
+///
+/// \param NumSelIdents The number of identifiers in \p SelIdents.
+///
+/// \param Results The set of results to augment.
+///
+/// \returns the Objective-C method declaration that would be invoked by 
+/// this "super" completion. If NULL, no completion was added.
+static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
+                                              IdentifierInfo **SelIdents,
+                                              unsigned NumSelIdents,
+                                              ResultBuilder &Results) {
+  ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
+  if (!CurMethod)
+    return 0;
+  
+  ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
+  if (!Class)
+    return 0;
+  
+  // Try to find a superclass method with the same selector.
+  ObjCMethodDecl *SuperMethod = 0;
+  while ((Class = Class->getSuperClass()) && !SuperMethod)
+    SuperMethod = Class->getMethod(CurMethod->getSelector(), 
+                                   CurMethod->isInstanceMethod());
+
+  if (!SuperMethod)
+    return 0;
+  
+  // Check whether the superclass method has the same signature.
+  if (CurMethod->param_size() != SuperMethod->param_size() ||
+      CurMethod->isVariadic() != SuperMethod->isVariadic())
+    return 0;
+      
+  for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
+                                   CurPEnd = CurMethod->param_end(),
+                                    SuperP = SuperMethod->param_begin();
+       CurP != CurPEnd; ++CurP, ++SuperP) {
+    // Make sure the parameter types are compatible.
+    if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(), 
+                                          (*SuperP)->getType()))
+      return 0;
+    
+    // Make sure we have a parameter name to forward!
+    if (!(*CurP)->getIdentifier())
+      return 0;
+  }
+  
+  // We have a superclass method. Now, form the send-to-super completion.
+  CodeCompletionString *Pattern = new CodeCompletionString;
+  
+  // Give this completion a return type.
+  AddResultTypeChunk(S.Context, SuperMethod, Pattern);
+
+  // If we need the "super" keyword, add it (plus some spacing).
+  if (NeedSuperKeyword) {
+    Pattern->AddTypedTextChunk("super");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  }
+  
+  Selector Sel = CurMethod->getSelector();
+  if (Sel.isUnarySelector()) {
+    if (NeedSuperKeyword)
+      Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
+    else
+      Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
+  } else {
+    ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
+    for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
+      if (I > NumSelIdents)
+        Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      
+      if (I < NumSelIdents)
+        Pattern->AddInformativeChunk(
+                       Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
+      else if (NeedSuperKeyword || I > NumSelIdents) {
+        Pattern->AddTextChunk(
+                        Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
+        Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
+      } else {
+        Pattern->AddTypedTextChunk(
+                              Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
+        Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());        
+      }
+    }
+  }
+  
+  Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
+                                         SuperMethod->isInstanceMethod()
+                                           ? CXCursor_ObjCInstanceMethodDecl
+                                           : CXCursor_ObjCClassMethodDecl));
+  return SuperMethod;
+}
+                                   
+void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
+  typedef CodeCompletionResult Result;
+  ResultBuilder Results(*this);
+  
+  // Find anything that looks like it could be a message receiver.
+  Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
+  CodeCompletionDeclConsumer Consumer(Results, CurContext);
+  Results.EnterNewScope();
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
+  
+  // If we are in an Objective-C method inside a class that has a superclass,
+  // add "super" as an option.
+  if (ObjCMethodDecl *Method = getCurMethodDecl())
+    if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
+      if (Iface->getSuperClass()) {
+        Results.AddResult(Result("super"));
+        
+        AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
+      }
+  
+  Results.ExitScope();
+  
+  if (CodeCompleter->includeMacros())
+    AddMacroResults(PP, Results);
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_ObjCMessageReceiver,
+                            Results.data(), Results.size());
+  
+}
+
 void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
                                         IdentifierInfo **SelIdents,
                                         unsigned NumSelIdents) {
@@ -2978,10 +4127,11 @@
       // an instance method.
       QualType SuperTy = Context.getObjCInterfaceType(CDecl);
       SuperTy = Context.getObjCObjectPointerType(SuperTy);
-      OwningExprResult Super
+      ExprResult Super
         = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
       return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
-                                             SelIdents, NumSelIdents);
+                                             SelIdents, NumSelIdents,
+                                             /*IsSuper=*/true);
     }
 
     // Fall through to send to the superclass in CDecl.
@@ -2994,9 +4144,9 @@
     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();
+      if (const ObjCObjectType *Iface
+            = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
+        CDecl = Iface->getInterface();
     } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
       // "super" names an unresolved type; we can't be more specific.
     } else {
@@ -3004,7 +4154,7 @@
       CXXScopeSpec SS;
       UnqualifiedId id;
       id.setIdentifier(Super, SuperLoc);
-      OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
+      ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
       return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
                                              SelIdents, NumSelIdents);
     }
@@ -3012,17 +4162,24 @@
     // Fall through
   }
 
-  TypeTy *Receiver = 0;
+  ParsedType Receiver;
   if (CDecl)
-    Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
+    Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
   return CodeCompleteObjCClassMessage(S, Receiver, SelIdents, 
-                                      NumSelIdents);
+                                      NumSelIdents, /*IsSuper=*/true);
 }
 
-void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
+void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
                                         IdentifierInfo **SelIdents,
                                         unsigned NumSelIdents) {
-  typedef CodeCompleteConsumer::Result Result;
+  CodeCompleteObjCClassMessage(S, Receiver, SelIdents, NumSelIdents, false);
+}
+
+void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
+                                        IdentifierInfo **SelIdents,
+                                        unsigned NumSelIdents,
+                                        bool IsSuper) {
+  typedef CodeCompletionResult Result;
   ObjCInterfaceDecl *CDecl = 0;
 
   // If the given name refers to an interface type, retrieve the
@@ -3030,8 +4187,8 @@
   if (Receiver) {
     QualType T = GetTypeFromParser(Receiver, 0);
     if (!T.isNull()) 
-      if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
-        CDecl = Interface->getDecl();
+      if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
+        CDecl = Interface->getInterface();
   }
 
   // Add all of the factory methods in this Objective-C class, its protocols,
@@ -3039,6 +4196,20 @@
   ResultBuilder Results(*this);
   Results.EnterNewScope();
 
+  // If this is a send-to-super, try to add the special "super" send 
+  // completion.
+  if (IsSuper) {
+    if (ObjCMethodDecl *SuperMethod
+          = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents, 
+                                   Results))
+      Results.Ignore(SuperMethod);
+  }
+
+  // If we're inside an Objective-C method definition, prefer its selector to
+  // others.
+  if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
+    Results.setPreferredSelector(CurMethod->getSelector());
+
   if (CDecl) 
     AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext, 
                    Results);  
@@ -3046,25 +4217,23 @@
     // 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.
+    // pool from the AST 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))
+      for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
+           I != N; ++I) {
+        Selector Sel = ExternalSource->GetExternalSelector(I);
+        if (Sel.isNull() || MethodPool.count(Sel))
           continue;
 
-        ReadMethodPool(Sel, /*isInstance=*/false);
+        ReadMethodPool(Sel);
       }
     }
 
-    for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
-           M = FactoryMethodPool.begin(),
-           MEnd = FactoryMethodPool.end();
-         M != MEnd;
-         ++M) {
-      for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method; 
+    for (GlobalMethodPool::iterator M = MethodPool.begin(),
+                                    MEnd = MethodPool.end();
+         M != MEnd; ++M) {
+      for (ObjCMethodList *MethList = &M->second.second;
+           MethList && MethList->Method; 
            MethList = MethList->Next) {
         if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, 
                                     NumSelIdents))
@@ -3079,15 +4248,22 @@
   }
 
   Results.ExitScope();
-  
-  // This also suppresses remaining diagnostics.
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
                                            IdentifierInfo **SelIdents,
                                            unsigned NumSelIdents) {
-  typedef CodeCompleteConsumer::Result Result;
+  CodeCompleteObjCInstanceMessage(S, Receiver, SelIdents, NumSelIdents, false);
+}
+
+void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
+                                           IdentifierInfo **SelIdents,
+                                           unsigned NumSelIdents,
+                                           bool IsSuper) {
+  typedef CodeCompletionResult Result;
   
   Expr *RecExpr = static_cast<Expr *>(Receiver);
   
@@ -3100,6 +4276,20 @@
   ResultBuilder Results(*this);
   Results.EnterNewScope();
 
+  // If this is a send-to-super, try to add the special "super" send 
+  // completion.
+  if (IsSuper) {
+    if (ObjCMethodDecl *SuperMethod
+          = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents, 
+                                   Results))
+      Results.Ignore(SuperMethod);
+  }
+  
+  // If we're inside an Objective-C method definition, prefer its selector to
+  // others.
+  if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
+    Results.setPreferredSelector(CurMethod->getSelector());
+
   // 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.
@@ -3149,25 +4339,23 @@
     // about as code-completion results.
 
     // If we have an external source, load the entire class method
-    // pool from the PCH file.
+    // pool from the AST 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))
+      for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
+           I != N; ++I) {
+        Selector Sel = ExternalSource->GetExternalSelector(I);
+        if (Sel.isNull() || MethodPool.count(Sel))
           continue;
 
-        ReadMethodPool(Sel, /*isInstance=*/true);
+        ReadMethodPool(Sel);
       }
     }
 
-    for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
-           M = InstanceMethodPool.begin(),
-           MEnd = InstanceMethodPool.end();
-         M != MEnd;
-         ++M) {
-      for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method; 
+    for (GlobalMethodPool::iterator M = MethodPool.begin(),
+                                    MEnd = MethodPool.end();
+         M != MEnd; ++M) {
+      for (ObjCMethodList *MethList = &M->second.first;
+           MethList && MethList->Method; 
            MethList = MethList->Next) {
         if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, 
                                     NumSelIdents))
@@ -3182,7 +4370,79 @@
   }
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCForCollection(Scope *S, 
+                                         DeclGroupPtrTy IterationVar) {
+  CodeCompleteExpressionData Data;
+  Data.ObjCCollection = true;
+  
+  if (IterationVar.getAsOpaquePtr()) {
+    DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
+    for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
+      if (*I)
+        Data.IgnoreDecls.push_back(*I);
+    }
+  }
+  
+  CodeCompleteExpression(S, Data);
+}
+
+void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
+                                    unsigned NumSelIdents) {
+  // If we have an external source, load the entire class method
+  // pool from the AST file.
+  if (ExternalSource) {
+    for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
+         I != N; ++I) {
+      Selector Sel = ExternalSource->GetExternalSelector(I);
+      if (Sel.isNull() || MethodPool.count(Sel))
+        continue;
+      
+      ReadMethodPool(Sel);
+    }
+  }
+  
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  for (GlobalMethodPool::iterator M = MethodPool.begin(),
+                               MEnd = MethodPool.end();
+       M != MEnd; ++M) {
+    
+    Selector Sel = M->first;
+    if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
+      continue;
+
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    if (Sel.isUnarySelector()) {
+      Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
+      Results.AddResult(Pattern);
+      continue;
+    }
+    
+    std::string Accumulator;
+    for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
+      if (I == NumSelIdents) {
+        if (!Accumulator.empty()) {
+          Pattern->AddInformativeChunk(Accumulator);
+          Accumulator.clear();
+        }
+      }
+      
+      Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
+      Accumulator += ':';
+    }
+    Pattern->AddTypedTextChunk(Accumulator);
+    Results.AddResult(Pattern);
+  }
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_SelectorName,
+                            Results.data(), Results.size());
 }
 
 /// \brief Add all of the protocol declarations that we find in the given
@@ -3190,7 +4450,7 @@
 static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
                                bool OnlyForwardDeclarations,
                                ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   
   for (DeclContext::decl_iterator D = Ctx->decls_begin(), 
                                DEnd = Ctx->decls_end();
@@ -3230,7 +4490,9 @@
                      Results);
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_ObjCProtocolName,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
@@ -3242,7 +4504,9 @@
                      Results);
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_ObjCProtocolName,
+                            Results.data(),Results.size());
 }
 
 /// \brief Add all of the Objective-C interface declarations that we find in
@@ -3251,7 +4515,7 @@
                                 bool OnlyForwardDeclarations,
                                 bool OnlyUnimplemented,
                                 ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   
   for (DeclContext::decl_iterator D = Ctx->decls_begin(), 
                                DEnd = Ctx->decls_end();
@@ -3283,7 +4547,9 @@
                       false, Results);
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter,
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
@@ -3302,7 +4568,9 @@
                       false, Results);
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteObjCImplementationDecl(Scope *S) { 
@@ -3314,13 +4582,15 @@
                       true, Results);
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteObjCInterfaceCategory(Scope *S, 
                                              IdentifierInfo *ClassName,
                                              SourceLocation ClassNameLoc) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   
   ResultBuilder Results(*this);
   
@@ -3345,13 +4615,15 @@
         Results.AddResult(Result(Category, 0), CurContext, 0, false);
   Results.ExitScope();
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());  
 }
 
 void Sema::CodeCompleteObjCImplementationCategory(Scope *S, 
                                                   IdentifierInfo *ClassName,
                                                   SourceLocation ClassNameLoc) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult 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
@@ -3382,16 +4654,18 @@
   }
   Results.ExitScope();
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());  
 }
 
-void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
-  typedef CodeCompleteConsumer::Result Result;
+void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this);
 
   // Figure out where this @synthesize lives.
   ObjCContainerDecl *Container
-    = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
+    = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
   if (!Container || 
       (!isa<ObjCImplementationDecl>(Container) && 
        !isa<ObjCCategoryImplDecl>(Container)))
@@ -3415,18 +4689,20 @@
                       false, CurContext, Results);
   Results.ExitScope();
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());  
 }
 
 void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, 
                                                   IdentifierInfo *PropertyName,
-                                                  DeclPtrTy ObjCImpDecl) {
-  typedef CodeCompleteConsumer::Result Result;
+                                                  Decl *ObjCImpDecl) {
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this);
 
   // Figure out where this @synthesize lives.
   ObjCContainerDecl *Container
-    = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
+    = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
   if (!Container || 
       (!isa<ObjCImplementationDecl>(Container) && 
        !isa<ObjCCategoryImplDecl>(Container)))
@@ -3453,10 +4729,15 @@
   }
   Results.ExitScope();
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
-typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
+// Mapping from selectors to the methods that implement that selector, along
+// with the "in original class" flag.
+typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> > 
+  KnownMethodsMap;
 
 /// \brief Find all of the methods that reside in the given container
 /// (and its superclasses, protocols, etc.) that meet the given
@@ -3467,7 +4748,8 @@
                                      bool WantInstanceMethods,
                                      QualType ReturnType,
                                      bool IsInImplementation,
-                                     KnownMethodsMap &KnownMethods) {
+                                     KnownMethodsMap &KnownMethods,
+                                     bool InOriginalClass = true) {
   if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
     // Recurse into protocols.
     const ObjCList<ObjCProtocolDecl> &Protocols
@@ -3476,25 +4758,25 @@
            E = Protocols.end(); 
          I != E; ++I)
       FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
-                               IsInImplementation, KnownMethods);
+                               IsInImplementation, KnownMethods,
+                               InOriginalClass);
 
     // 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);
+                               IsInImplementation, KnownMethods,
+                               false);
 
     // 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);      
-    }
+    for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
+         Cat = Cat->getNextClassExtension())
+      FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat), 
+                               WantInstanceMethods, ReturnType,
+                               IsInImplementation, KnownMethods,
+                               InOriginalClass);      
   }
 
   if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
@@ -3505,7 +4787,8 @@
            E = Protocols.end(); 
          I != E; ++I)
       FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
-                               IsInImplementation, KnownMethods);
+                               IsInImplementation, KnownMethods,
+                               InOriginalClass);
   }
 
   if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
@@ -3516,7 +4799,7 @@
            E = Protocols.end(); 
          I != E; ++I)
       FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
-                               IsInImplementation, KnownMethods);
+                               IsInImplementation, KnownMethods, false);
   }
 
   // Add methods in this container. This operation occurs last because
@@ -3530,15 +4813,15 @@
           !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
         continue;
 
-      KnownMethods[(*M)->getSelector()] = *M;
+      KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
     }
   }
 }
 
 void Sema::CodeCompleteObjCMethodDecl(Scope *S, 
                                       bool IsInstanceMethod,
-                                      TypeTy *ReturnTy,
-                                      DeclPtrTy IDecl) {
+                                      ParsedType ReturnTy,
+                                      Decl *IDecl) {
   // Determine the return type of the method we're declaring, if
   // provided.
   QualType ReturnType = GetTypeFromParser(ReturnTy);
@@ -3546,7 +4829,7 @@
   // 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 (Decl *D = IDecl) {
     if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
       SearchDecl = Impl->getClassInterface();
       CurrentDecl = Impl;
@@ -3570,7 +4853,9 @@
   }
 
   if (!SearchDecl || !CurrentDecl) {
-    HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
+    HandleCodeCompleteResults(this, CodeCompleter, 
+                              CodeCompletionContext::CCC_Other,
+                              0, 0);
     return;
   }
     
@@ -3593,7 +4878,7 @@
   }
 
   // Add declarations or definitions for each of the known methods.
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this);
   Results.EnterNewScope();
   PrintingPolicy Policy(Context.PrintingPolicy);
@@ -3601,7 +4886,7 @@
   for (KnownMethodsMap::iterator M = KnownMethods.begin(), 
                               MEnd = KnownMethods.end();
        M != MEnd; ++M) {
-    ObjCMethodDecl *Method = M->second;
+    ObjCMethodDecl *Method = M->second.first;
     CodeCompletionString *Pattern = new CodeCompletionString;
     
     // If the result type was not already provided, add it to the
@@ -3629,7 +4914,7 @@
         Pattern->AddChunk(CodeCompletionString::CK_Colon);
       else if (I < Sel.getNumArgs()) {
         Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
-        Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
+        Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
         Pattern->AddChunk(CodeCompletionString::CK_Colon);
       } else
         break;
@@ -3651,7 +4936,7 @@
       Pattern->AddTextChunk("...");
     }
 
-    if (IsInImplementation) {
+    if (IsInImplementation && Results.includeCodePatterns()) {
       // We will be defining the method here, so add a compound statement.
       Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
       Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
@@ -3669,10 +4954,348 @@
       Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
     }
 
-    Results.AddResult(Result(Pattern));
+    unsigned Priority = CCP_CodePattern;
+    if (!M->second.second)
+      Priority += CCD_InBaseClass;
+    
+    Results.AddResult(Result(Pattern, Priority, 
+                             Method->isInstanceMethod()
+                               ? CXCursor_ObjCInstanceMethodDecl
+                               : CXCursor_ObjCClassMethodDecl));
   }
 
   Results.ExitScope();
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, 
+                                              bool IsInstanceMethod,
+                                              bool AtParameterName,
+                                              ParsedType ReturnTy,
+                                              IdentifierInfo **SelIdents,
+                                              unsigned NumSelIdents) {
+  // If we have an external source, load the entire class method
+  // pool from the AST file.
+  if (ExternalSource) {
+    for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
+         I != N; ++I) {
+      Selector Sel = ExternalSource->GetExternalSelector(I);
+      if (Sel.isNull() || MethodPool.count(Sel))
+        continue;
+
+      ReadMethodPool(Sel);
+    }
+  }
+
+  // Build the set of methods we can see.
+  typedef CodeCompletionResult Result;
+  ResultBuilder Results(*this);
+  
+  if (ReturnTy)
+    Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
+
+  Results.EnterNewScope();  
+  for (GlobalMethodPool::iterator M = MethodPool.begin(),
+                                  MEnd = MethodPool.end();
+       M != MEnd; ++M) {
+    for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
+                                                       &M->second.second;
+         MethList && MethList->Method; 
+         MethList = MethList->Next) {
+      if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, 
+                                  NumSelIdents))
+        continue;
+      
+      if (AtParameterName) {
+        // Suggest parameter names we've seen before.
+        if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
+          ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
+          if (Param->getIdentifier()) {
+            CodeCompletionString *Pattern = new CodeCompletionString;
+            Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
+            Results.AddResult(Pattern);
+          }
+        }
+        
+        continue;
+      }
+      
+      Result R(MethList->Method, 0);
+      R.StartParameter = NumSelIdents;
+      R.AllParametersAreInformative = false;
+      R.DeclaringEntity = true;
+      Results.MaybeAddResult(R, CurContext);
+    }
+  }
+  
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
+}
+
+void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  
+  // #if <condition>
+  CodeCompletionString *Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("if");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("condition");
+  Results.AddResult(Pattern);
+  
+  // #ifdef <macro>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("ifdef");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Results.AddResult(Pattern);
+
+  // #ifndef <macro>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("ifndef");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Results.AddResult(Pattern);
+
+  if (InConditional) {
+    // #elif <condition>
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("elif");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddPlaceholderChunk("condition");
+    Results.AddResult(Pattern);
+
+    // #else
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("else");
+    Results.AddResult(Pattern);
+
+    // #endif
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("endif");
+    Results.AddResult(Pattern);
+  }
+  
+  // #include "header"
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("include");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("\"");
+  Pattern->AddPlaceholderChunk("header");
+  Pattern->AddTextChunk("\"");
+  Results.AddResult(Pattern);
+
+  // #include <header>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("include");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("<");
+  Pattern->AddPlaceholderChunk("header");
+  Pattern->AddTextChunk(">");
+  Results.AddResult(Pattern);
+  
+  // #define <macro>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("define");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Results.AddResult(Pattern);
+  
+  // #define <macro>(<args>)
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("define");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+  Pattern->AddPlaceholderChunk("args");
+  Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+  Results.AddResult(Pattern);
+  
+  // #undef <macro>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("undef");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Results.AddResult(Pattern);
+
+  // #line <number>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("line");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("number");
+  Results.AddResult(Pattern);
+  
+  // #line <number> "filename"
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("line");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("number");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("\"");
+  Pattern->AddPlaceholderChunk("filename");
+  Pattern->AddTextChunk("\"");
+  Results.AddResult(Pattern);
+  
+  // #error <message>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("error");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("message");
+  Results.AddResult(Pattern);
+
+  // #pragma <arguments>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("pragma");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("arguments");
+  Results.AddResult(Pattern);
+
+  if (getLangOptions().ObjC1) {
+    // #import "header"
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("import");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddTextChunk("\"");
+    Pattern->AddPlaceholderChunk("header");
+    Pattern->AddTextChunk("\"");
+    Results.AddResult(Pattern);
+    
+    // #import <header>
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("import");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddTextChunk("<");
+    Pattern->AddPlaceholderChunk("header");
+    Pattern->AddTextChunk(">");
+    Results.AddResult(Pattern);
+  }
+  
+  // #include_next "header"
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("include_next");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("\"");
+  Pattern->AddPlaceholderChunk("header");
+  Pattern->AddTextChunk("\"");
+  Results.AddResult(Pattern);
+  
+  // #include_next <header>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("include_next");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("<");
+  Pattern->AddPlaceholderChunk("header");
+  Pattern->AddTextChunk(">");
+  Results.AddResult(Pattern);
+
+  // #warning <message>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("warning");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("message");
+  Results.AddResult(Pattern);
+
+  // Note: #ident and #sccs are such crazy anachronisms that we don't provide
+  // completions for them. And __include_macros is a Clang-internal extension
+  // that we don't want to encourage anyone to use.
+
+  // FIXME: we don't support #assert or #unassert, so don't suggest them.
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_PreprocessorDirective,
+                            Results.data(), Results.size());
+}
+
+void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
+  CodeCompleteOrdinaryName(S,
+                           S->getFnParent()? Sema::PCC_RecoveryInFunction 
+                                           : Sema::PCC_Namespace);
+}
+
+void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
+  ResultBuilder Results(*this);
+  if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
+    // Add just the names of macros, not their arguments.    
+    Results.EnterNewScope();
+    for (Preprocessor::macro_iterator M = PP.macro_begin(), 
+                                   MEnd = PP.macro_end();
+         M != MEnd; ++M) {
+      CodeCompletionString *Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk(M->first->getName());
+      Results.AddResult(Pattern);
+    }
+    Results.ExitScope();
+  } else if (IsDefinition) {
+    // FIXME: Can we detect when the user just wrote an include guard above?
+  }
+  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                      IsDefinition? CodeCompletionContext::CCC_MacroName
+                                  : CodeCompletionContext::CCC_MacroNameUse,
+                            Results.data(), Results.size()); 
+}
+
+void Sema::CodeCompletePreprocessorExpression() {
+  ResultBuilder Results(*this);
+  
+  if (!CodeCompleter || CodeCompleter->includeMacros())
+    AddMacroResults(PP, Results);
+  
+    // defined (<macro>)
+  Results.EnterNewScope();
+  CodeCompletionString *Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("defined");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+  Pattern->AddPlaceholderChunk("macro");
+  Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+  Results.AddResult(Pattern);
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_PreprocessorExpression,
+                            Results.data(), Results.size()); 
+}
+
+void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
+                                                 IdentifierInfo *Macro,
+                                                 MacroInfo *MacroInfo,
+                                                 unsigned Argument) {
+  // FIXME: In the future, we could provide "overload" results, much like we
+  // do for function calls.
+  
+  CodeCompleteOrdinaryName(S,
+                           S->getFnParent()? Sema::PCC_RecoveryInFunction 
+                                           : Sema::PCC_Namespace);
+}
+
+void Sema::CodeCompleteNaturalLanguage() {
+  HandleCodeCompleteResults(this, CodeCompleter,
+                            CodeCompletionContext::CCC_NaturalLanguage,
+                            0, 0);
+}
+
+void Sema::GatherGlobalCodeCompletions(
+                 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
+  ResultBuilder Builder(*this);
+
+  if (!CodeCompleter || CodeCompleter->includeGlobals()) {
+    CodeCompletionDeclConsumer Consumer(Builder, 
+                                        Context.getTranslationUnitDecl());
+    LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName, 
+                       Consumer);
+  }
+  
+  if (!CodeCompleter || CodeCompleter->includeMacros())
+    AddMacroResults(PP, Builder);
+  
+  Results.clear();
+  Results.insert(Results.end(), 
+                 Builder.data(), Builder.data() + Builder.size());
 }
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 3f309bb..6f8d9a9 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -11,19 +11,24 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/CXXFieldCollector.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/StmtCXX.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/ParsedTemplate.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"
@@ -35,18 +40,10 @@
 #include <cstring>
 #include <functional>
 using namespace clang;
+using namespace sema;
 
-/// 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>()));
+Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(Decl *Ptr) {
+  return DeclGroupPtrTy::make(DeclGroupRef(Ptr));
 }
 
 /// \brief If the identifier refers to a type name within this scope,
@@ -60,14 +57,14 @@
 ///
 /// 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) {
+ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+                             Scope *S, CXXScopeSpec *SS,
+                             bool isClassName,
+                             ParsedType ObjectTypePtr) {
   // Determine where we will perform name lookup.
   DeclContext *LookupCtx = 0;
   if (ObjectTypePtr) {
-    QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+    QualType ObjectType = ObjectTypePtr.get();
     if (ObjectType->isRecordType())
       LookupCtx = computeDeclContext(ObjectType);
   } else if (SS && SS->isNotEmpty()) {
@@ -85,20 +82,22 @@
         // We therefore do not perform any name lookup if the result would
         // refer to a member of an unknown specialization.
         if (!isClassName)
-          return 0;
+          return ParsedType();
         
-        // 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();
+        // We know from the grammar that this name refers to a type,
+        // so build a dependent node to describe the type.
+        QualType T =
+          CheckTypenameType(ETK_None, SS->getScopeRep(), II,
+                            SourceLocation(), SS->getRange(), NameLoc);
+        return ParsedType::make(T);
       }
       
-      return 0;
+      return ParsedType();
     }
     
-    if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(*SS))
-      return 0;
+    if (!LookupCtx->isDependentContext() &&
+        RequireCompleteDeclContext(*SS, LookupCtx))
+      return ParsedType();
   }
 
   // FIXME: LookupNestedNameSpecifierName isn't the right kind of
@@ -134,7 +133,7 @@
   case LookupResult::FoundOverloaded:
   case LookupResult::FoundUnresolvedValue:
     Result.suppressDiagnostics();
-    return 0;
+    return ParsedType();
 
   case LookupResult::Ambiguous:
     // Recover from type-hiding ambiguities by hiding the type.  We'll
@@ -144,7 +143,7 @@
     // that only makes sense if the identifier was treated like a type.
     if (Result.getAmbiguityKind() == LookupResult::AmbiguousTagHiding) {
       Result.suppressDiagnostics();
-      return 0;
+      return ParsedType();
     }
 
     // Look to see if we have a type anywhere in the list of results.
@@ -166,7 +165,7 @@
       // will produce the ambiguity, or will complain that it expected
       // a type name.
       Result.suppressDiagnostics();
-      return 0;
+      return ParsedType();
     }
 
     // We found a type within the ambiguous lookup; diagnose the
@@ -190,23 +189,17 @@
       T = Context.getTypeDeclType(TD);
     
     if (SS)
-      T = getQualifiedNameType(*SS, T);
+      T = getElaboratedType(ETK_None, *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 ParsedType();
   }
 
-  return T.getAsOpaquePtr();
+  return ParsedType::make(T);
 }
 
 /// isTagName() - This method is called *for error recovery purposes only*
@@ -222,10 +215,11 @@
   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;
+      default:         return DeclSpec::TST_unspecified;
+      case TTK_Struct: return DeclSpec::TST_struct;
+      case TTK_Union:  return DeclSpec::TST_union;
+      case TTK_Class:  return DeclSpec::TST_class;
+      case TTK_Enum:   return DeclSpec::TST_enum;
       }
     }
 
@@ -236,9 +230,9 @@
                                    SourceLocation IILoc,
                                    Scope *S,
                                    CXXScopeSpec *SS,
-                                   TypeTy *&SuggestedType) {
+                                   ParsedType &SuggestedType) {
   // We don't have anything to suggest (yet).
-  SuggestedType = 0;
+  SuggestedType = ParsedType();
   
   // 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.
@@ -284,8 +278,10 @@
     Name.setIdentifier(&II, IILoc);
     CXXScopeSpec EmptySS;
     TemplateTy TemplateResult;
-    if (isTemplateName(S, SS ? *SS : EmptySS, Name, 0, true, TemplateResult)
-        == TNK_Type_template) {
+    bool MemberOfUnknownSpecialization;
+    if (isTemplateName(S, SS ? *SS : EmptySS, /*hasTemplateKeyword=*/false,
+                       Name, ParsedType(), true, TemplateResult,
+                       MemberOfUnknownSpecialization) == TNK_Type_template) {
       TemplateName TplName = TemplateResult.getAsVal<TemplateName>();
       Diag(IILoc, diag::err_template_missing_args) << TplName;
       if (TemplateDecl *TplDecl = TplName.getAsTemplateDecl()) {
@@ -309,7 +305,7 @@
       << (NestedNameSpecifier *)SS->getScopeRep() << II.getName()
       << SourceRange(SS->getRange().getBegin(), IILoc)
       << FixItHint::CreateInsertion(SS->getRange().getBegin(), "typename ");
-    SuggestedType = ActOnTypenameType(SourceLocation(), *SS, II, IILoc).get();
+    SuggestedType = ActOnTypenameType(S, SourceLocation(), *SS, II, IILoc).get();
   } else {
     assert(SS && SS->isInvalid() && 
            "Invalid scope specifier has already been diagnosed");
@@ -345,8 +341,10 @@
     return DC;
   }
 
+  // ObjCMethodDecls are parsed (for some reason) outside the context
+  // of the class.
   if (isa<ObjCMethodDecl>(DC))
-    return Context.getTranslationUnitDecl();
+    return DC->getLexicalParent()->getLexicalParent();
 
   return DC->getLexicalParent();
 }
@@ -362,6 +360,7 @@
   assert(CurContext && "DeclContext imbalance!");
 
   CurContext = getContainingDC(CurContext);
+  assert(CurContext && "Popped translation unit!");
 }
 
 /// EnterDeclaratorContext - Used when we must lookup names in the context
@@ -460,8 +459,8 @@
   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));
+    if (S->isDeclScope(*I) && D->declarationReplaces(*I)) {
+      S->RemoveDecl(*I);
       IdResolver.RemoveDecl(*I);
 
       // Should only need to replace one decl.
@@ -469,7 +468,7 @@
     }
   }
 
-  S->AddDecl(DeclPtrTy::make(D));
+  S->AddDecl(D);
   IdResolver.AddDecl(D);
 }
 
@@ -477,6 +476,17 @@
   return IdResolver.isDeclInScope(D, Ctx, Context, S);
 }
 
+Scope *Sema::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 0;
+}
+
 static bool isOutOfScopePreviousDeclaration(NamedDecl *,
                                             DeclContext*,
                                             ASTContext&);
@@ -519,6 +529,90 @@
   F.done();
 }
 
+/// \brief Check for this common pattern:
+/// @code
+/// class S {
+///   S(const S&); // DO NOT IMPLEMENT
+///   void operator=(const S&); // DO NOT IMPLEMENT
+/// };
+/// @endcode
+static bool IsDisallowedCopyOrAssign(const CXXMethodDecl *D) {
+  // FIXME: Should check for private access too but access is set after we get
+  // the decl here.
+  if (D->isThisDeclarationADefinition())
+    return false;
+
+  if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
+    return CD->isCopyConstructor();
+  return D->isCopyAssignment();
+}
+
+bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const {
+  assert(D);
+
+  if (D->isInvalidDecl() || D->isUsed() || D->hasAttr<UnusedAttr>())
+    return false;
+
+  // Ignore class templates.
+  if (D->getDeclContext()->isDependentContext())
+    return false;
+
+  // We warn for unused decls internal to the translation unit.
+  if (D->getLinkage() == ExternalLinkage)
+    return false;
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+      return false;
+
+    if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+      if (MD->isVirtual() || IsDisallowedCopyOrAssign(MD))
+        return false;
+    } else {
+      // 'static inline' functions are used in headers; don't warn.
+      if (FD->getStorageClass() == SC_Static &&
+          FD->isInlineSpecified())
+        return false;
+    }
+
+    if (FD->isThisDeclarationADefinition())
+      return !Context.DeclMustBeEmitted(FD);
+    return true;
+  }
+
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (VD->isStaticDataMember() &&
+        VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+      return false;
+
+    if ( VD->isFileVarDecl() &&
+        !VD->getType().isConstant(Context))
+      return !Context.DeclMustBeEmitted(VD);
+  }
+
+   return false;
+ }
+
+ void Sema::MarkUnusedFileScopedDecl(const DeclaratorDecl *D) {
+  if (!D)
+    return;
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    const FunctionDecl *First = FD->getFirstDeclaration();
+    if (FD != First && ShouldWarnIfUnusedFileScopedDecl(First))
+      return; // First should already be in the vector.
+  }
+
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    const VarDecl *First = VD->getFirstDeclaration();
+    if (VD != First && ShouldWarnIfUnusedFileScopedDecl(First))
+      return; // First should already be in the vector.
+  }
+
+   if (ShouldWarnIfUnusedFileScopedDecl(D))
+     UnusedFileScopedDecls.push_back(D);
+ }
+
 static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
   if (D->isInvalidDecl())
     return false;
@@ -543,15 +637,21 @@
         return false;
     }
 
+    // If we failed to complete the type for some reason, or if the type is
+    // dependent, don't diagnose the variable. 
+    if (Ty->isIncompleteType() || Ty->isDependentType())
+      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())
+        // FIXME: Checking for the presence of a user-declared constructor
+        // isn't completely accurate; we'd prefer to check that the initializer
+        // has no side effects.
+        if (RD->hasUserDeclaredConstructor() || !RD->hasTrivialDestructor())
           return false;
       }
     }
@@ -562,6 +662,18 @@
   return true;
 }
 
+void Sema::DiagnoseUnusedDecl(const NamedDecl *D) {
+  if (!ShouldDiagnoseUnusedDecl(D))
+    return;
+  
+  if (isa<VarDecl>(D) && cast<VarDecl>(D)->isExceptionVariable())
+    Diag(D->getLocation(), diag::warn_unused_exception_param)
+    << D->getDeclName();
+  else
+    Diag(D->getLocation(), diag::warn_unused_variable) 
+    << D->getDeclName();
+}
+
 void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
   if (S->decl_empty()) return;
   assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) &&
@@ -569,7 +681,7 @@
 
   for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
        I != E; ++I) {
-    Decl *TmpD = (*I).getAs<Decl>();
+    Decl *TmpD = (*I);
     assert(TmpD && "This decl didn't get pushed??");
 
     assert(isa<NamedDecl>(TmpD) && "Decl isn't NamedDecl?");
@@ -578,9 +690,8 @@
     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();
+    if (S->getNumErrorsAtStart() == getDiagnostics().getNumErrors())
+      DiagnoseUnusedDecl(D);
     
     // Remove this name from our lexical scope.
     IdResolver.RemoveDecl(D);
@@ -716,8 +827,8 @@
   FunctionDecl *New = FunctionDecl::Create(Context,
                                            Context.getTranslationUnitDecl(),
                                            Loc, II, R, /*TInfo=*/0,
-                                           FunctionDecl::Extern,
-                                           FunctionDecl::None, false,
+                                           SC_Extern,
+                                           SC_None, false,
                                            /*hasPrototype=*/true);
   New->setImplicit();
 
@@ -728,7 +839,7 @@
     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));
+                                           SC_None, SC_None, 0));
     New->setParams(Params.data(), Params.size());
   }
 
@@ -894,25 +1005,40 @@
 /// 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())
+DeclHasAttr(const Decl *D, const Attr *A) {
+  const OwnershipAttr *OA = dyn_cast<OwnershipAttr>(A);
+  for (Decl::attr_iterator i = D->attr_begin(), e = D->attr_end(); i != e; ++i)
+    if ((*i)->getKind() == A->getKind()) {
+      // FIXME: Don't hardcode this check
+      if (OA && isa<OwnershipAttr>(*i))
+        return OA->getOwnKind() == cast<OwnershipAttr>(*i)->getOwnKind();
       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);
+/// MergeDeclAttributes - append attributes from the Old decl to the New one.
+static void MergeDeclAttributes(Decl *New, Decl *Old, ASTContext &C) {
+  if (!Old->hasAttrs())
+    return;
+  // Ensure that any moving of objects within the allocated map is done before
+  // we process them.
+  if (!New->hasAttrs())
+    New->setAttrs(AttrVec());
+  for (Decl::attr_iterator i = Old->attr_begin(), e = Old->attr_end(); i != e;
+       ++i) {
+    // FIXME: Make this more general than just checking for Overloadable.
+    if (!DeclHasAttr(New, *i) && (*i)->getKind() != attr::Overloadable) {
+      Attr *NewAttr = (*i)->clone(C);
       NewAttr->setInherited(true);
       New->addAttr(NewAttr);
     }
   }
 }
 
+namespace {
+
 /// Used in MergeFunctionDecl to keep track of function parameters in
 /// C.
 struct GNUCompatibleParamWarning {
@@ -921,6 +1047,7 @@
   QualType PromotedType;
 };
 
+}
 
 /// getSpecialMember - get the special member enum for a method.
 Sema::CXXSpecialMember Sema::getSpecialMember(const CXXMethodDecl *MD) {
@@ -938,14 +1065,14 @@
   return Sema::CXXCopyAssignment;
 }
 
-/// canREdefineFunction - checks if a function can be redefined. Currently,
+/// 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);
+          FD->getStorageClass() == SC_Extern);
 }
 
 /// MergeFunctionDecl - We just parsed a function 'New' from
@@ -999,8 +1126,8 @@
   // 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 &&
+      New->getStorageClass() == SC_Static &&
+      Old->getStorageClass() != SC_Static &&
       !canRedefineFunction(Old, getLangOptions())) {
     Diag(New->getLocation(), diag::err_static_non_static)
       << New;
@@ -1042,13 +1169,27 @@
   }
 
   // FIXME: diagnose the other way around?
-  if (OldType->getNoReturnAttr() &&
-      !NewType->getNoReturnAttr()) {
+  if (OldType->getNoReturnAttr() && !NewType->getNoReturnAttr()) {
     NewQType = Context.getNoReturnType(NewQType);
     New->setType(NewQType);
     assert(NewQType.isCanonical());
   }
 
+  // Merge regparm attribute.
+  if (OldType->getRegParmType() != NewType->getRegParmType()) {
+    if (NewType->getRegParmType()) {
+      Diag(New->getLocation(), diag::err_regparm_mismatch)
+        << NewType->getRegParmType()
+        << OldType->getRegParmType();
+      Diag(Old->getLocation(), diag::note_previous_declaration);      
+      return true;
+    }
+    
+    NewQType = Context.getRegParmType(NewQType, OldType->getRegParmType());
+    New->setType(NewQType);
+    assert(NewQType.isCanonical());    
+  }
+  
   if (getLangOptions().CPlusPlus) {
     // (C++98 13.1p2):
     //   Certain function declarations cannot be overloaded:
@@ -1058,10 +1199,18 @@
       = cast<FunctionType>(OldQType.getTypePtr())->getResultType();
     QualType NewReturnType
       = cast<FunctionType>(NewQType.getTypePtr())->getResultType();
+    QualType ResQT;
     if (OldReturnType != NewReturnType) {
-      Diag(New->getLocation(), diag::err_ovl_diff_return_type);
-      Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
-      return true;
+      if (NewReturnType->isObjCObjectPointerType()
+          && OldReturnType->isObjCObjectPointerType())
+        ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType);
+      if (ResQT.isNull()) {
+        Diag(New->getLocation(), diag::err_ovl_diff_return_type);
+        Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
+        return true;
+      }
+      else
+        NewQType = ResQT;
     }
 
     const CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
@@ -1159,7 +1308,7 @@
         ParmVarDecl *Param = ParmVarDecl::Create(Context, New,
                                                  SourceLocation(), 0,
                                                  *ParamType, /*TInfo=*/0,
-                                                 VarDecl::None, VarDecl::None,
+                                                 SC_None, SC_None,
                                                  0);
         Param->setImplicit();
         Params.push_back(Param);
@@ -1205,7 +1354,8 @@
                                      NewProto->getArgType(Idx))) {
         ArgTypes.push_back(NewParm->getType());
       } else if (Context.typesAreCompatible(OldParm->getType(),
-                                            NewParm->getType())) {
+                                            NewParm->getType(),
+                                            /*CompareUnqualified=*/true)) {
         GNUCompatibleParamWarning Warn
           = { OldParm, NewParm, NewProto->getArgType(Idx) };
         Warnings.push_back(Warn);
@@ -1220,8 +1370,9 @@
              diag::ext_param_promoted_not_compatible_with_prototype)
           << Warnings[Warn].PromotedType
           << Warnings[Warn].OldParm->getType();
-        Diag(Warnings[Warn].OldParm->getLocation(),
-             diag::note_previous_declaration);
+        if (Warnings[Warn].OldParm->getLocation().isValid())
+          Diag(Warnings[Warn].OldParm->getLocation(),
+               diag::note_previous_declaration);
       }
 
       New->setType(Context.getFunctionType(MergedReturn, &ArgTypes[0],
@@ -1272,11 +1423,11 @@
 /// \returns false
 bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
   // Merge the attributes
-  MergeAttributes(New, Old, Context);
+  MergeDeclAttributes(New, Old, Context);
 
   // Merge the storage class.
-  if (Old->getStorageClass() != FunctionDecl::Extern &&
-      Old->getStorageClass() != FunctionDecl::None)
+  if (Old->getStorageClass() != SC_Extern &&
+      Old->getStorageClass() != SC_None)
     New->setStorageClass(Old->getStorageClass());
 
   // Merge "pure" flag.
@@ -1317,7 +1468,7 @@
     return New->setInvalidDecl();
   }
 
-  MergeAttributes(New, Old, Context);
+  MergeDeclAttributes(New, Old, Context);
 
   // Merge the types
   QualType MergedT;
@@ -1345,6 +1496,9 @@
         = Context.getCanonicalType(New->getType())->getAs<ArrayType>();
       if (OldArray->getElementType() == NewArray->getElementType())
         MergedT = Old->getType();
+    } else if (New->getType()->isObjCObjectPointerType()
+               && Old->getType()->isObjCObjectPointerType()) {
+        MergedT = Context.mergeObjCGCQualifiers(New->getType(), Old->getType());
     }
   } else {
     MergedT = Context.mergeTypes(New->getType(), Old->getType());
@@ -1358,8 +1512,8 @@
   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())) {
+  if (New->getStorageClass() == SC_Static &&
+      (Old->getStorageClass() == SC_None || Old->hasExternalStorage())) {
     Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName();
     Diag(Old->getLocation(), diag::note_previous_definition);
     return New->setInvalidDecl();
@@ -1375,8 +1529,8 @@
   //   identifier has external linkage.
   if (New->hasExternalStorage() && Old->hasLinkage())
     /* Okay */;
-  else if (New->getStorageClass() != VarDecl::Static &&
-           Old->getStorageClass() == VarDecl::Static) {
+  else if (New->getStorageClass() != SC_Static &&
+           Old->getStorageClass() == SC_Static) {
     Diag(New->getLocation(), diag::err_non_static_static) << New->getDeclName();
     Diag(Old->getLocation(), diag::note_previous_definition);
     return New->setInvalidDecl();
@@ -1414,6 +1568,17 @@
     New->setInvalidDecl();
     return;
   }
+  // c99 6.2.2 P4.
+  // 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.
+  // FIXME. revisit this code.
+  if (New->hasExternalStorage() &&
+      Old->getLinkage() == InternalLinkage &&
+      New->getDeclContext() == Old->getDeclContext())
+    New->setStorageClass(Old->getStorageClass());
 
   // Keep a chain of previous declarations.
   New->setPreviousDeclaration(Old);
@@ -1424,7 +1589,8 @@
 
 /// 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) {
+Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
+                                            DeclSpec &DS) {
   // FIXME: Error on auto/register at file scope
   // FIXME: Error on inline/virtual/explicit
   // FIXME: Warn on useless __thread
@@ -1437,10 +1603,10 @@
       DS.getTypeSpecType() == DeclSpec::TST_struct ||
       DS.getTypeSpecType() == DeclSpec::TST_union ||
       DS.getTypeSpecType() == DeclSpec::TST_enum) {
-    TagD = static_cast<Decl *>(DS.getTypeRep());
+    TagD = DS.getRepAsDecl();
 
     if (!TagD) // We probably had an error
-      return DeclPtrTy();
+      return 0;
 
     // Note that the above type specs guarantee that the
     // type rep is a Decl, whereas in many of the others
@@ -1461,20 +1627,18 @@
     // 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 0;
     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);
+    ProcessDeclAttributeList(S, Record, DS.getAttributes());
     
     if (!Record->getDeclName() && Record->isDefinition() &&
         DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
       if (getLangOptions().CPlusPlus ||
           Record->getDeclContext()->isRecord())
-        return BuildAnonymousStructOrUnion(S, DS, Record);
+        return BuildAnonymousStructOrUnion(S, DS, AS, Record);
 
       Diag(DS.getSourceRange().getBegin(), diag::ext_no_declarators)
         << DS.getSourceRange();
@@ -1484,25 +1648,33 @@
     // about them.
     // FIXME: Should we support Microsoft's extensions in this area?
     if (Record->getDeclName() && getLangOptions().Microsoft)
-      return DeclPtrTy::make(Tag);
+      return Tag;
   }
   
+  if (getLangOptions().CPlusPlus && 
+      DS.getStorageClassSpec() != DeclSpec::SCS_typedef)
+    if (EnumDecl *Enum = dyn_cast_or_null<EnumDecl>(Tag))
+      if (Enum->enumerator_begin() == Enum->enumerator_end() &&
+          !Enum->getIdentifier() && !Enum->isInvalidDecl())
+        Diag(Enum->getLocation(), diag::ext_no_declarators)
+          << DS.getSourceRange();
+      
   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.
+    // extension in both Microsoft and 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);
+      return Tag;
     }
 
     Diag(DS.getSourceRange().getBegin(), diag::ext_no_declarators)
       << DS.getSourceRange();
   }
 
-  return DeclPtrTy::make(Tag);
+  return TagD;
 }
 
 /// We are trying to inject an anonymous member into the given scope;
@@ -1552,8 +1724,10 @@
 ///
 /// 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) {
+static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S,
+                                                DeclContext *Owner,
+                                                RecordDecl *AnonRecord,
+                                                AccessSpecifier AS) {
   unsigned diagKind
     = AnonRecord->isUnion() ? diag::err_anonymous_union_member_redecl
                             : diag::err_anonymous_struct_member_redecl;
@@ -1563,7 +1737,7 @@
                                FEnd = AnonRecord->field_end();
        F != FEnd; ++F) {
     if ((*F)->getDeclName()) {
-      if (CheckAnonMemberRedeclaration(*this, S, Owner, (*F)->getDeclName(),
+      if (CheckAnonMemberRedeclaration(SemaRef, S, Owner, (*F)->getDeclName(),
                                        (*F)->getLocation(), diagKind)) {
         // C++ [class.union]p2:
         //   The names of the members of an anonymous union shall be
@@ -1577,15 +1751,19 @@
         //   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);
+        S->AddDecl(*F);
+        SemaRef.IdResolver.AddDecl(*F);
+
+        // That includes picking up the appropriate access specifier.
+        if (AS != AS_none) (*F)->setAccess(AS);
       }
     } else if (const RecordType *InnerRecordType
                  = (*F)->getType()->getAs<RecordType>()) {
       RecordDecl *InnerRecord = InnerRecordType->getDecl();
       if (InnerRecord->isAnonymousStructOrUnion())
         Invalid = Invalid ||
-          InjectAnonymousStructOrUnionMembers(S, Owner, InnerRecord);
+          InjectAnonymousStructOrUnionMembers(SemaRef, S, Owner,
+                                              InnerRecord, AS);
     }
   }
 
@@ -1594,38 +1772,38 @@
 
 /// 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
+/// illegal input values are mapped to SC_None.
+static 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;
+  case DeclSpec::SCS_unspecified:    return SC_None;
+  case DeclSpec::SCS_extern:         return SC_Extern;
+  case DeclSpec::SCS_static:         return SC_Static;
+  case DeclSpec::SCS_auto:           return SC_Auto;
+  case DeclSpec::SCS_register:       return SC_Register;
+  case DeclSpec::SCS_private_extern: return SC_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;
+  case DeclSpec::SCS_typedef:        return SC_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
+/// a StorageClass. Any error reporting is up to the caller:
+/// illegal input values are mapped to SC_None.
+static 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;
+  case DeclSpec::SCS_unspecified:    return SC_None;
+  case DeclSpec::SCS_extern:         return SC_Extern;
+  case DeclSpec::SCS_static:         return SC_Static;
+  case DeclSpec::SCS_private_extern: return SC_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;
+  case DeclSpec::SCS_typedef:        return SC_None;
   }
   llvm_unreachable("unknown storage class specifier");
 }
@@ -1634,8 +1812,9 @@
 /// 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) {
+Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
+                                             AccessSpecifier AS,
+                                             RecordDecl *Record) {
   DeclContext *Owner = Record->getDeclContext();
 
   // Diagnose whether this anonymous struct/union is an extension.
@@ -1689,11 +1868,15 @@
         // 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) {
+        assert(FD->getAccess() != AS_none);
+        if (FD->getAccess() != AS_public) {
           Diag(FD->getLocation(), diag::err_anonymous_record_nonpublic_member)
             << (int)Record->isUnion() << (int)(FD->getAccess() == AS_protected);
           Invalid = true;
         }
+
+        if (CheckNontrivialField(FD))
+          Invalid = true;
       } else if ((*Mem)->isImplicit()) {
         // Any implicit members are fine.
       } else if (isa<TagDecl>(*Mem) && (*Mem)->getDeclContext() != Record) {
@@ -1709,6 +1892,8 @@
             << (int)Record->isUnion();
           Invalid = true;
         }
+      } else if (isa<AccessSpecDecl>(*Mem)) {
+        // Any access specifier is fine.
       } else {
         // We have something that isn't a non-static data
         // member. Complain about it.
@@ -1734,8 +1919,7 @@
 
   // Mock up a declarator.
   Declarator Dc(DS, Declarator::TypeNameContext);
-  TypeSourceInfo *TInfo = 0;
-  GetTypeForDeclarator(Dc, S, &TInfo);
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S);
   assert(TInfo && "couldn't build declarator info for anonymous struct/union");
 
   // Create a declaration for this anonymous struct/union.
@@ -1746,9 +1930,12 @@
                              Context.getTypeDeclType(Record),
                              TInfo,
                              /*BitWidth=*/0, /*Mutable=*/false);
-    Anon->setAccess(AS_public);
-    if (getLangOptions().CPlusPlus)
+    Anon->setAccess(AS);
+    if (getLangOptions().CPlusPlus) {
       FieldCollector->Add(cast<FieldDecl>(Anon));
+      if (!cast<CXXRecordDecl>(Record)->isEmpty())
+        cast<CXXRecordDecl>(OwningClass)->setEmpty(false);
+    }
   } else {
     DeclSpec::SCS SCSpec = DS.getStorageClassSpec();
     assert(SCSpec != DeclSpec::SCS_typedef &&
@@ -1759,7 +1946,7 @@
       // an error here
       Diag(Record->getLocation(), diag::err_mutable_nonmember);
       Invalid = true;
-      SC = VarDecl::None;
+      SC = SC_None;
     }
     SCSpec = DS.getStorageClassSpecAsWritten();
     VarDecl::StorageClass SCAsWritten
@@ -1776,11 +1963,11 @@
   // 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))
+  if (InjectAnonymousStructOrUnionMembers(*this, S, Owner, Record, AS))
     Invalid = true;
 
   // Mark this as an anonymous struct/union type. Note that we do not
@@ -1794,85 +1981,115 @@
   if (Invalid)
     Anon->setInvalidDecl();
 
-  return DeclPtrTy::make(Anon);
+  return Anon;
 }
 
 
 /// GetNameForDeclarator - Determine the full declaration name for the
 /// given Declarator.
-DeclarationName Sema::GetNameForDeclarator(Declarator &D) {
+DeclarationNameInfo Sema::GetNameForDeclarator(Declarator &D) {
   return GetNameFromUnqualifiedId(D.getName());
 }
 
-/// \brief Retrieves the canonicalized name from a parsed unqualified-id.
-DeclarationName Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
+/// \brief Retrieves the declaration name from a parsed unqualified-id.
+DeclarationNameInfo
+Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
+  DeclarationNameInfo NameInfo;
+  NameInfo.setLoc(Name.StartLocation);
+
   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_Identifier:
+    NameInfo.setName(Name.Identifier);
+    NameInfo.setLoc(Name.StartLocation);
+    return NameInfo;
 
-    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();
+  case UnqualifiedId::IK_OperatorFunctionId:
+    NameInfo.setName(Context.DeclarationNames.getCXXOperatorName(
+                                           Name.OperatorFunctionId.Operator));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.getInfo().CXXOperatorName.BeginOpNameLoc
+      = Name.OperatorFunctionId.SymbolLocations[0];
+    NameInfo.getInfo().CXXOperatorName.EndOpNameLoc
+      = Name.EndLocation.getRawEncoding();
+    return NameInfo;
 
-      // Determine the type of the class being constructed.
-      QualType CurClassType = Context.getTypeDeclType(CurClass);
+  case UnqualifiedId::IK_LiteralOperatorId:
+    NameInfo.setName(Context.DeclarationNames.getCXXLiteralOperatorName(
+                                                           Name.Identifier));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.setCXXLiteralOperatorNameLoc(Name.EndLocation);
+    return NameInfo;
 
-      // 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);
-    }
+  case UnqualifiedId::IK_ConversionFunctionId: {
+    TypeSourceInfo *TInfo;
+    QualType Ty = GetTypeFromParser(Name.ConversionFunctionId, &TInfo);
+    if (Ty.isNull())
+      return DeclarationNameInfo();
+    NameInfo.setName(Context.DeclarationNames.getCXXConversionFunctionName(
+                                               Context.getCanonicalType(Ty)));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.setNamedTypeInfo(TInfo);
+    return NameInfo;
   }
-  
+
+  case UnqualifiedId::IK_ConstructorName: {
+    TypeSourceInfo *TInfo;
+    QualType Ty = GetTypeFromParser(Name.ConstructorName, &TInfo);
+    if (Ty.isNull())
+      return DeclarationNameInfo();
+    NameInfo.setName(Context.DeclarationNames.getCXXConstructorName(
+                                              Context.getCanonicalType(Ty)));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.setNamedTypeInfo(TInfo);
+    return NameInfo;
+  }
+
+  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 DeclarationNameInfo();
+
+    // 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.
+
+    NameInfo.setName(Context.DeclarationNames.getCXXConstructorName(
+                                    Context.getCanonicalType(CurClassType)));
+    NameInfo.setLoc(Name.StartLocation);
+    // FIXME: should we retrieve TypeSourceInfo?
+    NameInfo.setNamedTypeInfo(0);
+    return NameInfo;
+  }
+
+  case UnqualifiedId::IK_DestructorName: {
+    TypeSourceInfo *TInfo;
+    QualType Ty = GetTypeFromParser(Name.DestructorName, &TInfo);
+    if (Ty.isNull())
+      return DeclarationNameInfo();
+    NameInfo.setName(Context.DeclarationNames.getCXXDestructorName(
+                                              Context.getCanonicalType(Ty)));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.setNamedTypeInfo(TInfo);
+    return NameInfo;
+  }
+
+  case UnqualifiedId::IK_TemplateId: {
+    TemplateName TName = Name.TemplateId->Template.get();
+    SourceLocation TNameLoc = Name.TemplateId->TemplateNameLoc;
+    return Context.getNameForTemplate(TName, TNameLoc);
+  }
+
+  } // switch (Name.getKind())
+
   assert(false && "Unknown name kind");
-  return DeclarationName();  
+  return DeclarationNameInfo();
 }
 
 /// isNearlyMatchingFunction - Determine whether the C++ functions
@@ -1897,11 +2114,88 @@
   return true;
 }
 
-Sema::DeclPtrTy
-Sema::HandleDeclarator(Scope *S, Declarator &D,
-                       MultiTemplateParamsArg TemplateParamLists,
-                       bool IsFunctionDefinition) {
-  DeclarationName Name = GetNameForDeclarator(D);
+/// NeedsRebuildingInCurrentInstantiation - Checks whether the given
+/// declarator needs to be rebuilt in the current instantiation.
+/// Any bits of declarator which appear before the name are valid for
+/// consideration here.  That's specifically the type in the decl spec
+/// and the base type in any member-pointer chunks.
+static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D,
+                                                    DeclarationName Name) {
+  // The types we specifically need to rebuild are:
+  //   - typenames, typeofs, and decltypes
+  //   - types which will become injected class names
+  // Of course, we also need to rebuild any type referencing such a
+  // type.  It's safest to just say "dependent", but we call out a
+  // few cases here.
+
+  DeclSpec &DS = D.getMutableDeclSpec();
+  switch (DS.getTypeSpecType()) {
+  case DeclSpec::TST_typename:
+  case DeclSpec::TST_typeofType:
+  case DeclSpec::TST_decltype: {
+    // Grab the type from the parser.
+    TypeSourceInfo *TSI = 0;
+    QualType T = S.GetTypeFromParser(DS.getRepAsType(), &TSI);
+    if (T.isNull() || !T->isDependentType()) break;
+
+    // Make sure there's a type source info.  This isn't really much
+    // of a waste; most dependent types should have type source info
+    // attached already.
+    if (!TSI)
+      TSI = S.Context.getTrivialTypeSourceInfo(T, DS.getTypeSpecTypeLoc());
+
+    // Rebuild the type in the current instantiation.
+    TSI = S.RebuildTypeInCurrentInstantiation(TSI, D.getIdentifierLoc(), Name);
+    if (!TSI) return true;
+
+    // Store the new type back in the decl spec.
+    ParsedType LocType = S.CreateParsedType(TSI->getType(), TSI);
+    DS.UpdateTypeRep(LocType);
+    break;
+  }
+
+  case DeclSpec::TST_typeofExpr: {
+    Expr *E = DS.getRepAsExpr();
+    ExprResult Result = S.RebuildExprInCurrentInstantiation(E);
+    if (Result.isInvalid()) return true;
+    DS.UpdateExprRep(Result.get());
+    break;
+  }
+
+  default:
+    // Nothing to do for these decl specs.
+    break;
+  }
+
+  // It doesn't matter what order we do this in.
+  for (unsigned I = 0, E = D.getNumTypeObjects(); I != E; ++I) {
+    DeclaratorChunk &Chunk = D.getTypeObject(I);
+
+    // The only type information in the declarator which can come
+    // before the declaration name is the base type of a member
+    // pointer.
+    if (Chunk.Kind != DeclaratorChunk::MemberPointer)
+      continue;
+
+    // Rebuild the scope specifier in-place.
+    CXXScopeSpec &SS = Chunk.Mem.Scope();
+    if (S.RebuildNestedNameSpecifierInCurrentInstantiation(SS))
+      return true;
+  }
+
+  return false;
+}
+
+Decl *Sema::ActOnDeclarator(Scope *S, Declarator &D) {
+  return HandleDeclarator(S, D, MultiTemplateParamsArg(*this), false);
+}
+
+Decl *Sema::HandleDeclarator(Scope *S, Declarator &D,
+                             MultiTemplateParamsArg TemplateParamLists,
+                             bool IsFunctionDefinition) {
+  // TODO: consider using NameInfo for diagnostic.
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
 
   // All of these full declarators require an identifier.  If it doesn't have
   // one, the ParsedFreeStandingDeclSpec action should be used.
@@ -1910,7 +2204,7 @@
       Diag(D.getDeclSpec().getSourceRange().getBegin(),
            diag::err_declarator_need_ident)
         << D.getDeclSpec().getSourceRange() << D.getSourceRange();
-    return DeclPtrTy();
+    return 0;
   }
 
   // The scope passed in may not be a decl scope.  Zip up the scope tree until
@@ -1919,48 +2213,57 @@
          (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 *DC = CurContext;
+  if (D.getCXXScopeSpec().isInvalid())
+    D.setInvalidType();
+  else if (D.getCXXScopeSpec().isSet()) {
+    bool EnteringContext = !D.getDeclSpec().isFriendSpecified();
+    DC = computeDeclContext(D.getCXXScopeSpec(), EnteringContext);
+    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 0;
+    }
 
-      DeclContext *SavedContext = CurContext;
-      CurContext = DC;
-      T = RebuildTypeInCurrentInstantiation(T, D.getIdentifierLoc(), Name);
-      CurContext = SavedContext;
+    bool IsDependentContext = DC->isDependentContext();
 
-      if (T.isNull())
-        return DeclPtrTy();
-      DS.UpdateTypeRep(T.getAsOpaquePtr());
+    if (!IsDependentContext && 
+        RequireCompleteDeclContext(D.getCXXScopeSpec(), DC))
+      return 0;
+
+    if (isa<CXXRecordDecl>(DC) && !cast<CXXRecordDecl>(DC)->hasDefinition()) {
+      Diag(D.getIdentifierLoc(),
+           diag::err_member_def_undefined_record)
+        << Name << DC << D.getCXXScopeSpec().getRange();
+      D.setInvalidType();
+    }
+
+    // Check whether we need to rebuild the type of the given
+    // declaration in the current instantiation.
+    if (EnteringContext && IsDependentContext &&
+        TemplateParamLists.size() != 0) {
+      ContextRAII SavedContext(*this, DC);
+      if (RebuildDeclaratorInCurrentInstantiation(*this, D, Name))
+        D.setInvalidType();
     }
   }
 
-  DeclContext *DC;
   NamedDecl *New;
 
-  TypeSourceInfo *TInfo = 0;
-  QualType R = GetTypeForDeclarator(D, S, &TInfo);
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
+  QualType R = TInfo->getType();
 
-  LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+  LookupResult Previous(*this, NameInfo, 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()) {
+  if (!D.getCXXScopeSpec().isSet()) {
     bool IsLinkageLookup = false;
 
     // If the declaration we're planning to build will be a function
@@ -1981,34 +2284,8 @@
     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
@@ -2085,7 +2362,7 @@
   if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
     if (TemplateParamLists.size()) {
       Diag(D.getIdentifierLoc(), diag::err_template_typedef);
-      return DeclPtrTy();
+      return 0;
     }
 
     New = ActOnTypedefDeclarator(S, D, DC, R, TInfo, Previous, Redeclaration);
@@ -2100,14 +2377,14 @@
   }
 
   if (New == 0)
-    return DeclPtrTy();
+    return 0;
 
   // 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()))
+  if (New->getDeclName() && !(Redeclaration && New->isInvalidDecl()))
     PushOnScopeChains(New, S);
 
-  return DeclPtrTy::make(New);
+  return New;
 }
 
 /// TryToFixInvalidVariablyModifiedType - Helper method to turn variable array
@@ -2115,20 +2392,26 @@
 /// be errors (for GCC compatibility).
 static QualType TryToFixInvalidVariablyModifiedType(QualType T,
                                                     ASTContext &Context,
-                                                    bool &SizeIsNegative) {
+                                                    bool &SizeIsNegative,
+                                                    llvm::APSInt &Oversized) {
   // 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;
-
+  Oversized = 0;
+  
+  if (T->isDependentType())
+    return QualType();
+  
   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);
+        TryToFixInvalidVariablyModifiedType(Pointee, Context, SizeIsNegative,
+                                            Oversized);
     if (FixedType.isNull()) return FixedType;
     FixedType = Context.getPointerType(FixedType);
     return Qs.apply(FixedType);
@@ -2147,15 +2430,24 @@
       !EvalResult.Val.isInt())
     return QualType();
 
+  // Check whether the array size is negative.
   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);
+  if (Res.isSigned() && Res.isNegative()) {
+    SizeIsNegative = true;
+    return QualType();
   }
 
-  SizeIsNegative = true;
-  return QualType();
+  // Check whether the array is too large to be addressed.
+  unsigned ActiveSizeBits
+    = ConstantArrayType::getNumAddressingBits(Context, VLATy->getElementType(),
+                                              Res);
+  if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) {
+    Oversized = Res;
+    return QualType();
+  }
+  
+  return Context.getConstantArrayType(VLATy->getElementType(),
+                                      Res, ArrayType::Normal, 0);
 }
 
 /// \brief Register the given locally-scoped external C declaration so
@@ -2180,11 +2472,11 @@
   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)))
+    while (S && !S->isDeclScope(PrevDecl))
       S = S->getParent();
 
     if (S)
-      S->RemoveDecl(DeclPtrTy::make(PrevDecl));
+      S->RemoveDecl(PrevDecl);
   }
 }
 
@@ -2230,30 +2522,32 @@
   if (D.getDeclSpec().isThreadSpecified())
     Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
 
+  if (D.getName().Kind != UnqualifiedId::IK_Identifier) {
+    Diag(D.getName().StartLocation, diag::err_typedef_not_identifier)
+      << D.getName().getSourceRange();
+    return 0;
+  }
+
   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.
+  // Note that variably modified types must be fixed before merging the decl so
+  // that redeclarations will match.
   QualType T = NewTD->getUnderlyingType();
   if (T->isVariablyModifiedType()) {
-    FunctionNeedsScopeChecking() = true;
+    getCurFunction()->setHasBranchProtectedScope();
 
     if (S->getFnParent() == 0) {
       bool SizeIsNegative;
+      llvm::APSInt Oversized;
       QualType FixedTy =
-          TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative);
+          TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative,
+                                              Oversized);
       if (!FixedTy.isNull()) {
         Diag(D.getIdentifierLoc(), diag::warn_illegal_constant_array_size);
         NewTD->setTypeSourceInfo(Context.getTrivialTypeSourceInfo(FixedTy));
@@ -2262,6 +2556,9 @@
           Diag(D.getIdentifierLoc(), diag::err_typecheck_negative_array_size);
         else if (T->isVariableArrayType())
           Diag(D.getIdentifierLoc(), diag::err_vla_decl_in_file_scope);
+        else if (Oversized.getBoolValue())
+          Diag(D.getIdentifierLoc(), diag::err_array_too_large)
+            << Oversized.toString(10);
         else
           Diag(D.getIdentifierLoc(), diag::err_vm_decl_in_file_scope);
         NewTD->setInvalidDecl();
@@ -2269,6 +2566,14 @@
     }
   }
 
+  // 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);
+  }
+
   // If this is the C FILE type, notify the AST context.
   if (IdentifierInfo *II = NewTD->getIdentifier())
     if (!NewTD->isInvalidDecl() &&
@@ -2322,26 +2627,23 @@
     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();
+    
+    DeclContext *PrevOuterContext = PrevDecl->getDeclContext();
+    if (PrevOuterContext->isRecord())
+      // We found a member function: ignore it.
+      return false;
+    
+    // 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;
-      }
-    }
+    // The previous declaration is in a different namespace, so it
+    // isn't the same function.
+    if (!OuterContext->Equals(PrevOuterContext))
+      return false;
   }
 
   return true;
@@ -2360,7 +2662,7 @@
                               LookupResult &Previous,
                               MultiTemplateParamsArg TemplateParamLists,
                               bool &Redeclaration) {
-  DeclarationName Name = GetNameForDeclarator(D);
+  DeclarationName Name = GetNameForDeclarator(D).getName();
 
   // Check that there are no default arguments (C++ only).
   if (getLangOptions().CPlusPlus)
@@ -2375,7 +2677,7 @@
     // an error here
     Diag(D.getIdentifierLoc(), diag::err_mutable_nonmember);
     D.setInvalidType();
-    SC = VarDecl::None;
+    SC = SC_None;
   }
   SCSpec = D.getDeclSpec().getStorageClassSpecAsWritten();
   VarDecl::StorageClass SCAsWritten
@@ -2393,11 +2695,11 @@
   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 (SC == SC_Auto || SC == SC_Register) {
 
       // If this is a register variable with an asm label specified, then this
       // is a GNU extension.
-      if (SC == VarDecl::Register && D.getAsmLabel())
+      if (SC == SC_Register && D.getAsmLabel())
         Diag(D.getIdentifierLoc(), diag::err_unsupported_global_register);
       else
         Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope);
@@ -2406,14 +2708,14 @@
   }
   if (DC->isRecord() && !CurContext->isRecord()) {
     // This is an out-of-line definition of a static data member.
-    if (SC == VarDecl::Static) {
+    if (SC == SC_Static) {
       Diag(D.getDeclSpec().getStorageClassSpecLoc(),
            diag::err_static_out_of_line)
         << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
-    } else if (SC == VarDecl::None)
-      SC = VarDecl::Static;
+    } else if (SC == SC_None)
+      SC = SC_Static;
   }
-  if (SC == VarDecl::Static) {
+  if (SC == SC_Static) {
     if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) {
       if (RD->isLocalClass())
         Diag(D.getIdentifierLoc(),
@@ -2425,6 +2727,8 @@
   // Match up the template parameter lists with the scope specifier, then
   // determine whether we have a template or a template specialization.
   bool isExplicitSpecialization = false;
+  unsigned NumMatchedTemplateParamLists = TemplateParamLists.size();
+  bool Invalid = false;
   if (TemplateParameterList *TemplateParams
         = MatchTemplateParametersToScopeSpecifier(
                                   D.getDeclSpec().getSourceRange().getBegin(),
@@ -2432,7 +2736,11 @@
                         (TemplateParameterList**)TemplateParamLists.get(),
                                                    TemplateParamLists.size(),
                                                   /*never a friend*/ false,
-                                                  isExplicitSpecialization)) {
+                                                  isExplicitSpecialization,
+                                                  Invalid)) {
+    // All but one template parameter lists have been matching.
+    --NumMatchedTemplateParamLists;
+
     if (TemplateParams->size() > 0) {
       // There is no such thing as a variable template.
       Diag(D.getIdentifierLoc(), diag::err_template_variable)
@@ -2456,11 +2764,17 @@
   VarDecl *NewVD = VarDecl::Create(Context, DC, D.getIdentifierLoc(),
                                    II, R, TInfo, SC, SCAsWritten);
 
-  if (D.isInvalidType())
+  if (D.isInvalidType() || Invalid)
     NewVD->setInvalidDecl();
 
   SetNestedNameSpecifier(NewVD, D);
 
+  if (NumMatchedTemplateParamLists > 0 && D.getCXXScopeSpec().isSet()) {
+    NewVD->setTemplateParameterListsInfo(Context,
+                                         NumMatchedTemplateParamLists,
+                        (TemplateParameterList**)TemplateParamLists.release());
+  }
+
   if (D.getDeclSpec().isThreadSpecified()) {
     if (NewVD->hasLocalStorage())
       Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_thread_non_global);
@@ -2481,7 +2795,8 @@
   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()));
+    NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), 
+                                                Context, SE->getString()));
   }
 
   // Diagnose shadowed variables before filtering for scope.
@@ -2521,6 +2836,8 @@
     NewVD->setInvalidDecl();
 
   // attributes declared post-definition are currently ignored
+  // FIXME: This should be handled in attribute merging, not
+  // here.
   if (Previous.isSingleResult()) {
     VarDecl *Def = dyn_cast<VarDecl>(Previous.getFoundDecl());
     if (Def && (Def = Def->getDefinition()) &&
@@ -2536,6 +2853,13 @@
       !NewVD->isInvalidDecl())
     RegisterLocallyScopedExternCDecl(NewVD, Previous, S);
 
+  // If there's a #pragma GCC visibility in scope, and this isn't a class
+  // member, set the visibility of this variable.
+  if (NewVD->getLinkage() == ExternalLinkage && !DC->isRecord())
+    AddPushedVisibilityAttribute(NewVD);
+
+  MarkUnusedFileScopedDecl(NewVD);
+
   return NewVD;
 }
 
@@ -2629,7 +2953,7 @@
 
   QualType T = NewVD->getType();
 
-  if (T->isObjCInterfaceType()) {
+  if (T->isObjCObjectType()) {
     Diag(NewVD->getLocation(), diag::err_statically_allocated_object);
     return NewVD->setInvalidDecl();
   }
@@ -2649,19 +2973,16 @@
 
   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;
+      NewVD->hasAttr<BlocksAttr>())
+    getCurFunction()->setHasBranchProtectedScope();
 
   if ((isVM && NewVD->hasLinkage()) ||
       (T->isVariableArrayType() && NewVD->hasGlobalStorage())) {
     bool SizeIsNegative;
+    llvm::APSInt Oversized;
     QualType FixedTy =
-        TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative);
+        TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative,
+                                            Oversized);
 
     if (FixedTy.isNull() && T->isVariableArrayType()) {
       const VariableArrayType *VAT = Context.getAsVariableArrayType(T);
@@ -2672,7 +2993,7 @@
       if (NewVD->isFileVarDecl())
         Diag(NewVD->getLocation(), diag::err_vla_decl_in_file_scope)
         << SizeRange;
-      else if (NewVD->getStorageClass() == VarDecl::Static)
+      else if (NewVD->getStorageClass() == SC_Static)
         Diag(NewVD->getLocation(), diag::err_vla_decl_has_static_storage)
         << SizeRange;
       else
@@ -2719,6 +3040,23 @@
     return NewVD->setInvalidDecl();
   }
 
+  // Function pointers and references cannot have qualified function type, only
+  // function pointer-to-members can do that.
+  QualType Pointee;
+  unsigned PtrOrRef = 0;
+  if (const PointerType *Ptr = T->getAs<PointerType>())
+    Pointee = Ptr->getPointeeType();
+  else if (const ReferenceType *Ref = T->getAs<ReferenceType>()) {
+    Pointee = Ref->getPointeeType();
+    PtrOrRef = 1;
+  }
+  if (!Pointee.isNull() && Pointee->isFunctionProtoType() &&
+      Pointee->getAs<FunctionProtoType>()->getTypeQuals() != 0) {
+    Diag(NewVD->getLocation(), diag::err_invalid_qualified_function_pointer)
+        << PtrOrRef;
+    return NewVD->setInvalidDecl();
+  }
+
   if (!Previous.empty()) {
     Redeclaration = true;
     MergeVarDecl(NewVD, Previous);
@@ -2746,7 +3084,7 @@
   
   // FIXME: Do we care about other names here too?
   if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
-    // We really want to find the base class constructor here.
+    // We really want to find the base class destructor here.
     QualType T = Data->S->Context.getTypeDeclType(BaseRecord);
     CanQualType CT = Data->S->Context.getCanonicalType(T);
     
@@ -2756,8 +3094,9 @@
   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))
+    NamedDecl *D = *Path.Decls.first;
+    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+      if (MD->isVirtual() && !Data->S->IsOverload(Data->Method, MD, false))
         return true;
     }
   }
@@ -2794,8 +3133,10 @@
                               bool IsFunctionDefinition, bool &Redeclaration) {
   assert(R.getTypePtr()->isFunctionType());
 
-  DeclarationName Name = GetNameForDeclarator(D);
-  FunctionDecl::StorageClass SC = FunctionDecl::None;
+  // TODO: consider using NameInfo for diagnostic.
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
+  FunctionDecl::StorageClass SC = SC_None;
   switch (D.getDeclSpec().getStorageClassSpec()) {
   default: assert(0 && "Unknown storage class!");
   case DeclSpec::SCS_auto:
@@ -2805,8 +3146,8 @@
          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_unspecified: SC = SC_None; break;
+  case DeclSpec::SCS_extern:      SC = SC_Extern; break;
   case DeclSpec::SCS_static: {
     if (CurContext->getLookupContext()->isFunctionOrMethod()) {
       // C99 6.7.1p5:
@@ -2816,12 +3157,12 @@
       // See also (C++ [dcl.stc]p4).
       Diag(D.getDeclSpec().getStorageClassSpecLoc(),
            diag::err_static_block_func);
-      SC = FunctionDecl::None;
+      SC = SC_None;
     } else
-      SC = FunctionDecl::Static;
+      SC = SC_Static;
     break;
   }
-  case DeclSpec::SCS_private_extern: SC = FunctionDecl::PrivateExtern;break;
+  case DeclSpec::SCS_private_extern: SC = SC_PrivateExtern;break;
   }
 
   if (D.getDeclSpec().isThreadSpecified())
@@ -2847,7 +3188,7 @@
     D.setInvalidType();
 
   // Do not allow returning a objc interface by-value.
-  if (R->getAs<FunctionType>()->getResultType()->isObjCInterfaceType()) {
+  if (R->getAs<FunctionType>()->getResultType()->isObjCObjectType()) {
     Diag(D.getIdentifierLoc(),
          diag::err_object_cannot_be_passed_returned_by_value) << 0
       << R->getAs<FunctionType>()->getResultType();
@@ -2874,17 +3215,17 @@
     // Create the new declaration
     NewFD = CXXConstructorDecl::Create(Context,
                                        cast<CXXRecordDecl>(DC),
-                                       D.getIdentifierLoc(), Name, R, TInfo,
+                                       NameInfo, 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);
+      R = CheckDestructorDeclarator(D, R, SC);
 
       NewFD = CXXDestructorDecl::Create(Context,
                                         cast<CXXRecordDecl>(DC),
-                                        D.getIdentifierLoc(), Name, R,
+                                        NameInfo, R,
                                         isInline,
                                         /*isImplicitlyDeclared=*/false);
       NewFD->setTypeSourceInfo(TInfo);
@@ -2909,7 +3250,7 @@
 
     CheckConversionDeclarator(D, R, SC);
     NewFD = CXXConversionDecl::Create(Context, cast<CXXRecordDecl>(DC),
-                                      D.getIdentifierLoc(), Name, R, TInfo,
+                                      NameInfo, R, TInfo,
                                       isInline, isExplicit);
 
     isVirtualOkay = true;
@@ -2927,7 +3268,7 @@
       return 0;
     }
 
-    bool isStatic = SC == FunctionDecl::Static;
+    bool isStatic = SC == SC_Static;
     
     // [class.free]p1:
     // Any allocation function for a class T is a static member
@@ -2944,7 +3285,7 @@
     
     // This is a C++ method declaration.
     NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(DC),
-                                  D.getIdentifierLoc(), Name, R, TInfo,
+                                  NameInfo, R, TInfo,
                                   isStatic, SCAsWritten, isInline);
 
     isVirtualOkay = !isStatic;
@@ -2961,8 +3302,7 @@
        (!isa<FunctionType>(R.getTypePtr()) && R->isFunctionProtoType());
 
     NewFD = FunctionDecl::Create(Context, DC,
-                                 D.getIdentifierLoc(),
-                                 Name, R, TInfo, SC, SCAsWritten, isInline,
+                                 NameInfo, R, TInfo, SC, SCAsWritten, isInline,
                                  HasPrototype);
   }
 
@@ -2981,6 +3321,8 @@
   FunctionTemplateDecl *FunctionTemplate = 0;
   bool isExplicitSpecialization = false;
   bool isFunctionTemplateSpecialization = false;
+  unsigned NumMatchedTemplateParamLists = TemplateParamLists.size();
+  bool Invalid = false;
   if (TemplateParameterList *TemplateParams
         = MatchTemplateParametersToScopeSpecifier(
                                   D.getDeclSpec().getSourceRange().getBegin(),
@@ -2988,7 +3330,11 @@
                            (TemplateParameterList**)TemplateParamLists.get(),
                                                   TemplateParamLists.size(),
                                                   isFriend,
-                                                  isExplicitSpecialization)) {
+                                                  isExplicitSpecialization,
+                                                  Invalid)) {
+    // All but one template parameter lists have been matching.
+    --NumMatchedTemplateParamLists;
+
     if (TemplateParams->size() > 0) {
       // This is a function template
 
@@ -3028,9 +3374,18 @@
           << FixItHint::CreateInsertion(InsertLoc, "<>");
       }
     }
+  }
 
-    // FIXME: Free this memory properly.
-    TemplateParamLists.release();
+  if (NumMatchedTemplateParamLists > 0 && D.getCXXScopeSpec().isSet()) {
+    NewFD->setTemplateParameterListsInfo(Context,
+                                         NumMatchedTemplateParamLists,
+                        (TemplateParameterList**)TemplateParamLists.release());
+  }
+
+  if (Invalid) {
+    NewFD->setInvalidDecl();
+    if (FunctionTemplate)
+      FunctionTemplate->setInvalidDecl();
   }
   
   // C++ [dcl.fct.spec]p5:
@@ -3053,6 +3408,17 @@
     }
   }
 
+  // C++ [dcl.fct.spec]p3:
+  //  The inline specifier shall not appear on a block scope function declaration.
+  if (isInline && !NewFD->isInvalidDecl() && getLangOptions().CPlusPlus) {
+    if (CurContext->isFunctionOrMethod()) {
+      // 'inline' is not allowed on block scope function declaration.
+      Diag(D.getDeclSpec().getInlineSpecLoc(), 
+           diag::err_inline_declaration_block_scope) << Name
+        << FixItHint::CreateRemoval(D.getDeclSpec().getInlineSpecLoc());
+    }
+  }
+ 
   // 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
@@ -3091,7 +3457,7 @@
     NewFD->setAccess(AS_public);
   }
 
-  if (SC == FunctionDecl::Static && isa<CXXMethodDecl>(NewFD) &&
+  if (SC == SC_Static && isa<CXXMethodDecl>(NewFD) &&
       !CurContext->isRecord()) {
     // C++ [class.static]p1:
     //   A data or function member of a class may be declared static
@@ -3109,7 +3475,8 @@
   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()));
+    NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context,
+                                                SE->getString()));
   }
 
   // Copy the parameter declarations from the declarator D to the function
@@ -3125,9 +3492,9 @@
     // 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()) {
+        cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType()) {
       // Empty arg list, don't push any params.
-      ParmVarDecl *Param = FTI.ArgInfo[0].Param.getAs<ParmVarDecl>();
+      ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[0].Param);
 
       // In C++, the empty parameter-type-list must be spelled "void"; a
       // typedef of void is not permitted.
@@ -3137,7 +3504,7 @@
       // 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>();
+        ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
         assert(Param->getDeclContext() != NewFD && "Was set before ?");
         Param->setDeclContext(NewFD);
         Params.push_back(Param);
@@ -3160,12 +3527,8 @@
     // 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();
+      ParmVarDecl *Param =
+        BuildParmVarDeclForTypedef(NewFD, D.getIdentifierLoc(), *AI);
       Params.push_back(Param);
     }
   } else {
@@ -3292,14 +3655,14 @@
     // 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.
+    // C++ [temp.expl.spec]p2. We also allow these declarations as an extension
+    // for compatibility with old SWIG code which likes to generate them.
     if (!IsFunctionDefinition && !isFriend &&
         !isFunctionTemplateSpecialization && !isExplicitSpecialization) {
-      Diag(NewFD->getLocation(), diag::err_out_of_line_declaration)
+      Diag(NewFD->getLocation(), diag::ext_out_of_line_declaration)
         << D.getCXXScopeSpec().getRange();
-      NewFD->setInvalidDecl();
-    } else if (!Redeclaration && 
-               !(isFriend && CurContext->isDependentContext())) {
+    }
+    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,
@@ -3339,10 +3702,11 @@
   ProcessDeclAttributes(S, NewFD, D);
 
   // attributes declared post-definition are currently ignored
+  // FIXME: This should happen during attribute merging
   if (Redeclaration && Previous.isSingleResult()) {
     const FunctionDecl *Def;
     FunctionDecl *PrevFD = dyn_cast<FunctionDecl>(Previous.getFoundDecl());
-    if (PrevFD && PrevFD->getBody(Def) && D.hasAttributes()) {
+    if (PrevFD && PrevFD->hasBody(Def) && D.hasAttributes()) {
       Diag(NewFD->getLocation(), diag::warn_attribute_precede_definition);
       Diag(Def->getLocation(), diag::note_previous_definition);
     }
@@ -3350,7 +3714,7 @@
 
   AddKnownFunctionAttributes(NewFD);
 
-  if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>()) {
+  if (OverloadableAttrRequired && !NewFD->hasAttr<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)
@@ -3358,9 +3722,28 @@
     if (!Previous.empty())
       Diag(Previous.getRepresentativeDecl()->getLocation(),
            diag::note_attribute_overloadable_prev_overload);
-    NewFD->addAttr(::new (Context) OverloadableAttr());
+    NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(), Context));
   }
 
+  if (NewFD->hasAttr<OverloadableAttr>() && 
+      !NewFD->getType()->getAs<FunctionProtoType>()) {
+    Diag(NewFD->getLocation(),
+         diag::err_attribute_overloadable_no_prototype)
+      << NewFD;
+
+    // Turn this into a variadic function with no parameters.
+    const FunctionType *FT = NewFD->getType()->getAs<FunctionType>();
+    QualType R = Context.getFunctionType(FT->getResultType(),
+                                         0, 0, true, 0, false, false, 0, 0,
+                                         FT->getExtInfo());
+    NewFD->setType(R);
+  }
+
+  // If there's a #pragma GCC visibility in scope, and this isn't a class
+  // member, set the visibility of this function.
+  if (NewFD->getLinkage() == ExternalLinkage && !DC->isRecord())
+    AddPushedVisibilityAttribute(NewFD);
+
   // If this is a locally-scoped extern C function, update the
   // map of such names.
   if (CurContext->isFunctionOrMethod() && NewFD->isExternC()
@@ -3376,17 +3759,8 @@
   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);
-  
+  MarkUnusedFileScopedDecl(NewFD);
+
   return NewFD;
 }
 
@@ -3410,8 +3784,14 @@
                                     bool &Redeclaration,
                                     bool &OverloadableAttrRequired) {
   // If NewFD is already known erroneous, don't do any of this checking.
-  if (NewFD->isInvalidDecl())
+  if (NewFD->isInvalidDecl()) {
+    // If this is a class member, mark the class invalid immediately.
+    // This avoids some consistency errors later.
+    if (isa<CXXMethodDecl>(NewFD))
+      cast<CXXMethodDecl>(NewFD)->getParent()->setInvalidDecl();
+
     return;
+  }
 
   if (NewFD->getResultType()->isVariablyModifiedType()) {
     // Functions returning a variably modified type violate C99 6.7.5.2p2
@@ -3447,34 +3827,13 @@
       Redeclaration = true;
       OldDecl = Previous.getFoundDecl();
     } else {
-      if (!getLangOptions().CPlusPlus) {
+      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)) {
+      switch (CheckOverload(S, NewFD, Previous, OldDecl,
+                            /*NewIsUsingDecl*/ false)) {
       case Ovl_Match:
         Redeclaration = true;
-        if (isa<UsingShadowDecl>(OldDecl) && CurContext->isRecord()) {
-          HideUsingShadowDecl(S, cast<UsingShadowDecl>(OldDecl));
-          Redeclaration = false;
-        }
         break;
 
       case Ovl_NonFunction:
@@ -3533,12 +3892,14 @@
       CXXRecordDecl *Record = Destructor->getParent();
       QualType ClassType = Context.getTypeDeclType(Record);
       
-      // FIXME: Shouldn't we be able to perform thisc heck even when the class
+      // FIXME: Shouldn't we be able to perform this check 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));
+//         NewFD->getDeclName().dump();
+//         Name.dump();
         if (NewFD->getDeclName() != Name) {
           Diag(NewFD->getLocation(), diag::err_destructor_name);
           return NewFD->setInvalidDecl();
@@ -3566,12 +3927,6 @@
         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))
@@ -3597,7 +3952,7 @@
   //   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;
+  bool isStatic = FD->getStorageClass() == SC_Static;
   if (isInline || isStatic) {
     unsigned diagID = diag::warn_unusual_main_decl;
     if (isInline || getLangOptions().CPlusPlus)
@@ -3690,22 +4045,21 @@
   // "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))
+  if (Init->isConstantInitializer(Context, false))
     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);
+void Sema::AddInitializerToDecl(Decl *dcl, Expr *init) {
+  AddInitializerToDecl(dcl, 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>();
+void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
   // If there is no declaration, there was an error parsing it.  Just ignore
   // the initializer.
   if (RealDecl == 0)
@@ -3716,7 +4070,6 @@
     // 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());
@@ -3741,6 +4094,8 @@
     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.
@@ -3767,11 +4122,28 @@
     VDecl->setInvalidDecl();
     return;
   }
+  
+  // 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). In that case, the member can appear
+  //   in integral constant expressions. The member shall still be
+  //   defined in a namespace scope if it is used in the program and the
+  //   namespace scope definition shall not contain an initializer.
+  //
+  // We already performed a redefinition check above, but for static
+  // data members we also need to check whether there was an in-class
+  // declaration with an initializer.
+  const VarDecl* PrevInit = 0;
+  if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) {
+    Diag(VDecl->getLocation(), diag::err_redefinition) << VDecl->getDeclName();
+    Diag(PrevInit->getLocation(), diag::note_previous_definition);
+    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");
+  if (getLangOptions().CPlusPlus && VDecl->hasLocalStorage())
+    getCurFunction()->setHasBranchProtectedScope();
 
   // Capture the variable that is being initialized and the style of
   // initialization.
@@ -3794,8 +4166,8 @@
       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),
+      ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                                MultiExprArg(*this, &Init, 1),
                                                 &DclT);
       if (Result.isInvalid()) {
         VDecl->setInvalidDecl();
@@ -3807,7 +4179,7 @@
       // 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.
+        if (VDecl->getStorageClass() == SC_Static) // C99 6.7.8p4.
           CheckForConstantInitializer(Init, DclT);
       }
     }
@@ -3829,7 +4201,7 @@
     QualType T = VDecl->getType();
     if (!T->isDependentType() &&
         (!Context.getCanonicalType(T).isConstQualified() ||
-         !T->isIntegralType())) {
+         !T->isIntegralOrEnumerationType())) {
       Diag(VDecl->getLocation(), diag::err_member_initialization)
         << VDecl->getDeclName() << Init->getSourceRange();
       VDecl->setInvalidDecl();
@@ -3840,7 +4212,7 @@
       //   can specify a constant-initializer which shall be an
       //   integral constant expression (5.19).
       if (!Init->isTypeDependent() &&
-          !Init->getType()->isIntegralType()) {
+          !Init->getType()->isIntegralOrEnumerationType()) {
         // We have a non-dependent, non-integral or enumeration type.
         Diag(Init->getSourceRange().getBegin(),
              diag::err_in_class_initializer_non_integral_type)
@@ -3855,18 +4227,18 @@
             << Init->getSourceRange();
           VDecl->setInvalidDecl();
         } else if (!VDecl->getType()->isDependentType())
-          ImpCastExprToType(Init, VDecl->getType(), CastExpr::CK_IntegralCast);
+          ImpCastExprToType(Init, VDecl->getType(), CK_IntegralCast);
       }
     }
   } else if (VDecl->isFileVarDecl()) {
-    if (VDecl->getStorageClass() == VarDecl::Extern && 
+    if (VDecl->getStorageClass() == SC_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),
+      ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                                MultiExprArg(*this, &Init, 1),
                                                 &DclT);
       if (Result.isInvalid()) {
         VDecl->setInvalidDecl();
@@ -3897,6 +4269,14 @@
   VDecl->setInit(Init);
 
   if (getLangOptions().CPlusPlus) {
+    if (!VDecl->isInvalidDecl() &&
+        !VDecl->getDeclContext()->isDependentContext() &&
+        VDecl->hasGlobalStorage() &&
+        !Init->isConstantInitializer(Context,
+                                     VDecl->getType()->isReferenceType()))
+      Diag(VDecl->getLocation(), diag::warn_global_constructor)
+        << Init->getSourceRange();
+
     // Make sure we mark the destructor as used if necessary.
     QualType InitType = VDecl->getType();
     while (const ArrayType *Array = Context.getAsArrayType(InitType))
@@ -3911,10 +4291,9 @@
 /// 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) {
+void Sema::ActOnInitializerError(Decl *D) {
   // 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);
@@ -3943,10 +4322,8 @@
   // though.
 }
 
-void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
+void Sema::ActOnUninitializedDecl(Decl *RealDecl,
                                   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;
@@ -4006,7 +4383,7 @@
                                   ArrayT->getElementType(),
                                   diag::err_illegal_decl_array_incomplete_type))
             Var->setInvalidDecl();
-        } else if (Var->getStorageClass() == VarDecl::Static) {
+        } else if (Var->getStorageClass() == SC_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.
@@ -4037,15 +4414,15 @@
       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;
-   }
+    // 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.
@@ -4087,17 +4464,30 @@
       //   program is ill-formed.
       // FIXME: DPG thinks it is very fishy that C++0x disables this.
     } else {
+      // Check for jumps past the implicit initializer.  C++0x
+      // clarifies that this applies to a "variable with automatic
+      // storage duration", not a "local variable".
+      if (getLangOptions().CPlusPlus && Var->hasLocalStorage())
+        getCurFunction()->setHasBranchProtectedScope();
+
       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));
+      ExprResult Init = InitSeq.Perform(*this, Entity, Kind,
+                                        MultiExprArg(*this, 0, 0));
       if (Init.isInvalid())
         Var->setInvalidDecl();
-      else if (Init.get())
+      else if (Init.get()) {
         Var->setInit(MaybeCreateCXXExprWithTemporaries(Init.takeAs<Expr>()));
+
+        if (getLangOptions().CPlusPlus && !Var->isInvalidDecl() && 
+            Var->hasGlobalStorage() &&
+            !Var->getDeclContext()->isDependentContext() &&
+            !Var->getInit()->isConstantInitializer(Context, false))
+          Diag(Var->getLocation(), diag::warn_global_constructor);
+      }
     }
 
     if (!Var->isInvalidDecl() && getLangOptions().CPlusPlus && Record)
@@ -4105,16 +4495,16 @@
   }
 }
 
-Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
-                                                   DeclPtrTy *Group,
-                                                   unsigned NumDecls) {
+Sema::DeclGroupPtrTy
+Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
+                              Decl **Group, unsigned NumDecls) {
   llvm::SmallVector<Decl*, 8> Decls;
 
   if (DS.isTypeSpecOwned())
-    Decls.push_back((Decl*)DS.getTypeRep());
+    Decls.push_back(DS.getRepAsDecl());
 
   for (unsigned i = 0; i != NumDecls; ++i)
-    if (Decl *D = Group[i].getAs<Decl>())
+    if (Decl *D = Group[i])
       Decls.push_back(D);
 
   return DeclGroupPtrTy::make(DeclGroupRef::Create(Context,
@@ -4124,16 +4514,15 @@
 
 /// ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator()
 /// to introduce parameters into function prototype scope.
-Sema::DeclPtrTy
-Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
+Decl *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;
+  VarDecl::StorageClass StorageClass = SC_None;
+  VarDecl::StorageClass StorageClassAsWritten = SC_None;
   if (DS.getStorageClassSpec() == DeclSpec::SCS_register) {
-    StorageClass = VarDecl::Register;
-    StorageClassAsWritten = VarDecl::Register;
+    StorageClass = SC_Register;
+    StorageClassAsWritten = SC_Register;
   } else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified) {
     Diag(DS.getStorageClassSpecLoc(),
          diag::err_invalid_storage_class_in_func_decl);
@@ -4150,9 +4539,9 @@
   if (getLangOptions().CPlusPlus)
     CheckExtraCXXDefaultArguments(D);
 
-  TypeSourceInfo *TInfo = 0;
   TagDecl *OwnedDecl = 0;
-  QualType parmDeclType = GetTypeForDeclarator(D, S, &TInfo, &OwnedDecl);
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S, &OwnedDecl);
+  QualType parmDeclType = TInfo->getType();
 
   if (getLangOptions().CPlusPlus && OwnedDecl && OwnedDecl->isDefinition()) {
     // C++ [dcl.fct]p6:
@@ -4174,7 +4563,7 @@
         DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
         // Just pretend that we didn't see the previous declaration.
         PrevDecl = 0;
-      } else if (S->isDeclScope(DeclPtrTy::make(PrevDecl))) {
+      } else if (S->isDeclScope(PrevDecl)) {
         Diag(D.getIdentifierLoc(), diag::err_param_redefinition) << II;
         Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
 
@@ -4205,7 +4594,7 @@
   }
 
   // Add the parameter declaration into this scope.
-  S->AddDecl(DeclPtrTy::make(New));
+  S->AddDecl(New);
   if (II)
     IdResolver.AddDecl(New);
 
@@ -4214,7 +4603,39 @@
   if (New->hasAttr<BlocksAttr>()) {
     Diag(New->getLocation(), diag::err_block_on_nonlocal);
   }
-  return DeclPtrTy::make(New);
+  return New;
+}
+
+/// \brief Synthesizes a variable for a parameter arising from a
+/// typedef.
+ParmVarDecl *Sema::BuildParmVarDeclForTypedef(DeclContext *DC,
+                                              SourceLocation Loc,
+                                              QualType T) {
+  ParmVarDecl *Param = ParmVarDecl::Create(Context, DC, Loc, 0,
+                                T, Context.getTrivialTypeSourceInfo(T, Loc),
+                                           SC_None, SC_None, 0);
+  Param->setImplicit();
+  return Param;
+}
+
+void Sema::DiagnoseUnusedParameters(ParmVarDecl * const *Param,
+                                    ParmVarDecl * const *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)->hasAttr<UnusedAttr>()) {
+      Diag((*Param)->getLocation(), diag::warn_unused_parameter)
+        << (*Param)->getDeclName();
+    }
+  }
 }
 
 ParmVarDecl *Sema::CheckParameter(DeclContext *DC, 
@@ -4238,7 +4659,7 @@
 
   // Parameter declarators cannot be interface types. All ObjC objects are
   // passed by reference.
-  if (T->isObjCInterfaceType()) {
+  if (T->isObjCObjectType()) {
     Diag(NameLoc,
          diag::err_object_cannot_be_passed_returned_by_value) << 1 << T;
     New->setInvalidDecl();
@@ -4291,8 +4712,8 @@
   }
 }
 
-Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
-                                              Declarator &D) {
+Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
+                                         Declarator &D) {
   assert(getCurFunctionDecl() == 0 && "Function parsing confused");
   assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
          "Not a function declarator!");
@@ -4304,9 +4725,9 @@
 
   Scope *ParentScope = FnBodyScope->getParent();
 
-  DeclPtrTy DP = HandleDeclarator(ParentScope, D,
-                                  MultiTemplateParamsArg(*this),
-                                  /*IsFunctionDefinition=*/true);
+  Decl *DP = HandleDeclarator(ParentScope, D,
+                              MultiTemplateParamsArg(*this),
+                              /*IsFunctionDefinition=*/true);
   return ActOnStartOfFunctionDef(FnBodyScope, DP);
 }
 
@@ -4354,7 +4775,7 @@
   return MissingPrototype;
 }
 
-Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
+Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
   // Clear the last template instantiation error context.
   LastTemplateInstantiationErrorContext = ActiveTemplateInstantiation();
   
@@ -4362,11 +4783,10 @@
     return D;
   FunctionDecl *FD = 0;
 
-  if (FunctionTemplateDecl *FunTmpl
-        = dyn_cast<FunctionTemplateDecl>(D.getAs<Decl>()))
+  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
     FD = FunTmpl->getTemplatedDecl();
   else
-    FD = cast<FunctionDecl>(D.getAs<Decl>());
+    FD = cast<FunctionDecl>(D);
 
   // Enter a new function scope
   PushFunctionScope();
@@ -4375,7 +4795,7 @@
   // 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) &&
+  if (FD->hasBody(Definition) &&
       !canRedefineFunction(Definition, getLangOptions())) {
     Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName();
     Diag(Definition->getLocation(), diag::note_previous_definition);
@@ -4431,15 +4851,15 @@
 
   // 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()) {
+  DLLImportAttr *DA = FD->getAttr<DLLImportAttr>();
+  if (DA && (!FD->getAttr<DLLExportAttr>())) {
+    // dllimport attribute cannot be directly applied to definition.
+    if (!DA->isInherited()) {
       Diag(FD->getLocation(),
            diag::err_attribute_can_be_applied_only_to_symbol_declaration)
         << "dllimport";
       FD->setInvalidDecl();
-      return DeclPtrTy::make(FD);
+      return FD;
     }
 
     // Visual C++ appears to not think this is an issue, so only issue
@@ -4450,21 +4870,52 @@
       // emitted.
       Diag(FD->getLocation(),
            diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
-        << FD->getNameAsCString() << "dllimport";
+        << FD->getName() << "dllimport";
     }
   }
-  return DeclPtrTy::make(FD);
+  return FD;
 }
 
-Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg) {
+/// \brief Given the set of return statements within a function body,
+/// compute the variables that are subject to the named return value 
+/// optimization.
+///
+/// Each of the variables that is subject to the named return value 
+/// optimization will be marked as NRVO variables in the AST, and any
+/// return statement that has a marked NRVO variable as its NRVO candidate can
+/// use the named return value optimization.
+///
+/// This function applies a very simplistic algorithm for NRVO: if every return
+/// statement in the function has the same NRVO candidate, that candidate is
+/// the NRVO variable.
+///
+/// FIXME: Employ a smarter algorithm that accounts for multiple return 
+/// statements and the lifetimes of the NRVO candidates. We should be able to
+/// find a maximal set of NRVO variables.
+static void ComputeNRVO(Stmt *Body, FunctionScopeInfo *Scope) {
+  ReturnStmt **Returns = Scope->Returns.data();
+
+  const VarDecl *NRVOCandidate = 0;
+  for (unsigned I = 0, E = Scope->Returns.size(); I != E; ++I) {
+    if (!Returns[I]->getNRVOCandidate())
+      return;
+    
+    if (!NRVOCandidate)
+      NRVOCandidate = Returns[I]->getNRVOCandidate();
+    else if (NRVOCandidate != Returns[I]->getNRVOCandidate())
+      return;
+  }
+  
+  if (NRVOCandidate)
+    const_cast<VarDecl*>(NRVOCandidate)->setNRVOVariable(true);
+}
+
+Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *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>();
-
+Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
+                                    bool IsInstantiation) {
   FunctionDecl *FD = 0;
   FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(dcl);
   if (FunTmpl)
@@ -4483,12 +4934,16 @@
       WP.disableCheckFallThrough();
     }
 
-    if (!FD->isInvalidDecl())
+    if (!FD->isInvalidDecl()) {
       DiagnoseUnusedParameters(FD->param_begin(), FD->param_end());
-
-    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FD))
-      MaybeMarkVirtualMembersReferenced(Method->getLocation(), Method);
-
+      
+      // If this is a constructor, we need a vtable.
+      if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(FD))
+        MarkVTableUsed(FD->getLocation(), Constructor->getParent());
+      
+      ComputeNRVO(Body, getCurFunction());
+    }
+    
     assert(FD == getCurFunctionDecl() && "Function parsing confused");
   } else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) {
     assert(MD == getCurMethodDecl() && "Method parsing confused");
@@ -4497,15 +4952,15 @@
     if (!MD->isInvalidDecl())
       DiagnoseUnusedParameters(MD->param_begin(), MD->param_end());
   } else {
-    Body->Destroy(Context);
-    return DeclPtrTy();
+    return 0;
   }
 
   // Verify and clean out per-function state.
 
   // Check goto/label use.
+  FunctionScopeInfo *CurFn = getCurFunction();
   for (llvm::DenseMap<IdentifierInfo*, LabelStmt*>::iterator
-       I = getLabelMap().begin(), E = getLabelMap().end(); I != E; ++I) {
+         I = CurFn->LabelMap.begin(), E = CurFn->LabelMap.end(); I != E; ++I) {
     LabelStmt *L = I->second;
 
     // Verify that we have no forward references left.  If so, there was a goto
@@ -4521,8 +4976,7 @@
     // 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);
+      // The whole function wasn't parsed correctly.
       continue;
     }
 
@@ -4552,12 +5006,18 @@
     
     // 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())
+    if (getCurFunction()->NeedsScopeChecking() &&
+        !dcl->isInvalidDecl() &&
+        !hasAnyErrorsInThisFunction())
       DiagnoseInvalidJumps(Body);
 
-    if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(dcl))
+    if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(dcl)) {
+      if (!Destructor->getParent()->isDependentType())
+        CheckDestructor(Destructor);
+
       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
@@ -4569,13 +5029,11 @@
       // enabled.
       QualType ResultType;
       if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(dcl)) {
-        ResultType = FD->getResultType();
-      }
-      else {
+        AnalysisWarnings.IssueWarnings(WP, FD);
+      } else {
         ObjCMethodDecl *MD = cast<ObjCMethodDecl>(dcl);
-        ResultType = MD->getResultType();
+        AnalysisWarnings.IssueWarnings(WP, MD);
       }
-      AnalysisWarnings.IssueWarnings(WP, dcl);
     }
 
     assert(ExprTemporaries.empty() && "Leftover temporaries in function");
@@ -4591,8 +5049,8 @@
   // deletion in some later function.
   if (getDiagnostics().hasErrorOccurred())
     ExprTemporaries.clear();
-  
-  return D;
+
+  return dcl;
 }
 
 /// ImplicitlyDefineFunction - An undeclared identifier was used in a function
@@ -4638,8 +5096,7 @@
   DeclContext *PrevDC = CurContext;
   CurContext = Context.getTranslationUnitDecl();
 
-  FunctionDecl *FD =
- dyn_cast<FunctionDecl>(ActOnDeclarator(TUScope, D).getAs<Decl>());
+  FunctionDecl *FD = dyn_cast<FunctionDecl>(ActOnDeclarator(TUScope, D));
   FD->setImplicit();
 
   CurContext = PrevDC;
@@ -4667,9 +5124,17 @@
     bool HasVAListArg;
     if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
       if (!FD->getAttr<FormatAttr>())
-        FD->addAttr(::new (Context) FormatAttr(Context, "printf", FormatIdx+1,
+        FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+                                                "printf", FormatIdx+1,
                                                HasVAListArg ? 0 : FormatIdx+2));
     }
+    if (Context.BuiltinInfo.isScanfLike(BuiltinID, FormatIdx,
+                                             HasVAListArg)) {
+     if (!FD->getAttr<FormatAttr>())
+       FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+                                              "scanf", 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
@@ -4677,15 +5142,15 @@
     if (!getLangOptions().MathErrno &&
         Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
       if (!FD->getAttr<ConstAttr>())
-        FD->addAttr(::new (Context) ConstAttr());
+        FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
     }
 
     if (Context.BuiltinInfo.isNoReturn(BuiltinID))
       FD->setType(Context.getNoReturnType(FD->getType()));
     if (Context.BuiltinInfo.isNoThrow(BuiltinID))
-      FD->addAttr(::new (Context) NoThrowAttr());
+      FD->addAttr(::new (Context) NoThrowAttr(FD->getLocation(), Context));
     if (Context.BuiltinInfo.isConst(BuiltinID))
-      FD->addAttr(::new (Context) ConstAttr());
+      FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
   }
 
   IdentifierInfo *Name = FD->getIdentifier();
@@ -4707,13 +5172,15 @@
       // FIXME: We known better than our headers.
       const_cast<FormatAttr *>(Format)->setType(Context, "printf");
     } else
-      FD->addAttr(::new (Context) FormatAttr(Context, "printf", 1,
+      FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), 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,
+      FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+                                             "printf", 2,
                                              Name->isStr("vasprintf") ? 0 : 3));
   }
 }
@@ -4754,38 +5221,38 @@
 ///
 /// \returns true if the new tag kind is acceptable, false otherwise.
 bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous,
-                                        TagDecl::TagKind NewTag,
+                                        TagTypeKind 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
+  //   declaration to which the name in the elaborated-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
+  //   refer to an enumeration (7.2), the union class-key shall 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();
+  TagTypeKind 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)) {
+  if ((OldTag == TTK_Struct || OldTag == TTK_Class) &&
+      (NewTag == TTK_Struct || NewTag == TTK_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)
+      << (NewTag == TTK_Class)
       << isTemplate << &Name
       << FixItHint::CreateReplacement(SourceRange(NewTagLoc),
-                              OldTag == TagDecl::TK_class? "class" : "struct");
+                              OldTag == TTK_Class? "class" : "struct");
     Diag(Previous->getLocation(), diag::note_previous_use);
     return true;
   }
@@ -4796,7 +5263,7 @@
 /// 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,
+Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
                                SourceLocation KWLoc, CXXScopeSpec &SS,
                                IdentifierInfo *Name, SourceLocation NameLoc,
                                AttributeList *Attr, AccessSpecifier AS,
@@ -4807,20 +5274,29 @@
          "Nameless record must be a definition!");
 
   OwnedDecl = false;
-  TagDecl::TagKind Kind = TagDecl::getTagKindForTypeSpec(TagSpec);
+  TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
 
   // FIXME: Check explicit specializations more carefully.
   bool isExplicitSpecialization = false;
+  unsigned NumMatchedTemplateParamLists = TemplateParameterLists.size();
+  bool Invalid = false;
   if (TUK != TUK_Reference) {
     if (TemplateParameterList *TemplateParams
           = MatchTemplateParametersToScopeSpecifier(KWLoc, SS,
                         (TemplateParameterList**)TemplateParameterLists.get(),
                                               TemplateParameterLists.size(),
                                                     TUK == TUK_Friend,
-                                                    isExplicitSpecialization)) {
+                                                    isExplicitSpecialization,
+                                                    Invalid)) {
+      // All but one template parameter lists have been matching.
+      --NumMatchedTemplateParamLists;
+
       if (TemplateParams->size() > 0) {
         // This is a declaration or definition of a class template (which may
         // be a member of another template).
+        if (Invalid)
+          return 0;
+        
         OwnedDecl = false;
         DeclResult Result = CheckClassTemplate(S, TagSpec, TUK, KWLoc,
                                                SS, Name, NameLoc, Attr,
@@ -4831,18 +5307,15 @@
       } else {
         // The "template<>" header is extraneous.
         Diag(TemplateParams->getTemplateLoc(), diag::err_template_tag_noparams)
-          << ElaboratedType::getNameForTagKind(Kind) << Name;
+          << TypeWithKeyword::getTagTypeKindName(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)
@@ -4865,20 +5338,26 @@
       DC = computeDeclContext(SS, false);
       if (!DC) {
         IsDependent = true;
-        return DeclPtrTy();
+        return 0;
+      }
+    } else {
+      DC = computeDeclContext(SS, true);
+      if (!DC) {
+        Diag(SS.getRange().getBegin(), diag::err_dependent_nested_name_spec)
+          << SS.getRange();
+        return 0;
       }
     }
 
-    if (RequireCompleteDeclContext(SS))
-      return DeclPtrTy::make((Decl *)0);
+    if (RequireCompleteDeclContext(SS, DC))
+      return 0;
 
-    DC = computeDeclContext(SS, true);
     SearchDC = DC;
     // Look-up name inside 'foo::'.
     LookupQualifiedName(Previous, DC);
 
     if (Previous.isAmbiguous())
-      return DeclPtrTy();
+      return 0;
 
     if (Previous.empty()) {
       // Name lookup did not find anything. However, if the
@@ -4888,7 +5367,7 @@
       // this as a dependent elaborated-type-specifier.
       if (Previous.wasNotFoundInCurrentInstantiation()) {
         IsDependent = true;
-        return DeclPtrTy();
+        return 0;
       }
 
       // A tag 'foo::bar' must already exist.
@@ -4908,7 +5387,7 @@
 
     // Note:  there used to be some attempt at recovery here.
     if (Previous.isAmbiguous())
-      return DeclPtrTy();
+      return 0;
 
     if (!getLangOptions().CPlusPlus && TUK != TUK_Reference) {
       // FIXME: This makes sure that we ignore the contexts associated
@@ -4929,7 +5408,7 @@
   }
 
   if (getLangOptions().CPlusPlus && Name && DC && StdNamespace &&
-      DC->Equals(StdNamespace) && Name->isStr("bad_alloc")) {
+      DC->Equals(getStdNamespace()) && Name->isStr("bad_alloc")) {
     // This is a declaration of or a reference to "std::bad_alloc".
     isStdBadAlloc = true;
     
@@ -4937,7 +5416,7 @@
       // 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);
+      Previous.addDecl(getStdBadAlloc());
     }
   }
 
@@ -5024,10 +5503,12 @@
         if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) {
           TagDecl *Tag = TT->getDecl();
           if (Tag->getDeclName() == Name &&
-              Tag->getDeclContext()->Equals(TD->getDeclContext())) {
+              Tag->getDeclContext()->getLookupContext()
+                          ->Equals(TD->getDeclContext()->getLookupContext())) {
             PrevDecl = Tag;
             Previous.clear();
             Previous.addDecl(Tag);
+            Previous.resolveKind();
           }
         }
       }
@@ -5043,8 +5524,8 @@
         // struct or something similar.
         if (!isAcceptableTagRedeclaration(PrevTagDecl, Kind, KWLoc, *Name)) {
           bool SafeToContinue
-            = (PrevTagDecl->getTagKind() != TagDecl::TK_enum &&
-               Kind != TagDecl::TK_enum);
+            = (PrevTagDecl->getTagKind() != TTK_Enum &&
+               Kind != TTK_Enum);
           if (SafeToContinue)
             Diag(KWLoc, diag::err_use_with_wrong_tag)
               << Name
@@ -5071,8 +5552,9 @@
           // 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);
+          if ((TUK == TUK_Reference && !PrevTagDecl->getFriendObjectKind()) ||
+              TUK == TUK_Friend)
+            return PrevTagDecl;
 
           // Diagnose attempts to redefine a tag.
           if (TUK == TUK_Definition) {
@@ -5198,16 +5680,23 @@
   // PrevDecl.
   TagDecl *New;
 
-  if (Kind == TagDecl::TK_enum) {
+  if (Kind == TTK_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);
+    if (TUK != TUK_Definition && !Invalid) {
+      TagDecl *Def;
+      if (PrevDecl && (Def = cast<EnumDecl>(PrevDecl)->getDefinition())) {
+        Diag(Loc, diag::ext_forward_ref_enum_def)
+          << New;
+        Diag(Def->getLocation(), diag::note_previous_definition);
+      } else {
+        Diag(Loc, 
+             getLangOptions().CPlusPlus? diag::err_forward_ref_enum
+                                       : diag::ext_forward_ref_enum);
+      }
     }
   } else {
     // struct/union/class
@@ -5219,7 +5708,7 @@
       New = CXXRecordDecl::Create(Context, Kind, SearchDC, Loc, Name, KWLoc,
                                   cast_or_null<CXXRecordDecl>(PrevDecl));
       
-      if (isStdBadAlloc && (!StdBadAlloc || StdBadAlloc->isImplicit()))
+      if (isStdBadAlloc && (!StdBadAlloc || getStdBadAlloc()->isImplicit()))
         StdBadAlloc = cast<CXXRecordDecl>(New);
     } else
       New = RecordDecl::Create(Context, Kind, SearchDC, Loc, Name, KWLoc,
@@ -5228,16 +5717,23 @@
 
   // Maybe add qualifier info.
   if (SS.isNotEmpty()) {
-    NestedNameSpecifier *NNS
-      = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
-    New->setQualifierInfo(NNS, SS.getRange());
+    if (SS.isSet()) {
+      NestedNameSpecifier *NNS
+        = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
+      New->setQualifierInfo(NNS, SS.getRange());
+      if (NumMatchedTemplateParamLists > 0) {
+        New->setTemplateParameterListsInfo(Context,
+                                           NumMatchedTemplateParamLists,
+                    (TemplateParameterList**) TemplateParameterLists.release());
+      }
+    }
+    else
+      Invalid = true;
   }
 
-  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.
+  if (RecordDecl *RD = dyn_cast<RecordDecl>(New)) {
+    // Add alignment attributes if necessary; 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
@@ -5245,15 +5741,14 @@
     // 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));
+    AddAlignmentAttributesForRecord(RD);
   }
 
   // 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();
 
@@ -5307,21 +5802,21 @@
       Context.setFILEDecl(New);
 
   OwnedDecl = true;
-  return DeclPtrTy::make(New);
+  return New;
 }
 
-void Sema::ActOnTagStartDefinition(Scope *S, DeclPtrTy TagD) {
+void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) {
   AdjustDeclIfTemplate(TagD);
-  TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+  TagDecl *Tag = cast<TagDecl>(TagD);
   
   // Enter the tag context.
   PushDeclContext(S, Tag);
 }
 
-void Sema::ActOnStartCXXMemberDeclarations(Scope *S, DeclPtrTy TagD,
+void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD,
                                            SourceLocation LBraceLoc) {
   AdjustDeclIfTemplate(TagD);
-  CXXRecordDecl *Record = cast<CXXRecordDecl>(TagD.getAs<Decl>());
+  CXXRecordDecl *Record = cast<CXXRecordDecl>(TagD);
 
   FieldCollector->StartClass();
 
@@ -5348,41 +5843,10 @@
          "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,
+void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD,
                                     SourceLocation RBraceLoc) {
   AdjustDeclIfTemplate(TagD);
-  TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+  TagDecl *Tag = cast<TagDecl>(TagD);
   Tag->setRBraceLoc(RBraceLoc);
 
   if (isa<CXXRecordDecl>(Tag))
@@ -5390,18 +5854,14 @@
 
   // 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) {
+void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) {
   AdjustDeclIfTemplate(TagD);
-  TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+  TagDecl *Tag = cast<TagDecl>(TagD);
   Tag->setInvalidDecl();
 
   // We're undoing ActOnTagStartDefinition here, not
@@ -5421,7 +5881,7 @@
 
   // 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()) {
+  if (!FieldTy->isDependentType() && !FieldTy->isIntegralOrEnumerationType()) {
     // Handle incomplete types with specific error.
     if (RequireCompleteType(FieldLoc, FieldTy, diag::err_field_incomplete))
       return true;
@@ -5484,13 +5944,13 @@
 
 /// 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,
+Decl *Sema::ActOnField(Scope *S, Decl *TagD,
                                  SourceLocation DeclStart,
                                  Declarator &D, ExprTy *BitfieldWidth) {
-  FieldDecl *Res = HandleField(S, cast_or_null<RecordDecl>(TagD.getAs<Decl>()),
+  FieldDecl *Res = HandleField(S, cast_or_null<RecordDecl>(TagD),
                                DeclStart, D, static_cast<Expr*>(BitfieldWidth),
                                AS_public);
-  return DeclPtrTy::make(Res);
+  return Res;
 }
 
 /// HandleField - Analyze a field of a C struct or a C++ data member.
@@ -5503,8 +5963,8 @@
   SourceLocation Loc = DeclStart;
   if (II) Loc = D.getIdentifierLoc();
 
-  TypeSourceInfo *TInfo = 0;
-  QualType T = GetTypeForDeclarator(D, S, &TInfo);
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
+  QualType T = TInfo->getType();
   if (getLangOptions().CPlusPlus)
     CheckExtraCXXDefaultArguments(D);
 
@@ -5577,21 +6037,29 @@
 
   QualType EltTy = Context.getBaseElementType(T);
   if (!EltTy->isDependentType() &&
-      RequireCompleteType(Loc, EltTy, diag::err_field_incomplete))
+      RequireCompleteType(Loc, EltTy, diag::err_field_incomplete)) {
+    // Fields of incomplete type force their record to be invalid.
+    Record->setInvalidDecl();
     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;
+    llvm::APSInt Oversized;
     QualType FixedTy = TryToFixInvalidVariablyModifiedType(T, Context,
-                                                           SizeIsNegative);
+                                                           SizeIsNegative,
+                                                           Oversized);
     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 if (Oversized.getBoolValue())
+        Diag(Loc, diag::err_array_too_large)
+          << Oversized.toString(10);
       else
         Diag(Loc, diag::err_typecheck_field_variable_size);
       InvalidDecl = true;
@@ -5614,6 +6082,24 @@
     ZeroWidth = false;
   }
 
+  // Check that 'mutable' is consistent with the type of the declaration.
+  if (!InvalidDecl && Mutable) {
+    unsigned DiagID = 0;
+    if (T->isReferenceType())
+      DiagID = diag::err_mutable_reference;
+    else if (T.isConstQualified())
+      DiagID = diag::err_mutable_const;
+
+    if (DiagID) {
+      SourceLocation ErrLoc = Loc;
+      if (D && D->getDeclSpec().getStorageClassSpecLoc().isValid())
+        ErrLoc = D->getDeclSpec().getStorageClassSpecLoc();
+      Diag(ErrLoc, DiagID);
+      Mutable = false;
+      InvalidDecl = true;
+    }
+  }
+
   FieldDecl *NewFD = FieldDecl::Create(Context, Record, Loc, II, T, TInfo,
                                        BitWidth, Mutable);
   if (InvalidDecl)
@@ -5635,42 +6121,24 @@
 
     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->getDefinition()) {
+        if (!RDecl->hasTrivialConstructor())
+          CXXRecord->setHasTrivialConstructor(false);
         if (!RDecl->hasTrivialCopyConstructor())
-          member = CXXCopyConstructor;
-        else if (!RDecl->hasTrivialConstructor())
-          member = CXXConstructor;
-        else if (!RDecl->hasTrivialCopyAssignment())
-          member = CXXCopyAssignment;
-        else if (!RDecl->hasTrivialDestructor())
-          member = CXXDestructor;
+          CXXRecord->setHasTrivialCopyConstructor(false);
+        if (!RDecl->hasTrivialCopyAssignment())
+          CXXRecord->setHasTrivialCopyAssignment(false);
+        if (!RDecl->hasTrivialDestructor())
+          CXXRecord->setHasTrivialDestructor(false);
 
-        if (member != CXXInvalid) {
-          Diag(Loc, diag::err_illegal_union_member) << Name << member;
-          DiagnoseNontrivial(RT, member);
+        // 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() && CheckNontrivialField(NewFD))
           NewFD->setInvalidDecl();
-        }
       }
     }
   }
@@ -5700,6 +6168,43 @@
   return NewFD;
 }
 
+bool Sema::CheckNontrivialField(FieldDecl *FD) {
+  assert(FD);
+  assert(getLangOptions().CPlusPlus && "valid check only for C++");
+
+  if (FD->isInvalidDecl())
+    return true;
+
+  QualType EltTy = Context.getBaseElementType(FD->getType());
+  if (const RecordType *RT = EltTy->getAs<RecordType>()) {
+    CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
+    if (RDecl->getDefinition()) {
+      // 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(FD->getLocation(), diag::err_illegal_union_or_anon_struct_member)
+              << (int)FD->getParent()->isUnion() << FD->getDeclName() << member;
+        DiagnoseNontrivial(RT, member);
+        return true;
+      }
+    }
+  }
+  
+  return false;
+}
+
 /// DiagnoseNontrivial - Given that a class has a non-trivial
 /// special member, figure out why.
 void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) {
@@ -5716,7 +6221,7 @@
       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);
+        ci->hasBody(body);
         if (!body || !cast<CXXConstructorDecl>(body)->isImplicitlyDefined()) {
           SourceLocation CtorLoc = ci->getLocation();
           Diag(CtorLoc, diag::note_nontrivial_user_defined) << QT << member;
@@ -5750,7 +6255,7 @@
 
   case CXXDestructor:
     if (RD->hasUserDeclaredDestructor()) {
-      SourceLocation DtorLoc = RD->getDestructor(Context)->getLocation();
+      SourceLocation DtorLoc = LookupDestructor(RD)->getLocation();
       Diag(DtorLoc, diag::note_nontrivial_user_defined) << QT << member;
       return;
     }
@@ -5845,9 +6350,9 @@
 
 /// 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,
+Decl *Sema::ActOnIvar(Scope *S,
                                 SourceLocation DeclStart,
-                                DeclPtrTy IntfDecl,
+                                Decl *IntfDecl,
                                 Declarator &D, ExprTy *BitfieldWidth,
                                 tok::ObjCKeywordKind Visibility) {
 
@@ -5859,8 +6364,8 @@
   // 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);
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
+  QualType T = TInfo->getType();
 
   if (BitWidth) {
     // 6.7.2.1p3, 6.7.2.1p4
@@ -5891,19 +6396,23 @@
     Visibility != tok::objc_not_keyword ? TranslateIvarVisibility(Visibility)
                                         : ObjCIvarDecl::None;
   // Must set ivar's DeclContext to its enclosing interface.
-  ObjCContainerDecl *EnclosingDecl = IntfDecl.getAs<ObjCContainerDecl>();
+  ObjCContainerDecl *EnclosingDecl = cast<ObjCContainerDecl>(IntfDecl);
   ObjCContainerDecl *EnclosingContext;
   if (ObjCImplementationDecl *IMPDecl =
       dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
+    if (!LangOpts.ObjCNonFragileABI2) {
     // Case of ivar declared in an implementation. Context is that of its class.
-    EnclosingContext = IMPDecl->getClassInterface();
-    assert(EnclosingContext && "Implementation has no class interface!");
+      EnclosingContext = IMPDecl->getClassInterface();
+      assert(EnclosingContext && "Implementation has no class interface!");
+    }
+    else
+      EnclosingContext = EnclosingDecl;
   } else {
     if (ObjCCategoryDecl *CDecl = 
         dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
       if (!LangOpts.ObjCNonFragileABI2 || !CDecl->IsClassExtension()) {
         Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension();
-        return DeclPtrTy();
+        return 0;
       }
     }
     EnclosingContext = EnclosingDecl;
@@ -5934,19 +6443,59 @@
   if (II) {
     // FIXME: When interfaces are DeclContexts, we'll need to add
     // these to the interface.
-    S->AddDecl(DeclPtrTy::make(NewID));
+    S->AddDecl(NewID);
     IdResolver.AddDecl(NewID);
   }
 
-  return DeclPtrTy::make(NewID);
+  return NewID;
+}
+
+/// ActOnLastBitfield - This routine handles synthesized bitfields rules for 
+/// class and class extensions. For every class @interface and class 
+/// extension @interface, if the last ivar is a bitfield of any type, 
+/// then add an implicit `char :0` ivar to the end of that interface.
+void Sema::ActOnLastBitfield(SourceLocation DeclLoc, Decl *EnclosingDecl,
+                             llvm::SmallVectorImpl<Decl *> &AllIvarDecls) {
+  if (!LangOpts.ObjCNonFragileABI2 || AllIvarDecls.empty())
+    return;
+  
+  Decl *ivarDecl = AllIvarDecls[AllIvarDecls.size()-1];
+  ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(ivarDecl);
+  
+  if (!Ivar->isBitField())
+    return;
+  uint64_t BitFieldSize =
+    Ivar->getBitWidth()->EvaluateAsInt(Context).getZExtValue();
+  if (BitFieldSize == 0)
+    return;
+  ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl);
+  if (!ID) {
+    if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
+      if (!CD->IsClassExtension())
+        return;
+    }
+    // No need to add this to end of @implementation.
+    else
+      return;
+  }
+  // All conditions are met. Add a new bitfield to the tail end of ivars.
+  llvm::APInt Zero(Context.getTypeSize(Context.CharTy), 0);
+  Expr * BW = IntegerLiteral::Create(Context, Zero, Context.CharTy, DeclLoc);
+
+  Ivar = ObjCIvarDecl::Create(Context, cast<ObjCContainerDecl>(EnclosingDecl),
+                              DeclLoc, 0,
+                              Context.CharTy, 
+                              Context.CreateTypeSourceInfo(Context.CharTy),
+                              ObjCIvarDecl::Private, BW,
+                              true);
+  AllIvarDecls.push_back(Ivar);
 }
 
 void Sema::ActOnFields(Scope* S,
-                       SourceLocation RecLoc, DeclPtrTy RecDecl,
-                       DeclPtrTy *Fields, unsigned NumFields,
+                       SourceLocation RecLoc, Decl *EnclosingDecl,
+                       Decl **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
@@ -5963,7 +6512,7 @@
 
   RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl);
   for (unsigned i = 0; i != NumFields; ++i) {
-    FieldDecl *FD = cast<FieldDecl>(Fields[i].getAs<Decl>());
+    FieldDecl *FD = cast<FieldDecl>(Fields[i]);
 
     // Get the type for the field.
     Type *FDTy = FD->getType().getTypePtr();
@@ -6007,6 +6556,15 @@
         EnclosingDecl->setInvalidDecl();
         continue;
       }
+      if (!FD->getType()->isDependentType() &&
+          !Context.getBaseElementType(FD->getType())->isPODType()) {
+        Diag(FD->getLocation(), diag::err_flexible_array_has_nonpod_type)
+          << FD->getDeclName() << FD->getType();
+        FD->setInvalidDecl();
+        EnclosingDecl->setInvalidDecl();
+        continue;
+      }
+      
       // Okay, we have a legal flexible array member at the end of the struct.
       if (Record)
         Record->setHasFlexibleArrayMember(true);
@@ -6041,7 +6599,7 @@
       }
       if (Record && FDTTy->getDecl()->hasObjectMember())
         Record->setHasObjectMember(true);
-    } else if (FDTy->isObjCInterfaceType()) {
+    } else if (FDTy->isObjCObjectType()) {
       /// A field cannot be an Objective-c object
       Diag(FD->getLocation(), diag::err_statically_allocated_object);
       FD->setInvalidDecl();
@@ -6053,6 +6611,12 @@
                (FD->getType()->isObjCObjectPointerType() ||
                 FD->getType().isObjCGCStrong()))
       Record->setHasObjectMember(true);
+    else if (Context.getAsArrayType(FD->getType())) {
+      QualType BaseType = Context.getBaseElementType(FD->getType());
+      if (Record && BaseType->isRecordType() && 
+          BaseType->getAs<RecordType>()->getDecl()->hasObjectMember())
+        Record->setHasObjectMember(true);
+    }
     // Keep track of the number of named members.
     if (FD->getIdentifier())
       ++NumNamedMembers;
@@ -6099,6 +6663,11 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, Record, Attr);
+
+  // If there's a #pragma GCC visibility in scope, and this isn't a subclass,
+  // set the visibility of this record.
+  if (Record && !Record->getDeclContext()->isRecord())
+    AddPushedVisibilityAttribute(Record);
 }
 
 /// \brief Determine whether the given integral value is representable within
@@ -6106,7 +6675,7 @@
 static bool isRepresentableIntegerValue(ASTContext &Context,
                                         llvm::APSInt &Value,
                                         QualType T) {
-  assert(T->isIntegralType() && "Integral type required!");
+  assert(T->isIntegralType(Context) && "Integral type required!");
   unsigned BitWidth = Context.getIntWidth(T);
   
   if (Value.isUnsigned() || Value.isNonNegative())
@@ -6120,7 +6689,7 @@
 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!");
+  assert(T->isIntegralType(Context) && "Integral type required!");
   const unsigned NumTypes = 4;
   QualType SignedIntegralTypes[NumTypes] = { 
     Context.ShortTy, Context.IntTy, Context.LongTy, Context.LongLongTy
@@ -6144,9 +6713,7 @@
                                           EnumConstantDecl *LastEnumConst,
                                           SourceLocation IdLoc,
                                           IdentifierInfo *Id,
-                                          ExprArg val) {
-  Expr *Val = (Expr *)val.get();
-
+                                          Expr *Val) {
   unsigned IntWidth = Context.Target.getIntWidth();
   llvm::APSInt EnumVal(IntWidth);
   QualType EltTy;
@@ -6173,12 +6740,7 @@
               << (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;
-            }
+            ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast);
           }
         }
         
@@ -6266,20 +6828,19 @@
     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,
+Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl,
+                                        Decl *lastEnumConst,
                                         SourceLocation IdLoc,
                                         IdentifierInfo *Id,
                                         SourceLocation EqualLoc, ExprTy *val) {
-  EnumDecl *TheEnumDecl = cast<EnumDecl>(theEnumDecl.getAs<Decl>());
+  EnumDecl *TheEnumDecl = cast<EnumDecl>(theEnumDecl);
   EnumConstantDecl *LastEnumConst =
-    cast_or_null<EnumConstantDecl>(lastEnumConst.getAs<Decl>());
+    cast_or_null<EnumConstantDecl>(lastEnumConst);
   Expr *Val = static_cast<Expr*>(val);
 
   // The scope passed in may not be a decl scope.  Zip up the scope tree until
@@ -6308,13 +6869,12 @@
       else
         Diag(IdLoc, diag::err_redefinition) << Id;
       Diag(PrevDecl->getLocation(), diag::note_previous_definition);
-      if (Val) Val->Destroy(Context);
-      return DeclPtrTy();
+      return 0;
     }
   }
 
   EnumConstantDecl *New = CheckEnumConstant(TheEnumDecl, LastEnumConst,
-                                            IdLoc, Id, Owned(Val));
+                                            IdLoc, Id, Val);
 
   // Register this decl in the current scope stack.
   if (New) {
@@ -6322,14 +6882,14 @@
     PushOnScopeChains(New, S);
   }
 
-  return DeclPtrTy::make(New);
+  return New;
 }
 
 void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
-                         SourceLocation RBraceLoc, DeclPtrTy EnumDeclX,
-                         DeclPtrTy *Elements, unsigned NumElements,
+                         SourceLocation RBraceLoc, Decl *EnumDeclX,
+                         Decl **Elements, unsigned NumElements,
                          Scope *S, AttributeList *Attr) {
-  EnumDecl *Enum = cast<EnumDecl>(EnumDeclX.getAs<Decl>());
+  EnumDecl *Enum = cast<EnumDecl>(EnumDeclX);
   QualType EnumType = Context.getTypeDeclType(Enum);
 
   if (Attr)
@@ -6338,13 +6898,13 @@
   if (Enum->isDependentType()) {
     for (unsigned i = 0; i != NumElements; ++i) {
       EnumConstantDecl *ECD =
-        cast_or_null<EnumConstantDecl>(Elements[i].getAs<Decl>());
+        cast_or_null<EnumConstantDecl>(Elements[i]);
       if (!ECD) continue;
 
       ECD->setType(EnumType);
     }
 
-    Enum->completeDefinition(Context.DependentTy, Context.DependentTy);
+    Enum->completeDefinition(Context.DependentTy, Context.DependentTy, 0, 0);
     return;
   }
 
@@ -6365,7 +6925,7 @@
 
   for (unsigned i = 0; i != NumElements; ++i) {
     EnumConstantDecl *ECD =
-      cast_or_null<EnumConstantDecl>(Elements[i].getAs<Decl>());
+      cast_or_null<EnumConstantDecl>(Elements[i]);
     if (!ECD) continue;  // Already issued a diagnostic.
 
     const llvm::APSInt &InitVal = ECD->getInitVal();
@@ -6467,8 +7027,7 @@
   // 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>());
+    EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(Elements[i]);
     if (!ECD) continue;  // Already issued a diagnostic.
 
     // Standard C says the enumerators have int type, but we allow, as an
@@ -6511,11 +7070,11 @@
 
     // Adjust the Expr initializer and type.
     if (ECD->getInitExpr())
-      ECD->setInitExpr(new (Context) ImplicitCastExpr(NewTy,
-                                                      CastExpr::CK_IntegralCast,
-                                                      ECD->getInitExpr(),
-                                                      CXXBaseSpecifierArray(),
-                                                      /*isLvalue=*/false));
+      ECD->setInitExpr(ImplicitCastExpr::Create(Context, NewTy,
+                                                CK_IntegralCast,
+                                                ECD->getInitExpr(),
+                                                /*base paths*/ 0,
+                                                VK_RValue));
     if (getLangOptions().CPlusPlus)
       // C++ [dcl.enum]p4: Following the closing brace of an
       // enum-specifier, each enumerator has the type of its
@@ -6525,17 +7084,17 @@
       ECD->setType(NewTy);
   }
 
-  Enum->completeDefinition(BestType, BestPromotionType);
+  Enum->completeDefinition(BestType, BestPromotionType,
+                           NumPositiveBits, NumNegativeBits);
 }
 
-Sema::DeclPtrTy Sema::ActOnFileScopeAsmDecl(SourceLocation Loc,
-                                            ExprArg expr) {
-  StringLiteral *AsmString = cast<StringLiteral>(expr.takeAs<Expr>());
+Decl *Sema::ActOnFileScopeAsmDecl(SourceLocation Loc, Expr *expr) {
+  StringLiteral *AsmString = cast<StringLiteral>(expr);
 
   FileScopeAsmDecl *New = FileScopeAsmDecl::Create(Context, CurContext,
                                                    Loc, AsmString);
   CurContext->addDecl(New);
-  return DeclPtrTy::make(New);
+  return New;
 }
 
 void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
@@ -6544,7 +7103,7 @@
   Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc, LookupOrdinaryName);
 
   if (PrevDecl) {
-    PrevDecl->addAttr(::new (Context) WeakAttr());
+    PrevDecl->addAttr(::new (Context) WeakAttr(PragmaLoc, Context));
   } else {
     (void)WeakUndeclaredIdentifiers.insert(
       std::pair<IdentifierInfo*,WeakInfo>
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 1c07d9b..9b36b31 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -11,15 +11,18 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
 #include "TargetAttributesSema.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/Basic/TargetInfo.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/DelayedDiagnostic.h"
 #include "llvm/ADT/StringExtras.h"
 using namespace clang;
+using namespace sema;
 
 //===----------------------------------------------------------------------===//
 //  Helper functions
@@ -118,7 +121,7 @@
     const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
     return proto->isVariadic();
   } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
-    return BD->IsVariadic();
+    return BD->isVariadic();
   else {
     return cast<ObjCMethodDecl>(d)->isVariadic();
   }
@@ -129,11 +132,11 @@
   if (!PT)
     return false;
 
-  const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAs<ObjCInterfaceType>();
-  if (!ClsT)
+  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
+  if (!Cls)
     return false;
 
-  IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
+  IdentifierInfo* ClsName = Cls->getIdentifier();
 
   // FIXME: Should we walk the chain of classes?
   return ClsName == &Ctx.Idents.get("NSString") ||
@@ -150,7 +153,7 @@
     return false;
 
   const RecordDecl *RD = RT->getDecl();
-  if (RD->getTagKind() != TagDecl::TK_struct)
+  if (RD->getTagKind() != TTK_Struct)
     return false;
 
   return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
@@ -193,7 +196,7 @@
 
   // 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());
+  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
   if (!T.isNull()) {
     // FIXME: preserve the old source info.
     tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
@@ -211,7 +214,7 @@
   }
 
   if (TagDecl *TD = dyn_cast<TagDecl>(d))
-    TD->addAttr(::new (S.Context) PackedAttr);
+    TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
   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.
@@ -220,7 +223,7 @@
       S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
         << Attr.getName() << FD->getType();
     else
-      FD->addAttr(::new (S.Context) PackedAttr);
+      FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
   } else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 }
@@ -235,7 +238,7 @@
   // The IBAction attributes only apply to instance methods.
   if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
     if (MD->isInstanceMethod()) {
-      d->addAttr(::new (S.Context) IBActionAttr());
+      d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
       return;
     }
 
@@ -252,13 +255,65 @@
   // 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());
+    d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
     return;
   }
 
   S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName();
 }
 
+static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
+                                     Sema &S) {
+
+  // The iboutletcollection attribute can have zero or one arguments.
+  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+
+  // The IBOutletCollection attributes only apply to instance variables of
+  // Objective-C classes.
+  if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName();
+    return;
+  }
+  if (const ValueDecl *VD = dyn_cast<ValueDecl>(d))
+    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
+      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 
+        << VD->getType() << 0;
+      return;
+    }
+  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d))
+    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
+      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 
+        << PD->getType() << 1;
+      return;
+    }
+  
+  IdentifierInfo *II = Attr.getParameterName();
+  if (!II)
+    II = &S.Context.Idents.get("id");
+  
+  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 
+                        S.getScopeForContext(d->getDeclContext()->getParent()));
+  if (!TypeRep) {
+    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
+    return;
+  }
+  QualType QT = TypeRep.get();
+  // Diagnose use of non-object type in iboutletcollection attribute.
+  // FIXME. Gnu attribute extension ignores use of builtin types in
+  // attributes. So, __attribute__((iboutletcollection(char))) will be
+  // treated as __attribute__((iboutletcollection())).
+  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
+      !QT->isObjCObjectType()) {
+    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
+    return;
+  }
+  d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
+                                                      QT));
+}
+
 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
@@ -280,7 +335,8 @@
     // The argument must be an integer constant expression.
     Expr *Ex = static_cast<Expr *>(*I);
     llvm::APSInt ArgNum(32);
-    if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
+    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
+        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
       S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
         << "nonnull" << Ex->getSourceRange();
       return;
@@ -300,7 +356,7 @@
     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)
+      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
         << "nonnull" << Ex->getSourceRange();
       continue;
     }
@@ -325,15 +381,162 @@
 
   unsigned* start = &NonNullArgs[0];
   unsigned size = NonNullArgs.size();
-  std::sort(start, start + size);
-  d->addAttr(::new (S.Context) NonNullAttr(S.Context, start, size));
+  llvm::array_pod_sort(start, start + size);
+  d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
+                                           size));
+}
+
+static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
+  // This attribute must be applied to a function declaration.
+  // The first argument to the attribute must be a string,
+  // the name of the resource, for example "malloc".
+  // The following arguments must be argument indexes, the arguments must be
+  // of integer type for Returns, otherwise of pointer type.
+  // The difference between Holds and Takes is that a pointer may still be used
+  // after being held.  free() should be __attribute((ownership_takes)), whereas
+  // a list append function may well be __attribute((ownership_holds)).
+
+  if (!AL.getParameterName()) {
+    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
+        << AL.getName()->getName() << 1;
+    return;
+  }
+  // Figure out our Kind, and check arguments while we're at it.
+  OwnershipAttr::OwnershipKind K;
+  switch (AL.getKind()) {
+  case AttributeList::AT_ownership_takes:
+    K = OwnershipAttr::Takes;
+    if (AL.getNumArgs() < 1) {
+      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
+      return;
+    }
+    break;
+  case AttributeList::AT_ownership_holds:
+    K = OwnershipAttr::Holds;
+    if (AL.getNumArgs() < 1) {
+      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
+      return;
+    }
+    break;
+  case AttributeList::AT_ownership_returns:
+    K = OwnershipAttr::Returns;
+    if (AL.getNumArgs() > 1) {
+      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
+          << AL.getNumArgs() + 1;
+      return;
+    }
+    break;
+  default:
+    // This should never happen given how we are called.
+    llvm_unreachable("Unknown ownership attribute");
+  }
+
+  if (!isFunction(d) || !hasFunctionProto(d)) {
+    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL.getName()
+        << 0 /*function*/;
+    return;
+  }
+
+  unsigned NumArgs = getFunctionOrMethodNumArgs(d);
+
+  llvm::StringRef Module = AL.getParameterName()->getName();
+
+  // Normalize the argument, __foo__ becomes foo.
+  if (Module.startswith("__") && Module.endswith("__"))
+    Module = Module.substr(2, Module.size() - 4);
+
+  llvm::SmallVector<unsigned, 10> OwnershipArgs;
+
+  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
+       ++I) {
+
+    Expr *IdxExpr = static_cast<Expr *>(*I);
+    llvm::APSInt ArgNum(32);
+    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
+        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
+      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
+          << AL.getName()->getName() << IdxExpr->getSourceRange();
+      continue;
+    }
+
+    unsigned x = (unsigned) ArgNum.getZExtValue();
+
+    if (x > NumArgs || x < 1) {
+      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
+          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
+      continue;
+    }
+    --x;
+    switch (K) {
+    case OwnershipAttr::Takes:
+    case OwnershipAttr::Holds: {
+      // 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(AL.getLoc(), diag::err_ownership_type)
+            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
+            << "pointer"
+            << IdxExpr->getSourceRange();
+        continue;
+      }
+      break;
+    }
+    case OwnershipAttr::Returns: {
+      if (AL.getNumArgs() > 1) {
+          // Is the function argument an integer type?
+          Expr *IdxExpr = static_cast<Expr *>(AL.getArg(0));
+          llvm::APSInt ArgNum(32);
+          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
+              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
+            S.Diag(AL.getLoc(), diag::err_ownership_type)
+                << "ownership_returns" << "integer"
+                << IdxExpr->getSourceRange();
+            return;
+          }
+      }
+      break;
+    }
+    default:
+      llvm_unreachable("Unknown ownership attribute");
+    } // switch
+
+    // Check we don't have a conflict with another ownership attribute.
+    for (specific_attr_iterator<OwnershipAttr>
+          i = d->specific_attr_begin<OwnershipAttr>(),
+          e = d->specific_attr_end<OwnershipAttr>();
+        i != e; ++i) {
+      if ((*i)->getOwnKind() != K) {
+        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
+             I!=E; ++I) {
+          if (x == *I) {
+            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
+                << AL.getName()->getName() << "ownership_*";
+          }
+        }
+      }
+    }
+    OwnershipArgs.push_back(x);
+  }
+
+  unsigned* start = OwnershipArgs.data();
+  unsigned size = OwnershipArgs.size();
+  llvm::array_pod_sort(start, start + size);
+
+  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
+    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
+                                             start, size));
 }
 
 static bool isStaticVarOrStaticFunciton(Decl *D) {
   if (VarDecl *VD = dyn_cast<VarDecl>(D))
-    return VD->getStorageClass() == VarDecl::Static;
+    return VD->getStorageClass() == SC_Static;
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
-    return FD->getStorageClass() == FunctionDecl::Static;
+    return FD->getStorageClass() == SC_Static;
   return false;
 }
 
@@ -358,7 +561,7 @@
     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();
+    dyn_cast<NamedDecl>(d)->getNameAsString();
       return;
     }
   }
@@ -403,10 +606,10 @@
     }
     // 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) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
   }
 
-  d->addAttr(::new (S.Context) WeakRefAttr());
+  d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -428,7 +631,7 @@
 
   // FIXME: check if target symbol exists in current file
 
-  d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
+  d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
 }
 
 static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
@@ -445,7 +648,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) AlwaysInlineAttr());
+  d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -458,7 +661,7 @@
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
     QualType RetTy = FD->getResultType();
     if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
-      d->addAttr(::new (S.Context) MallocAttr());
+      d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
       return;
     }
   }
@@ -466,46 +669,75 @@
   S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
 }
 
-static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
-                                     Sema &S) {
-  // check the attribute arguments.
+static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
+  assert(Attr.isInvalid() == false);
+  d->addAttr(::new (S.Context) NoReturnAttr(Attr.getLoc(), S.Context));
+}
+
+static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
+                                       Sema &S) {
+  
+  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
+  // because 'analyzer_noreturn' does not impact the type.
+  
   if (Attr.getNumArgs() != 0) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
-    return false;
+    return;
   }
-
+  
   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;
+             : diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 0 /*function*/;
+      return;
     }
   }
-
-  return true;
+  
+  d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
 }
 
-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,
+// PS3 PPU-specific.
+static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
                                        Sema &S) {
-  if (HandleCommonNoReturnAttr(d, Attr, S))
-    d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
+/*
+  Returning a Vector Class in Registers
+  
+  According to the PPU ABI specifications, a class with a single member of vector type is returned in
+  memory when used as the return value of a function. This results in inefficient code when implementing
+  vector classes. To return the value in a single vector register, add the vecreturn attribute to the class
+  definition. This attribute is also applicable to struct types.
+  
+  Example:
+  
+  struct Vector
+  {
+    __vector float xyzw;
+  } __attribute__((vecreturn));
+  
+  Vector Add(Vector lhs, Vector rhs)
+  {
+    Vector result;
+    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
+    return result; // This will be returned in a register
+  }
+*/
+  if (!isa<CXXRecordDecl>(d)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << 9 /*class*/;
+    return;
+  }
+
+  if (d->getAttr<VecReturnAttr>()) {
+    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
+    return;
+  }
+
+  d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -531,7 +763,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) UnusedAttr());
+  d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -552,7 +784,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) UsedAttr());
+  d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -567,7 +799,8 @@
   if (Attr.getNumArgs() > 0) {
     Expr *E = static_cast<Expr *>(Attr.getArg(0));
     llvm::APSInt Idx(32);
-    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
+    if (E->isTypeDependent() || E->isValueDependent() ||
+        !E->isIntegerConstantExpr(Idx, S.Context)) {
       S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
         << "constructor" << 1 << E->getSourceRange();
       return;
@@ -581,7 +814,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) ConstructorAttr(priority));
+  d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, priority));
 }
 
 static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -596,7 +829,8 @@
   if (Attr.getNumArgs() > 0) {
     Expr *E = static_cast<Expr *>(Attr.getArg(0));
     llvm::APSInt Idx(32);
-    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
+    if (E->isTypeDependent() || E->isValueDependent() ||
+        !E->isIntegerConstantExpr(Idx, S.Context)) {
       S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
         << "destructor" << 1 << E->getSourceRange();
       return;
@@ -610,7 +844,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) DestructorAttr(priority));
+  d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, priority));
 }
 
 static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -620,7 +854,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) DeprecatedAttr());
+  d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -630,7 +864,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) UnavailableAttr());
+  d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -651,22 +885,22 @@
   }
 
   llvm::StringRef TypeStr = Str->getString();
-  VisibilityAttr::VisibilityTypes type;
+  VisibilityAttr::VisibilityType type;
 
   if (TypeStr == "default")
-    type = VisibilityAttr::DefaultVisibility;
+    type = VisibilityAttr::Default;
   else if (TypeStr == "hidden")
-    type = VisibilityAttr::HiddenVisibility;
+    type = VisibilityAttr::Hidden;
   else if (TypeStr == "internal")
-    type = VisibilityAttr::HiddenVisibility; // FIXME
+    type = VisibilityAttr::Hidden; // FIXME
   else if (TypeStr == "protected")
-    type = VisibilityAttr::ProtectedVisibility;
+    type = VisibilityAttr::Protected;
   else {
     S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
     return;
   }
 
-  d->addAttr(::new (S.Context) VisibilityAttr(type));
+  d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
 }
 
 static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
@@ -682,7 +916,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) ObjCExceptionAttr());
+  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -698,7 +932,7 @@
       return;
     }
   }
-  D->addAttr(::new (S.Context) ObjCNSObjectAttr());
+  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
 }
 
 static void
@@ -713,7 +947,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) OverloadableAttr());
+  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -728,7 +962,7 @@
     return;
   }
 
-  BlocksAttr::BlocksAttrTypes type;
+  BlocksAttr::BlockType type;
   if (Attr.getParameterName()->isStr("byref"))
     type = BlocksAttr::ByRef;
   else {
@@ -737,7 +971,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) BlocksAttr(type));
+  d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
 }
 
 static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -752,7 +986,8 @@
   if (Attr.getNumArgs() > 0) {
     Expr *E = static_cast<Expr *>(Attr.getArg(0));
     llvm::APSInt Idx(32);
-    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
+    if (E->isTypeDependent() || E->isValueDependent() ||
+        !E->isIntegerConstantExpr(Idx, S.Context)) {
       S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
        << "sentinel" << 1 << E->getSourceRange();
       return;
@@ -770,7 +1005,8 @@
   if (Attr.getNumArgs() > 1) {
     Expr *E = static_cast<Expr *>(Attr.getArg(1));
     llvm::APSInt Idx(32);
-    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
+    if (E->isTypeDependent() || E->isValueDependent() ||
+        !E->isIntegerConstantExpr(Idx, S.Context)) {
       S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
         << "sentinel" << 2 << E->getSourceRange();
       return;
@@ -828,7 +1064,7 @@
       << Attr.getName() << 6 /*function, method or block */;
     return;
   }
-  d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
+  d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, nullPos));
 }
 
 static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -856,7 +1092,7 @@
       return;
     }
   
-  D->addAttr(::new (S.Context) WarnUnusedResultAttr());
+  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -880,7 +1116,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) WeakAttr());
+  D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -895,7 +1131,7 @@
   if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
     isDef = (!VD->hasExternalStorage() || VD->getInit());
   } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    isDef = FD->getBody();
+    isDef = FD->hasBody();
   } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
     // We ignore weak import on properties and methods
     return;
@@ -916,7 +1152,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) WeakImportAttr());
+  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
@@ -931,14 +1167,16 @@
   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)) {
+    if (E->isTypeDependent() || E->isValueDependent() ||
+        !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],
+  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
+                                                     WGSize[0], WGSize[1],
                                                      WGSize[2]));
 }
 
@@ -972,7 +1210,7 @@
     return;
   }
   
-  D->addAttr(::new (S.Context) SectionAttr(S.Context, SE->getString()));
+  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, SE->getString()));
 }
 
 
@@ -983,7 +1221,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) NoThrowAttr());
+  d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -993,7 +1231,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) ConstAttr());
+  d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1003,7 +1241,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) PureAttr());
+  d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1061,7 +1299,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) CleanupAttr(FD));
+  d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
 }
 
 /// Handle __attribute__((format_arg((idx)))) attribute based on
@@ -1083,7 +1321,8 @@
   // checks for the 2nd argument
   Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
   llvm::APSInt Idx(32);
-  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
+  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
+      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
     << "format" << 2 << IdxExpr->getSourceRange();
     return;
@@ -1123,7 +1362,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
+  d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, Idx.getZExtValue()));
 }
 
 enum FormatAttrKind {
@@ -1160,6 +1399,54 @@
   return InvalidFormat;
 }
 
+/// Handle __attribute__((init_priority(priority))) attributes based on
+/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
+static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr, 
+                                   Sema &S) {
+  if (!S.getLangOptions().CPlusPlus) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+    return;
+  }
+  
+  if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) {
+    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
+    Attr.setInvalid();
+    return;
+  }
+  QualType T = dyn_cast<VarDecl>(d)->getType();
+  if (S.Context.getAsArrayType(T))
+    T = S.Context.getBaseElementType(T);
+  if (!T->getAs<RecordType>()) {
+    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
+    Attr.setInvalid();
+    return;
+  }
+  
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    Attr.setInvalid();
+    return;
+  }
+  Expr *priorityExpr = static_cast<Expr *>(Attr.getArg(0));
+  
+  llvm::APSInt priority(32);
+  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
+      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
+    << "init_priority" << priorityExpr->getSourceRange();
+    Attr.setInvalid();
+    return;
+  }
+  unsigned prioritynum = priority.getZExtValue();
+  if (prioritynum < 101 || prioritynum > 65535) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
+    <<  priorityExpr->getSourceRange();
+    Attr.setInvalid();
+    return;
+  }
+  d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, prioritynum));
+}
+
 /// 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) {
@@ -1205,7 +1492,8 @@
   // checks for the 2nd argument
   Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
   llvm::APSInt Idx(32);
-  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
+  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
+      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
       << "format" << 2 << IdxExpr->getSourceRange();
     return;
@@ -1268,7 +1556,8 @@
   // check the 3rd argument
   Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
   llvm::APSInt FirstArg(32);
-  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
+  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
+      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
       << "format" << 3 << FirstArgExpr->getSourceRange();
     return;
@@ -1299,7 +1588,8 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) FormatAttr(S.Context, Format, Idx.getZExtValue(),
+  d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
+                                          Idx.getZExtValue(),
                                           FirstArg.getZExtValue()));
 }
 
@@ -1340,9 +1630,10 @@
 
   FieldDecl *FirstField = *Field;
   QualType FirstType = FirstField->getType();
-  if (FirstType->isFloatingType() || FirstType->isVectorType()) {
+  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
     S.Diag(FirstField->getLocation(),
-           diag::warn_transparent_union_attribute_floating);
+           diag::warn_transparent_union_attribute_floating)
+      << FirstType->isVectorType() << FirstType;
     return;
   }
 
@@ -1367,7 +1658,7 @@
     }
   }
 
-  RD->addAttr(::new (S.Context) TransparentUnionAttr());
+  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1385,10 +1676,10 @@
     S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
     return;
   }
-  d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString()));
+  d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, SE->getString()));
 }
 
-static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+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;
@@ -1399,29 +1690,42 @@
   //       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));
+    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
     return;
   }
 
-  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
+  S.AddAlignedAttr(Attr.getLoc(), D, static_cast<Expr *>(Attr.getArg(0)));
+}
+
+void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
+  if (E->isTypeDependent() || E->isValueDependent()) {
+    // Save dependent expressions in the AST to be instantiated.
+    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
+    return;
+  }
+
+  // FIXME: Cache the number on the Attr object?
   llvm::APSInt Alignment(32);
-  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
-      << "aligned" << alignmentExpr->getSourceRange();
+  if (!E->isIntegerConstantExpr(Alignment, Context)) {
+    Diag(AttrLoc, diag::err_attribute_argument_not_int)
+      << "aligned" << E->getSourceRange();
     return;
   }
   if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two)
-      << alignmentExpr->getSourceRange();
+    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
+      << E->getSourceRange();
     return;
   }
 
-  d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
+  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
+}
+
+void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
+  // FIXME: Cache the number on the Attr object if non-dependent?
+  // FIXME: Perform checking of type validity
+  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
+  return;
 }
 
 /// HandleModeAttr - This attribute modifies the width of a decl with primitive
@@ -1502,7 +1806,7 @@
   if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
     S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
   else if (IntegerMode) {
-    if (!OldTy->isIntegralType())
+    if (!OldTy->isIntegralOrEnumerationType())
       S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
   } else if (ComplexMode) {
     if (!OldTy->isComplexType())
@@ -1608,7 +1912,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) NoDebugAttr());
+  d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1624,7 +1928,24 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) NoInlineAttr());
+  d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
+}
+
+static void HandleNoInstrumentFunctionAttr(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) NoInstrumentFunctionAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1646,7 +1967,30 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) GNUInlineAttr());
+  d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
+}
+
+static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
+  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
+  assert(Attr.isInvalid() == false);
+
+  switch (Attr.getKind()) {
+  case AttributeList::AT_fastcall:
+    d->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
+    return;
+  case AttributeList::AT_stdcall:
+    d->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
+    return;
+  case AttributeList::AT_thiscall:
+    d->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
+  case AttributeList::AT_cdecl:
+    d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
+    return;
+  default:
+    llvm_unreachable("unexpected attribute kind");
+    return;
+  }
 }
 
 static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1664,7 +2008,8 @@
 
   Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
   llvm::APSInt NumParams(32);
-  if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
+  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
+      !NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
       << "regparm" << NumParamsExpr->getSourceRange();
     return;
@@ -1682,7 +2027,8 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
+  d->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context,
+                                           NumParams.getZExtValue()));
 }
 
 static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1708,7 +2054,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) FinalAttr());
+  d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context));
 }
 
 //===----------------------------------------------------------------------===//
@@ -1734,7 +2080,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) BaseCheckAttr());
+  d->addAttr(::new (S.Context) BaseCheckAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1759,7 +2105,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) HidingAttr());
+  d->addAttr(::new (S.Context) HidingAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1784,7 +2130,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) OverrideAttr());
+  d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context));
 }
 
 //===----------------------------------------------------------------------===//
@@ -1820,16 +2166,16 @@
       assert(0 && "invalid ownership attribute");
       return;
     case AttributeList::AT_cf_returns_not_retained:
-      d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr());
+      d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
       return;
     case AttributeList::AT_ns_returns_not_retained:
-      d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr());
+      d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
       return;
     case AttributeList::AT_cf_returns_retained:
-      d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
+      d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), S.Context));
       return;
     case AttributeList::AT_ns_returns_retained:
-      d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
+      d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), S.Context));
       return;
   };
 }
@@ -1849,12 +2195,17 @@
 /// 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.isInvalid())
+    return;
+
   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_IBOutlet:          HandleIBOutlet(D, Attr, S); break;
+  case AttributeList::AT_IBOutletCollection:
+      HandleIBOutletCollection(D, Attr, S); break;
   case AttributeList::AT_address_space:
   case AttributeList::AT_objc_gc:
   case AttributeList::AT_vector_size:
@@ -1885,9 +2236,14 @@
   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_ownership_returns:
+  case AttributeList::AT_ownership_takes:
+  case AttributeList::AT_ownership_holds:
+      HandleOwnershipAttr     (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;
+  case AttributeList::AT_vecreturn:   HandleVecReturnAttr   (D, Attr, S); break;
 
   // Checker-specific.
   case AttributeList::AT_ns_returns_not_retained:
@@ -1899,6 +2255,9 @@
   case AttributeList::AT_reqd_wg_size:
     HandleReqdWorkGroupSize(D, Attr, S); break;
 
+  case AttributeList::AT_init_priority: 
+      HandleInitPriorityAttr(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;
@@ -1927,19 +2286,23 @@
   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_no_instrument_function:  // Interacts with -pg.
+    HandleNoInstrumentFunctionAttr(D, Attr, S);
+    break;
   case AttributeList::AT_stdcall:
   case AttributeList::AT_cdecl:
   case AttributeList::AT_fastcall:
-    // These are all treated as type attributes.
+  case AttributeList::AT_thiscall:
+    HandleCallConvAttr(D, Attr, S);
     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();
+      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
+        << Attr.getName();
     break;
   }
 }
@@ -1956,7 +2319,7 @@
   // 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();
+    dyn_cast<NamedDecl>(D)->getNameAsString();
     return;
   }
 }
@@ -1996,8 +2359,9 @@
   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());
+    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
+                                            NDId->getName()));
+    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
     WeakTopLevelDecl.push_back(NewD);
     // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
     // to insert Decl at TU scope, sorry.
@@ -2006,7 +2370,7 @@
     PushOnScopeChains(NewD, S);
     CurContext = SavedContext;
   } else { // just add weak to existing
-    ND->addAttr(::new (Context) WeakAttr());
+    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
   }
 }
 
@@ -2048,12 +2412,12 @@
 ///
 /// The state token we use is the start index of this scope
 /// on the warning stack.
-Action::ParsingDeclStackState Sema::PushParsingDeclaration() {
+Sema::ParsingDeclStackState Sema::PushParsingDeclaration() {
   ParsingDeclDepth++;
   return (ParsingDeclStackState) DelayedDiagnostics.size();
 }
 
-void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) {
+void Sema::PopParsingDeclaration(ParsingDeclStackState S, Decl *D) {
   assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack");
   ParsingDeclDepth--;
 
@@ -2068,7 +2432,6 @@
 
   // 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:
@@ -2107,7 +2470,7 @@
   return false;
 }
 
-void Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD,
+void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
                                          Decl *Ctx) {
   if (isDeclDeprecated(Ctx))
     return;
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index f6ff400..35920c2 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -11,21 +11,25 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/CXXFieldCollector.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/RecordLayout.h"
+#include "clang/AST/CharUnits.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclVisitor.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/StmtVisitor.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/Sema/DeclSpec.h"
+#include "clang/Sema/ParsedTemplate.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/STLExtras.h"
 #include <map>
 #include <set>
@@ -107,7 +111,7 @@
 }
 
 bool
-Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
+Sema::SetParamDefaultArgument(ParmVarDecl *Param, Expr *Arg,
                               SourceLocation EqualLoc) {
   if (RequireCompleteType(Param->getLocation(), Param->getType(),
                           diag::err_typecheck_decl_incomplete_type)) {
@@ -115,8 +119,6 @@
     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
@@ -127,8 +129,8 @@
   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));
+  ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                            MultiExprArg(*this, &Arg, 1));
   if (Result.isInvalid())
     return true;
   Arg = Result.takeAs<Expr>();
@@ -138,8 +140,6 @@
   // Okay: add the default argument to the parameter
   Param->setDefaultArg(Arg);
 
-  DefaultArg.release();
-
   return false;
 }
 
@@ -147,16 +147,14 @@
 /// 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())
+Sema::ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc,
+                                Expr *DefaultArg) {
+  if (!param || !DefaultArg)
     return;
 
-  ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
+  ParmVarDecl *Param = cast<ParmVarDecl>(param);
   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)
@@ -166,26 +164,26 @@
   }
 
   // Check that the default argument is well-formed
-  CheckDefaultArgumentVisitor DefaultArgChecker(DefaultArg.get(), this);
-  if (DefaultArgChecker.Visit(DefaultArg.get())) {
+  CheckDefaultArgumentVisitor DefaultArgChecker(DefaultArg, this);
+  if (DefaultArgChecker.Visit(DefaultArg)) {
     Param->setInvalidDecl();
     return;
   }
 
-  SetParamDefaultArgument(Param, move(DefaultArg), EqualLoc);
+  SetParamDefaultArgument(Param, 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,
+void Sema::ActOnParamUnparsedDefaultArgument(Decl *param,
                                              SourceLocation EqualLoc,
                                              SourceLocation ArgLoc) {
   if (!param)
     return;
 
-  ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
+  ParmVarDecl *Param = cast<ParmVarDecl>(param);
   if (Param)
     Param->setUnparsedDefaultArg();
 
@@ -194,11 +192,11 @@
 
 /// ActOnParamDefaultArgumentError - Parsing or semantic analysis of
 /// the default argument for the parameter param failed.
-void Sema::ActOnParamDefaultArgumentError(DeclPtrTy param) {
+void Sema::ActOnParamDefaultArgumentError(Decl *param) {
   if (!param)
     return;
 
-  ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
+  ParmVarDecl *Param = cast<ParmVarDecl>(param);
 
   Param->setInvalidDecl();
 
@@ -223,7 +221,7 @@
     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>());
+          cast<ParmVarDecl>(chunk.Fun.ArgInfo[argIdx].Param);
         if (Param->hasUnparsedDefaultArg()) {
           CachedTokens *Toks = chunk.Fun.ArgInfo[argIdx].DefaultArgTokens;
           Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc)
@@ -297,13 +295,15 @@
         << OldParam->getDefaultArgRange();
       Invalid = true;
     } else if (OldParam->hasDefaultArg()) {
-      // Merge the old default argument into the new parameter
+      // Merge the old default argument into the new parameter.
+      // It's important to use getInit() here;  getDefaultArg()
+      // strips off any top-level CXXExprWithTemporaries.
       NewParam->setHasInheritedDefaultArg();
       if (OldParam->hasUninstantiatedDefaultArg())
         NewParam->setUninstantiatedDefaultArg(
                                       OldParam->getUninstantiatedDefaultArg());
       else
-        NewParam->setDefaultArg(OldParam->getDefaultArg());
+        NewParam->setDefaultArg(OldParam->getInit());
     } else if (NewParam->hasDefaultArg()) {
       if (New->getDescribedFunctionTemplate()) {
         // Paragraph 4, quoted above, only applies to non-template functions.
@@ -409,8 +409,6 @@
     for (p = 0; p <= LastMissingDefaultArg; ++p) {
       ParmVarDecl *Param = FD->getParamDecl(p);
       if (Param->hasDefaultArg()) {
-        if (!Param->hasUnparsedDefaultArg())
-          Param->getDefaultArg()->Destroy(Context);
         Param->setDefaultArg(0);
       }
     }
@@ -446,8 +444,9 @@
 Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
                          SourceRange SpecifierRange,
                          bool Virtual, AccessSpecifier Access,
-                         QualType BaseType,
-                         SourceLocation BaseLoc) {
+                         TypeSourceInfo *TInfo) {
+  QualType BaseType = TInfo->getType();
+
   // C++ [class.union]p1:
   //   A union shall not have base classes.
   if (Class->isUnion()) {
@@ -458,8 +457,10 @@
 
   if (BaseType->isDependentType())
     return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual,
-                                Class->getTagKind() == RecordDecl::TK_class,
-                                Access, BaseType);
+                                          Class->getTagKind() == TTK_Class,
+                                          Access, TInfo);
+
+  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
 
   // Base specifiers must be record types.
   if (!BaseType->isRecordType()) {
@@ -479,8 +480,10 @@
   //   defined class.
   if (RequireCompleteType(BaseLoc, BaseType,
                           PDiag(diag::err_incomplete_base_class)
-                            << SpecifierRange))
+                            << SpecifierRange)) {
+    Class->setInvalidDecl();
     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();
@@ -499,12 +502,14 @@
   }
 
   SetClassDeclAttributesFromBase(Class, CXXBaseDecl, Virtual);
+
+  if (BaseDecl->isInvalidDecl())
+    Class->setInvalidDecl();
   
   // Create the base specifier.
-  // FIXME: Allocate via ASTContext?
   return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual,
-                              Class->getTagKind() == RecordDecl::TK_class,
-                              Access, BaseType);
+                                        Class->getTagKind() == TTK_Class,
+                                        Access, TInfo);
 }
 
 void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
@@ -579,22 +584,22 @@
 /// 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,
+BaseResult
+Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange,
                          bool Virtual, AccessSpecifier Access,
-                         TypeTy *basetype, SourceLocation BaseLoc) {
+                         ParsedType basetype, SourceLocation BaseLoc) {
   if (!classdecl)
     return true;
 
   AdjustDeclIfTemplate(classdecl);
-  CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(classdecl.getAs<Decl>());
+  CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(classdecl);
   if (!Class)
     return true;
 
-  QualType BaseType = GetTypeFromParser(basetype);
+  TypeSourceInfo *TInfo = 0;
+  GetTypeFromParser(basetype, &TInfo);
   if (CXXBaseSpecifier *BaseSpec = CheckBaseSpecifier(Class, SpecifierRange,
-                                                      Virtual, Access,
-                                                      BaseType, BaseLoc))
+                                                      Virtual, Access, TInfo))
     return BaseSpec;
 
   return true;
@@ -620,7 +625,13 @@
     QualType NewBaseType
       = Context.getCanonicalType(Bases[idx]->getType());
     NewBaseType = NewBaseType.getLocalUnqualifiedType();
-
+    if (!Class->hasObjectMember()) {
+      if (const RecordType *FDTTy = 
+            NewBaseType.getTypePtr()->getAs<RecordType>())
+        if (FDTTy->getDecl()->hasObjectMember())
+          Class->setHasObjectMember(true);
+    }
+    
     if (KnownBaseTypes[NewBaseType]) {
       // C++ [class.mi]p3:
       //   A class shall not be specified as a direct base class of a
@@ -656,13 +667,13 @@
 /// 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,
+void Sema::ActOnBaseSpecifiers(Decl *ClassDecl, BaseTy **Bases,
                                unsigned NumBases) {
   if (!ClassDecl || !Bases || !NumBases)
     return;
 
   AdjustDeclIfTemplate(ClassDecl);
-  AttachBaseSpecifiers(cast<CXXRecordDecl>(ClassDecl.getAs<Decl>()),
+  AttachBaseSpecifiers(cast<CXXRecordDecl>(ClassDecl),
                        (CXXBaseSpecifier**)(Bases), NumBases);
 }
 
@@ -711,7 +722,7 @@
 }
 
 void Sema::BuildBasePathArray(const CXXBasePaths &Paths, 
-                              CXXBaseSpecifierArray &BasePathArray) {
+                              CXXCastPath &BasePathArray) {
   assert(BasePathArray.empty() && "Base path array must be empty!");
   assert(Paths.isRecordingPaths() && "Must record paths!");
   
@@ -730,7 +741,19 @@
 
   // Now add all bases.
   for (unsigned I = Start, E = Path.size(); I != E; ++I)
-    BasePathArray.push_back(Path[I].Base);
+    BasePathArray.push_back(const_cast<CXXBaseSpecifier*>(Path[I].Base));
+}
+
+/// \brief Determine whether the given base path includes a virtual
+/// base class.
+bool Sema::BasePathInvolvesVirtualBase(const CXXCastPath &BasePath) {
+  for (CXXCastPath::const_iterator B = BasePath.begin(), 
+                                BEnd = BasePath.end();
+       B != BEnd; ++B)
+    if ((*B)->isVirtual())
+      return true;
+
+  return false;
 }
 
 /// CheckDerivedToBaseConversion - Check whether the Derived-to-Base
@@ -747,7 +770,7 @@
                                    unsigned AmbigiousBaseConvID,
                                    SourceLocation Loc, SourceRange Range,
                                    DeclarationName Name,
-                                   CXXBaseSpecifierArray *BasePath) {
+                                   CXXCastPath *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
@@ -805,7 +828,7 @@
 bool
 Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
                                    SourceLocation Loc, SourceRange Range,
-                                   CXXBaseSpecifierArray *BasePath,
+                                   CXXCastPath *BasePath,
                                    bool IgnoreAccess) {
   return CheckDerivedToBaseConversion(Derived, Base,
                                       IgnoreAccess ? 0
@@ -851,25 +874,45 @@
 // C++ class member Handling
 //===----------------------------------------------------------------------===//
 
+/// ActOnAccessSpecifier - Parsed an access specifier followed by a colon.
+Decl *Sema::ActOnAccessSpecifier(AccessSpecifier Access,
+                                 SourceLocation ASLoc,
+                                 SourceLocation ColonLoc) {
+  assert(Access != AS_none && "Invalid kind for syntactic access specifier!");
+  AccessSpecDecl *ASDecl = AccessSpecDecl::Create(Context, Access, CurContext,
+                                                  ASLoc, ColonLoc);
+  CurContext->addHiddenDecl(ASDecl);
+  return ASDecl;
+}
+
 /// 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
+Decl *
 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);
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
+  SourceLocation Loc = NameInfo.getLoc();
   Expr *BitWidth = static_cast<Expr*>(BW);
   Expr *Init = static_cast<Expr*>(InitExpr);
-  SourceLocation Loc = D.getIdentifierLoc();
 
-  bool isFunc = D.isFunctionDeclarator();
-
+  assert(isa<CXXRecordDecl>(CurContext));
   assert(!DS.isFriendSpecified());
 
+  bool isFunc = false;
+  if (D.isFunctionDeclarator())
+    isFunc = true;
+  else if (D.getNumTypeObjects() == 0 &&
+           D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typename) {
+    QualType TDType = GetTypeFromParser(DS.getRepAsType());
+    isFunc = TDType->isFunctionType();
+  }
+
   // 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
@@ -891,22 +934,6 @@
         // 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:
@@ -918,18 +945,6 @@
       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);
@@ -941,11 +956,10 @@
                          AS);
     assert(Member && "HandleField never returns null");
   } else {
-    Member = HandleDeclarator(S, D, move(TemplateParameterLists), IsDefinition)
-               .getAs<Decl>();
+    Member = HandleDeclarator(S, D, move(TemplateParameterLists), IsDefinition);
     if (!Member) {
       if (BitWidth) DeleteExpr(BitWidth);
-      return DeclPtrTy();
+      return 0;
     }
 
     // Non-instance-fields can't have a bitfield.
@@ -985,15 +999,15 @@
   assert((Name || isInstField) && "No identifier for non-field ?");
 
   if (Init)
-    AddInitializerToDecl(DeclPtrTy::make(Member), ExprArg(*this, Init), false);
+    AddInitializerToDecl(Member, Init, false);
   if (Deleted) // FIXME: Source location is not very good.
-    SetDeclDeleted(DeclPtrTy::make(Member), D.getSourceRange().getBegin());
+    SetDeclDeleted(Member, D.getSourceRange().getBegin());
 
   if (isInstField) {
     FieldCollector->Add(cast<FieldDecl>(Member));
-    return DeclPtrTy();
+    return 0;
   }
-  return DeclPtrTy::make(Member);
+  return Member;
 }
 
 /// \brief Find the direct and/or virtual base specifiers that
@@ -1042,12 +1056,12 @@
 }
 
 /// ActOnMemInitializer - Handle a C++ member initializer.
-Sema::MemInitResult
-Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
+MemInitResult
+Sema::ActOnMemInitializer(Decl *ConstructorD,
                           Scope *S,
                           CXXScopeSpec &SS,
                           IdentifierInfo *MemberOrBase,
-                          TypeTy *TemplateTypeTy,
+                          ParsedType TemplateTypeTy,
                           SourceLocation IdLoc,
                           SourceLocation LParenLoc,
                           ExprTy **Args, unsigned NumArgs,
@@ -1059,7 +1073,7 @@
   AdjustDeclIfTemplate(ConstructorD);
 
   CXXConstructorDecl *Constructor
-    = dyn_cast<CXXConstructorDecl>(ConstructorD.getAs<Decl>());
+    = dyn_cast<CXXConstructorDecl>(ConstructorD);
   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
@@ -1122,11 +1136,13 @@
           // specialization, we take it as a type name.
           BaseType = CheckTypenameType(ETK_None,
                                        (NestedNameSpecifier *)SS.getScopeRep(),
-                                       *MemberOrBase, SS.getRange());
+                                       *MemberOrBase, SourceLocation(),
+                                       SS.getRange(), IdLoc);
           if (BaseType.isNull())
             return true;
 
           R.clear();
+          R.setLookupName(MemberOrBase);
         }
       }
 
@@ -1189,7 +1205,7 @@
           static_cast<NestedNameSpecifier*>(SS.getScopeRep());
 
         // FIXME: preserve source range information
-        BaseType = Context.getQualifiedNameType(Qualifier, BaseType);
+        BaseType = Context.getElaboratedType(ETK_None, Qualifier, BaseType);
       }
     }
   }
@@ -1205,18 +1221,25 @@
 /// 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();
+static bool InitExprContainsUninitializedFields(const Stmt *S,
+                                                const FieldDecl *LhsField,
+                                                SourceLocation *L) {
+  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.
+    return false;
+  }
+  if (const MemberExpr *ME = dyn_cast<MemberExpr>(S)) {
+    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();
+      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;
@@ -1227,24 +1250,19 @@
       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.
+  for (Stmt::const_child_iterator it = S->child_begin(), e = S->child_end();
+       it != e; ++it) {
+    if (!*it) {
+      // An expression such as 'member(arg ?: "")' may trigger this.
       continue;
     }
-    found = InitExprContainsUninitializedFields(*it, LhsField, L);
+    if (InitExprContainsUninitializedFields(*it, LhsField, L))
+      return true;
   }
-  return found;
+  return false;
 }
 
-Sema::MemInitResult
+MemInitResult
 Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
                              unsigned NumArgs, SourceLocation IdLoc,
                              SourceLocation LParenLoc,
@@ -1270,15 +1288,12 @@
   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) {
+  if (Member->getType()->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));
+    Expr *Init
+      = 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
@@ -1289,7 +1304,7 @@
     
     return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
                                                     LParenLoc, 
-                                                    Init.takeAs<Expr>(),
+                                                    Init,
                                                     RParenLoc);
     
   }
@@ -1305,16 +1320,16 @@
   
   InitializationSequence InitSeq(*this, MemberEntity, Kind, Args, NumArgs);
   
-  OwningExprResult MemberInit =
+  ExprResult MemberInit =
     InitSeq.Perform(*this, MemberEntity, Kind, 
-                    MultiExprArg(*this, (void**)Args, NumArgs), 0);
+                    MultiExprArg(*this, 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));
+  MemberInit = MaybeCreateCXXExprWithTemporaries(MemberInit.get());
   if (MemberInit.isInvalid())
     return true;
   
@@ -1330,22 +1345,21 @@
     for (unsigned I = 0; I != NumArgs; ++I)
       Args[I]->Retain();
 
-    OwningExprResult Init
-      = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
-                                          RParenLoc));
+    Expr *Init = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
+                                             RParenLoc);
     return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
                                                     LParenLoc, 
-                                                    Init.takeAs<Expr>(),
+                                                    Init,
                                                     RParenLoc);
   }
 
   return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
                                                   LParenLoc, 
-                                                  MemberInit.takeAs<Expr>(),
+                                                  MemberInit.get(),
                                                   RParenLoc);
 }
 
-Sema::MemInitResult
+MemInitResult
 Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
                            Expr **Args, unsigned NumArgs, 
                            SourceLocation LParenLoc, SourceLocation RParenLoc, 
@@ -1354,11 +1368,51 @@
   for (unsigned i = 0; i < NumArgs; i++)
     HasDependentArg |= Args[i]->isTypeDependent();
 
-  SourceLocation BaseLoc = BaseTInfo->getTypeLoc().getSourceRange().getBegin();
-  if (BaseType->isDependentType() || HasDependentArg) {
+  SourceLocation BaseLoc
+    = BaseTInfo->getTypeLoc().getLocalSourceRange().getBegin();
+  
+  if (!BaseType->isDependentType() && !BaseType->isRecordType())
+    return Diag(BaseLoc, diag::err_base_init_does_not_name_class)
+             << BaseType << BaseTInfo->getTypeLoc().getLocalSourceRange();
+
+  // 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.
+  bool Dependent = BaseType->isDependentType() || HasDependentArg;
+
+  // Check for direct and virtual base classes.
+  const CXXBaseSpecifier *DirectBaseSpec = 0;
+  const CXXBaseSpecifier *VirtualBaseSpec = 0;
+  if (!Dependent) { 
+    FindBaseInitializer(*this, ClassDecl, BaseType, DirectBaseSpec, 
+                        VirtualBaseSpec);
+
+    // C++ [base.class.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.
+    if (!DirectBaseSpec && !VirtualBaseSpec) {
+      // If the class has any dependent bases, then it's possible that
+      // one of those types will resolve to the same type as
+      // BaseType. Therefore, just treat this as a dependent base
+      // class initialization.  FIXME: Should we try to check the
+      // initialization anyway? It seems odd.
+      if (ClassDecl->hasAnyDependentBases())
+        Dependent = true;
+      else
+        return Diag(BaseLoc, diag::err_not_direct_base_or_virtual)
+          << BaseType << Context.getTypeDeclType(ClassDecl)
+          << BaseTInfo->getTypeLoc().getLocalSourceRange();
+    }
+  }
+
+  if (Dependent) {
     // Can't check initialization for a base of dependent type or when
     // any of the arguments are type-dependent expressions.
-    OwningExprResult BaseInit
+    ExprResult BaseInit
       = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
                                           RParenLoc));
 
@@ -1375,23 +1429,6 @@
                                                     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
@@ -1399,15 +1436,7 @@
   //   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();
+      << BaseType << BaseTInfo->getTypeLoc().getLocalSourceRange();
 
   CXXBaseSpecifier *BaseSpec
     = const_cast<CXXBaseSpecifier *>(DirectBaseSpec);
@@ -1422,16 +1451,16 @@
   
   InitializationSequence InitSeq(*this, BaseEntity, Kind, Args, NumArgs);
   
-  OwningExprResult BaseInit =
+  ExprResult BaseInit =
     InitSeq.Perform(*this, BaseEntity, Kind, 
-                    MultiExprArg(*this, (void**)Args, NumArgs), 0);
+                    MultiExprArg(*this, 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));
+  BaseInit = MaybeCreateCXXExprWithTemporaries(BaseInit.get());
   if (BaseInit.isInvalid())
     return true;
 
@@ -1447,7 +1476,7 @@
     for (unsigned I = 0; I != NumArgs; ++I)
       Args[I]->Retain();
 
-    OwningExprResult Init
+    ExprResult Init
       = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
                                           RParenLoc));
     return new (Context) CXXBaseOrMemberInitializer(Context, BaseTInfo,
@@ -1482,7 +1511,7 @@
     = InitializedEntity::InitializeBase(SemaRef.Context, BaseSpec,
                                         IsInheritedVirtualBase);
 
-  Sema::OwningExprResult BaseInit(SemaRef);
+  ExprResult BaseInit;
   
   switch (ImplicitInitKind) {
   case IIK_Default: {
@@ -1490,7 +1519,7 @@
       = InitializationKind::CreateDefault(Constructor->getLocation());
     InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 0, 0);
     BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind,
-                               Sema::MultiExprArg(SemaRef, 0, 0));
+                               MultiExprArg(SemaRef, 0, 0));
     break;
   }
 
@@ -1500,13 +1529,18 @@
     
     Expr *CopyCtorArg = 
       DeclRefExpr::Create(SemaRef.Context, 0, SourceRange(), Param, 
-                          SourceLocation(), ParamType, 0);
+                          Constructor->getLocation(), ParamType, 0);
     
     // Cast to the base class to avoid ambiguities.
-    SemaRef.ImpCastExprToType(CopyCtorArg, BaseSpec->getType(), 
-                              CastExpr::CK_UncheckedDerivedToBase,
-                              /*isLvalue=*/true, 
-                              CXXBaseSpecifierArray(BaseSpec));
+    QualType ArgTy = 
+      SemaRef.Context.getQualifiedType(BaseSpec->getType().getUnqualifiedType(), 
+                                       ParamType.getQualifiers());
+
+    CXXCastPath BasePath;
+    BasePath.push_back(BaseSpec);
+    SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy,
+                              CK_UncheckedDerivedToBase,
+                              VK_LValue, &BasePath);
 
     InitializationKind InitKind
       = InitializationKind::CreateDirect(Constructor->getLocation(),
@@ -1514,16 +1548,18 @@
     InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 
                                    &CopyCtorArg, 1);
     BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind,
-                               Sema::MultiExprArg(SemaRef, 
-                                                  (void**)&CopyCtorArg, 1));
+                               MultiExprArg(&CopyCtorArg, 1));
     break;
   }
 
   case IIK_Move:
     assert(false && "Unhandled initializer kind!");
   }
+
+  if (BaseInit.isInvalid())
+    return true;
       
-  BaseInit = SemaRef.MaybeCreateCXXExprWithTemporaries(move(BaseInit));
+  BaseInit = SemaRef.MaybeCreateCXXExprWithTemporaries(BaseInit.get());
   if (BaseInit.isInvalid())
     return true;
         
@@ -1544,37 +1580,108 @@
                                ImplicitInitializerKind ImplicitInitKind,
                                FieldDecl *Field,
                                CXXBaseOrMemberInitializer *&CXXMemberInit) {
+  if (Field->isInvalidDecl())
+    return true;
+
+  SourceLocation Loc = Constructor->getLocation();
+
   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())
+                          Loc, ParamType, 0);
+
+    // Build a reference to this field within the parameter.
+    CXXScopeSpec SS;
+    LookupResult MemberLookup(SemaRef, Field->getDeclName(), Loc,
+                              Sema::LookupMemberName);
+    MemberLookup.addDecl(Field, AS_public);
+    MemberLookup.resolveKind();
+    ExprResult CopyCtorArg 
+      = SemaRef.BuildMemberReferenceExpr(MemberExprBase,
+                                         ParamType, Loc,
+                                         /*IsArrow=*/false,
+                                         SS,
+                                         /*FirstQualifierInScope=*/0,
+                                         MemberLookup,
+                                         /*TemplateArgs=*/0);    
+    if (CopyCtorArg.isInvalid())
       return true;
     
-    CXXMemberInit = 0;
+    // When the field we are copying is an array, create index variables for 
+    // each dimension of the array. We use these index variables to subscript
+    // the source array, and other clients (e.g., CodeGen) will perform the
+    // necessary iteration with these index variables.
+    llvm::SmallVector<VarDecl *, 4> IndexVariables;
+    QualType BaseType = Field->getType();
+    QualType SizeType = SemaRef.Context.getSizeType();
+    while (const ConstantArrayType *Array
+                          = SemaRef.Context.getAsConstantArrayType(BaseType)) {
+      // Create the iteration variable for this array index.
+      IdentifierInfo *IterationVarName = 0;
+      {
+        llvm::SmallString<8> Str;
+        llvm::raw_svector_ostream OS(Str);
+        OS << "__i" << IndexVariables.size();
+        IterationVarName = &SemaRef.Context.Idents.get(OS.str());
+      }
+      VarDecl *IterationVar
+        = VarDecl::Create(SemaRef.Context, SemaRef.CurContext, Loc,
+                          IterationVarName, SizeType,
+                        SemaRef.Context.getTrivialTypeSourceInfo(SizeType, Loc),
+                          SC_None, SC_None);
+      IndexVariables.push_back(IterationVar);
+      
+      // Create a reference to the iteration variable.
+      ExprResult IterationVarRef
+        = SemaRef.BuildDeclRefExpr(IterationVar, SizeType, Loc);
+      assert(!IterationVarRef.isInvalid() &&
+             "Reference to invented variable cannot fail!");
+      
+      // Subscript the array with this iteration variable.
+      CopyCtorArg = SemaRef.CreateBuiltinArraySubscriptExpr(CopyCtorArg.take(),
+                                                            Loc,
+                                                        IterationVarRef.take(),
+                                                            Loc);
+      if (CopyCtorArg.isInvalid())
+        return true;
+      
+      BaseType = Array->getElementType();
+    }
+    
+    // Construct the entity that we will be initializing. For an array, this
+    // will be first element in the array, which may require several levels
+    // of array-subscript entities. 
+    llvm::SmallVector<InitializedEntity, 4> Entities;
+    Entities.reserve(1 + IndexVariables.size());
+    Entities.push_back(InitializedEntity::InitializeMember(Field));
+    for (unsigned I = 0, N = IndexVariables.size(); I != N; ++I)
+      Entities.push_back(InitializedEntity::InitializeElement(SemaRef.Context,
+                                                              0,
+                                                              Entities.back()));
+    
+    // Direct-initialize to use the copy constructor.
+    InitializationKind InitKind =
+      InitializationKind::CreateDirect(Loc, SourceLocation(), SourceLocation());
+    
+    Expr *CopyCtorArgE = CopyCtorArg.takeAs<Expr>();
+    InitializationSequence InitSeq(SemaRef, Entities.back(), InitKind,
+                                   &CopyCtorArgE, 1);
+    
+    ExprResult MemberInit
+      = InitSeq.Perform(SemaRef, Entities.back(), InitKind, 
+                        MultiExprArg(&CopyCtorArgE, 1));
+    MemberInit = SemaRef.MaybeCreateCXXExprWithTemporaries(MemberInit.get());
+    if (MemberInit.isInvalid())
+      return true;
+
+    CXXMemberInit
+      = CXXBaseOrMemberInitializer::Create(SemaRef.Context, Field, Loc, Loc,
+                                           MemberInit.takeAs<Expr>(), Loc,
+                                           IndexVariables.data(),
+                                           IndexVariables.size());
     return false;
   }
 
@@ -1586,22 +1693,23 @@
   if (FieldBaseElementType->isRecordType()) {
     InitializedEntity InitEntity = InitializedEntity::InitializeMember(Field);
     InitializationKind InitKind = 
-      InitializationKind::CreateDefault(Constructor->getLocation());
+      InitializationKind::CreateDefault(Loc);
     
     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));
+    ExprResult MemberInit = 
+      InitSeq.Perform(SemaRef, InitEntity, InitKind, MultiExprArg());
+    if (MemberInit.isInvalid())
+      return true;
+
+    MemberInit = SemaRef.MaybeCreateCXXExprWithTemporaries(MemberInit.get());
     if (MemberInit.isInvalid())
       return true;
     
     CXXMemberInit =
       new (SemaRef.Context) CXXBaseOrMemberInitializer(SemaRef.Context,
-                                                       Field, SourceLocation(),
-                                                       SourceLocation(),
-                                                      MemberInit.takeAs<Expr>(),
-                                                       SourceLocation());
+                                                       Field, Loc, Loc,
+                                                       MemberInit.get(),
+                                                       Loc);
     return false;
   }
 
@@ -1629,6 +1737,106 @@
   CXXMemberInit = 0;
   return false;
 }
+
+namespace {
+struct BaseAndFieldInfo {
+  Sema &S;
+  CXXConstructorDecl *Ctor;
+  bool AnyErrorsInInits;
+  ImplicitInitializerKind IIK;
+  llvm::DenseMap<const void *, CXXBaseOrMemberInitializer*> AllBaseFields;
+  llvm::SmallVector<CXXBaseOrMemberInitializer*, 8> AllToInit;
+
+  BaseAndFieldInfo(Sema &S, CXXConstructorDecl *Ctor, bool ErrorsInInits)
+    : S(S), Ctor(Ctor), AnyErrorsInInits(ErrorsInInits) {
+    // FIXME: Handle implicit move constructors.
+    if (Ctor->isImplicit() && Ctor->isCopyConstructor())
+      IIK = IIK_Copy;
+    else
+      IIK = IIK_Default;
+  }
+};
+}
+
+static void RecordFieldInitializer(BaseAndFieldInfo &Info,
+                                   FieldDecl *Top, FieldDecl *Field,
+                                   CXXBaseOrMemberInitializer *Init) {
+  // If the member doesn't need to be initialized, Init will still be null.
+  if (!Init)
+    return;
+
+  Info.AllToInit.push_back(Init);
+  if (Field != Top) {
+    Init->setMember(Top);
+    Init->setAnonUnionMember(Field);
+  }
+}
+
+static bool CollectFieldInitializer(BaseAndFieldInfo &Info,
+                                    FieldDecl *Top, FieldDecl *Field) {
+
+  // Overwhelmingly common case: we have a direct initializer for this field.
+  if (CXXBaseOrMemberInitializer *Init = Info.AllBaseFields.lookup(Field)) {
+    RecordFieldInitializer(Info, Top, Field, Init);
+    return false;
+  }
+
+  if (Info.IIK == IIK_Default && Field->isAnonymousStructOrUnion()) {
+    const RecordType *FieldClassType = Field->getType()->getAs<RecordType>();
+    assert(FieldClassType && "anonymous struct/union without record type");
+    CXXRecordDecl *FieldClassDecl
+      = cast<CXXRecordDecl>(FieldClassType->getDecl());
+
+    // Even though union members never have non-trivial default
+    // constructions in C++03, we still build member initializers for aggregate
+    // record types which can be union members, and C++0x allows non-trivial
+    // default constructors for union members, so we ensure that only one
+    // member is initialized for these.
+    if (FieldClassDecl->isUnion()) {
+      // First check for an explicit initializer for one field.
+      for (RecordDecl::field_iterator FA = FieldClassDecl->field_begin(),
+           EA = FieldClassDecl->field_end(); FA != EA; FA++) {
+        if (CXXBaseOrMemberInitializer *Init = Info.AllBaseFields.lookup(*FA)) {
+          RecordFieldInitializer(Info, Top, *FA, Init);
+
+          // Once we've initialized a field of an anonymous union, the union
+          // field in the class is also initialized, so exit immediately.
+          return false;
+        } else if ((*FA)->isAnonymousStructOrUnion()) {
+          if (CollectFieldInitializer(Info, Top, *FA))
+            return true;
+        }
+      }
+
+      // Fallthrough and construct a default initializer for the union as
+      // a whole, which can call its default constructor if such a thing exists
+      // (C++0x perhaps). FIXME: It's not clear that this is the correct
+      // behavior going forward with C++0x, when anonymous unions there are
+      // finalized, we should revisit this.
+    } else {
+      // For structs, we simply descend through to initialize all members where
+      // necessary.
+      for (RecordDecl::field_iterator FA = FieldClassDecl->field_begin(),
+           EA = FieldClassDecl->field_end(); FA != EA; FA++) {
+        if (CollectFieldInitializer(Info, Top, *FA))
+          return true;
+      }
+    }
+  }
+
+  // Don't try to build an implicit initializer if there were semantic
+  // errors in any of the initializers (and therefore we might be
+  // missing some that the user actually wrote).
+  if (Info.AnyErrorsInInits)
+    return false;
+
+  CXXBaseOrMemberInitializer *Init = 0;
+  if (BuildImplicitMemberInitializer(Info.S, Info.Ctor, Info.IIK, Field, Init))
+    return true;
+
+  RecordFieldInitializer(Info, Top, Field, Init);
+  return false;
+}
                                
 bool
 Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
@@ -1650,11 +1858,7 @@
     return false;
   }
 
-  ImplicitInitializerKind ImplicitInitKind = IIK_Default;
-  
-  // FIXME: Handle implicit move constructors.
-  if (Constructor->isImplicit() && Constructor->isCopyConstructor())
-    ImplicitInitKind = IIK_Copy;
+  BaseAndFieldInfo Info(*this, Constructor, AnyErrors);
 
   // We need to build the initializer AST according to order of construction
   // and not what user specified in the Initializers list.
@@ -1662,17 +1866,15 @@
   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;
+      Info.AllBaseFields[Member->getBaseClass()->getAs<RecordType>()] = Member;
     else
-      AllBaseFields[Member->getMember()] = Member;
+      Info.AllBaseFields[Member->getMember()] = Member;
   }
 
   // Keep track of the direct virtual bases.
@@ -1688,22 +1890,23 @@
        E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
 
     if (CXXBaseOrMemberInitializer *Value
-        = AllBaseFields.lookup(VBase->getType()->getAs<RecordType>())) {
-      AllToInit.push_back(Value);
+        = Info.AllBaseFields.lookup(VBase->getType()->getAs<RecordType>())) {
+      Info.AllToInit.push_back(Value);
     } else if (!AnyErrors) {
       bool IsInheritedVirtualBase = !DirectVBases.count(VBase);
       CXXBaseOrMemberInitializer *CXXBaseInit;
-      if (BuildImplicitBaseInitializer(*this, Constructor, ImplicitInitKind,
+      if (BuildImplicitBaseInitializer(*this, Constructor, Info.IIK,
                                        VBase, IsInheritedVirtualBase, 
                                        CXXBaseInit)) {
         HadError = true;
         continue;
       }
 
-      AllToInit.push_back(CXXBaseInit);
+      Info.AllToInit.push_back(CXXBaseInit);
     }
   }
 
+  // Non-virtual bases.
   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.
@@ -1711,70 +1914,39 @@
       continue;
 
     if (CXXBaseOrMemberInitializer *Value
-          = AllBaseFields.lookup(Base->getType()->getAs<RecordType>())) {
-      AllToInit.push_back(Value);
+          = Info.AllBaseFields.lookup(Base->getType()->getAs<RecordType>())) {
+      Info.AllToInit.push_back(Value);
     } else if (!AnyErrors) {
       CXXBaseOrMemberInitializer *CXXBaseInit;
-      if (BuildImplicitBaseInitializer(*this, Constructor, ImplicitInitKind,
+      if (BuildImplicitBaseInitializer(*this, Constructor, Info.IIK,
                                        Base, /*IsInheritedVirtualBase=*/false,
                                        CXXBaseInit)) {
         HadError = true;
         continue;
       }
 
-      AllToInit.push_back(CXXBaseInit);
+      Info.AllToInit.push_back(CXXBaseInit);
     }
   }
 
-  // non-static data members.
+  // Fields.
   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;
-          }
-        }
-      }
+    if ((*Field)->getType()->isIncompleteArrayType()) {
+      assert(ClassDecl->hasFlexibleArrayMember() &&
+             "Incomplete array type is not valid");
       continue;
     }
-    if (CXXBaseOrMemberInitializer *Value = AllBaseFields.lookup(*Field)) {
-      AllToInit.push_back(Value);
-      continue;
-    }
-
-    if (AnyErrors)
-      continue;
-    
-    CXXBaseOrMemberInitializer *Member;
-    if (BuildImplicitMemberInitializer(*this, Constructor, ImplicitInitKind,
-                                       *Field, Member)) {
+    if (CollectFieldInitializer(Info, *Field, *Field))
       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();
+  NumInitializers = Info.AllToInit.size();
   if (NumInitializers > 0) {
     Constructor->setNumBaseOrMemberInitializers(NumInitializers);
     CXXBaseOrMemberInitializer **baseOrMemberInitializers =
       new (Context) CXXBaseOrMemberInitializer*[NumInitializers];
-    memcpy(baseOrMemberInitializers, AllToInit.data(),
+    memcpy(baseOrMemberInitializers, Info.AllToInit.data(),
            NumInitializers * sizeof(CXXBaseOrMemberInitializer*));
     Constructor->setBaseOrMemberInitializers(baseOrMemberInitializers);
 
@@ -1889,9 +2061,7 @@
     // 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");
-
+    if (IdealIndex == NumIdealInits && PrevInit) {
       Sema::SemaDiagnosticBuilder D =
         SemaRef.Diag(PrevInit->getSourceLocation(),
                      diag::warn_initializer_out_of_order);
@@ -1985,7 +2155,7 @@
 }
 
 /// ActOnMemInitializers - Handle the member initializers for a constructor.
-void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
+void Sema::ActOnMemInitializers(Decl *ConstructorDecl,
                                 SourceLocation ColonLoc,
                                 MemInitTy **meminits, unsigned NumMemInits,
                                 bool AnyErrors) {
@@ -1995,7 +2165,7 @@
   AdjustDeclIfTemplate(ConstructorDecl);
 
   CXXConstructorDecl *Constructor
-    = dyn_cast<CXXConstructorDecl>(ConstructorDecl.getAs<Decl>());
+    = dyn_cast<CXXConstructorDecl>(ConstructorDecl);
 
   if (!Constructor) {
     Diag(ColonLoc, diag::err_only_constructors_take_base_inits);
@@ -2017,6 +2187,9 @@
   for (unsigned i = 0; i < NumMemInits; i++) {
     CXXBaseOrMemberInitializer *Init = MemInits[i];
 
+    // Set the source order index.
+    Init->setSourceOrder(i);
+
     if (Init->isMemberInitializer()) {
       FieldDecl *Field = Init->getMember();
       if (CheckRedundantInit(*this, Init, Members[Field]) ||
@@ -2053,7 +2226,8 @@
   for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
        E = ClassDecl->field_end(); I != E; ++I) {
     FieldDecl *Field = *I;
-    
+    if (Field->isInvalidDecl())
+      continue;
     QualType FieldType = Context.getBaseElementType(Field->getType());
     
     const RecordType* RT = FieldType->getAs<RecordType>();
@@ -2064,7 +2238,7 @@
     if (FieldClassDecl->hasTrivialDestructor())
       continue;
 
-    CXXDestructorDecl *Dtor = FieldClassDecl->getDestructor(Context);
+    CXXDestructorDecl *Dtor = LookupDestructor(FieldClassDecl);
     CheckDestructorAccess(Field->getLocation(), Dtor,
                           PDiag(diag::err_access_dtor_field)
                             << Field->getDeclName()
@@ -2090,7 +2264,7 @@
     if (BaseClassDecl->hasTrivialDestructor())
       continue;
 
-    CXXDestructorDecl *Dtor = BaseClassDecl->getDestructor(Context);
+    CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl);
 
     // FIXME: caret should be on the start of the class name
     CheckDestructorAccess(Base->getSourceRange().getBegin(), Dtor,
@@ -2117,7 +2291,7 @@
     if (BaseClassDecl->hasTrivialDestructor())
       continue;
 
-    CXXDestructorDecl *Dtor = BaseClassDecl->getDestructor(Context);
+    CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl);
     CheckDestructorAccess(ClassDecl->getLocation(), Dtor,
                           PDiag(diag::err_access_dtor_vbase)
                             << VBase->getType());
@@ -2126,35 +2300,30 @@
   }
 }
 
-void Sema::ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) {
+void Sema::ActOnDefaultCtorInitializers(Decl *CDtorDecl) {
   if (!CDtorDecl)
     return;
 
   if (CXXConstructorDecl *Constructor
-      = dyn_cast<CXXConstructorDecl>(CDtorDecl.getAs<Decl>()))
+      = dyn_cast<CXXConstructorDecl>(CDtorDecl))
     SetBaseOrMemberInitializers(Constructor, 0, 0, /*AnyErrors=*/false);
 }
 
 bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
-                                  unsigned DiagID, AbstractDiagSelID SelID,
-                                  const CXXRecordDecl *CurrentRD) {
+                                  unsigned DiagID, AbstractDiagSelID SelID) {
   if (SelID == -1)
-    return RequireNonAbstractType(Loc, T,
-                                  PDiag(DiagID), CurrentRD);
+    return RequireNonAbstractType(Loc, T, PDiag(DiagID));
   else
-    return RequireNonAbstractType(Loc, T,
-                                  PDiag(DiagID) << SelID, CurrentRD);
+    return RequireNonAbstractType(Loc, T, PDiag(DiagID) << SelID);
 }
 
 bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
-                                  const PartialDiagnostic &PD,
-                                  const CXXRecordDecl *CurrentRD) {
+                                  const PartialDiagnostic &PD) {
   if (!getLangOptions().CPlusPlus)
     return false;
 
   if (const ArrayType *AT = Context.getAsArrayType(T))
-    return RequireNonAbstractType(Loc, AT->getElementType(), PD,
-                                  CurrentRD);
+    return RequireNonAbstractType(Loc, AT->getElementType(), PD);
 
   if (const PointerType *PT = T->getAs<PointerType>()) {
     // Find the innermost pointer type.
@@ -2162,7 +2331,7 @@
       PT = T;
 
     if (const ArrayType *AT = Context.getAsArrayType(PT->getPointeeType()))
-      return RequireNonAbstractType(Loc, AT->getElementType(), PD, CurrentRD);
+      return RequireNonAbstractType(Loc, AT->getElementType(), PD);
   }
 
   const RecordType *RT = T->getAs<RecordType>();
@@ -2171,26 +2340,35 @@
 
   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())
+  // We can't answer whether something is abstract until it has a
+  // definition.  If it's currently being defined, we'll walk back
+  // over all the declarations when we have a full definition.
+  const CXXRecordDecl *Def = RD->getDefinition();
+  if (!Def || Def->isBeingDefined())
     return false;
 
   if (!RD->isAbstract())
     return false;
 
   Diag(Loc, PD) << RD->getDeclName();
+  DiagnoseAbstractType(RD);
 
-  // Check if we've already emitted the list of pure virtual functions for this
-  // class.
+  return true;
+}
+
+void Sema::DiagnoseAbstractType(const CXXRecordDecl *RD) {
+  // Check if we've already emitted the list of pure virtual functions
+  // for this class.
   if (PureVirtualClassDiagSet && PureVirtualClassDiagSet->count(RD))
-    return true;
+    return;
 
   CXXFinalOverriderMap FinalOverriders;
   RD->getFinalOverriders(FinalOverriders);
 
+  // Keep a set of seen pure methods so we won't diagnose the same method
+  // more than once.
+  llvm::SmallPtrSet<const CXXMethodDecl *, 8> SeenPureMethods;
+  
   for (CXXFinalOverriderMap::iterator M = FinalOverriders.begin(), 
                                    MEnd = FinalOverriders.end();
        M != MEnd; 
@@ -2210,6 +2388,9 @@
       if (!SO->second.front().Method->isPure())
         continue;
 
+      if (!SeenPureMethods.insert(SO->second.front().Method))
+        continue;
+
       Diag(SO->second.front().Method->getLocation(), 
            diag::note_pure_virtual_function) 
         << SO->second.front().Method->getDeclName();
@@ -2219,80 +2400,179 @@
   if (!PureVirtualClassDiagSet)
     PureVirtualClassDiagSet.reset(new RecordDeclSetTy);
   PureVirtualClassDiagSet->insert(RD);
-
-  return true;
 }
 
 namespace {
-  class AbstractClassUsageDiagnoser
-    : public DeclVisitor<AbstractClassUsageDiagnoser, bool> {
-    Sema &SemaRef;
-    CXXRecordDecl *AbstractClass;
+struct AbstractUsageInfo {
+  Sema &S;
+  CXXRecordDecl *Record;
+  CanQualType AbstractType;
+  bool Invalid;
 
-    bool VisitDeclContext(const DeclContext *DC) {
-      bool Invalid = false;
+  AbstractUsageInfo(Sema &S, CXXRecordDecl *Record)
+    : S(S), Record(Record),
+      AbstractType(S.Context.getCanonicalType(
+                   S.Context.getTypeDeclType(Record))),
+      Invalid(false) {}
 
-      for (CXXRecordDecl::decl_iterator I = DC->decls_begin(),
-           E = DC->decls_end(); I != E; ++I)
-        Invalid |= Visit(*I);
+  void DiagnoseAbstractType() {
+    if (Invalid) return;
+    S.DiagnoseAbstractType(Record);
+    Invalid = true;
+  }
 
-      return Invalid;
+  void CheckType(const NamedDecl *D, TypeLoc TL, Sema::AbstractDiagSelID Sel);
+};
+
+struct CheckAbstractUsage {
+  AbstractUsageInfo &Info;
+  const NamedDecl *Ctx;
+
+  CheckAbstractUsage(AbstractUsageInfo &Info, const NamedDecl *Ctx)
+    : Info(Info), Ctx(Ctx) {}
+
+  void Visit(TypeLoc TL, Sema::AbstractDiagSelID Sel) {
+    switch (TL.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+    case TypeLoc::CLASS: Check(cast<CLASS##TypeLoc>(TL), Sel); break;
+#include "clang/AST/TypeLocNodes.def"
     }
+  }
 
-  public:
-    AbstractClassUsageDiagnoser(Sema& SemaRef, CXXRecordDecl *ac)
-      : SemaRef(SemaRef), AbstractClass(ac) {
-        Visit(SemaRef.Context.getTranslationUnitDecl());
+  void Check(FunctionProtoTypeLoc TL, Sema::AbstractDiagSelID Sel) {
+    Visit(TL.getResultLoc(), Sema::AbstractReturnType);
+    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+      TypeSourceInfo *TSI = TL.getArg(I)->getTypeSourceInfo();
+      if (TSI) Visit(TSI->getTypeLoc(), Sema::AbstractParamType);
     }
+  }
 
-    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);
-      }
+  void Check(ArrayTypeLoc TL, Sema::AbstractDiagSelID Sel) {
+    Visit(TL.getElementLoc(), Sema::AbstractArrayType);
+  }
 
-      // 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;
+  void Check(TemplateSpecializationTypeLoc TL, Sema::AbstractDiagSelID Sel) {
+    // Visit the type parameters from a permissive context.
+    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+      TemplateArgumentLoc TAL = TL.getArgLoc(I);
+      if (TAL.getArgument().getKind() == TemplateArgument::Type)
+        if (TypeSourceInfo *TSI = TAL.getTypeSourceInfo())
+          Visit(TSI->getTypeLoc(), Sema::AbstractNone);
+      // TODO: other template argument types?
     }
+  }
 
-    bool VisitDecl(const Decl* D) {
-      if (const DeclContext *DC = dyn_cast<DeclContext>(D))
-        return VisitDeclContext(DC);
+  // Visit pointee types from a permissive context.
+#define CheckPolymorphic(Type) \
+  void Check(Type TL, Sema::AbstractDiagSelID Sel) { \
+    Visit(TL.getNextTypeLoc(), Sema::AbstractNone); \
+  }
+  CheckPolymorphic(PointerTypeLoc)
+  CheckPolymorphic(ReferenceTypeLoc)
+  CheckPolymorphic(MemberPointerTypeLoc)
+  CheckPolymorphic(BlockPointerTypeLoc)
 
-      return false;
+  /// Handle all the types we haven't given a more specific
+  /// implementation for above.
+  void Check(TypeLoc TL, Sema::AbstractDiagSelID Sel) {
+    // Every other kind of type that we haven't called out already
+    // that has an inner type is either (1) sugar or (2) contains that
+    // inner type in some way as a subobject.
+    if (TypeLoc Next = TL.getNextTypeLoc())
+      return Visit(Next, Sel);
+
+    // If there's no inner type and we're in a permissive context,
+    // don't diagnose.
+    if (Sel == Sema::AbstractNone) return;
+
+    // Check whether the type matches the abstract type.
+    QualType T = TL.getType();
+    if (T->isArrayType()) {
+      Sel = Sema::AbstractArrayType;
+      T = Info.S.Context.getBaseElementType(T);
     }
-  };
+    CanQualType CT = T->getCanonicalTypeUnqualified().getUnqualifiedType();
+    if (CT != Info.AbstractType) return;
+
+    // It matched; do some magic.
+    if (Sel == Sema::AbstractArrayType) {
+      Info.S.Diag(Ctx->getLocation(), diag::err_array_of_abstract_type)
+        << T << TL.getSourceRange();
+    } else {
+      Info.S.Diag(Ctx->getLocation(), diag::err_abstract_type_in_decl)
+        << Sel << T << TL.getSourceRange();
+    }
+    Info.DiagnoseAbstractType();
+  }
+};
+
+void AbstractUsageInfo::CheckType(const NamedDecl *D, TypeLoc TL,
+                                  Sema::AbstractDiagSelID Sel) {
+  CheckAbstractUsage(*this, D).Visit(TL, Sel);
+}
+
+}
+
+/// Check for invalid uses of an abstract type in a method declaration.
+static void CheckAbstractClassUsage(AbstractUsageInfo &Info,
+                                    CXXMethodDecl *MD) {
+  // No need to do the check on definitions, which require that
+  // the return/param types be complete.
+  if (MD->isThisDeclarationADefinition())
+    return;
+
+  // For safety's sake, just ignore it if we don't have type source
+  // information.  This should never happen for non-implicit methods,
+  // but...
+  if (TypeSourceInfo *TSI = MD->getTypeSourceInfo())
+    Info.CheckType(MD, TSI->getTypeLoc(), Sema::AbstractNone);
+}
+
+/// Check for invalid uses of an abstract type within a class definition.
+static void CheckAbstractClassUsage(AbstractUsageInfo &Info,
+                                    CXXRecordDecl *RD) {
+  for (CXXRecordDecl::decl_iterator
+         I = RD->decls_begin(), E = RD->decls_end(); I != E; ++I) {
+    Decl *D = *I;
+    if (D->isImplicit()) continue;
+
+    // Methods and method templates.
+    if (isa<CXXMethodDecl>(D)) {
+      CheckAbstractClassUsage(Info, cast<CXXMethodDecl>(D));
+    } else if (isa<FunctionTemplateDecl>(D)) {
+      FunctionDecl *FD = cast<FunctionTemplateDecl>(D)->getTemplatedDecl();
+      CheckAbstractClassUsage(Info, cast<CXXMethodDecl>(FD));
+
+    // Fields and static variables.
+    } else if (isa<FieldDecl>(D)) {
+      FieldDecl *FD = cast<FieldDecl>(D);
+      if (TypeSourceInfo *TSI = FD->getTypeSourceInfo())
+        Info.CheckType(FD, TSI->getTypeLoc(), Sema::AbstractFieldType);
+    } else if (isa<VarDecl>(D)) {
+      VarDecl *VD = cast<VarDecl>(D);
+      if (TypeSourceInfo *TSI = VD->getTypeSourceInfo())
+        Info.CheckType(VD, TSI->getTypeLoc(), Sema::AbstractVariableType);
+
+    // Nested classes and class templates.
+    } else if (isa<CXXRecordDecl>(D)) {
+      CheckAbstractClassUsage(Info, cast<CXXRecordDecl>(D));
+    } else if (isa<ClassTemplateDecl>(D)) {
+      CheckAbstractClassUsage(Info,
+                             cast<ClassTemplateDecl>(D)->getTemplatedDecl());
+    }
+  }
 }
 
 /// \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) {
+void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
   if (!Record || Record->isInvalidDecl())
     return;
 
   if (!Record->isDependentType())
-    AddImplicitlyDeclaredMembersToClass(S, Record);
+    AddImplicitlyDeclaredMembersToClass(Record);
   
   if (Record->isInvalidDecl())
     return;
@@ -2366,8 +2646,10 @@
     }
   }
 
-  if (Record->isAbstract() && !Record->isInvalidDecl())
-    (void)AbstractClassUsageDiagnoser(*this, Record);
+  if (Record->isAbstract() && !Record->isInvalidDecl()) {
+    AbstractUsageInfo Info(*this, Record);
+    CheckAbstractClassUsage(Info, 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
@@ -2392,10 +2674,13 @@
       }
     }
   }
+
+  if (Record->isDynamicClass())
+    DynamicClasses.push_back(Record);
 }
 
 void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
-                                             DeclPtrTy TagDecl,
+                                             Decl *TagDecl,
                                              SourceLocation LBrac,
                                              SourceLocation RBrac,
                                              AttributeList *AttrList) {
@@ -2405,276 +2690,109 @@
   AdjustDeclIfTemplate(TagDecl);
 
   ActOnFields(S, RLoc, TagDecl,
-              (DeclPtrTy*)FieldCollector->getCurFields(),
+              // strict aliasing violation!
+              reinterpret_cast<Decl**>(FieldCollector->getCurFields()),
               FieldCollector->getCurNumFields(), LBrac, RBrac, AttrList);
 
-  CheckCompletedCXXClass(S, 
-                      dyn_cast_or_null<CXXRecordDecl>(TagDecl.getAs<Decl>()));
+  CheckCompletedCXXClass(
+                        dyn_cast_or_null<CXXRecordDecl>(TagDecl));
 }
 
+namespace {
+  /// \brief Helper class that collects exception specifications for 
+  /// implicitly-declared special member functions.
+  class ImplicitExceptionSpecification {
+    ASTContext &Context;
+    bool AllowsAllExceptions;
+    llvm::SmallPtrSet<CanQualType, 4> ExceptionsSeen;
+    llvm::SmallVector<QualType, 4> Exceptions;
+    
+  public:
+    explicit ImplicitExceptionSpecification(ASTContext &Context) 
+      : Context(Context), AllowsAllExceptions(false) { }
+    
+    /// \brief Whether the special member function should have any
+    /// exception specification at all.
+    bool hasExceptionSpecification() const {
+      return !AllowsAllExceptions;
+    }
+    
+    /// \brief Whether the special member function should have a
+    /// throw(...) exception specification (a Microsoft extension).
+    bool hasAnyExceptionSpecification() const {
+      return false;
+    }
+    
+    /// \brief The number of exceptions in the exception specification.
+    unsigned size() const { return Exceptions.size(); }
+    
+    /// \brief The set of exceptions in the exception specification.
+    const QualType *data() const { return Exceptions.data(); }
+    
+    /// \brief Note that 
+    void CalledDecl(CXXMethodDecl *Method) {
+      // If we already know that we allow all exceptions, do nothing.
+      if (AllowsAllExceptions || !Method)
+        return;
+      
+      const FunctionProtoType *Proto
+        = Method->getType()->getAs<FunctionProtoType>();
+      
+      // If this function can throw any exceptions, make a note of that.
+      if (!Proto->hasExceptionSpec() || Proto->hasAnyExceptionSpec()) {
+        AllowsAllExceptions = true;
+        ExceptionsSeen.clear();
+        Exceptions.clear();
+        return;
+      }
+        
+      // Record the exceptions in this function's exception specification.
+      for (FunctionProtoType::exception_iterator E = Proto->exception_begin(),
+                                              EEnd = Proto->exception_end();
+           E != EEnd; ++E) 
+        if (ExceptionsSeen.insert(Context.getCanonicalType(*E)))
+          Exceptions.push_back(*E);
+    }
+  };
+}
+
+
 /// 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));
+void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
+  if (!ClassDecl->hasUserDeclaredConstructor())
+    ++ASTContext::NumImplicitDefaultConstructors;
 
-  // 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->hasUserDeclaredCopyConstructor())
+    ++ASTContext::NumImplicitCopyConstructors;
 
   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);
+    ++ASTContext::NumImplicitCopyAssignmentOperators;
+    
+    // If we have a dynamic class, then the copy assignment operator may be 
+    // virtual, so we have to declare it immediately. This ensures that, e.g.,
+    // it shows up in the right place in the vtable and that we diagnose 
+    // problems with the implicit exception specification.    
+    if (ClassDecl->isDynamicClass())
+      DeclareImplicitCopyAssignment(ClassDecl);
   }
 
   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));
+    ++ASTContext::NumImplicitDestructors;
     
-    AddOverriddenMethods(ClassDecl, Destructor);
+    // If we have a dynamic class, then the destructor may be virtual, so we 
+    // have to declare the destructor immediately. This ensures that, e.g., it
+    // shows up in the right place in the vtable and that we diagnose problems
+    // with the implicit exception specification.
+    if (ClassDecl->isDynamicClass())
+      DeclareImplicitDestructor(ClassDecl);
   }
 }
 
-void Sema::ActOnReenterTemplateScope(Scope *S, DeclPtrTy TemplateD) {
-  Decl *D = TemplateD.getAs<Decl>();
+void Sema::ActOnReenterTemplateScope(Scope *S, Decl *D) {
   if (!D)
     return;
   
@@ -2692,20 +2810,20 @@
        Param != ParamEnd; ++Param) {
     NamedDecl *Named = cast<NamedDecl>(*Param);
     if (Named->getDeclName()) {
-      S->AddDecl(DeclPtrTy::make(Named));
+      S->AddDecl(Named);
       IdResolver.AddDecl(Named);
     }
   }
 }
 
-void Sema::ActOnStartDelayedMemberDeclarations(Scope *S, DeclPtrTy RecordD) {
+void Sema::ActOnStartDelayedMemberDeclarations(Scope *S, Decl *RecordD) {
   if (!RecordD) return;
   AdjustDeclIfTemplate(RecordD);
-  CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordD.getAs<Decl>());
+  CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordD);
   PushDeclContext(S, Record);
 }
 
-void Sema::ActOnFinishDelayedMemberDeclarations(Scope *S, DeclPtrTy RecordD) {
+void Sema::ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *RecordD) {
   if (!RecordD) return;
   PopDeclContext();
 }
@@ -2718,7 +2836,7 @@
 /// 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) {
+void Sema::ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *MethodD) {
 }
 
 /// ActOnDelayedCXXMethodParameter - We've already started a delayed
@@ -2726,18 +2844,18 @@
 /// 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) {
+void Sema::ActOnDelayedCXXMethodParameter(Scope *S, Decl *ParamD) {
   if (!ParamD)
     return;
 
-  ParmVarDecl *Param = cast<ParmVarDecl>(ParamD.getAs<Decl>());
+  ParmVarDecl *Param = cast<ParmVarDecl>(ParamD);
 
   // 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));
+  S->AddDecl(Param);
   if (Param->getDeclName())
     IdResolver.AddDecl(Param);
 }
@@ -2748,13 +2866,13 @@
 /// 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) {
+void Sema::ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *MethodD) {
   if (!MethodD)
     return;
 
   AdjustDeclIfTemplate(MethodD);
 
-  FunctionDecl *Method = cast<FunctionDecl>(MethodD.getAs<Decl>());
+  FunctionDecl *Method = cast<FunctionDecl>(MethodD);
 
   // Now that we have our default arguments, check the constructor
   // again. It could produce additional diagnostics or affect whether
@@ -2775,7 +2893,7 @@
 /// will be updated to reflect a well-formed type for the constructor and
 /// returned.
 QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R,
-                                          FunctionDecl::StorageClass &SC) {
+                                          StorageClass &SC) {
   bool isVirtual = D.getDeclSpec().isVirtualSpecified();
 
   // C++ [class.ctor]p3:
@@ -2790,13 +2908,13 @@
         << SourceRange(D.getIdentifierLoc());
     D.setInvalidType();
   }
-  if (SC == FunctionDecl::Static) {
+  if (SC == SC_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;
+    SC = SC_None;
   }
 
   DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
@@ -2814,9 +2932,7 @@
 
   // 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.
+  // return type, since constructors don't have return types.
   const FunctionProtoType *Proto = R->getAs<FunctionProtoType>();
   return Context.getFunctionType(Context.VoidTy, Proto->arg_type_begin(),
                                  Proto->getNumArgs(),
@@ -2852,8 +2968,11 @@
     QualType ClassTy = Context.getTagDeclType(ClassDecl);
     if (Context.getCanonicalType(ParamType).getUnqualifiedType() == ClassTy) {
       SourceLocation ParamLoc = Constructor->getParamDecl(0)->getLocation();
+      const char *ConstRef 
+        = Constructor->getParamDecl(0)->getIdentifier() ? "const &" 
+                                                        : " const &";
       Diag(ParamLoc, diag::err_constructor_byvalue_arg)
-        << FixItHint::CreateInsertion(ParamLoc, " const &");
+        << FixItHint::CreateInsertion(ParamLoc, ConstRef);
 
       // FIXME: Rather that making the constructor invalid, we should endeavor
       // to fix the type.
@@ -2869,8 +2988,9 @@
     ClassDecl->addedConstructor(Context, Constructor);
 }
 
-/// CheckDestructor - Checks a fully-formed destructor for well-formedness, 
-/// issuing any diagnostics required. Returns true on error.
+/// CheckDestructor - Checks a fully-formed destructor definition for
+/// well-formedness, issuing any diagnostics required.  Returns true
+/// on error.
 bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
   CXXRecordDecl *RD = Destructor->getParent();
   
@@ -2888,6 +3008,8 @@
     Context.DeclarationNames.getCXXOperatorName(OO_Delete);
     if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete))
       return true;
+
+    MarkDeclarationReferenced(Loc, OperatorDelete);
     
     Destructor->setOperatorDelete(OperatorDelete);
   }
@@ -2899,7 +3021,7 @@
 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());
+          cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType());
 }
 
 /// CheckDestructorDeclarator - Called by ActOnDeclarator to check
@@ -2908,19 +3030,17 @@
 /// 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) {
+QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,
+                                         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)) {
+  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
@@ -2930,13 +3050,14 @@
   //   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 (SC == SC_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();
+        << SourceRange(D.getIdentifierLoc())
+        << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
+    
+    SC = SC_None;
   }
   if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) {
     // Destructors don't have return types, but the parser will
@@ -2984,11 +3105,17 @@
   // 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!
+  // types. 
+  const FunctionProtoType *Proto = R->getAs<FunctionProtoType>();
+  if (!Proto)
+    return QualType();
+  
   return Context.getFunctionType(Context.VoidTy, 0, 0, false, 0,
-                                 false, false, 0, 0, FunctionType::ExtInfo());
+                                 Proto->hasExceptionSpec(),
+                                 Proto->hasAnyExceptionSpec(),
+                                 Proto->getNumExceptions(),
+                                 Proto->exception_begin(),
+                                 Proto->getExtInfo());
 }
 
 /// CheckConversionDeclarator - Called by ActOnDeclarator to check the
@@ -2998,18 +3125,18 @@
 /// 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) {
+                                     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 (SC == SC_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;
+    SC = SC_None;
   }
 
   QualType ConvType = GetTypeFromParser(D.getName().ConversionFunctionId);
@@ -3089,7 +3216,7 @@
 /// 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) {
+Decl *Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
   assert(Conversion && "Expected to receive a conversion function declaration");
 
   CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Conversion->getDeclContext());
@@ -3130,10 +3257,10 @@
       if (ClassDecl->replaceConversion(
                                    ConversionTemplate->getPreviousDeclaration(),
                                        ConversionTemplate))
-        return DeclPtrTy::make(ConversionTemplate);
+        return ConversionTemplate;
     } else if (ClassDecl->replaceConversion(Conversion->getPreviousDeclaration(),
                                             Conversion))
-      return DeclPtrTy::make(Conversion);
+      return Conversion;
     assert(Conversion->isInvalidDecl() && "Conversion should not get here.");
   } else if (FunctionTemplateDecl *ConversionTemplate
                = Conversion->getDescribedFunctionTemplate())
@@ -3141,28 +3268,35 @@
   else 
     ClassDecl->addConversionFunction(Conversion);
 
-  return DeclPtrTy::make(Conversion);
+  return 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);
+Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
+                                   SourceLocation InlineLoc,
+                                   SourceLocation IdentLoc,
+                                   IdentifierInfo *II,
+                                   SourceLocation LBrace,
+                                   AttributeList *AttrList) {
+  // anonymous namespace starts at its left brace
+  NamespaceDecl *Namespc = NamespaceDecl::Create(Context, CurContext,
+    (II ? IdentLoc : LBrace) , II);
   Namespc->setLBracLoc(LBrace);
 
   Scope *DeclRegionScope = NamespcScope->getParent();
 
   ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
 
+  if (const VisibilityAttr *attr = Namespc->getAttr<VisibilityAttr>())
+    PushVisibilityAttr(attr);
+
   if (II) {
     // C++ [namespace.def]p2:
     // The identifier in an original-namespace-definition shall not have been
@@ -3183,9 +3317,9 @@
       Namespc->setOriginalNamespace(OrigNS->getOriginalNamespace());
 
       // Remove the previous declaration from the scope.
-      if (DeclRegionScope->isDeclScope(DeclPtrTy::make(OrigNS))) {
+      if (DeclRegionScope->isDeclScope(OrigNS)) {
         IdResolver.RemoveDecl(OrigNS);
-        DeclRegionScope->RemoveDecl(DeclPtrTy::make(OrigNS));
+        DeclRegionScope->RemoveDecl(OrigNS);
       }
     } else if (PrevDecl) {
       // This is an invalid name redefinition.
@@ -3198,12 +3332,12 @@
                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) {
+      if (NamespaceDecl *StdNS = getStdNamespace()) {
         // 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());
+        StdNS->setNextNamespace(Namespc);
+        StdNS->setLocation(IdentLoc);
+        Namespc->setOriginalNamespace(StdNS->getOriginalNamespace());
       }
       
       // Make our StdNamespace cache point at the first real definition of the
@@ -3275,7 +3409,7 @@
   // for the namespace has the declarations that showed up in that particular
   // namespace definition.
   PushDeclContext(NamespcScope, Namespc);
-  return DeclPtrTy::make(Namespc);
+  return Namespc;
 }
 
 /// getNamespaceDecl - Returns the namespace a decl represents. If the decl
@@ -3288,15 +3422,41 @@
 
 /// 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>();
+void Sema::ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace) {
   NamespaceDecl *Namespc = dyn_cast_or_null<NamespaceDecl>(Dcl);
   assert(Namespc && "Invalid parameter, expected NamespaceDecl");
   Namespc->setRBracLoc(RBrace);
   PopDeclContext();
+  if (Namespc->hasAttr<VisibilityAttr>())
+    PopPragmaVisibility();
 }
 
-Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S,
+CXXRecordDecl *Sema::getStdBadAlloc() const {
+  return cast_or_null<CXXRecordDecl>(
+                                  StdBadAlloc.get(Context.getExternalSource()));
+}
+
+NamespaceDecl *Sema::getStdNamespace() const {
+  return cast_or_null<NamespaceDecl>(
+                                 StdNamespace.get(Context.getExternalSource()));
+}
+
+/// \brief Retrieve the special "std" namespace, which may require us to 
+/// implicitly define the namespace.
+NamespaceDecl *Sema::getOrCreateStdNamespace() {
+  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"));
+    getStdNamespace()->setImplicit(true);
+  }
+  
+  return getStdNamespace();
+}
+
+Decl *Sema::ActOnUsingDirective(Scope *S,
                                           SourceLocation UsingLoc,
                                           SourceLocation NamespcLoc,
                                           CXXScopeSpec &SS,
@@ -3309,13 +3469,49 @@
   assert(S->getFlags() & Scope::DeclScope && "Invalid Scope.");
 
   UsingDirectiveDecl *UDir = 0;
-
+  NestedNameSpecifier *Qualifier = 0;
+  if (SS.isSet())
+    Qualifier = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  
   // Lookup namespace name.
   LookupResult R(*this, NamespcName, IdentLoc, LookupNamespaceName);
   LookupParsedName(R, S, &SS);
   if (R.isAmbiguous())
-    return DeclPtrTy();
+    return 0;
 
+  if (R.empty()) {
+    // Allow "using namespace std;" or "using namespace ::std;" even if 
+    // "std" hasn't been defined yet, for GCC compatibility.
+    if ((!Qualifier || Qualifier->getKind() == NestedNameSpecifier::Global) &&
+        NamespcName->isStr("std")) {
+      Diag(IdentLoc, diag::ext_using_undefined_std);
+      R.addDecl(getOrCreateStdNamespace());
+      R.resolveKind();
+    } 
+    // Otherwise, attempt typo correction.
+    else if (DeclarationName Corrected = CorrectTypo(R, S, &SS, 0, false, 
+                                                       CTC_NoKeywords, 0)) {
+      if (R.getAsSingle<NamespaceDecl>() || 
+          R.getAsSingle<NamespaceAliasDecl>()) {
+        if (DeclContext *DC = computeDeclContext(SS, false))
+          Diag(IdentLoc, diag::err_using_directive_member_suggest)
+            << NamespcName << DC << Corrected << SS.getRange()
+            << FixItHint::CreateReplacement(IdentLoc, Corrected.getAsString());        
+        else
+          Diag(IdentLoc, diag::err_using_directive_suggest)
+            << NamespcName << Corrected
+            << FixItHint::CreateReplacement(IdentLoc, Corrected.getAsString());
+        Diag(R.getFoundDecl()->getLocation(), diag::note_namespace_defined_here)
+          << Corrected;
+        
+        NamespcName = Corrected.getAsIdentifierInfo();
+      } else {
+        R.clear();
+        R.setLookupName(NamespcName);
+      }
+    }
+  }
+  
   if (!R.empty()) {
     NamedDecl *Named = R.getFoundDecl();
     assert((isa<NamespaceDecl>(Named) || isa<NamespaceAliasDecl>(Named))
@@ -3348,7 +3544,7 @@
 
   // FIXME: We ignore attributes for now.
   delete AttrList;
-  return DeclPtrTy::make(UDir);
+  return UDir;
 }
 
 void Sema::PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir) {
@@ -3360,11 +3556,11 @@
   else
     // Otherwise it is block-sope. using-directives will affect lookup
     // only to the end of scope.
-    S->PushUsingDirective(DeclPtrTy::make(UDir));
+    S->PushUsingDirective(UDir);
 }
 
 
-Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S,
+Decl *Sema::ActOnUsingDeclaration(Scope *S,
                                             AccessSpecifier AS,
                                             bool HasUsingKeyword,
                                             SourceLocation UsingLoc,
@@ -3389,22 +3585,23 @@
 
     Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_constructor)
       << SS.getRange();
-    return DeclPtrTy();
+    return 0;
       
   case UnqualifiedId::IK_DestructorName:
     Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_destructor)
       << SS.getRange();
-    return DeclPtrTy();
+    return 0;
       
   case UnqualifiedId::IK_TemplateId:
     Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_template_id)
       << SourceRange(Name.TemplateId->LAngleLoc, Name.TemplateId->RAngleLoc);
-    return DeclPtrTy();
+    return 0;
   }
-  
-  DeclarationName TargetName = GetNameFromUnqualifiedId(Name);
+
+  DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name);
+  DeclarationName TargetName = TargetNameInfo.getName();
   if (!TargetName)
-    return DeclPtrTy();
+    return 0;
 
   // Warn about using declarations.
   // TODO: store that the declaration was written without 'using' and
@@ -3418,16 +3615,37 @@
   }
 
   NamedDecl *UD = BuildUsingDeclaration(S, AS, UsingLoc, SS,
-                                        Name.getSourceRange().getBegin(),
-                                        TargetName, AttrList,
+                                        TargetNameInfo, AttrList,
                                         /* IsInstantiation */ false,
                                         IsTypeName, TypenameLoc);
   if (UD)
     PushOnScopeChains(UD, S, /*AddToContext*/ false);
 
-  return DeclPtrTy::make(UD);
+  return UD;
 }
 
+/// \brief Determine whether a using declaration considers the given
+/// declarations as "equivalent", e.g., if they are redeclarations of
+/// the same entity or are both typedefs of the same type.
+static bool 
+IsEquivalentForUsingDecl(ASTContext &Context, NamedDecl *D1, NamedDecl *D2,
+                         bool &SuppressRedeclaration) {
+  if (D1->getCanonicalDecl() == D2->getCanonicalDecl()) {
+    SuppressRedeclaration = false;
+    return true;
+  }
+
+  if (TypedefDecl *TD1 = dyn_cast<TypedefDecl>(D1))
+    if (TypedefDecl *TD2 = dyn_cast<TypedefDecl>(D2)) {
+      SuppressRedeclaration = true;
+      return Context.hasSameType(TD1->getUnderlyingType(),
+                                 TD2->getUnderlyingType());
+    }
+
+  return false;
+}
+
+
 /// 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,
@@ -3494,8 +3712,9 @@
   for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
          I != E; ++I) {
     NamedDecl *D = (*I)->getUnderlyingDecl();
-    if (D->getCanonicalDecl() == Target->getCanonicalDecl())
-      return false;
+    bool Result;
+    if (IsEquivalentForUsingDecl(Context, D, Target, Result))
+      return Result;
 
     (isa<TagDecl>(D) ? Tag : NonTag) = D;
   }
@@ -3508,7 +3727,7 @@
       FD = cast<FunctionDecl>(Target);
 
     NamedDecl *OldDecl = 0;
-    switch (CheckOverload(FD, Previous, OldDecl)) {
+    switch (CheckOverload(0, FD, Previous, OldDecl, /*IsForUsingDecl*/ true)) {
     case Ovl_Overload:
       return false;
 
@@ -3518,11 +3737,6 @@
       
     // 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.
@@ -3631,7 +3845,7 @@
 
   // ...and the scope, if applicable...
   if (S) {
-    S->RemoveDecl(DeclPtrTy::make(static_cast<Decl*>(Shadow)));
+    S->RemoveDecl(Shadow);
     IdResolver.RemoveDecl(Shadow);
   }
 
@@ -3650,13 +3864,13 @@
 NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
                                        SourceLocation UsingLoc,
                                        CXXScopeSpec &SS,
-                                       SourceLocation IdentLoc,
-                                       DeclarationName Name,
+                                       const DeclarationNameInfo &NameInfo,
                                        AttributeList *AttrList,
                                        bool IsInstantiation,
                                        bool IsTypeName,
                                        SourceLocation TypenameLoc) {
   assert(!SS.isInvalid() && "Invalid CXXScopeSpec.");
+  SourceLocation IdentLoc = NameInfo.getLoc();
   assert(IdentLoc.isValid() && "Invalid TargetName location.");
 
   // FIXME: We ignore attributes for now.
@@ -3668,7 +3882,7 @@
   }
 
   // Do the redeclaration lookup in the current scope.
-  LookupResult Previous(*this, Name, IdentLoc, LookupUsingDeclName,
+  LookupResult Previous(*this, NameInfo, LookupUsingDeclName,
                         ForRedeclaration);
   Previous.setHideTags(false);
   if (S) {
@@ -3707,15 +3921,15 @@
       D = UnresolvedUsingTypenameDecl::Create(Context, CurContext,
                                               UsingLoc, TypenameLoc,
                                               SS.getRange(), NNS,
-                                              IdentLoc, Name);
+                                              IdentLoc, NameInfo.getName());
     } else {
       D = UnresolvedUsingValueDecl::Create(Context, CurContext,
-                                           UsingLoc, SS.getRange(), NNS,
-                                           IdentLoc, Name);
+                                           UsingLoc, SS.getRange(),
+                                           NNS, NameInfo);
     }
   } else {
-    D = UsingDecl::Create(Context, CurContext, IdentLoc,
-                          SS.getRange(), UsingLoc, NNS, Name,
+    D = UsingDecl::Create(Context, CurContext,
+                          SS.getRange(), UsingLoc, NNS, NameInfo,
                           IsTypeName);
   }
   D->setAccess(AS);
@@ -3724,14 +3938,14 @@
   if (!LookupContext) return D;
   UsingDecl *UD = cast<UsingDecl>(D);
 
-  if (RequireCompleteDeclContext(SS)) {
+  if (RequireCompleteDeclContext(SS, LookupContext)) {
     UD->setInvalidDecl();
     return UD;
   }
 
   // Look up the target name.
 
-  LookupResult R(*this, Name, IdentLoc, LookupOrdinaryName);
+  LookupResult R(*this, NameInfo, LookupOrdinaryName);
 
   // Unlike most lookups, we don't always want to hide tag
   // declarations: tag names are visible through the using declaration
@@ -3744,7 +3958,7 @@
 
   if (R.empty()) {
     Diag(IdentLoc, diag::err_no_member) 
-      << Name << LookupContext << SS.getRange();
+      << NameInfo.getName() << LookupContext << SS.getRange();
     UD->setInvalidDecl();
     return UD;
   }
@@ -3806,8 +4020,9 @@
   //   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())
+  //
+  // That's in non-member contexts.
+  if (!CurContext->getLookupContext()->isRecord())
     return false;
 
   NestedNameSpecifier *Qual
@@ -3982,7 +4197,7 @@
   return true;
 }
 
-Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
+Decl *Sema::ActOnNamespaceAliasDef(Scope *S,
                                              SourceLocation NamespaceLoc,
                                              SourceLocation AliasLoc,
                                              IdentifierInfo *Alias,
@@ -3995,9 +4210,13 @@
   LookupParsedName(R, S, &SS);
 
   // Check if we have a previous declaration with the same name.
-  if (NamedDecl *PrevDecl
-        = LookupSingleName(S, Alias, AliasLoc, LookupOrdinaryName, 
-                           ForRedeclaration)) {
+  NamedDecl *PrevDecl
+    = LookupSingleName(S, Alias, AliasLoc, LookupOrdinaryName, 
+                       ForRedeclaration);
+  if (PrevDecl && !isDeclInScope(PrevDecl, CurContext, S))
+    PrevDecl = 0;
+
+  if (PrevDecl) {
     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.
@@ -4005,22 +4224,47 @@
       // declaration to maintain better source information.
       if (!R.isAmbiguous() && !R.empty() &&
           AD->getNamespace()->Equals(getNamespaceDecl(R.getFoundDecl())))
-        return DeclPtrTy();
+        return 0;
     }
 
     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();
+    return 0;
   }
 
   if (R.isAmbiguous())
-    return DeclPtrTy();
+    return 0;
 
   if (R.empty()) {
-    Diag(NamespaceLoc, diag::err_expected_namespace_name) << SS.getRange();
-    return DeclPtrTy();
+    if (DeclarationName Corrected = CorrectTypo(R, S, &SS, 0, false, 
+                                                CTC_NoKeywords, 0)) {
+      if (R.getAsSingle<NamespaceDecl>() || 
+          R.getAsSingle<NamespaceAliasDecl>()) {
+        if (DeclContext *DC = computeDeclContext(SS, false))
+          Diag(IdentLoc, diag::err_using_directive_member_suggest)
+            << Ident << DC << Corrected << SS.getRange()
+            << FixItHint::CreateReplacement(IdentLoc, Corrected.getAsString());        
+        else
+          Diag(IdentLoc, diag::err_using_directive_suggest)
+            << Ident << Corrected
+            << FixItHint::CreateReplacement(IdentLoc, Corrected.getAsString());
+        
+        Diag(R.getFoundDecl()->getLocation(), diag::note_namespace_defined_here)
+          << Corrected;
+        
+        Ident = Corrected.getAsIdentifierInfo();
+      } else {
+        R.clear();
+        R.setLookupName(Ident);
+      }
+    }
+    
+    if (R.empty()) {
+      Diag(NamespaceLoc, diag::err_expected_namespace_name) << SS.getRange();
+      return 0;
+    }
   }
 
   NamespaceAliasDecl *AliasDecl =
@@ -4030,158 +4274,1104 @@
                                IdentLoc, R.getFoundDecl());
 
   PushOnScopeChains(AliasDecl, S);
-  return DeclPtrTy::make(AliasDecl);
+  return AliasDecl;
+}
+
+namespace {
+  /// \brief Scoped object used to handle the state changes required in Sema
+  /// to implicitly define the body of a C++ member function;
+  class ImplicitlyDefinedFunctionScope {
+    Sema &S;
+    DeclContext *PreviousContext;
+    
+  public:
+    ImplicitlyDefinedFunctionScope(Sema &S, CXXMethodDecl *Method)
+      : S(S), PreviousContext(S.CurContext) 
+    {
+      S.CurContext = Method;
+      S.PushFunctionScope();
+      S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
+    }
+    
+    ~ImplicitlyDefinedFunctionScope() {
+      S.PopExpressionEvaluationContext();
+      S.PopFunctionOrBlockScope();
+      S.CurContext = PreviousContext;
+    }
+  };
+}
+
+CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
+                                                     CXXRecordDecl *ClassDecl) {
+  // 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.
+  assert(!ClassDecl->hasUserDeclaredConstructor() && 
+         "Should not build implicit default constructor!");
+  
+  // C++ [except.spec]p14:
+  //   An implicitly declared special member function (Clause 12) shall have an 
+  //   exception-specification. [...]
+  ImplicitExceptionSpecification ExceptSpec(Context);
+
+  // Direct base-class destructors.
+  for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(),
+                                       BEnd = ClassDecl->bases_end();
+       B != BEnd; ++B) {
+    if (B->isVirtual()) // Handled below.
+      continue;
+    
+    if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) {
+      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
+      if (!BaseClassDecl->hasDeclaredDefaultConstructor())
+        ExceptSpec.CalledDecl(DeclareImplicitDefaultConstructor(BaseClassDecl));
+      else if (CXXConstructorDecl *Constructor 
+                                       = BaseClassDecl->getDefaultConstructor())
+        ExceptSpec.CalledDecl(Constructor);
+    }
+  }
+  
+  // Virtual base-class destructors.
+  for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(),
+                                       BEnd = ClassDecl->vbases_end();
+       B != BEnd; ++B) {
+    if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) {
+      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
+      if (!BaseClassDecl->hasDeclaredDefaultConstructor())
+        ExceptSpec.CalledDecl(DeclareImplicitDefaultConstructor(BaseClassDecl));
+      else if (CXXConstructorDecl *Constructor
+                                       = BaseClassDecl->getDefaultConstructor())
+        ExceptSpec.CalledDecl(Constructor);
+    }
+  }
+  
+  // Field destructors.
+  for (RecordDecl::field_iterator F = ClassDecl->field_begin(),
+                               FEnd = ClassDecl->field_end();
+       F != FEnd; ++F) {
+    if (const RecordType *RecordTy
+              = Context.getBaseElementType(F->getType())->getAs<RecordType>()) {
+      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RecordTy->getDecl());
+      if (!FieldClassDecl->hasDeclaredDefaultConstructor())
+        ExceptSpec.CalledDecl(
+                            DeclareImplicitDefaultConstructor(FieldClassDecl));
+      else if (CXXConstructorDecl *Constructor
+                                      = FieldClassDecl->getDefaultConstructor())
+        ExceptSpec.CalledDecl(Constructor);
+    }
+  }
+  
+  
+  // Create the actual constructor declaration.
+  CanQualType ClassType
+    = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
+  DeclarationName Name
+    = Context.DeclarationNames.getCXXConstructorName(ClassType);
+  DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
+  CXXConstructorDecl *DefaultCon
+    = CXXConstructorDecl::Create(Context, ClassDecl, NameInfo,
+                                 Context.getFunctionType(Context.VoidTy,
+                                                         0, 0, false, 0,
+                                       ExceptSpec.hasExceptionSpecification(),
+                                     ExceptSpec.hasAnyExceptionSpecification(),
+                                                         ExceptSpec.size(),
+                                                         ExceptSpec.data(),
+                                                       FunctionType::ExtInfo()),
+                                 /*TInfo=*/0,
+                                 /*isExplicit=*/false,
+                                 /*isInline=*/true,
+                                 /*isImplicitlyDeclared=*/true);
+  DefaultCon->setAccess(AS_public);
+  DefaultCon->setImplicit();
+  DefaultCon->setTrivial(ClassDecl->hasTrivialConstructor());
+  
+  // Note that we have declared this constructor.
+  ClassDecl->setDeclaredDefaultConstructor(true);
+  ++ASTContext::NumImplicitDefaultConstructorsDeclared;
+  
+  if (Scope *S = getScopeForContext(ClassDecl))
+    PushOnScopeChains(DefaultCon, S, false);
+  ClassDecl->addDecl(DefaultCon);
+  
+  return DefaultCon;
 }
 
 void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
                                             CXXConstructorDecl *Constructor) {
   assert((Constructor->isImplicit() && Constructor->isDefaultConstructor() &&
-          !Constructor->isUsed()) &&
+          !Constructor->isUsed(false)) &&
     "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)) {
+  ImplicitlyDefinedFunctionScope Scope(*this, Constructor);
+  ErrorTrap Trap(*this);
+  if (SetBaseOrMemberInitializers(Constructor, 0, 0, /*AnyErrors=*/false) ||
+      Trap.hasErrorOccurred()) {
     Diag(CurrentLocation, diag::note_member_synthesized_at) 
       << CXXConstructor << Context.getTagDeclType(ClassDecl);
     Constructor->setInvalidDecl();
   } else {
     Constructor->setUsed();
+    MarkVTableUsed(CurrentLocation, ClassDecl);
   }
-  CurContext = PreviousContext;
+}
+
+CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
+  // 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.
+  
+  // C++ [except.spec]p14: 
+  //   An implicitly declared special member function (Clause 12) shall have 
+  //   an exception-specification.
+  ImplicitExceptionSpecification ExceptSpec(Context);
+  
+  // Direct base-class destructors.
+  for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(),
+                                       BEnd = ClassDecl->bases_end();
+       B != BEnd; ++B) {
+    if (B->isVirtual()) // Handled below.
+      continue;
+    
+    if (const RecordType *BaseType = B->getType()->getAs<RecordType>())
+      ExceptSpec.CalledDecl(
+                    LookupDestructor(cast<CXXRecordDecl>(BaseType->getDecl())));
+  }
+  
+  // Virtual base-class destructors.
+  for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(),
+                                       BEnd = ClassDecl->vbases_end();
+       B != BEnd; ++B) {
+    if (const RecordType *BaseType = B->getType()->getAs<RecordType>())
+      ExceptSpec.CalledDecl(
+                    LookupDestructor(cast<CXXRecordDecl>(BaseType->getDecl())));
+  }
+  
+  // Field destructors.
+  for (RecordDecl::field_iterator F = ClassDecl->field_begin(),
+                               FEnd = ClassDecl->field_end();
+       F != FEnd; ++F) {
+    if (const RecordType *RecordTy
+        = Context.getBaseElementType(F->getType())->getAs<RecordType>())
+      ExceptSpec.CalledDecl(
+                    LookupDestructor(cast<CXXRecordDecl>(RecordTy->getDecl())));
+  }
+  
+  // Create the actual destructor declaration.
+  QualType Ty = Context.getFunctionType(Context.VoidTy,
+                                        0, 0, false, 0,
+                                        ExceptSpec.hasExceptionSpecification(),
+                                    ExceptSpec.hasAnyExceptionSpecification(),
+                                        ExceptSpec.size(),
+                                        ExceptSpec.data(),
+                                        FunctionType::ExtInfo());
+  
+  CanQualType ClassType
+    = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
+  DeclarationName Name
+    = Context.DeclarationNames.getCXXDestructorName(ClassType);
+  DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
+  CXXDestructorDecl *Destructor
+    = CXXDestructorDecl::Create(Context, ClassDecl, NameInfo, Ty,
+                                /*isInline=*/true,
+                                /*isImplicitlyDeclared=*/true);
+  Destructor->setAccess(AS_public);
+  Destructor->setImplicit();
+  Destructor->setTrivial(ClassDecl->hasTrivialDestructor());
+  
+  // Note that we have declared this destructor.
+  ClassDecl->setDeclaredDestructor(true);
+  ++ASTContext::NumImplicitDestructorsDeclared;
+  
+  // Introduce this destructor into its scope.
+  if (Scope *S = getScopeForContext(ClassDecl))
+    PushOnScopeChains(Destructor, S, false);
+  ClassDecl->addDecl(Destructor);
+  
+  // This could be uniqued if it ever proves significant.
+  Destructor->setTypeSourceInfo(Context.getTrivialTypeSourceInfo(Ty));
+  
+  AddOverriddenMethods(ClassDecl, Destructor);
+  
+  return Destructor;
 }
 
 void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
                                     CXXDestructorDecl *Destructor) {
-  assert((Destructor->isImplicit() && !Destructor->isUsed()) &&
+  assert((Destructor->isImplicit() && !Destructor->isUsed(false)) &&
          "DefineImplicitDestructor - call it for implicit default dtor");
   CXXRecordDecl *ClassDecl = Destructor->getParent();
   assert(ClassDecl && "DefineImplicitDestructor - invalid destructor");
 
-  DeclContext *PreviousContext = CurContext;
-  CurContext = Destructor;
+  if (Destructor->isInvalidDecl())
+    return;
 
+  ImplicitlyDefinedFunctionScope Scope(*this, Destructor);
+
+  ErrorTrap Trap(*this);
   MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(),
                                          Destructor->getParent());
 
-  // FIXME: If CheckDestructor fails, we should emit a note about where the
-  // implicit destructor was needed.
-  if (CheckDestructor(Destructor)) {
+  if (CheckDestructor(Destructor) || Trap.hasErrorOccurred()) {
     Diag(CurrentLocation, diag::note_member_synthesized_at) 
       << CXXDestructor << Context.getTagDeclType(ClassDecl);
 
     Destructor->setInvalidDecl();
-    CurContext = PreviousContext;
-
     return;
   }
-  CurContext = PreviousContext;
 
   Destructor->setUsed();
+  MarkVTableUsed(CurrentLocation, ClassDecl);
 }
 
-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");
+/// \brief Builds a statement that copies the given entity from \p From to
+/// \c To.
+///
+/// This routine is used to copy the members of a class with an
+/// implicitly-declared copy assignment operator. When the entities being
+/// copied are arrays, this routine builds for loops to copy them.
+///
+/// \param S The Sema object used for type-checking.
+///
+/// \param Loc The location where the implicit copy is being generated.
+///
+/// \param T The type of the expressions being copied. Both expressions must
+/// have this type.
+///
+/// \param To The expression we are copying to.
+///
+/// \param From The expression we are copying from.
+///
+/// \param CopyingBaseSubobject Whether we're copying a base subobject.
+/// Otherwise, it's a non-static member subobject.
+///
+/// \param Depth Internal parameter recording the depth of the recursion.
+///
+/// \returns A statement or a loop that copies the expressions.
+static StmtResult
+BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, 
+                      Expr *To, Expr *From,
+                      bool CopyingBaseSubobject, unsigned Depth = 0) {
+  // C++0x [class.copy]p30:
+  //   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 (const RecordType *RecordTy = T->getAs<RecordType>()) {
+    CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(RecordTy->getDecl());
+    
+    // Look for operator=.
+    DeclarationName Name
+      = S.Context.DeclarationNames.getCXXOperatorName(OO_Equal);
+    LookupResult OpLookup(S, Name, Loc, Sema::LookupOrdinaryName);
+    S.LookupQualifiedName(OpLookup, ClassDecl, false);
+    
+    // Filter out any result that isn't a copy-assignment operator.
+    LookupResult::Filter F = OpLookup.makeFilter();
+    while (F.hasNext()) {
+      NamedDecl *D = F.next();
+      if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
+        if (Method->isCopyAssignmentOperator())
+          continue;
+      
+      F.erase();
+    }
+    F.done();
+    
+    // Suppress the protected check (C++ [class.protected]) for each of the
+    // assignment operators we found. This strange dance is required when 
+    // we're assigning via a base classes's copy-assignment operator. To
+    // ensure that we're getting the right base class subobject (without 
+    // ambiguities), we need to cast "this" to that subobject type; to
+    // ensure that we don't go through the virtual call mechanism, we need
+    // to qualify the operator= name with the base class (see below). However,
+    // this means that if the base class has a protected copy assignment
+    // operator, the protected member access check will fail. So, we
+    // rewrite "protected" access to "public" access in this case, since we
+    // know by construction that we're calling from a derived class.
+    if (CopyingBaseSubobject) {
+      for (LookupResult::iterator L = OpLookup.begin(), LEnd = OpLookup.end();
+           L != LEnd; ++L) {
+        if (L.getAccess() == AS_protected)
+          L.setAccess(AS_public);
+      }
+    }
+    
+    // Create the nested-name-specifier that will be used to qualify the
+    // reference to operator=; this is required to suppress the virtual
+    // call mechanism.
+    CXXScopeSpec SS;
+    SS.setRange(Loc);
+    SS.setScopeRep(NestedNameSpecifier::Create(S.Context, 0, false, 
+                                               T.getTypePtr()));
+    
+    // Create the reference to operator=.
+    ExprResult OpEqualRef
+      = S.BuildMemberReferenceExpr(To, T, Loc, /*isArrow=*/false, SS, 
+                                   /*FirstQualifierInScope=*/0, OpLookup, 
+                                   /*TemplateArgs=*/0,
+                                   /*SuppressQualifierCheck=*/true);
+    if (OpEqualRef.isInvalid())
+      return StmtError();
+    
+    // Build the call to the assignment operator.
 
-  CXXRecordDecl *ClassDecl
-    = cast<CXXRecordDecl>(MethodDecl->getDeclContext());
+    ExprResult Call = S.BuildCallToMemberFunction(/*Scope=*/0, 
+                                                      OpEqualRef.takeAs<Expr>(),
+                                                        Loc, &From, 1, 0, Loc);
+    if (Call.isInvalid())
+      return StmtError();
+    
+    return S.Owned(Call.takeAs<Stmt>());
+  }
 
-  DeclContext *PreviousContext = CurContext;
-  CurContext = MethodDecl;
+  //     - if the subobject is of scalar type, the built-in assignment 
+  //       operator is used.
+  const ConstantArrayType *ArrayTy = S.Context.getAsConstantArrayType(T);  
+  if (!ArrayTy) {
+    ExprResult Assignment = S.CreateBuiltinBinOp(Loc, BO_Assign, To, From);
+    if (Assignment.isInvalid())
+      return StmtError();
+    
+    return S.Owned(Assignment.takeAs<Stmt>());
+  }
+    
+  //     - if the subobject is an array, each element is assigned, in the 
+  //       manner appropriate to the element type;
+  
+  // Construct a loop over the array bounds, e.g.,
+  //
+  //   for (__SIZE_TYPE__ i0 = 0; i0 != array-size; ++i0)
+  //
+  // that will copy each of the array elements. 
+  QualType SizeType = S.Context.getSizeType();
+  
+  // Create the iteration variable.
+  IdentifierInfo *IterationVarName = 0;
+  {
+    llvm::SmallString<8> Str;
+    llvm::raw_svector_ostream OS(Str);
+    OS << "__i" << Depth;
+    IterationVarName = &S.Context.Idents.get(OS.str());
+  }
+  VarDecl *IterationVar = VarDecl::Create(S.Context, S.CurContext, Loc,
+                                          IterationVarName, SizeType,
+                            S.Context.getTrivialTypeSourceInfo(SizeType, Loc),
+                                          SC_None, SC_None);
+  
+  // Initialize the iteration variable to zero.
+  llvm::APInt Zero(S.Context.getTypeSize(SizeType), 0);
+  IterationVar->setInit(IntegerLiteral::Create(S.Context, Zero, SizeType, Loc));
 
-  // 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;
+  // Create a reference to the iteration variable; we'll use this several
+  // times throughout.
+  Expr *IterationVarRef
+    = S.BuildDeclRefExpr(IterationVar, SizeType, Loc).takeAs<Expr>();
+  assert(IterationVarRef && "Reference to invented variable cannot fail!");
+  
+  // Create the DeclStmt that holds the iteration variable.
+  Stmt *InitStmt = new (S.Context) DeclStmt(DeclGroupRef(IterationVar),Loc,Loc);
+  
+  // Create the comparison against the array bound.
+  llvm::APInt Upper = ArrayTy->getSize();
+  Upper.zextOrTrunc(S.Context.getTypeSize(SizeType));
+  Expr *Comparison
+    = new (S.Context) BinaryOperator(IterationVarRef->Retain(),
+                           IntegerLiteral::Create(S.Context,
+                                                  Upper, SizeType, Loc),
+                                                  BO_NE, S.Context.BoolTy, Loc);
+  
+  // Create the pre-increment of the iteration variable.
+  Expr *Increment
+    = new (S.Context) UnaryOperator(IterationVarRef->Retain(),
+                                    UO_PreInc,
+                                    SizeType, Loc);
+  
+  // Subscript the "from" and "to" expressions with the iteration variable.
+  From = AssertSuccess(S.CreateBuiltinArraySubscriptExpr(From, Loc,
+                                                         IterationVarRef, Loc));
+  To = AssertSuccess(S.CreateBuiltinArraySubscriptExpr(To, Loc,
+                                                       IterationVarRef, Loc));
+  
+  // Build the copy for an individual element of the array.
+  StmtResult Copy = BuildSingleCopyAssign(S, Loc, 
+                                                ArrayTy->getElementType(),
+                                                To, From, 
+                                                CopyingBaseSubobject, Depth+1);
+  if (Copy.isInvalid())
+    return StmtError();
+  
+  // Construct the loop that copies all elements of this array.
+  return S.ActOnForStmt(Loc, Loc, InitStmt, 
+                        S.MakeFullExpr(Comparison),
+                        0, S.MakeFullExpr(Increment),
+                        Loc, Copy.take());
+}
+
+/// \brief Determine whether the given class has a copy assignment operator 
+/// that accepts a const-qualified argument.
+static bool hasConstCopyAssignment(Sema &S, const CXXRecordDecl *CClass) {
+  CXXRecordDecl *Class = const_cast<CXXRecordDecl *>(CClass);
+  
+  if (!Class->hasDeclaredCopyAssignment())
+    S.DeclareImplicitCopyAssignment(Class);
+  
+  QualType ClassType = S.Context.getCanonicalType(S.Context.getTypeDeclType(Class));
+  DeclarationName OpName 
+    = S.Context.DeclarationNames.getCXXOperatorName(OO_Equal);
+    
+  DeclContext::lookup_const_iterator Op, OpEnd;
+  for (llvm::tie(Op, OpEnd) = Class->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 (!S.Context.hasSameUnqualifiedType(ArgType, ClassType))
+      continue;
+    
+    // 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(Class->isInvalidDecl() &&
+         "No copy assignment operator declared in valid code.");
+  return false;  
+}
+
+CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
+  // 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(),
-       E = ClassDecl->bases_end(); Base != E; ++Base) {
-    CXXRecordDecl *BaseClassDecl
+                                       BaseEnd = ClassDecl->bases_end();
+       HasConstCopyAssignment && Base != BaseEnd; ++Base) {
+    assert(!Base->getType()->isDependentType() &&
+           "Cannot generate implicit members for class with dependent bases.");
+    const 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);
+    HasConstCopyAssignment = hasConstCopyAssignment(*this, BaseClassDecl);
+  }
+  
+  //       -- 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(),
+                                  FieldEnd = ClassDecl->field_end();
+       HasConstCopyAssignment && Field != FieldEnd;
+       ++Field) {
+    QualType FieldType = Context.getBaseElementType((*Field)->getType());
+    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+      const CXXRecordDecl *FieldClassDecl
+        = cast<CXXRecordDecl>(FieldClassType->getDecl());
+      HasConstCopyAssignment = hasConstCopyAssignment(*this, FieldClassDecl);
     }
   }
+  
+  //   Otherwise, the implicitly declared copy assignment operator will
+  //   have the form
+  //
+  //       X& X::operator=(X&)
+  QualType ArgType = Context.getTypeDeclType(ClassDecl);
+  QualType RetType = Context.getLValueReferenceType(ArgType);
+  if (HasConstCopyAssignment)
+    ArgType = ArgType.withConst();
+  ArgType = Context.getLValueReferenceType(ArgType);
+  
+  // C++ [except.spec]p14:
+  //   An implicitly declared special member function (Clause 12) shall have an 
+  //   exception-specification. [...]
+  ImplicitExceptionSpecification ExceptSpec(Context);
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+                                       BaseEnd = ClassDecl->bases_end();
+       Base != BaseEnd; ++Base) {
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    
+    if (!BaseClassDecl->hasDeclaredCopyAssignment())
+      DeclareImplicitCopyAssignment(BaseClassDecl);
+
+    if (CXXMethodDecl *CopyAssign
+           = BaseClassDecl->getCopyAssignmentOperator(HasConstCopyAssignment))
+      ExceptSpec.CalledDecl(CopyAssign);
+  }
   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();
+                                  FieldEnd = ClassDecl->field_end();
+       Field != FieldEnd;
+       ++Field) {
+    QualType FieldType = Context.getBaseElementType((*Field)->getType());
     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());
+      
+      if (!FieldClassDecl->hasDeclaredCopyAssignment())
+        DeclareImplicitCopyAssignment(FieldClassDecl);
 
-        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 (CXXMethodDecl *CopyAssign
+            = FieldClassDecl->getCopyAssignmentOperator(HasConstCopyAssignment))
+        ExceptSpec.CalledDecl(CopyAssign);      
+    }      
   }
-  if (!err)
-    MethodDecl->setUsed();
-
-  CurContext = PreviousContext;
+  
+  //   An implicitly-declared copy assignment operator is an inline public
+  //   member of its class.
+  DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal);
+  DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
+  CXXMethodDecl *CopyAssignment
+    = CXXMethodDecl::Create(Context, ClassDecl, NameInfo,
+                            Context.getFunctionType(RetType, &ArgType, 1,
+                                                    false, 0,
+                                         ExceptSpec.hasExceptionSpecification(),
+                                      ExceptSpec.hasAnyExceptionSpecification(),
+                                                    ExceptSpec.size(),
+                                                    ExceptSpec.data(),
+                                                    FunctionType::ExtInfo()),
+                            /*TInfo=*/0, /*isStatic=*/false,
+                            /*StorageClassAsWritten=*/SC_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(),
+                                               /*Id=*/0,
+                                               ArgType, /*TInfo=*/0,
+                                               SC_None,
+                                               SC_None, 0);
+  CopyAssignment->setParams(&FromParam, 1);
+  
+  // Note that we have added this copy-assignment operator.
+  ClassDecl->setDeclaredCopyAssignment(true);
+  ++ASTContext::NumImplicitCopyAssignmentOperatorsDeclared;
+  
+  if (Scope *S = getScopeForContext(ClassDecl))
+    PushOnScopeChains(CopyAssignment, S, false);
+  ClassDecl->addDecl(CopyAssignment);
+  
+  AddOverriddenMethods(ClassDecl, CopyAssignment);
+  return CopyAssignment;
 }
 
-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::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
+                                        CXXMethodDecl *CopyAssignOperator) {
+  assert((CopyAssignOperator->isImplicit() && 
+          CopyAssignOperator->isOverloadedOperator() &&
+          CopyAssignOperator->getOverloadedOperator() == OO_Equal &&
+          !CopyAssignOperator->isUsed(false)) &&
+         "DefineImplicitCopyAssignment called for wrong function");
+
+  CXXRecordDecl *ClassDecl = CopyAssignOperator->getParent();
+
+  if (ClassDecl->isInvalidDecl() || CopyAssignOperator->isInvalidDecl()) {
+    CopyAssignOperator->setInvalidDecl();
+    return;
+  }
+  
+  CopyAssignOperator->setUsed();
+
+  ImplicitlyDefinedFunctionScope Scope(*this, CopyAssignOperator);
+  ErrorTrap Trap(*this);
+
+  // C++0x [class.copy]p30:
+  //   The implicitly-defined or explicitly-defaulted copy assignment operator
+  //   for a non-union class X performs memberwise copy assignment of its 
+  //   subobjects. The direct base classes of X are assigned first, in the 
+  //   order of their declaration in the base-specifier-list, and then the 
+  //   immediate non-static data members of X are assigned, in the order in 
+  //   which they were declared in the class definition.
+  
+  // The statements that form the synthesized function body.
+  ASTOwningVector<Stmt*> Statements(*this);
+  
+  // The parameter for the "other" object, which we are copying from.
+  ParmVarDecl *Other = CopyAssignOperator->getParamDecl(0);
+  Qualifiers OtherQuals = Other->getType().getQualifiers();
+  QualType OtherRefType = Other->getType();
+  if (const LValueReferenceType *OtherRef
+                                = OtherRefType->getAs<LValueReferenceType>()) {
+    OtherRefType = OtherRef->getPointeeType();
+    OtherQuals = OtherRefType.getQualifiers();
+  }
+  
+  // Our location for everything implicitly-generated.
+  SourceLocation Loc = CopyAssignOperator->getLocation();
+  
+  // Construct a reference to the "other" object. We'll be using this 
+  // throughout the generated ASTs.
+  Expr *OtherRef = BuildDeclRefExpr(Other, OtherRefType, Loc).takeAs<Expr>();
+  assert(OtherRef && "Reference to parameter cannot fail!");
+  
+  // Construct the "this" pointer. We'll be using this throughout the generated
+  // ASTs.
+  Expr *This = ActOnCXXThis(Loc).takeAs<Expr>();
+  assert(This && "Reference to this cannot fail!");
+  
+  // Assign base classes.
+  bool Invalid = false;
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+       E = ClassDecl->bases_end(); Base != E; ++Base) {
+    // Form the assignment:
+    //   static_cast<Base*>(this)->Base::operator=(static_cast<Base&>(other));
+    QualType BaseType = Base->getType().getUnqualifiedType();
+    CXXRecordDecl *BaseClassDecl = 0;
+    if (const RecordType *BaseRecordT = BaseType->getAs<RecordType>())
+      BaseClassDecl = cast<CXXRecordDecl>(BaseRecordT->getDecl());
+    else {
+      Invalid = true;
+      continue;
+    }
+
+    CXXCastPath BasePath;
+    BasePath.push_back(Base);
+
+    // Construct the "from" expression, which is an implicit cast to the
+    // appropriately-qualified base type.
+    Expr *From = OtherRef->Retain();
+    ImpCastExprToType(From, Context.getQualifiedType(BaseType, OtherQuals),
+                      CK_UncheckedDerivedToBase,
+                      VK_LValue, &BasePath);
+
+    // Dereference "this".
+    ExprResult To = CreateBuiltinUnaryOp(Loc, UO_Deref, This);
+    
+    // Implicitly cast "this" to the appropriately-qualified base type.
+    Expr *ToE = To.takeAs<Expr>();
+    ImpCastExprToType(ToE, 
+                      Context.getCVRQualifiedType(BaseType,
+                                      CopyAssignOperator->getTypeQualifiers()),
+                      CK_UncheckedDerivedToBase, 
+                      VK_LValue, &BasePath);
+    To = Owned(ToE);
+
+    // Build the copy.
+    StmtResult Copy = BuildSingleCopyAssign(*this, Loc, BaseType,
+                                            To.get(), From,
+                                            /*CopyingBaseSubobject=*/true);
+    if (Copy.isInvalid()) {
+      Diag(CurrentLocation, diag::note_member_synthesized_at) 
+        << CXXCopyAssignment << Context.getTagDeclType(ClassDecl);
+      CopyAssignOperator->setInvalidDecl();
+      return;
+    }
+    
+    // Success! Record the copy.
+    Statements.push_back(Copy.takeAs<Expr>());
+  }
+  
+  // \brief Reference to the __builtin_memcpy function.
+  Expr *BuiltinMemCpyRef = 0;
+  // \brief Reference to the __builtin_objc_memmove_collectable function.
+  Expr *CollectableMemCpyRef = 0;
+  
+  // Assign non-static members.
+  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+                                  FieldEnd = ClassDecl->field_end(); 
+       Field != FieldEnd; ++Field) {
+    // Check for members of reference type; we can't copy those.
+    if (Field->getType()->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_member_synthesized_at) 
+        << CXXCopyAssignment << Context.getTagDeclType(ClassDecl);
+      Invalid = true;
+      continue;
+    }
+    
+    // Check for members of const-qualified, non-class type.
+    QualType BaseType = Context.getBaseElementType(Field->getType());
+    if (!BaseType->getAs<RecordType>() && BaseType.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_member_synthesized_at) 
+        << CXXCopyAssignment << Context.getTagDeclType(ClassDecl);
+      Invalid = true;      
+      continue;
+    }
+    
+    QualType FieldType = Field->getType().getNonReferenceType();
+    if (FieldType->isIncompleteArrayType()) {
+      assert(ClassDecl->hasFlexibleArrayMember() && 
+             "Incomplete array type is not valid");
+      continue;
+    }
+    
+    // Build references to the field in the object we're copying from and to.
+    CXXScopeSpec SS; // Intentionally empty
+    LookupResult MemberLookup(*this, Field->getDeclName(), Loc,
+                              LookupMemberName);
+    MemberLookup.addDecl(*Field);
+    MemberLookup.resolveKind();
+    ExprResult From = BuildMemberReferenceExpr(OtherRef, OtherRefType,
+                                                     Loc, /*IsArrow=*/false,
+                                                     SS, 0, MemberLookup, 0);
+    ExprResult To = BuildMemberReferenceExpr(This, This->getType(),
+                                                   Loc, /*IsArrow=*/true,
+                                                   SS, 0, MemberLookup, 0);
+    assert(!From.isInvalid() && "Implicit field reference cannot fail");
+    assert(!To.isInvalid() && "Implicit field reference cannot fail");
+    
+    // If the field should be copied with __builtin_memcpy rather than via
+    // explicit assignments, do so. This optimization only applies for arrays 
+    // of scalars and arrays of class type with trivial copy-assignment 
+    // operators.
+    if (FieldType->isArrayType() &&
+        (!BaseType->isRecordType() || 
+         cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl())
+           ->hasTrivialCopyAssignment())) {
+      // Compute the size of the memory buffer to be copied.
+      QualType SizeType = Context.getSizeType();
+      llvm::APInt Size(Context.getTypeSize(SizeType), 
+                       Context.getTypeSizeInChars(BaseType).getQuantity());
+      for (const ConstantArrayType *Array
+              = Context.getAsConstantArrayType(FieldType);
+           Array; 
+           Array = Context.getAsConstantArrayType(Array->getElementType())) {
+        llvm::APInt ArraySize = Array->getSize();
+        ArraySize.zextOrTrunc(Size.getBitWidth());
+        Size *= ArraySize;
+      }
+          
+      // Take the address of the field references for "from" and "to".
+      From = CreateBuiltinUnaryOp(Loc, UO_AddrOf, From.get());
+      To = CreateBuiltinUnaryOp(Loc, UO_AddrOf, To.get());
+          
+      bool NeedsCollectableMemCpy = 
+          (BaseType->isRecordType() && 
+           BaseType->getAs<RecordType>()->getDecl()->hasObjectMember());
+          
+      if (NeedsCollectableMemCpy) {
+        if (!CollectableMemCpyRef) {
+          // Create a reference to the __builtin_objc_memmove_collectable function.
+          LookupResult R(*this, 
+                         &Context.Idents.get("__builtin_objc_memmove_collectable"), 
+                         Loc, LookupOrdinaryName);
+          LookupName(R, TUScope, true);
+        
+          FunctionDecl *CollectableMemCpy = R.getAsSingle<FunctionDecl>();
+          if (!CollectableMemCpy) {
+            // Something went horribly wrong earlier, and we will have 
+            // complained about it.
+            Invalid = true;
+            continue;
+          }
+        
+          CollectableMemCpyRef = BuildDeclRefExpr(CollectableMemCpy, 
+                                                  CollectableMemCpy->getType(),
+                                                  Loc, 0).takeAs<Expr>();
+          assert(CollectableMemCpyRef && "Builtin reference cannot fail");
+        }
+      }
+      // Create a reference to the __builtin_memcpy builtin function.
+      else if (!BuiltinMemCpyRef) {
+        LookupResult R(*this, &Context.Idents.get("__builtin_memcpy"), Loc,
+                       LookupOrdinaryName);
+        LookupName(R, TUScope, true);
+        
+        FunctionDecl *BuiltinMemCpy = R.getAsSingle<FunctionDecl>();
+        if (!BuiltinMemCpy) {
+          // Something went horribly wrong earlier, and we will have complained
+          // about it.
+          Invalid = true;
+          continue;
+        }
+
+        BuiltinMemCpyRef = BuildDeclRefExpr(BuiltinMemCpy, 
+                                            BuiltinMemCpy->getType(),
+                                            Loc, 0).takeAs<Expr>();
+        assert(BuiltinMemCpyRef && "Builtin reference cannot fail");
+      }
+          
+      ASTOwningVector<Expr*> CallArgs(*this);
+      CallArgs.push_back(To.takeAs<Expr>());
+      CallArgs.push_back(From.takeAs<Expr>());
+      CallArgs.push_back(IntegerLiteral::Create(Context, Size, SizeType, Loc));
+      llvm::SmallVector<SourceLocation, 4> Commas; // FIXME: Silly
+      Commas.push_back(Loc);
+      Commas.push_back(Loc);
+      ExprResult Call = ExprError();
+      if (NeedsCollectableMemCpy)
+        Call = ActOnCallExpr(/*Scope=*/0,
+                             CollectableMemCpyRef,
+                             Loc, move_arg(CallArgs), 
+                             Commas.data(), Loc);
+      else
+        Call = ActOnCallExpr(/*Scope=*/0,
+                             BuiltinMemCpyRef,
+                             Loc, move_arg(CallArgs), 
+                             Commas.data(), Loc);
+          
+      assert(!Call.isInvalid() && "Call to __builtin_memcpy cannot fail!");
+      Statements.push_back(Call.takeAs<Expr>());
+      continue;
+    }
+    
+    // Build the copy of this field.
+    StmtResult Copy = BuildSingleCopyAssign(*this, Loc, FieldType, 
+                                                  To.get(), From.get(),
+                                              /*CopyingBaseSubobject=*/false);
+    if (Copy.isInvalid()) {
+      Diag(CurrentLocation, diag::note_member_synthesized_at) 
+        << CXXCopyAssignment << Context.getTagDeclType(ClassDecl);
+      CopyAssignOperator->setInvalidDecl();
+      return;
+    }
+    
+    // Success! Record the copy.
+    Statements.push_back(Copy.takeAs<Stmt>());
+  }
+
+  if (!Invalid) {
+    // Add a "return *this;"
+    ExprResult ThisObj = CreateBuiltinUnaryOp(Loc, UO_Deref, This);
+    
+    StmtResult Return = ActOnReturnStmt(Loc, ThisObj.get());
+    if (Return.isInvalid())
+      Invalid = true;
+    else {
+      Statements.push_back(Return.takeAs<Stmt>());
+
+      if (Trap.hasErrorOccurred()) {
+        Diag(CurrentLocation, diag::note_member_synthesized_at) 
+          << CXXCopyAssignment << Context.getTagDeclType(ClassDecl);
+        Invalid = true;
+      }
+    }
+  }
+
+  if (Invalid) {
+    CopyAssignOperator->setInvalidDecl();
+    return;
+  }
+  
+  StmtResult Body = ActOnCompoundStmt(Loc, Loc, move_arg(Statements),
+                                            /*isStmtExpr=*/false);
+  assert(!Body.isInvalid() && "Compound statement creation cannot fail");
+  CopyAssignOperator->setBody(Body.takeAs<Stmt>());
+}
+
+CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
+                                                    CXXRecordDecl *ClassDecl) {
+  // 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(),
+                                       BaseEnd = ClassDecl->bases_end();
+       HasConstCopyConstructor && Base != BaseEnd; 
+       ++Base) {
+    // Virtual bases are handled below.
+    if (Base->isVirtual())
+      continue;
+    
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    if (!BaseClassDecl->hasDeclaredCopyConstructor())
+      DeclareImplicitCopyConstructor(BaseClassDecl);
+  
+    HasConstCopyConstructor
+      = BaseClassDecl->hasConstCopyConstructor(Context);
+  }
+
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
+                                       BaseEnd = ClassDecl->vbases_end();
+       HasConstCopyConstructor && Base != BaseEnd; 
+       ++Base) {
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    if (!BaseClassDecl->hasDeclaredCopyConstructor())
+      DeclareImplicitCopyConstructor(BaseClassDecl);
+    
+    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(),
+                                  FieldEnd = ClassDecl->field_end();
+       HasConstCopyConstructor && Field != FieldEnd;
+       ++Field) {
+    QualType FieldType = Context.getBaseElementType((*Field)->getType());
+    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+      CXXRecordDecl *FieldClassDecl
+        = cast<CXXRecordDecl>(FieldClassType->getDecl());
+      if (!FieldClassDecl->hasDeclaredCopyConstructor())
+        DeclareImplicitCopyConstructor(FieldClassDecl);
+
+      HasConstCopyConstructor
+        = FieldClassDecl->hasConstCopyConstructor(Context);
+    }
+  }
+  
+  //   Otherwise, the implicitly declared copy constructor will have
+  //   the form
+  //
+  //       X::X(X&)
+  QualType ClassType = Context.getTypeDeclType(ClassDecl);
+  QualType ArgType = ClassType;
+  if (HasConstCopyConstructor)
+    ArgType = ArgType.withConst();
+  ArgType = Context.getLValueReferenceType(ArgType);
+  
+  // C++ [except.spec]p14:
+  //   An implicitly declared special member function (Clause 12) shall have an 
+  //   exception-specification. [...]
+  ImplicitExceptionSpecification ExceptSpec(Context);
+  unsigned Quals = HasConstCopyConstructor? Qualifiers::Const : 0;
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+                                       BaseEnd = ClassDecl->bases_end();
+       Base != BaseEnd; 
+       ++Base) {
+    // Virtual bases are handled below.
+    if (Base->isVirtual())
+      continue;
+    
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    if (!BaseClassDecl->hasDeclaredCopyConstructor())
+      DeclareImplicitCopyConstructor(BaseClassDecl);
+
+    if (CXXConstructorDecl *CopyConstructor
+                          = BaseClassDecl->getCopyConstructor(Context, Quals))
+      ExceptSpec.CalledDecl(CopyConstructor);
+  }
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
+                                       BaseEnd = ClassDecl->vbases_end();
+       Base != BaseEnd; 
+       ++Base) {
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    if (!BaseClassDecl->hasDeclaredCopyConstructor())
+      DeclareImplicitCopyConstructor(BaseClassDecl);
+
+    if (CXXConstructorDecl *CopyConstructor
+                          = BaseClassDecl->getCopyConstructor(Context, Quals))
+      ExceptSpec.CalledDecl(CopyConstructor);
+  }
+  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+                                  FieldEnd = ClassDecl->field_end();
+       Field != FieldEnd;
+       ++Field) {
+    QualType FieldType = Context.getBaseElementType((*Field)->getType());
+    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+      CXXRecordDecl *FieldClassDecl
+        = cast<CXXRecordDecl>(FieldClassType->getDecl());
+      if (!FieldClassDecl->hasDeclaredCopyConstructor())
+        DeclareImplicitCopyConstructor(FieldClassDecl);
+
+      if (CXXConstructorDecl *CopyConstructor
+                          = FieldClassDecl->getCopyConstructor(Context, Quals))
+        ExceptSpec.CalledDecl(CopyConstructor);
+    }
+  }
+  
+  //   An implicitly-declared copy constructor is an inline public
+  //   member of its class.
+  DeclarationName Name
+    = Context.DeclarationNames.getCXXConstructorName(
+                                           Context.getCanonicalType(ClassType));
+  DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
+  CXXConstructorDecl *CopyConstructor
+    = CXXConstructorDecl::Create(Context, ClassDecl, NameInfo,
+                                 Context.getFunctionType(Context.VoidTy,
+                                                         &ArgType, 1,
+                                                         false, 0,
+                                         ExceptSpec.hasExceptionSpecification(),
+                                      ExceptSpec.hasAnyExceptionSpecification(),
+                                                         ExceptSpec.size(),
+                                                         ExceptSpec.data(),
+                                                       FunctionType::ExtInfo()),
+                                 /*TInfo=*/0,
+                                 /*isExplicit=*/false,
+                                 /*isInline=*/true,
+                                 /*isImplicitlyDeclared=*/true);
+  CopyConstructor->setAccess(AS_public);
+  CopyConstructor->setImplicit();
+  CopyConstructor->setTrivial(ClassDecl->hasTrivialCopyConstructor());
+  
+  // Note that we have declared this constructor.
+  ClassDecl->setDeclaredCopyConstructor(true);
+  ++ASTContext::NumImplicitCopyConstructorsDeclared;
+  
+  // Add the parameter to the constructor.
+  ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyConstructor,
+                                               ClassDecl->getLocation(),
+                                               /*IdentifierInfo=*/0,
+                                               ArgType, /*TInfo=*/0,
+                                               SC_None,
+                                               SC_None, 0);
+  CopyConstructor->setParams(&FromParam, 1);
+  if (Scope *S = getScopeForContext(ClassDecl))
+    PushOnScopeChains(CopyConstructor, S, false);
+  ClassDecl->addDecl(CopyConstructor);
+  
+  return CopyConstructor;
 }
 
 void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
@@ -4189,65 +5379,37 @@
                                    unsigned TypeQuals) {
   assert((CopyConstructor->isImplicit() &&
           CopyConstructor->isCopyConstructor(TypeQuals) &&
-          !CopyConstructor->isUsed()) &&
+          !CopyConstructor->isUsed(false)) &&
          "DefineImplicitCopyConstructor - call it for implicit copy ctor");
 
   CXXRecordDecl *ClassDecl = CopyConstructor->getParent();
   assert(ClassDecl && "DefineImplicitCopyConstructor - invalid constructor");
 
-  DeclContext *PreviousContext = CurContext;
-  CurContext = CopyConstructor;
+  ImplicitlyDefinedFunctionScope Scope(*this, CopyConstructor);
+  ErrorTrap Trap(*this);
 
-  // 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);
-    }
+  if (SetBaseOrMemberInitializers(CopyConstructor, 0, 0, /*AnyErrors=*/false) ||
+      Trap.hasErrorOccurred()) {
+    Diag(CurrentLocation, diag::note_member_synthesized_at) 
+      << CXXCopyConstructor << Context.getTagDeclType(ClassDecl);
+    CopyConstructor->setInvalidDecl();
+  }  else {
+    CopyConstructor->setBody(ActOnCompoundStmt(CopyConstructor->getLocation(),
+                                               CopyConstructor->getLocation(),
+                                               MultiStmtArg(*this, 0, 0), 
+                                               /*isStmtExpr=*/false)
+                                                              .takeAs<Stmt>());
   }
-  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
+ExprResult
 Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
                             CXXConstructorDecl *Constructor,
                             MultiExprArg ExprArgs,
                             bool RequiresZeroInit,
-                            bool BaseInitialization) {
+                            unsigned ConstructKind) {
   bool Elidable = false;
 
   // C++0x [class.copy]p34:
@@ -4263,38 +5425,40 @@
   if (Constructor->isCopyConstructor() && ExprArgs.size() >= 1) {
     Expr *SubExpr = ((Expr **)ExprArgs.get())[0];
     Elidable = SubExpr->isTemporaryObject() &&
+      ConstructKind == CXXConstructExpr::CK_Complete &&
       Context.hasSameUnqualifiedType(SubExpr->getType(), 
                            Context.getTypeDeclType(Constructor->getParent()));
   }
 
   return BuildCXXConstructExpr(ConstructLoc, DeclInitType, Constructor,
                                Elidable, move(ExprArgs), RequiresZeroInit,
-                               BaseInitialization);
+                               ConstructKind);
 }
 
 /// BuildCXXConstructExpr - Creates a complete call to a constructor,
 /// including handling of its default argument expressions.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
                             CXXConstructorDecl *Constructor, bool Elidable,
                             MultiExprArg ExprArgs,
                             bool RequiresZeroInit,
-                            bool BaseInitialization) {
+                            unsigned ConstructKind) {
   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));
+                                        RequiresZeroInit,
+              static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind)));
 }
 
 bool Sema::InitializeVarWithConstructor(VarDecl *VD,
                                         CXXConstructorDecl *Constructor,
                                         MultiExprArg Exprs) {
-  OwningExprResult TempResult =
+  ExprResult TempResult =
     BuildCXXConstructExpr(VD->getLocation(), VD->getType(), Constructor,
-                          move(Exprs));
+                          move(Exprs), false, CXXConstructExpr::CK_Complete);
   if (TempResult.isInvalid())
     return true;
 
@@ -4309,26 +5473,28 @@
 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);
+      !ClassDecl->hasTrivialDestructor() && !ClassDecl->isDependentContext()) {
+    CXXDestructorDecl *Destructor = LookupDestructor(ClassDecl);
     MarkDeclarationReferenced(VD->getLocation(), Destructor);
     CheckDestructorAccess(VD->getLocation(), Destructor,
                           PDiag(diag::err_access_dtor_var)
                             << VD->getDeclName()
                             << VD->getType());
+
+    if (!VD->isInvalidDecl() && VD->hasGlobalStorage())
+      Diag(VD->getLocation(), diag::warn_global_destructor);
   }
 }
 
 /// 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,
+void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl,
                                          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.
@@ -4356,9 +5522,6 @@
   // 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(),
@@ -4382,6 +5545,25 @@
     return;
   }
 
+  // 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). In that case, the member can appear
+  //   in integral constant expressions. The member shall still be
+  //   defined in a namespace scope if it is used in the program and the
+  //   namespace scope definition shall not contain an initializer.
+  //
+  // We already performed a redefinition check above, but for static
+  // data members we also need to check whether there was an in-class
+  // declaration with an initializer.
+  const VarDecl* PrevInit = 0;
+  if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) {
+    Diag(VDecl->getLocation(), diag::err_redefinition) << VDecl->getDeclName();
+    Diag(PrevInit->getLocation(), diag::note_previous_definition);
+    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.
@@ -4408,17 +5590,25 @@
                                        LParenLoc, RParenLoc);
   
   InitializationSequence InitSeq(*this, Entity, Kind, 
-                                 (Expr**)Exprs.get(), Exprs.size());
-  OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(Exprs));
+                                 Exprs.get(), Exprs.size());
+  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(Exprs));
   if (Result.isInvalid()) {
     VDecl->setInvalidDecl();
     return;
   }
   
-  Result = MaybeCreateCXXExprWithTemporaries(move(Result));
+  Result = MaybeCreateCXXExprWithTemporaries(Result.get());
   VDecl->setInit(Result.takeAs<Expr>());
   VDecl->setCXXDirectInitializer(true);
 
+    if (!VDecl->isInvalidDecl() &&
+        !VDecl->getDeclContext()->isDependentContext() &&
+        VDecl->hasGlobalStorage() &&
+        !VDecl->getInit()->isConstantInitializer(Context,
+                                        VDecl->getType()->isReferenceType()))
+      Diag(VDecl->getLocation(), diag::warn_global_constructor)
+        << VDecl->getInit()->getSourceRange();
+
   if (const RecordType *Record = VDecl->getType()->getAs<RecordType>())
     FinalizeVarWithDestructor(VDecl, Record);
 }
@@ -4432,7 +5622,7 @@
 Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor,
                               MultiExprArg ArgsPtr,
                               SourceLocation Loc,                                    
-                     ASTOwningVector<&ActionBase::DeleteExpr> &ConvertedArgs) {
+                              ASTOwningVector<Expr*> &ConvertedArgs) {
   // FIXME: This duplicates a lot of code from Sema::ConvertArgumentsForCall.
   unsigned NumArgs = ArgsPtr.size();
   Expr **Args = (Expr **)ArgsPtr.get();
@@ -4470,7 +5660,7 @@
   }
   
   if (isa<TranslationUnitDecl>(DC) && 
-      FnDecl->getStorageClass() == FunctionDecl::Static) {
+      FnDecl->getStorageClass() == SC_Static) {
     return SemaRef.Diag(FnDecl->getLocation(),
                         diag::err_operator_new_delete_declared_static)
       << FnDecl->getDeclName();
@@ -4576,18 +5766,6 @@
                                  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;
 }
 
@@ -4845,20 +6023,19 @@
 /// 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,
+Decl *Sema::ActOnStartLinkageSpecification(Scope *S,
                                                      SourceLocation ExternLoc,
                                                      SourceLocation LangLoc,
-                                                     const char *Lang,
-                                                     unsigned StrSize,
+                                                     llvm::StringRef Lang,
                                                      SourceLocation LBraceLoc) {
   LinkageSpecDecl::LanguageIDs Language;
-  if (strncmp(Lang, "\"C\"", StrSize) == 0)
+  if (Lang == "\"C\"")
     Language = LinkageSpecDecl::lang_c;
-  else if (strncmp(Lang, "\"C++\"", StrSize) == 0)
+  else if (Lang == "\"C++\"")
     Language = LinkageSpecDecl::lang_cxx;
   else {
     Diag(LangLoc, diag::err_bad_language);
-    return DeclPtrTy();
+    return 0;
   }
 
   // FIXME: Add all the various semantics of linkage specifications
@@ -4868,15 +6045,15 @@
                                                LBraceLoc.isValid());
   CurContext->addDecl(D);
   PushDeclContext(S, D);
-  return DeclPtrTy::make(D);
+  return D;
 }
 
-/// ActOnFinishLinkageSpecification - Completely the definition of
+/// ActOnFinishLinkageSpecification - Complete 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,
+Decl *Sema::ActOnFinishLinkageSpecification(Scope *S,
+                                                      Decl *LinkageSpec,
                                                       SourceLocation RBraceLoc) {
   if (LinkageSpec)
     PopDeclContext();
@@ -4938,10 +6115,32 @@
                              AbstractVariableType))
     Invalid = true;
 
-  VarDecl *ExDecl = VarDecl::Create(Context, CurContext, Loc,
-                                    Name, ExDeclType, TInfo, VarDecl::None,
-                                    VarDecl::None);
+  // Only the non-fragile NeXT runtime currently supports C++ catches
+  // of ObjC types, and no runtime supports catching ObjC types by value.
+  if (!Invalid && getLangOptions().ObjC1) {
+    QualType T = ExDeclType;
+    if (const ReferenceType *RT = T->getAs<ReferenceType>())
+      T = RT->getPointeeType();
 
+    if (T->isObjCObjectType()) {
+      Diag(Loc, diag::err_objc_object_catch);
+      Invalid = true;
+    } else if (T->isObjCObjectPointerType()) {
+      if (!getLangOptions().NeXTRuntime) {
+        Diag(Loc, diag::err_objc_pointer_cxx_catch_gnu);
+        Invalid = true;
+      } else if (!getLangOptions().ObjCNonFragileABI) {
+        Diag(Loc, diag::err_objc_pointer_cxx_catch_fragile);
+        Invalid = true;
+      }
+    }
+  }
+
+  VarDecl *ExDecl = VarDecl::Create(Context, CurContext, Loc,
+                                    Name, ExDeclType, TInfo, SC_None,
+                                    SC_None);
+  ExDecl->setExceptionVariable(true);
+  
   if (!Invalid) {
     if (const RecordType *RecordTy = ExDeclType->getAs<RecordType>()) {
       // C++ [except.handle]p16:
@@ -4959,8 +6158,8 @@
       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));
+      ExprResult Result = InitSeq.Perform(*this, Entity, Kind, 
+                                         MultiExprArg(*this, &ExDeclRef, 1));
       if (Result.isInvalid())
         Invalid = true;
       else 
@@ -4976,9 +6175,9 @@
 
 /// 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);
+Decl *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
+  QualType ExDeclType = TInfo->getType();
 
   bool Invalid = D.isInvalidType();
   IdentifierInfo *II = D.getIdentifier();
@@ -4987,7 +6186,7 @@
                                              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)));
+    assert(!S->isDeclScope(PrevDecl));
     if (PrevDecl->isTemplateParameter()) {
       // Maybe we will complain about the shadowed template parameter.
       DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
@@ -5015,22 +6214,20 @@
     CurContext->addDecl(ExDecl);
 
   ProcessDeclAttributes(S, ExDecl, D);
-  return DeclPtrTy::make(ExDecl);
+  return ExDecl;
 }
 
-Sema::DeclPtrTy Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
-                                                   ExprArg assertexpr,
-                                                   ExprArg assertmessageexpr) {
-  Expr *AssertExpr = (Expr *)assertexpr.get();
-  StringLiteral *AssertMessage =
-    cast<StringLiteral>((Expr *)assertmessageexpr.get());
+Decl *Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
+                                         Expr *AssertExpr,
+                                         Expr *AssertMessageExpr_) {
+  StringLiteral *AssertMessage = cast<StringLiteral>(AssertMessageExpr_);
 
   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();
+      return 0;
     }
 
     if (Value == 0) {
@@ -5039,13 +6236,11 @@
     }
   }
 
-  assertexpr.release();
-  assertmessageexpr.release();
   Decl *Decl = StaticAssertDecl::Create(Context, CurContext, AssertLoc,
                                         AssertExpr, AssertMessage);
 
   CurContext->addDecl(Decl);
-  return DeclPtrTy::make(Decl);
+  return Decl;
 }
 
 /// \brief Perform semantic analysis of the given friend type declaration.
@@ -5056,7 +6251,7 @@
   assert(TSInfo && "NULL TypeSourceInfo for friend type declaration");
   
   QualType T = TSInfo->getType();
-  SourceRange TypeRange = TSInfo->getTypeLoc().getSourceRange();
+  SourceRange TypeRange = TSInfo->getTypeLoc().getLocalSourceRange();
   
   if (!getLangOptions().CPlusPlus0x) {
     // C++03 [class.friend]p2:
@@ -5121,7 +6316,7 @@
 /// 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,
+Decl *Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
                                           MultiTemplateParamsArg TempParams) {
   SourceLocation Loc = DS.getSourceRange().getBegin();
 
@@ -5132,14 +6327,11 @@
   // 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);
+  TypeSourceInfo *TSI = GetTypeForDeclarator(TheDeclarator, S);
+  QualType T = TSI->getType();
   if (TheDeclarator.isInvalidType())
-    return DeclPtrTy();
+    return 0;
 
-  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.
@@ -5157,7 +6349,7 @@
   if (TempParams.size() && !T->isElaboratedTypeSpecifier()) {
     Diag(Loc, diag::err_tagless_friend_type_template)
       << DS.getSourceRange();
-    return DeclPtrTy();
+    return 0;
   }
   
   // C++98 [class.friend]p1: A friend of a class is a function
@@ -5182,18 +6374,17 @@
     D = CheckFriendTypeDecl(DS.getFriendSpecLoc(), TSI);
   
   if (!D)
-    return DeclPtrTy();
+    return 0;
   
   D->setAccess(AS_public);
   CurContext->addDecl(D);
 
-  return DeclPtrTy::make(D);
+  return D;
 }
 
-Sema::DeclPtrTy
-Sema::ActOnFriendFunctionDecl(Scope *S,
-                              Declarator &D,
-                              bool IsDefinition,
+Decl *Sema::ActOnFriendFunctionDecl(Scope *S,
+                                         Declarator &D,
+                                         bool IsDefinition,
                               MultiTemplateParamsArg TemplateParams) {
   const DeclSpec &DS = D.getDeclSpec();
 
@@ -5201,8 +6392,8 @@
   assert(DS.getStorageClassSpec() == DeclSpec::SCS_unspecified);
 
   SourceLocation Loc = D.getIdentifierLoc();
-  TypeSourceInfo *TInfo = 0;
-  QualType T = GetTypeForDeclarator(D, S, &TInfo);
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
+  QualType T = TInfo->getType();
 
   // C++ [class.friend]p1
   //   A friend of a class is a function or class....
@@ -5219,7 +6410,7 @@
 
     // It might be worthwhile to try to recover by creating an
     // appropriate declaration.
-    return DeclPtrTy();
+    return 0;
   }
 
   // C++ [namespace.memdef]p3
@@ -5238,7 +6429,8 @@
   //    namespace scope are not considered.
 
   CXXScopeSpec &ScopeQual = D.getCXXScopeSpec();
-  DeclarationName Name = GetNameForDeclarator(D);
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
   assert(Name);
 
   // The context we found the declaration in, or in which we should
@@ -5248,27 +6440,32 @@
   // FIXME: handle local classes
 
   // Recover from invalid scope qualifiers as if they just weren't there.
-  LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+  LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
                         ForRedeclaration);
   if (!ScopeQual.isInvalid() && ScopeQual.isSet()) {
-    // FIXME: RequireCompleteDeclContext
     DC = computeDeclContext(ScopeQual);
 
     // FIXME: handle dependent contexts
-    if (!DC) return DeclPtrTy();
+    if (!DC) return 0;
+    if (RequireCompleteDeclContext(ScopeQual, DC)) return 0;
 
     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.
+    // Ignore things found implicitly in the wrong scope.
     // 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)) {
+    LookupResult::Filter F = Previous.makeFilter();
+    while (F.hasNext()) {
+      NamedDecl *D = F.next();
+      if (!D->getDeclContext()->getLookupContext()->Equals(DC))
+        F.erase();
+    }
+    F.done();
+
+    if (Previous.empty()) {
       D.setInvalidType();
       Diag(Loc, diag::err_qualified_friend_not_found) << Name << T;
-      return DeclPtrTy();
+      return 0;
     }
 
     // C++ [class.friend]p1: A friend of a class is a function or
@@ -5320,7 +6517,7 @@
       Diag(Loc, diag::err_introducing_special_friend) <<
         (D.getName().getKind() == UnqualifiedId::IK_ConstructorName ? 0 :
          D.getName().getKind() == UnqualifiedId::IK_DestructorName ? 1 : 2);
-      return DeclPtrTy();
+      return 0;
     }
   }
 
@@ -5329,7 +6526,7 @@
                                           move(TemplateParams),
                                           IsDefinition,
                                           Redeclaration);
-  if (!ND) return DeclPtrTy();
+  if (!ND) return 0;
 
   assert(ND->getDeclContext() == DC);
   assert(ND->getLexicalDeclContext() == CurContext);
@@ -5353,13 +6550,12 @@
   FrD->setAccess(AS_public);
   CurContext->addDecl(FrD);
 
-  return DeclPtrTy::make(ND);
+  return ND;
 }
 
-void Sema::SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc) {
-  AdjustDeclIfTemplate(dcl);
+void Sema::SetDeclDeleted(Decl *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);
@@ -5527,9 +6723,8 @@
 /// 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) {
+void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) {
   // 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:
@@ -5539,10 +6734,9 @@
 }
 
 /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
-/// initializer for the out-of-line declaration 'Dcl'.
-void Sema::ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+/// initializer for the out-of-line declaration 'D'.
+void Sema::ActOnCXXExitDeclInitializer(Scope *S, Decl *D) {
   // If there is no declaration, there was an error parsing it.
-  Decl *D = Dcl.getAs<Decl>();
   if (D == 0) return;
 
   assert(D->isOutOfLine());
@@ -5552,8 +6746,7 @@
 /// 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) {
+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
@@ -5561,9 +6754,9 @@
   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);
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S, &OwnedTag);
+  QualType Ty = TInfo->getType();
   
   if (Ty->isFunctionType()) { // The declarator shall not specify a function...
                               // We exit without creating a CXXConditionDeclExpr because a FunctionDecl
@@ -5576,99 +6769,132 @@
     Diag(OwnedTag->getLocation(), diag::err_type_defined_in_condition);
   }
   
-  DeclPtrTy Dcl = ActOnDeclarator(S, D);
+  Decl *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))
+void Sema::MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,
+                          bool DefinitionRequired) {
+  // Ignore any vtable uses in unevaluated operands or for classes that do
+  // not have a vtable.
+  if (!Class->isDynamicClass() || Class->isDependentContext() ||
+      CurContext->isDependentContext() ||
+      ExprEvalContexts.back().Context == Unevaluated)
     return;
 
-  TemplateSpecializationKind kind = RD->getTemplateSpecializationKind();
-  if (kind == TSK_ImplicitInstantiation)
-    ClassesWithUnmarkedVirtualMembers.push_back(std::make_pair(RD, Loc));
+  // Try to insert this class into the map.
+  Class = cast<CXXRecordDecl>(Class->getCanonicalDecl());
+  std::pair<llvm::DenseMap<CXXRecordDecl *, bool>::iterator, bool>
+    Pos = VTablesUsed.insert(std::make_pair(Class, DefinitionRequired));
+  if (!Pos.second) {
+    // If we already had an entry, check to see if we are promoting this vtable
+    // to required a definition. If so, we need to reappend to the VTableUses
+    // list, since we may have already processed the first entry.
+    if (DefinitionRequired && !Pos.first->second) {
+      Pos.first->second = true;
+    } else {
+      // Otherwise, we can early exit.
+      return;
+    }
+  }
+
+  // Local classes need to have their virtual members marked
+  // immediately. For all other classes, we mark their virtual members
+  // at the end of the translation unit.
+  if (Class->isLocalClass())
+    MarkVirtualMembersReferenced(Loc, Class);
   else
-    MarkVirtualMembersReferenced(Loc, RD);
+    VTableUses.push_back(std::make_pair(Class, Loc));
 }
 
-bool Sema::ProcessPendingClassesWithUnmarkedVirtualMembers() {
-  if (ClassesWithUnmarkedVirtualMembers.empty())
+bool Sema::DefineUsedVTables() {
+  // If any dynamic classes have their key function defined within
+  // this translation unit, then those vtables are considered "used" and must
+  // be emitted.
+  for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I) {
+    if (const CXXMethodDecl *KeyFunction
+                             = Context.getKeyFunction(DynamicClasses[I])) {
+      const FunctionDecl *Definition = 0;
+      if (KeyFunction->hasBody(Definition))
+        MarkVTableUsed(Definition->getLocation(), DynamicClasses[I], true);
+    }
+  }
+
+  if (VTableUses.empty())
     return false;
   
-  while (!ClassesWithUnmarkedVirtualMembers.empty()) {
-    CXXRecordDecl *RD = ClassesWithUnmarkedVirtualMembers.back().first;
-    SourceLocation Loc = ClassesWithUnmarkedVirtualMembers.back().second;
-    ClassesWithUnmarkedVirtualMembers.pop_back();
-    MarkVirtualMembersReferenced(Loc, RD);
+  // Note: The VTableUses vector could grow as a result of marking
+  // the members of a class as "used", so we check the size each
+  // time through the loop and prefer indices (with are stable) to
+  // iterators (which are not).
+  for (unsigned I = 0; I != VTableUses.size(); ++I) {
+    CXXRecordDecl *Class = VTableUses[I].first->getDefinition();
+    if (!Class)
+      continue;
+
+    SourceLocation Loc = VTableUses[I].second;
+
+    // If this class has a key function, but that key function is
+    // defined in another translation unit, we don't need to emit the
+    // vtable even though we're using it.
+    const CXXMethodDecl *KeyFunction = Context.getKeyFunction(Class);
+    if (KeyFunction && !KeyFunction->hasBody()) {
+      switch (KeyFunction->getTemplateSpecializationKind()) {
+      case TSK_Undeclared:
+      case TSK_ExplicitSpecialization:
+      case TSK_ExplicitInstantiationDeclaration:
+        // The key function is in another translation unit.
+        continue;
+
+      case TSK_ExplicitInstantiationDefinition:
+      case TSK_ImplicitInstantiation:
+        // We will be instantiating the key function.
+        break;
+      }
+    } else if (!KeyFunction) {
+      // If we have a class with no key function that is the subject
+      // of an explicit instantiation declaration, suppress the
+      // vtable; it will live with the explicit instantiation
+      // definition.
+      bool IsExplicitInstantiationDeclaration
+        = Class->getTemplateSpecializationKind()
+                                      == TSK_ExplicitInstantiationDeclaration;
+      for (TagDecl::redecl_iterator R = Class->redecls_begin(),
+                                 REnd = Class->redecls_end();
+           R != REnd; ++R) {
+        TemplateSpecializationKind TSK
+          = cast<CXXRecordDecl>(*R)->getTemplateSpecializationKind();
+        if (TSK == TSK_ExplicitInstantiationDeclaration)
+          IsExplicitInstantiationDeclaration = true;
+        else if (TSK == TSK_ExplicitInstantiationDefinition) {
+          IsExplicitInstantiationDeclaration = false;
+          break;
+        }
+      }
+
+      if (IsExplicitInstantiationDeclaration)
+        continue;
+    }
+
+    // Mark all of the virtual members of this class as referenced, so
+    // that we can build a vtable. Then, tell the AST consumer that a
+    // vtable for this class is required.
+    MarkVirtualMembersReferenced(Loc, Class);
+    CXXRecordDecl *Canonical = cast<CXXRecordDecl>(Class->getCanonicalDecl());
+    Consumer.HandleVTable(Class, VTablesUsed[Canonical]);
+
+    // Optionally warn if we're emitting a weak vtable.
+    if (Class->getLinkage() == ExternalLinkage &&
+        Class->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
+      if (!KeyFunction || (KeyFunction->hasBody() && KeyFunction->isInlined()))
+        Diag(Class->getLocation(), diag::warn_weak_vtable) << Class;
+    }
   }
-  
+  VTableUses.clear();
+
   return true;
 }
 
@@ -5692,10 +6918,64 @@
            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);
   }
 }
+
+/// SetIvarInitializers - This routine builds initialization ASTs for the
+/// Objective-C implementation whose ivars need be initialized.
+void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) {
+  if (!getLangOptions().CPlusPlus)
+    return;
+  if (ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) {
+    llvm::SmallVector<ObjCIvarDecl*, 8> ivars;
+    CollectIvarsToConstructOrDestruct(OID, ivars);
+    if (ivars.empty())
+      return;
+    llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToInit;
+    for (unsigned i = 0; i < ivars.size(); i++) {
+      FieldDecl *Field = ivars[i];
+      if (Field->isInvalidDecl())
+        continue;
+      
+      CXXBaseOrMemberInitializer *Member;
+      InitializedEntity InitEntity = InitializedEntity::InitializeMember(Field);
+      InitializationKind InitKind = 
+        InitializationKind::CreateDefault(ObjCImplementation->getLocation());
+      
+      InitializationSequence InitSeq(*this, InitEntity, InitKind, 0, 0);
+      ExprResult MemberInit = 
+        InitSeq.Perform(*this, InitEntity, InitKind, MultiExprArg());
+      MemberInit = MaybeCreateCXXExprWithTemporaries(MemberInit.get());
+      // Note, MemberInit could actually come back empty if no initialization 
+      // is required (e.g., because it would call a trivial default constructor)
+      if (!MemberInit.get() || MemberInit.isInvalid())
+        continue;
+      
+      Member =
+        new (Context) CXXBaseOrMemberInitializer(Context,
+                                                 Field, SourceLocation(),
+                                                 SourceLocation(),
+                                                 MemberInit.takeAs<Expr>(),
+                                                 SourceLocation());
+      AllToInit.push_back(Member);
+      
+      // Be sure that the destructor is accessible and is marked as referenced.
+      if (const RecordType *RecordTy
+                  = Context.getBaseElementType(Field->getType())
+                                                        ->getAs<RecordType>()) {
+                    CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
+        if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) {
+          MarkDeclarationReferenced(Field->getLocation(), Destructor);
+          CheckDestructorAccess(Field->getLocation(), Destructor,
+                            PDiag(diag::err_access_dtor_ivar)
+                              << Context.getBaseElementType(Field->getType()));
+        }
+      }      
+    }
+    ObjCImplementation->setIvarInitializers(Context, 
+                                            AllToInit.data(), AllToInit.size());
+  }
+}
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 0e93ebd..ac9d076 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -11,20 +11,24 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
 #include "clang/Sema/ExternalSemaSource.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Sema/DeclSpec.h"
+#include "llvm/ADT/DenseSet.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) {
+void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
   assert(getCurMethodDecl() == 0 && "Method parsing confused");
-  ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D.getAs<Decl>());
+  ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
 
   // If we don't have a valid method decl, simply return.
   if (!MDecl)
@@ -32,10 +36,10 @@
 
   // Allow the rest of sema to find private method decl implementations.
   if (MDecl->isInstanceMethod())
-    AddInstanceMethodToGlobalPool(MDecl);
+    AddInstanceMethodToGlobalPool(MDecl, true);
   else
-    AddFactoryMethodToGlobalPool(MDecl);
-
+    AddFactoryMethodToGlobalPool(MDecl, true);
+  
   // Allow all of Sema to see that we are entering a method definition.
   PushDeclContext(FnBodyScope, MDecl);
   PushFunctionScope();
@@ -56,11 +60,11 @@
       PushOnScopeChains(*PI, FnBodyScope);
 }
 
-Sema::DeclPtrTy Sema::
+Decl *Sema::
 ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
                          IdentifierInfo *ClassName, SourceLocation ClassLoc,
                          IdentifierInfo *SuperName, SourceLocation SuperLoc,
-                         const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs,
+                         Decl * const *ProtoRefs, unsigned NumProtoRefs,
                          const SourceLocation *ProtoLocs, 
                          SourceLocation EndProtoLoc, AttributeList *AttrList) {
   assert(ClassName && "Missing class identifier");
@@ -84,11 +88,14 @@
 
       // Return the previous class interface.
       // FIXME: don't leak the objects passed in!
-      return DeclPtrTy::make(IDecl);
+      return IDecl;
     } else {
       IDecl->setLocation(AtInterfaceLoc);
       IDecl->setForwardDecl(false);
       IDecl->setClassLoc(ClassLoc);
+      // If the forward decl was in a PCH, we need to write it again in a
+      // dependent AST file.
+      IDecl->setChangedSinceDeserialization(true);
       
       // Since this ObjCInterfaceDecl was created by a forward declaration,
       // we now add it to the DeclContext since it wasn't added before
@@ -142,8 +149,8 @@
         // 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())
+          if (T->isObjCObjectType()) {
+            if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface())
               SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
           }
         }
@@ -176,7 +183,7 @@
     IDecl->setLocEnd(ClassLoc);
   }
 
-  /// Check then save referenced protocols.
+  // Check then save referenced protocols.
   if (NumProtoRefs) {
     IDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
                            ProtoLocs, Context);
@@ -184,16 +191,16 @@
   }
 
   CheckObjCDeclScope(IDecl);
-  return DeclPtrTy::make(IDecl);
+  return 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) {
+Decl *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);
@@ -203,15 +210,15 @@
     else
       Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName;
     Diag(ADecl->getLocation(), diag::note_previous_declaration);
-    return DeclPtrTy();
+    return 0;
   }
   // 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()) {
+    if (T->isObjCObjectType()) {
+      if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) {
         ClassName = IDecl->getIdentifier();
         CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
                                   LookupOrdinaryName, ForRedeclaration);
@@ -223,7 +230,7 @@
     Diag(ClassLocation, diag::warn_undef_interface) << ClassName;
     if (CDeclU)
       Diag(CDeclU->getLocation(), diag::note_previous_declaration);
-    return DeclPtrTy();
+    return 0;
   }
 
   // Everything checked out, instantiate a new alias declaration AST.
@@ -233,7 +240,7 @@
   if (!CheckObjCDeclScope(AliasDecl))
     PushOnScopeChains(AliasDecl, TUScope);
 
-  return DeclPtrTy::make(AliasDecl);
+  return AliasDecl;
 }
 
 void Sema::CheckForwardProtocolDeclarationForCircularDependency(
@@ -255,11 +262,11 @@
   }
 }
 
-Sema::DeclPtrTy
+Decl *
 Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
                                   IdentifierInfo *ProtocolName,
                                   SourceLocation ProtocolLoc,
-                                  const DeclPtrTy *ProtoRefs,
+                                  Decl * const *ProtoRefs,
                                   unsigned NumProtoRefs,
                                   const SourceLocation *ProtoLocs,
                                   SourceLocation EndProtoLoc,
@@ -274,17 +281,19 @@
       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);
+      return 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);
+    CurContext->addDecl(PDecl);
+    // Repeat in dependent AST files.
+    PDecl->setChangedSinceDeserialization(true);
   } else {
     PDecl = ObjCProtocolDecl::Create(Context, CurContext,
                                      AtProtoInterfaceLoc,ProtocolName);
@@ -301,7 +310,7 @@
   }
 
   CheckObjCDeclScope(PDecl);
-  return DeclPtrTy::make(PDecl);
+  return PDecl;
 }
 
 /// FindProtocolDeclaration - This routine looks up protocols and
@@ -311,7 +320,7 @@
 Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
                               const IdentifierLocPair *ProtocolId,
                               unsigned NumProtocols,
-                              llvm::SmallVectorImpl<DeclPtrTy> &Protocols) {
+                              llvm::SmallVectorImpl<Decl *> &Protocols) {
   for (unsigned i = 0; i != NumProtocols; ++i) {
     ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolId[i].first,
                                              ProtocolId[i].second);
@@ -340,7 +349,7 @@
     if (WarnOnDeclarations && PDecl->isForwardDecl())
       Diag(ProtocolId[i].second, diag::warn_undef_protocolref)
         << ProtocolId[i].first;
-    Protocols.push_back(DeclPtrTy::make(PDecl));
+    Protocols.push_back(PDecl);
   }
 }
 
@@ -374,7 +383,7 @@
 }
 
 /// ActOnForwardProtocolDeclaration - Handle @protocol foo;
-Action::DeclPtrTy
+Decl *
 Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
                                       const IdentifierLocPair *IdentList,
                                       unsigned NumElts,
@@ -385,13 +394,18 @@
   for (unsigned i = 0; i != NumElts; ++i) {
     IdentifierInfo *Ident = IdentList[i].first;
     ObjCProtocolDecl *PDecl = LookupProtocol(Ident, IdentList[i].second);
+    bool isNew = false;
     if (PDecl == 0) { // Not already seen?
       PDecl = ObjCProtocolDecl::Create(Context, CurContext,
                                        IdentList[i].second, Ident);
-      PushOnScopeChains(PDecl, TUScope);
+      PushOnScopeChains(PDecl, TUScope, false);
+      isNew = true;
     }
-    if (attrList)
+    if (attrList) {
       ProcessDeclAttributeList(TUScope, PDecl, attrList);
+      if (!isNew)
+        PDecl->setChangedSinceDeserialization(true);
+    }
     Protocols.push_back(PDecl);
     ProtoLocs.push_back(IdentList[i].second);
   }
@@ -402,19 +416,19 @@
                                     ProtoLocs.data());
   CurContext->addDecl(PDecl);
   CheckObjCDeclScope(PDecl);
-  return DeclPtrTy::make(PDecl);
+  return PDecl;
 }
 
-Sema::DeclPtrTy Sema::
+Decl *Sema::
 ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
                             IdentifierInfo *ClassName, SourceLocation ClassLoc,
                             IdentifierInfo *CategoryName,
                             SourceLocation CategoryLoc,
-                            const DeclPtrTy *ProtoRefs,
+                            Decl * const *ProtoRefs,
                             unsigned NumProtoRefs,
                             const SourceLocation *ProtoLocs,
                             SourceLocation EndProtoLoc) {
-  ObjCCategoryDecl *CDecl = 0;
+  ObjCCategoryDecl *CDecl;
   ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
 
   /// Check that class of this category is already completely declared.
@@ -426,31 +440,24 @@
                                      ClassLoc, CategoryLoc, CategoryName);
     CDecl->setInvalidDecl();
     Diag(ClassLoc, diag::err_undef_interface) << ClassName;
-    return DeclPtrTy::make(CDecl);
+    return 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 (!CategoryName && 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 = 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();
-  }
+  CDecl->setClassInterface(IDecl);
+  // Insert 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);
@@ -483,13 +490,13 @@
   }
 
   CheckObjCDeclScope(CDecl);
-  return DeclPtrTy::make(CDecl);
+  return CDecl;
 }
 
 /// ActOnStartCategoryImplementation - Perform semantic checks on the
 /// category implementation declaration and build an ObjCCategoryImplDecl
 /// object.
-Sema::DeclPtrTy Sema::ActOnStartCategoryImplementation(
+Decl *Sema::ActOnStartCategoryImplementation(
                       SourceLocation AtCatImplLoc,
                       IdentifierInfo *ClassName, SourceLocation ClassLoc,
                       IdentifierInfo *CatName, SourceLocation CatLoc) {
@@ -530,10 +537,10 @@
   }
 
   CheckObjCDeclScope(CDecl);
-  return DeclPtrTy::make(CDecl);
+  return CDecl;
 }
 
-Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
+Decl *Sema::ActOnStartClassImplementation(
                       SourceLocation AtClassImplLoc,
                       IdentifierInfo *ClassName, SourceLocation ClassLoc,
                       IdentifierInfo *SuperClassname,
@@ -624,7 +631,7 @@
                                    IDecl, SDecl);
 
   if (CheckObjCDeclScope(IMPDecl))
-    return DeclPtrTy::make(IMPDecl);
+    return IMPDecl;
 
   // Check that there is no duplicate implementation of this class.
   if (IDecl->getImplementation()) {
@@ -636,7 +643,7 @@
     IDecl->setImplementation(IMPDecl);
     PushOnScopeChains(IMPDecl, TUScope);
   }
-  return DeclPtrTy::make(IMPDecl);
+  return IMPDecl;
 }
 
 void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
@@ -763,6 +770,10 @@
       << (*IM)->getType();
     Diag((*IF)->getLocation(), diag::note_previous_definition);
   }
+  if (ImpMethodDecl->isVariadic() != IntfMethodDecl->isVariadic()) {
+    Diag(ImpMethodDecl->getLocation(), diag::warn_conflicting_variadic);
+    Diag(IntfMethodDecl->getLocation(), diag::note_previous_declaration);
+  }
 }
 
 /// FIXME: Type hierarchies in Objective-C can be deep. We could most likely
@@ -925,7 +936,7 @@
   }
 }
 
-void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
+void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
                                      ObjCContainerDecl* CDecl,
                                      bool IncompleteImpl) {
   llvm::DenseSet<Selector> InsMap;
@@ -938,8 +949,8 @@
   // 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);
+  if (isa<ObjCInterfaceDecl>(CDecl) && !LangOpts.ObjCNonFragileABI2)
+    DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, InsMap);
       
   llvm::DenseSet<Selector> ClsMap;
   for (ObjCImplementationDecl::classmeth_iterator
@@ -965,13 +976,11 @@
       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;
-      }
-    }
+    for (const ObjCCategoryDecl *Categories = I->getFirstClassExtension();
+         Categories; Categories = Categories->getNextClassExtension())
+      ImplMethodsVsClassMethods(S, IMPDecl, 
+                                const_cast<ObjCCategoryDecl*>(Categories), 
+                                IncompleteImpl);
   } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
     // For extended class, unimplemented methods in its protocols will
     // be reported in the primary class.
@@ -990,14 +999,14 @@
                I = IMP->instmeth_begin(), E = IMP->instmeth_end(); I!=E; ++I)
             InsMap.insert((*I)->getSelector());
         }
-      DiagnoseUnimplementedProperties(IMPDecl, CDecl, InsMap);      
+      DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, InsMap);      
     } 
   } else
     assert(false && "invalid ObjCContainerDecl type.");
 }
 
 /// ActOnForwardClassDeclaration -
-Action::DeclPtrTy
+Decl *
 Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
                                    IdentifierInfo **IdentList,
                                    SourceLocation *IdentLocs,
@@ -1024,15 +1033,15 @@
       //
       // FIXME: Make an extension?
       TypedefDecl *TDD = dyn_cast<TypedefDecl>(PrevDecl);
-      if (!TDD || !isa<ObjCInterfaceType>(TDD->getUnderlyingType())) {
+      if (!TDD || !TDD->getUnderlyingType()->isObjCObjectType()) {
         Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i];
         Diag(PrevDecl->getLocation(), diag::note_previous_definition);
-      } else if (TDD) {
+      } else {
         // 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();
+        if (const ObjCObjectType *OI =
+              TDD->getUnderlyingType()->getAs<ObjCObjectType>())
+          PrevDecl = OI->getInterface();
       }
     }
     ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
@@ -1058,7 +1067,7 @@
                                                Interfaces.size());
   CurContext->addDecl(CDecl);
   CheckObjCDeclScope(CDecl);
-  return DeclPtrTy::make(CDecl);
+  return CDecl;
 }
 
 
@@ -1067,13 +1076,14 @@
 /// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
 bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
                                       const ObjCMethodDecl *PrevMethod,
-                                      bool matchBasedOnSizeAndAlignment) {
+                                      bool matchBasedOnSizeAndAlignment,
+                                      bool matchBasedOnStrictEqulity) {
   QualType T1 = Context.getCanonicalType(Method->getResultType());
   QualType T2 = Context.getCanonicalType(PrevMethod->getResultType());
 
   if (T1 != T2) {
     // The result types are different.
-    if (!matchBasedOnSizeAndAlignment)
+    if (!matchBasedOnSizeAndAlignment || matchBasedOnStrictEqulity)
       return false;
     // Incomplete types don't have a size and alignment.
     if (T1->isIncompleteType() || T2->isIncompleteType())
@@ -1093,7 +1103,7 @@
     T2 = Context.getCanonicalType((*PrevI)->getType());
     if (T1 != T2) {
       // The result types are different.
-      if (!matchBasedOnSizeAndAlignment)
+      if (!matchBasedOnSizeAndAlignment || matchBasedOnStrictEqulity)
         return false;
       // Incomplete types don't have a size and alignment.
       if (T1->isIncompleteType() || T2->isIncompleteType())
@@ -1106,47 +1116,34 @@
   return true;
 }
 
-/// \brief Read the contents of the instance and factory method pools
-/// for a given selector from external storage.
+/// \brief Read the contents of the method pool 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) {
+/// This routine should only be called once, when the method pool has no entry
+/// for this selector.
+Sema::GlobalMethodPool::iterator Sema::ReadMethodPool(Selector Sel) {
   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");
+  assert(MethodPool.find(Sel) == MethodPool.end() &&
+         "Selector data already loaded into the method pool");
 
   // Read the method list from the external source.
-  std::pair<ObjCMethodList, ObjCMethodList> Methods
-    = ExternalSource->ReadMethodPool(Sel);
+  GlobalMethods 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;
+  return MethodPool.insert(std::make_pair(Sel, Methods)).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);
+void Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl,
+                                 bool instance) {
+  GlobalMethodPool::iterator Pos = MethodPool.find(Method->getSelector());
+  if (Pos == MethodPool.end()) {
+    if (ExternalSource)
+      Pos = ReadMethodPool(Method->getSelector());
     else
-      Pos = InstanceMethodPool.insert(std::make_pair(Method->getSelector(),
-                                                     ObjCMethodList())).first;
+      Pos = MethodPool.insert(std::make_pair(Method->getSelector(),
+                                             GlobalMethods())).first;
   }
-
-  ObjCMethodList &Entry = Pos->second;
+  Method->setDefined(impl);
+  ObjCMethodList &Entry = instance ? Pos->second.first : Pos->second.second;
   if (Entry.Method == 0) {
     // Haven't seen a method with this selector name yet - add it.
     Entry.Method = Method;
@@ -1157,8 +1154,10 @@
   // 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))
+    if (MatchTwoMethodDeclarations(Method, List->Method)) {
+      List->Method->setDefined(impl);
       return;
+    }
 
   // We have a new signature for an existing method - add it.
   // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
@@ -1166,102 +1165,65 @@
   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);
+ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R,
+                                               bool receiverIdOrClass,
+                                               bool warn, bool instance) {
+  GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
+  if (Pos == MethodPool.end()) {
+    if (ExternalSource)
+      Pos = ReadMethodPool(Sel);
     else
       return 0;
   }
 
-  ObjCMethodList &MethList = Pos->second;
-  bool issueWarning = false;
+  ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;
 
-  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;
-}
+  bool strictSelectorMatch = receiverIdOrClass && warn &&
+    (Diags.getDiagnosticLevel(diag::warn_strict_multiple_method_decl) != 
+      Diagnostic::Ignored);
+  if (warn && MethList.Method && MethList.Next) {
+    bool issueWarning = false;
+    if (strictSelectorMatch)
+      for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next) {
+        // This checks if the methods differ in type mismatch.
+        if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, false, true))
+          issueWarning = true;
+      }
 
-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;
-  }
+    if (!issueWarning)
+      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;
+      }
 
-  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;
+    if (issueWarning) {
+      if (strictSelectorMatch)
+        Diag(R.getBegin(), diag::warn_strict_multiple_method_decl) << Sel << R;
+      else
+        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;
 }
 
-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;
-  }
+ObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) {
+  GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
+  if (Pos == MethodPool.end())
+    return 0;
 
-  ObjCMethodList &MethList = Pos->second;
-  bool issueWarning = false;
+  GlobalMethods &Methods = Pos->second;
 
-  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;
+  if (Methods.first.Method && Methods.first.Method->isDefined())
+    return Methods.first.Method;
+  if (Methods.second.Method && Methods.second.Method->isDefined())
+    return Methods.second.Method;
+  return 0;
 }
 
 /// CompareMethodParamsInBaseAndSuper - This routine compares methods with
@@ -1326,13 +1288,11 @@
 
 // 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,
+void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
+                      Decl *ClassDecl,
+                      Decl **allMethods, unsigned allNum,
+                      Decl **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.
@@ -1361,7 +1321,7 @@
 
   for (unsigned i = 0; i < allNum; i++ ) {
     ObjCMethodDecl *Method =
-      cast_or_null<ObjCMethodDecl>(allMethods[i].getAs<Decl>());
+      cast_or_null<ObjCMethodDecl>(allMethods[i]);
 
     if (!Method) continue;  // Already issued a diagnostic.
     if (Method->isInstanceMethod()) {
@@ -1408,14 +1368,14 @@
     // Compares properties declared in this class to those of its
     // super class.
     ComparePropertiesInBaseAndSuper(I);
-    CompareProperties(I, DeclPtrTy::make(I));
+    CompareProperties(I, 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));
+    CompareProperties(C, C);
     if (C->IsClassExtension())
       DiagnoseClassExtensionDupMethods(C, C->getClassInterface());
   }
@@ -1433,14 +1393,18 @@
   if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
     IC->setAtEndRange(AtEnd);
     if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) {
-      ImplMethodsVsClassMethods(IC, IDecl);
+      if (LangOpts.ObjCNonFragileABI2)
+        DefaultSynthesizeProperties(S, IC, IDecl);
+      ImplMethodsVsClassMethods(S, IC, IDecl);
       AtomicPropertySetterGetterRules(IC, IDecl);
+  
       if (LangOpts.ObjCNonFragileABI2)
         while (IDecl->getSuperClass()) {
           DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass());
           IDecl = IDecl->getSuperClass();
         }
     }
+    SetIvarInitializers(IC);
   } else if (ObjCCategoryImplDecl* CatImplClass =
                                    dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
     CatImplClass->setAtEndRange(AtEnd);
@@ -1451,7 +1415,7 @@
       for (ObjCCategoryDecl *Categories = IDecl->getCategoryList();
            Categories; Categories = Categories->getNextClassCategory()) {
         if (Categories->getIdentifier() == CatImplClass->getIdentifier()) {
-          ImplMethodsVsClassMethods(CatImplClass, Categories);
+          ImplMethodsVsClassMethods(S, CatImplClass, Categories);
           break;
         }
       }
@@ -1493,19 +1457,20 @@
 }
 
 static inline
-bool containsInvalidMethodImplAttribute(const AttributeList *A) {
+bool containsInvalidMethodImplAttribute(const AttrVec &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;
+  for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i)
+    if ((*i)->getKind() != attr::IBAction)
+      return true;
+  return false;
 }
 
-Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
+Decl *Sema::ActOnMethodDeclaration(
     SourceLocation MethodLoc, SourceLocation EndLoc,
-    tok::TokenKind MethodType, DeclPtrTy classDecl,
-    ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
+    tok::TokenKind MethodType, Decl *ClassDecl,
+    ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
     Selector Sel,
     // optional arguments. The number of types/arguments is obtained
     // from the Sel.getNumArgs().
@@ -1513,13 +1478,11 @@
     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();
+    getCurFunction()->LabelMap.clear();
+    return 0;
   }
   QualType resultDeclType;
 
@@ -1529,10 +1492,10 @@
 
     // Methods cannot return interface types. All ObjC objects are
     // passed by reference.
-    if (resultDeclType->isObjCInterfaceType()) {
+    if (resultDeclType->isObjCObjectType()) {
       Diag(MethodLoc, diag::err_object_cannot_be_passed_returned_by_value)
         << 0 << resultDeclType;
-      return DeclPtrTy();
+      return 0;
     }
   } else // get the type for "id".
     resultDeclType = Context.getObjCIdType();
@@ -1542,7 +1505,7 @@
                            ResultTInfo,
                            cast<DeclContext>(ClassDecl),
                            MethodType == tok::minus, isVariadic,
-                           false,
+                           false, false,
                            MethodDeclKind == tok::objc_optional ?
                            ObjCMethodDecl::Optional :
                            ObjCMethodDecl::Required);
@@ -1565,9 +1528,9 @@
     ParmVarDecl* Param
       = ParmVarDecl::Create(Context, ObjCMethod, ArgInfo[i].NameLoc,
                             ArgInfo[i].Name, ArgType, DI,
-                            VarDecl::None, VarDecl::None, 0);
+                            SC_None, SC_None, 0);
 
-    if (ArgType->isObjCInterfaceType()) {
+    if (ArgType->isObjCObjectType()) {
       Diag(ArgInfo[i].NameLoc,
            diag::err_object_cannot_be_passed_returned_by_value)
         << 1 << ArgType;
@@ -1584,21 +1547,22 @@
   }
 
   for (unsigned i = 0, e = CNumArgs; i != e; ++i) {
-    ParmVarDecl *Param = CParamInfo[i].Param.getAs<ParmVarDecl>();
+    ParmVarDecl *Param = cast<ParmVarDecl>(CParamInfo[i].Param);
     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()) {
+    if (ArgType->isObjCObjectType()) {
       Diag(Param->getLocation(),
            diag::err_object_cannot_be_passed_returned_by_value)
       << 1 << ArgType;
       Param->setInvalidDecl();
     }
     Param->setDeclContext(ObjCMethod);
-    IdResolver.RemoveDecl(Param);
+    if (Param->getDeclName())
+      IdResolver.RemoveDecl(Param);
     Params.push_back(Param);
   }
   
@@ -1628,7 +1592,8 @@
     }
     InterfaceMD = ImpDecl->getClassInterface()->getMethod(Sel,
                                                    MethodType == tok::minus);
-    if (containsInvalidMethodImplAttribute(AttrList))
+    if (ObjCMethod->hasAttrs() &&
+        containsInvalidMethodImplAttribute(ObjCMethod->getAttrs()))
       Diag(EndLoc, diag::warn_attribute_method_def);
   } else if (ObjCCategoryImplDecl *CatImpDecl =
              dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
@@ -1639,7 +1604,8 @@
       PrevMethod = CatImpDecl->getClassMethod(Sel);
       CatImpDecl->addClassMethod(ObjCMethod);
     }
-    if (containsInvalidMethodImplAttribute(AttrList))
+    if (ObjCMethod->hasAttrs() &&
+        containsInvalidMethodImplAttribute(ObjCMethod->getAttrs()))
       Diag(EndLoc, diag::warn_attribute_method_def);
   }
   if (PrevMethod) {
@@ -1651,10 +1617,12 @@
 
   // 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());
+  if (InterfaceMD)
+   if (Attr *DA = InterfaceMD->getAttr<DeprecatedAttr>())
+    ObjCMethod->addAttr(::new (Context) DeprecatedAttr(DA->getLocation(),
+                                                       Context));
 
-  return DeclPtrTy::make(ObjCMethod);
+  return ObjCMethod;
 }
 
 bool Sema::CheckObjCDeclScope(Decl *D) {
@@ -1669,9 +1637,9 @@
 
 /// 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,
+void Sema::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart,
                      IdentifierInfo *ClassName,
-                     llvm::SmallVectorImpl<DeclPtrTy> &Decls) {
+                     llvm::SmallVectorImpl<Decl*> &Decls) {
   // Check that ClassName is a valid class
   ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName, DeclStart);
   if (!Class) {
@@ -1684,25 +1652,25 @@
   }
 
   // Collect the instance variables
-  llvm::SmallVector<FieldDecl*, 32> RecFields;
-  Context.CollectObjCIvars(Class, RecFields);
+  llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
+  Context.DeepCollectObjCIvars(Class, true, Ivars);
   // 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>());
+  for (unsigned i = 0; i < Ivars.size(); i++) {
+    FieldDecl* ID = cast<FieldDecl>(Ivars[i]);
+    RecordDecl *Record = dyn_cast<RecordDecl>(TagD);
     Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record, ID->getLocation(),
                                            ID->getIdentifier(), ID->getType(),
                                            ID->getBitWidth());
-    Decls.push_back(Sema::DeclPtrTy::make(FD));
+    Decls.push_back(FD);
   }
 
   // Introduce all of these fields into the appropriate scope.
-  for (llvm::SmallVectorImpl<DeclPtrTy>::iterator D = Decls.begin();
+  for (llvm::SmallVectorImpl<Decl*>::iterator D = Decls.begin();
        D != Decls.end(); ++D) {
-    FieldDecl *FD = cast<FieldDecl>(D->getAs<Decl>());
+    FieldDecl *FD = cast<FieldDecl>(*D);
     if (getLangOptions().CPlusPlus)
       PushOnScopeChains(cast<FieldDecl>(FD), S);
-    else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>()))
+    else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD))
       Record->addDecl(FD);
   }
 }
@@ -1737,13 +1705,15 @@
   }
   
   VarDecl *New = VarDecl::Create(Context, CurContext, NameLoc, Name, T, TInfo,
-                                 VarDecl::None, VarDecl::None);  
+                                 SC_None, SC_None);
+  New->setExceptionVariable(true);
+  
   if (Invalid)
     New->setInvalidDecl();
   return New;
 }
 
-Sema::DeclPtrTy Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
+Decl *Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
   const DeclSpec &DS = D.getDeclSpec();
   
   // We allow the "register" storage class on exception variables because
@@ -1766,9 +1736,9 @@
   if (getLangOptions().CPlusPlus)
     CheckExtraCXXDefaultArguments(D);
   
-  TypeSourceInfo *TInfo = 0;
   TagDecl *OwnedDecl = 0;
-  QualType ExceptionType = GetTypeForDeclarator(D, S, &TInfo, &OwnedDecl);
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S, &OwnedDecl);
+  QualType ExceptionType = TInfo->getType();
   
   if (getLangOptions().CPlusPlus && OwnedDecl && OwnedDecl->isDefinition()) {
     // Objective-C++: Types shall not be defined in exception types.
@@ -1788,7 +1758,7 @@
   }
   
   // Add the parameter declaration into this scope.
-  S->AddDecl(DeclPtrTy::make(New));
+  S->AddDecl(New);
   if (D.getIdentifier())
     IdResolver.AddDecl(New);
   
@@ -1796,5 +1766,43 @@
   
   if (New->hasAttr<BlocksAttr>())
     Diag(New->getLocation(), diag::err_block_on_nonlocal);
-  return DeclPtrTy::make(New);
+  return New;
+}
+
+/// CollectIvarsToConstructOrDestruct - Collect those ivars which require
+/// initialization.
+void Sema::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI,
+                                llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
+  for (ObjCIvarDecl *Iv = OI->all_declared_ivar_begin(); Iv; 
+       Iv= Iv->getNextIvar()) {
+    QualType QT = Context.getBaseElementType(Iv->getType());
+    if (QT->isRecordType())
+      Ivars.push_back(Iv);
+  }
+}
+
+void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
+                                    CXXBaseOrMemberInitializer ** initializers,
+                                                 unsigned numInitializers) {
+  if (numInitializers > 0) {
+    NumIvarInitializers = numInitializers;
+    CXXBaseOrMemberInitializer **ivarInitializers =
+    new (C) CXXBaseOrMemberInitializer*[NumIvarInitializers];
+    memcpy(ivarInitializers, initializers,
+           numInitializers * sizeof(CXXBaseOrMemberInitializer*));
+    IvarInitializers = ivarInitializers;
+  }
+}
+
+void Sema::DiagnoseUseOfUnimplementedSelectors() {
+  if (ReferencedSelectors.empty())
+    return;
+  for (llvm::DenseMap<Selector, SourceLocation>::iterator S = 
+        ReferencedSelectors.begin(),
+       E = ReferencedSelectors.end(); S != E; ++S) {
+    Selector Sel = (*S).first;
+    if (!LookupImplementedMethodInGlobalPool(Sel))
+      Diag((*S).second, diag::warn_unimplemented_selector) << Sel;
+  }
+  return;
 }
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index 53e9385..101d741 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -11,7 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
@@ -249,6 +249,10 @@
                                         SourceLocation NewLoc,
                                         bool *MissingExceptionSpecification,
                                      bool *MissingEmptyExceptionSpecification)  {
+  // Just completely ignore this under -fno-exceptions.
+  if (!getLangOptions().Exceptions)
+    return false;
+
   if (MissingExceptionSpecification)
     *MissingExceptionSpecification = false;
 
@@ -318,6 +322,11 @@
     const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
     const FunctionProtoType *Superset, SourceLocation SuperLoc,
     const FunctionProtoType *Subset, SourceLocation SubLoc) {
+
+  // Just auto-succeed under -fno-exceptions.
+  if (!getLangOptions().Exceptions)
+    return false;
+
   // FIXME: As usual, we could be more specific in our error messages, but
   // that better waits until we've got types with source locations.
 
@@ -389,7 +398,7 @@
       if (!IsDerivedFrom(CanonicalSubT, CanonicalSuperT, Paths))
         continue;
 
-      if (Paths.isAmbiguous(CanonicalSuperT))
+      if (Paths.isAmbiguous(Context.getCanonicalType(CanonicalSuperT)))
         continue;
 
       // Do this check from a context without privileges.
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 088ca96..1a065eb 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -11,25 +11,32 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
-#include "AnalysisBasedWarnings.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/AnalysisBasedWarnings.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/CXXInheritance.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/RecursiveASTVisitor.h"
+#include "clang/AST/TypeLoc.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"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Designator.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Sema/Template.h"
 using namespace clang;
+using namespace sema;
 
 
 /// \brief Determine whether the use of this declaration is valid, and
@@ -55,7 +62,7 @@
 
   // See if the decl is unavailable
   if (D->getAttr<UnavailableAttr>()) {
-    Diag(Loc, diag::warn_unavailable) << D->getDeclName();
+    Diag(Loc, diag::err_unavailable) << D->getDeclName();
     Diag(D->getLocation(), diag::note_unavailable_here) << 0;
   }
 
@@ -157,16 +164,19 @@
     ++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;
+  if (!sentinelExpr) return;
+  if (sentinelExpr->isTypeDependent()) return;
+  if (sentinelExpr->isValueDependent()) return;
+  if (sentinelExpr->getType()->isAnyPointerType() &&
+      sentinelExpr->IgnoreParenCasts()->isNullPointerConstant(Context,
+                                            Expr::NPC_ValueDependentIsNull))
+    return;
+
+  // Unfortunately, __null has type 'int'.
+  if (isa<GNUNullExpr>(sentinelExpr)) return;
+
+  Diag(Loc, diag::warn_missing_sentinel) << isMethod;
+  Diag(D->getLocation(), diag::note_sentinel_here) << isMethod;
 }
 
 SourceRange Sema::getExprRange(ExprTy *E) const {
@@ -185,7 +195,7 @@
 
   if (Ty->isFunctionType())
     ImpCastExprToType(E, Context.getPointerType(Ty),
-                      CastExpr::CK_FunctionToPointerDecay);
+                      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
@@ -201,7 +211,7 @@
     if (getLangOptions().C99 || getLangOptions().CPlusPlus ||
         E->isLvalue(Context) == Expr::LV_Valid)
       ImpCastExprToType(E, Context.getArrayDecayedType(Ty),
-                        CastExpr::CK_ArrayToPointerDecay);
+                        CK_ArrayToPointerDecay);
   }
 }
 
@@ -222,7 +232,7 @@
     //   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);
+    ImpCastExprToType(E, Ty.getUnqualifiedType(), CK_NoOp);
   }
 }
 
@@ -251,12 +261,12 @@
   //   other types are unchanged by the integer promotions.
   QualType PTy = Context.isPromotableBitField(Expr);
   if (!PTy.isNull()) {
-    ImpCastExprToType(Expr, PTy, CastExpr::CK_IntegralCast);
+    ImpCastExprToType(Expr, PTy, CK_IntegralCast);
     return Expr;
   }
   if (Ty->isPromotableIntegerType()) {
     QualType PT = Context.getPromotedIntegerType(Ty);
-    ImpCastExprToType(Expr, PT, CastExpr::CK_IntegralCast);
+    ImpCastExprToType(Expr, PT, CK_IntegralCast);
     return Expr;
   }
 
@@ -272,10 +282,9 @@
   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);
+  if (Ty->isSpecificBuiltinType(BuiltinType::Float))
+    return ImpCastExprToType(Expr, Context.DoubleTy,
+                             CK_FloatingCast);
 
   UsualUnaryConversions(Expr);
 }
@@ -284,10 +293,17 @@
 /// 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) {
+bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT,
+                                            FunctionDecl *FDecl) {
   DefaultArgumentPromotion(Expr);
 
-  if (Expr->getType()->isObjCInterfaceType() &&
+  // __builtin_va_start takes the second argument as a "varargs" argument, but
+  // it doesn't actually do anything with it.  It doesn't need to be non-pod
+  // etc.
+  if (FDecl && FDecl->getBuiltinID() == Builtin::BI__builtin_va_start)
+    return false;
+  
+  if (Expr->getType()->isObjCObjectType() &&
       DiagRuntimeBehavior(Expr->getLocStart(),
         PDiag(diag::err_cannot_pass_objc_interface_to_vararg)
           << Expr->getType() << CT))
@@ -342,8 +358,8 @@
 
   QualType destType = Context.UsualArithmeticConversionsType(lhs, rhs);
   if (!isCompAssign)
-    ImpCastExprToType(lhsExpr, destType, CastExpr::CK_Unknown);
-  ImpCastExprToType(rhsExpr, destType, CastExpr::CK_Unknown);
+    ImpCastExprToType(lhsExpr, destType, CK_Unknown);
+  ImpCastExprToType(rhsExpr, destType, CK_Unknown);
   return destType;
 }
 
@@ -358,7 +374,7 @@
 /// multiple tokens.  However, the common case is that StringToks points to one
 /// string.
 ///
-Action::OwningExprResult
+ExprResult
 Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) {
   assert(NumStringToks && "Must have at least one string!");
 
@@ -375,7 +391,7 @@
   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 )
+  if (getLangOptions().CPlusPlus || getLangOptions().ConstStrings)
     StrTy.addConst();
 
   // Get an array type for the string, according to C99 6.4.5.  This includes
@@ -446,23 +462,35 @@
 }
 
 
-
-/// BuildDeclRefExpr - Build a DeclRefExpr.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
                        const CXXScopeSpec *SS) {
+  DeclarationNameInfo NameInfo(D->getDeclName(), Loc);
+  return BuildDeclRefExpr(D, Ty, NameInfo, SS);
+}
+
+/// BuildDeclRefExpr - Build a DeclRefExpr.
+ExprResult
+Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty,
+                       const DeclarationNameInfo &NameInfo,
+                       const CXXScopeSpec *SS) {
   if (Context.getCanonicalType(Ty) == Context.UndeducedAutoTy) {
-    Diag(Loc,
+    Diag(NameInfo.getLoc(),
          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 (isa<NonTypeTemplateParmDecl>(VD)) {
+      // Non-type template parameters can be referenced anywhere they are
+      // visible.
+      Ty = Ty.getNonLValueExprType(Context);
+    } else 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)
+          Diag(NameInfo.getLoc(),
+               diag::err_reference_to_local_var_in_enclosing_function)
             << D->getIdentifier() << FD->getDeclName();
           Diag(D->getLocation(), diag::note_local_variable_declared_here)
             << D->getIdentifier();
@@ -472,41 +500,12 @@
     }
   }
 
-  MarkDeclarationReferenced(Loc, D);
+  MarkDeclarationReferenced(NameInfo.getLoc(), 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;
+                                   D, NameInfo, Ty));
 }
 
 /// \brief Given a field that represents a member of an anonymous
@@ -533,7 +532,7 @@
   DeclContext *Ctx = Field->getDeclContext();
   do {
     RecordDecl *Record = cast<RecordDecl>(Ctx);
-    Decl *AnonObject = getObjectForAnonymousRecordDecl(Context, Record);
+    ValueDecl *AnonObject = Record->getAnonymousStructOrUnionObject();
     if (FieldDecl *AnonField = dyn_cast<FieldDecl>(AnonObject))
       Path.push_back(AnonField);
     else {
@@ -547,7 +546,7 @@
   return BaseObject;
 }
 
-Sema::OwningExprResult
+ExprResult
 Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
                                                FieldDecl *Field,
                                                Expr *BaseObjectExpr,
@@ -565,7 +564,6 @@
   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());
@@ -586,7 +584,8 @@
     // 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)) {
+    DeclContext *DC = getFunctionLevelDeclContext();
+    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC)) {
       if (!MD->isStatic()) {
         QualType AnonFieldType
           = Context.getTagDeclType(
@@ -651,7 +650,7 @@
   return Owned(Result);
 }
 
-/// Decomposes the given name into a DeclarationName, its location, and
+/// Decomposes the given name into a DeclarationNameInfo, its location, and
 /// possibly a list of template arguments.
 ///
 /// If this produces template arguments, it is permitted to call
@@ -663,8 +662,7 @@
 static void DecomposeUnqualifiedId(Sema &SemaRef,
                                    const UnqualifiedId &Id,
                                    TemplateArgumentListInfo &Buffer,
-                                   DeclarationName &Name,
-                                   SourceLocation &NameLoc,
+                                   DeclarationNameInfo &NameInfo,
                              const TemplateArgumentListInfo *&TemplateArgs) {
   if (Id.getKind() == UnqualifiedId::IK_TemplateId) {
     Buffer.setLAngleLoc(Id.TemplateId->LAngleLoc);
@@ -676,39 +674,16 @@
     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;
+    TemplateName TName = Id.TemplateId->Template.get();
+    SourceLocation TNameLoc = Id.TemplateId->TemplateNameLoc;
+    NameInfo = SemaRef.Context.getNameForTemplate(TName, TNameLoc);
     TemplateArgs = &Buffer;
   } else {
-    Name = SemaRef.GetNameFromUnqualifiedId(Id);
-    NameLoc = Id.StartLocation;
+    NameInfo = SemaRef.GetNameFromUnqualifiedId(Id);
     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.
@@ -731,23 +706,6 @@
   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,
@@ -822,9 +780,10 @@
                                             const LookupResult &R) {
   assert(!R.empty() && (*R.begin())->isCXXClassMember());
 
+  DeclContext *DC = SemaRef.getFunctionLevelDeclContext();
   bool isStaticContext =
-    (!isa<CXXMethodDecl>(SemaRef.CurContext) ||
-     cast<CXXMethodDecl>(SemaRef.CurContext)->isStatic());
+    (!isa<CXXMethodDecl>(DC) ||
+     cast<CXXMethodDecl>(DC)->isStatic());
 
   if (R.isUnresolvableResult())
     return isStaticContext ? IMA_Unresolved_StaticContext : IMA_Unresolved;
@@ -864,7 +823,7 @@
   // 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(),
+                               cast<CXXMethodDecl>(DC)->getParent(),
                                Classes))
     return (hasNonInstance ? IMA_Mixed_Unrelated : IMA_Error_Unrelated);
 
@@ -900,8 +859,8 @@
 /// Diagnose an empty lookup.
 ///
 /// \return false if new lookup candidates were found
-bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS,
-                               LookupResult &R) {
+bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
+                               CorrectTypoContext CTC) {
   DeclarationName Name = R.getLookupName();
 
   unsigned diagnostic = diag::err_undeclared_var_use;
@@ -917,7 +876,7 @@
   // 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;
+  for (DeclContext *DC = SS.isEmpty() ? CurContext : 0;
        DC; DC = DC->getParent()) {
     if (isa<CXXRecordDecl>(DC)) {
       LookupQualifiedName(R, DC);
@@ -934,11 +893,34 @@
         // 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
+        if (isInstance) {
+          UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(
+              CallsUndergoingInstantiation.back()->getCallee());
+          CXXMethodDecl *DepMethod = cast_or_null<CXXMethodDecl>(
+              CurMethod->getInstantiatedFromMemberFunction());
+          if (DepMethod) {
+            Diag(R.getNameLoc(), diagnostic) << Name
+              << FixItHint::CreateInsertion(R.getNameLoc(), "this->");
+            QualType DepThisType = DepMethod->getThisType(Context);
+            CXXThisExpr *DepThis = new (Context) CXXThisExpr(
+                                       R.getNameLoc(), DepThisType, false);
+            TemplateArgumentListInfo TList;
+            if (ULE->hasExplicitTemplateArgs())
+              ULE->copyTemplateArgumentsInto(TList);
+            CXXDependentScopeMemberExpr *DepExpr =
+                CXXDependentScopeMemberExpr::Create(
+                    Context, DepThis, DepThisType, true, SourceLocation(),
+                    ULE->getQualifier(), ULE->getQualifierRange(), NULL,
+                    R.getLookupNameInfo(), &TList);
+            CallsUndergoingInstantiation.back()->setCallee(DepExpr);
+          } else {
+            // FIXME: we should be able to handle this case too. It is correct
+            // to add this-> here. This is a workaround for PR7947.
+            Diag(R.getNameLoc(), diagnostic) << Name;
+          }
+        } 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)
@@ -947,12 +929,14 @@
         // Tell the callee to try to recover.
         return false;
       }
+
+      R.clear();
     }
   }
 
   // We didn't find anything, so try to correct for a typo.
   DeclarationName Corrected;
-  if (S && (Corrected = CorrectTypo(R, S, &SS))) {
+  if (S && (Corrected = CorrectTypo(R, S, &SS, 0, false, CTC))) {
     if (!R.empty()) {
       if (isa<ValueDecl>(*R.begin()) || isa<FunctionTemplateDecl>(*R.begin())) {
         if (SS.isEmpty())
@@ -972,7 +956,7 @@
         // 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
@@ -990,7 +974,7 @@
         return true;
       }
     } else {
-      // FIXME: We found a keyword. Suggest it, but don't provide a fix-it 
+      // 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;
@@ -1017,11 +1001,74 @@
   return true;
 }
 
-Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
-                                               CXXScopeSpec &SS,
-                                               UnqualifiedId &Id,
-                                               bool HasTrailingLParen,
-                                               bool isAddressOfOperand) {
+static ObjCPropertyDecl *OkToSynthesizeProvisionalIvar(Sema &SemaRef,
+                                                       IdentifierInfo *II,
+                                                       SourceLocation NameLoc) {
+  ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl();
+  ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface();
+  if (!IDecl)
+    return 0;
+  ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation();
+  if (!ClassImpDecl)
+    return 0;
+  ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II);
+  if (!property)
+    return 0;
+  if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II))
+    if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      return 0;
+  return property;
+}
+
+static ObjCIvarDecl *SynthesizeProvisionalIvar(Sema &SemaRef,
+                                               LookupResult &Lookup,
+                                               IdentifierInfo *II,
+                                               SourceLocation NameLoc) {
+  ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl();
+  bool LookForIvars;
+  if (Lookup.empty())
+    LookForIvars = true;
+  else if (CurMeth->isClassMethod())
+    LookForIvars = false;
+  else
+    LookForIvars = (Lookup.isSingleResult() &&
+                    Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod());
+  if (!LookForIvars)
+    return 0;
+  
+  ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface();
+  if (!IDecl)
+    return 0;
+  ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation();
+  if (!ClassImpDecl)
+    return 0;
+  bool DynamicImplSeen = false;
+  ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II);
+  if (!property)
+    return 0;
+  if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II))
+    DynamicImplSeen = 
+      (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
+  if (!DynamicImplSeen) {
+    QualType PropType = SemaRef.Context.getCanonicalType(property->getType());
+    ObjCIvarDecl *Ivar = ObjCIvarDecl::Create(SemaRef.Context, ClassImpDecl, 
+                                              NameLoc,
+                                              II, PropType, /*Dinfo=*/0,
+                                              ObjCIvarDecl::Protected,
+                                              (Expr *)0, true);
+    ClassImpDecl->addDecl(Ivar);
+    IDecl->makeDeclVisibleInContext(Ivar, false);
+    property->setPropertyIvarDecl(Ivar);
+    return Ivar;
+  }
+  return 0;
+}
+
+ExprResult Sema::ActOnIdExpression(Scope *S,
+                                   CXXScopeSpec &SS,
+                                   UnqualifiedId &Id,
+                                   bool HasTrailingLParen,
+                                   bool isAddressOfOperand) {
   assert(!(isAddressOfOperand && HasTrailingLParen) &&
          "cannot be direct & operand and have a trailing lparen");
 
@@ -1031,13 +1078,13 @@
   TemplateArgumentListInfo TemplateArgsBuffer;
 
   // Decompose the UnqualifiedId into the following data.
-  DeclarationName Name;
-  SourceLocation NameLoc;
+  DeclarationNameInfo NameInfo;
   const TemplateArgumentListInfo *TemplateArgs;
-  DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer,
-                         Name, NameLoc, TemplateArgs);
+  DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer, NameInfo, TemplateArgs);
 
+  DeclarationName Name = NameInfo.getName();
   IdentifierInfo *II = Name.getAsIdentifierInfo();
+  SourceLocation NameLoc = NameInfo.getLoc();
 
   // C++ [temp.dep.expr]p3:
   //   An id-expression is type-dependent if it contains:
@@ -1050,32 +1097,60 @@
   //        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);
+  bool DependentID = false;
+  if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
+      Name.getCXXNameType()->isDependentType()) {
+    DependentID = true;
+  } else if (SS.isSet()) {
+    DeclContext *DC = computeDeclContext(SS, false);
+    if (DC) {
+      if (RequireCompleteDeclContext(SS, DC))
+        return ExprError();
+      // FIXME: We should be checking whether DC is the current instantiation.
+      if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC))
+        DependentID = !IsFullyFormedScope(*this, RD);
+    } else {
+      DependentID = true;
+    }
   }
 
+  if (DependentID) {
+    return ActOnDependentIdExpression(SS, NameInfo, isAddressOfOperand,
+                                      TemplateArgs);
+  }
+  bool IvarLookupFollowUp = false;
   // Perform the required lookup.
-  LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+  LookupResult R(*this, NameInfo, LookupOrdinaryName);
   if (TemplateArgs) {
-    // Just re-use the lookup done by isTemplateName.
-    DecomposeTemplateName(R, Id);
+    // Lookup the template name again to correctly establish the context in
+    // which it was found. This is really unfortunate as we already did the
+    // lookup to determine that it was a template name in the first place. If
+    // this becomes a performance hit, we can work harder to preserve those
+    // results until we get here but it's likely not worth it.
+    bool MemberOfUnknownSpecialization;
+    LookupTemplateName(R, S, SS, QualType(), /*EnteringContext=*/false,
+                       MemberOfUnknownSpecialization);
   } else {
-    bool IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl());
+    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));
+      ExprResult E(LookupInObjCMethod(R, S, II, true));
       if (E.isInvalid())
         return ExprError();
 
       Expr *Ex = E.takeAs<Expr>();
       if (Ex) return Owned(Ex);
+      // Synthesize ivars lazily
+      if (getLangOptions().ObjCNonFragileABI2) {
+        if (SynthesizeProvisionalIvar(*this, R, II, NameLoc))
+          return ActOnIdExpression(S, SS, Id, HasTrailingLParen,
+                                   isAddressOfOperand);
+      }
+      // for further use, this must be set to false if in class method.
+      IvarLookupFollowUp = getCurMethodDecl()->isInstanceMethod();
     }
   }
 
@@ -1097,7 +1172,7 @@
     // 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))
+      if (DiagnoseEmptyLookup(S, SS, R, CTC_Unknown))
         return ExprError();
 
       assert(!R.empty() &&
@@ -1108,7 +1183,7 @@
       // reference the ivar.
       if (ObjCIvarDecl *Ivar = R.getAsSingle<ObjCIvarDecl>()) {
         R.clear();
-        OwningExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
+        ExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
         assert(E.isInvalid() || E.get());
         return move(E);
       }
@@ -1119,23 +1194,15 @@
   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();
+    if (getLangOptions().ObjCNonFragileABI && IvarLookupFollowUp &&
+        !getLangOptions().ObjCNonFragileABI2 &&
+        Var->isFileVarDecl()) {
+      ObjCPropertyDecl *Property = 
+        OkToSynthesizeProvisionalIvar(*this, II, NameLoc);
+      if (Property) {
+        Diag(NameLoc, diag::warn_ivar_variable_conflict) << Var->getDeclName();
+        Diag(Property->getLocation(), diag::note_property_declare);
+        Diag(Var->getLocation(), diag::note_global_declared_at);
       }
     }
   } else if (FunctionDecl *Func = R.getAsSingle<FunctionDecl>()) {
@@ -1151,21 +1218,48 @@
       QualType T = Func->getType();
       QualType NoProtoType = T;
       if (const FunctionProtoType *Proto = T->getAs<FunctionProtoType>())
-        NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType());
+        NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType(),
+                                                     Proto->getExtInfo());
       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.
+  // C++ [class.mfct.non-static]p3:
+  //   When an id-expression that is not part of a class member access
+  //   syntax and not used to form a pointer to member is used in the
+  //   body of a non-static member function of class X, if name lookup
+  //   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 using (*this) as the
+  //   postfix-expression to the left of the . operator.
+  //
+  // But we don't actually need to do this for '&' operands if R
+  // resolved to a function or overloaded function set, because the
+  // expression is ill-formed if it actually works out to be a
+  // non-static member function:
+  //
+  // C++ [expr.ref]p4:
+  //   Otherwise, if E1.E2 refers to a non-static member function. . .
+  //   [t]he expression can be used only as the left-hand operand of a
+  //   member function call.
+  //
+  // There are other safeguards against such uses, but it's important
+  // to get this right here so that we don't end up making a
+  // spuriously dependent expression if we're inside a dependent
+  // instance method.
   if (!R.empty() && (*R.begin())->isCXXClassMember()) {
-    bool isAbstractMemberPointer = (isAddressOfOperand && !SS.isEmpty());
-    if (!isAbstractMemberPointer)
+    bool MightBeImplicitMember;
+    if (!isAddressOfOperand)
+      MightBeImplicitMember = true;
+    else if (!SS.isEmpty())
+      MightBeImplicitMember = false;
+    else if (R.isOverloadedResult())
+      MightBeImplicitMember = false;
+    else
+      MightBeImplicitMember = isa<FieldDecl>(R.getFoundDecl());
+
+    if (MightBeImplicitMember)
       return BuildPossibleImplicitMemberExpr(SS, R, TemplateArgs);
   }
 
@@ -1176,7 +1270,7 @@
 }
 
 /// Builds an expression which might be an implicit member expression.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
                                       LookupResult &R,
                                 const TemplateArgumentListInfo *TemplateArgs) {
@@ -1215,24 +1309,25 @@
 /// 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
+ExprResult
 Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
-                                        DeclarationName Name,
-                                        SourceLocation NameLoc) {
+                                        const DeclarationNameInfo &NameInfo) {
   DeclContext *DC;
-  if (!(DC = computeDeclContext(SS, false)) ||
-      DC->isDependentContext() ||
-      RequireCompleteDeclContext(SS))
-    return BuildDependentDeclRefExpr(SS, Name, NameLoc, 0);
+  if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext())
+    return BuildDependentDeclRefExpr(SS, NameInfo, 0);
 
-  LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+  if (RequireCompleteDeclContext(SS, DC))
+    return ExprError();
+
+  LookupResult R(*this, NameInfo, LookupOrdinaryName);
   LookupQualifiedName(R, DC);
 
   if (R.isAmbiguous())
     return ExprError();
 
   if (R.empty()) {
-    Diag(NameLoc, diag::err_no_member) << Name << DC << SS.getRange();
+    Diag(NameInfo.getLoc(), diag::err_no_member)
+      << NameInfo.getName() << DC << SS.getRange();
     return ExprError();
   }
 
@@ -1247,12 +1342,12 @@
 /// actually quite a lot of extra work involved.
 ///
 /// Returns a null sentinel to indicate trivial success.
-Sema::OwningExprResult
+ExprResult
 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.
@@ -1302,7 +1397,7 @@
       UnqualifiedId SelfName;
       SelfName.setIdentifier(&II, SourceLocation());
       CXXScopeSpec SelfScopeSpec;
-      OwningExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
+      ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
                                                     SelfName, false, false);
       MarkDeclarationReferenced(Loc, IV);
       return Owned(new (Context)
@@ -1407,6 +1502,8 @@
   SourceRange FromRange = From->getSourceRange();
   SourceLocation FromLoc = FromRange.getBegin();
 
+  ExprValueKind VK = CastCategory(From);
+
   // C++ [class.member.lookup]p8:
   //   [...] Ambiguities can often be resolved by qualifying a name with its
   //   class name.
@@ -1436,15 +1533,15 @@
     // type of the object type, in which case we just ignore it.
     // Otherwise build the appropriate casts.
     if (IsDerivedFrom(FromRecordType, QRecordType)) {
-      CXXBaseSpecifierArray BasePath;
+      CXXCastPath 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);
+      ImpCastExprToType(From, QType, CK_UncheckedDerivedToBase,
+                        VK, &BasePath);
 
       FromType = QType;
       FromRecordType = QRecordType;
@@ -1472,16 +1569,16 @@
     // conversion is non-trivial.
     if (!Context.hasSameUnqualifiedType(FromRecordType, URecordType)) {
       assert(IsDerivedFrom(FromRecordType, URecordType));
-      CXXBaseSpecifierArray BasePath;
+      CXXCastPath 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);
+      ImpCastExprToType(From, UType, CK_UncheckedDerivedToBase,
+                        VK, &BasePath);
       FromType = UType;
       FromRecordType = URecordType;
     }
@@ -1491,14 +1588,14 @@
     IgnoreAccess = true;
   }
 
-  CXXBaseSpecifierArray BasePath;
+  CXXCastPath BasePath;
   if (CheckDerivedToBaseConversion(FromRecordType, DestRecordType,
                                    FromLoc, FromRange, &BasePath,
                                    IgnoreAccess))
     return true;
 
-  ImpCastExprToType(From, DestType, CastExpr::CK_UncheckedDerivedToBase,
-                    /*isLvalue=*/!PointerConversions, BasePath);
+  ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase,
+                    VK, &BasePath);
   return false;
 }
 
@@ -1506,7 +1603,8 @@
 static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
                                    const CXXScopeSpec &SS, ValueDecl *Member,
                                    DeclAccessPair FoundDecl,
-                                   SourceLocation Loc, QualType Ty,
+                                   const DeclarationNameInfo &MemberNameInfo,
+                                   QualType Ty,
                           const TemplateArgumentListInfo *TemplateArgs = 0) {
   NestedNameSpecifier *Qualifier = 0;
   SourceRange QualifierRange;
@@ -1516,14 +1614,15 @@
   }
 
   return MemberExpr::Create(C, Base, isArrow, Qualifier, QualifierRange,
-                            Member, FoundDecl, Loc, TemplateArgs, Ty);
+                            Member, FoundDecl, MemberNameInfo,
+                            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
+ExprResult
 Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS,
                               LookupResult &R,
                               const TemplateArgumentListInfo *TemplateArgs,
@@ -1542,7 +1641,8 @@
 
   // If this is known to be an instance access, go ahead and build a
   // 'this' expression now.
-  QualType ThisType = cast<CXXMethodDecl>(CurContext)->getThisType(Context);
+  DeclContext *DC = getFunctionLevelDeclContext();
+  QualType ThisType = cast<CXXMethodDecl>(DC)->getThisType(Context);
   Expr *This = 0; // null signifies implicit access
   if (IsKnownInstance) {
     SourceLocation Loc = R.getNameLoc();
@@ -1551,7 +1651,7 @@
     This = new (Context) CXXThisExpr(Loc, ThisType, /*isImplicit=*/true);
   }
 
-  return BuildMemberReferenceExpr(ExprArg(*this, This), ThisType,
+  return BuildMemberReferenceExpr(This, ThisType,
                                   /*OpLoc*/ SourceLocation(),
                                   /*IsArrow*/ true,
                                   SS,
@@ -1638,14 +1738,15 @@
   return false;
 }
 
-Sema::OwningExprResult
+ExprResult
 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());
+    return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(),
+                                    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
@@ -1664,23 +1765,24 @@
   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());
+                                   SS.getRange(), R.getLookupNameInfo(),
+                                   NeedsADL, R.isOverloadedResult(),
+                                   R.begin(), R.end());
 
   return Owned(ULE);
 }
 
 
 /// \brief Complete semantic analysis for a reference to the given declaration.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
-                               SourceLocation Loc, NamedDecl *D) {
+                               const DeclarationNameInfo &NameInfo,
+                               NamedDecl *D) {
   assert(D && "Cannot refer to a NULL declaration");
   assert(!isa<FunctionTemplateDecl>(D) &&
          "Cannot refer unambiguously to a function template");
 
+  SourceLocation Loc = NameInfo.getLoc();
   if (CheckDeclInExpr(*this, Loc, D))
     return ExprError();
 
@@ -1745,16 +1847,38 @@
     // Variable will be bound by-copy, make it const within the closure.
 
     ExprTy.addConst();
-    return Owned(new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, false,
-                                                constAdded));
+    QualType T = VD->getType();
+    BlockDeclRefExpr *BDRE = new (Context) BlockDeclRefExpr(VD, 
+                                                            ExprTy, Loc, false,
+                                                            constAdded);
+    if (getLangOptions().CPlusPlus) {
+      if (!T->isDependentType() && !T->isReferenceType()) {
+        Expr *E = new (Context) 
+                    DeclRefExpr(const_cast<ValueDecl*>(BDRE->getDecl()), T,
+                                          SourceLocation());
+      
+        ExprResult Res = PerformCopyInitialization(
+                          InitializedEntity::InitializeBlock(VD->getLocation(), 
+                                                         T, false),
+                                                         SourceLocation(),
+                                                         Owned(E));
+        if (!Res.isInvalid()) {
+          Res = MaybeCreateCXXExprWithTemporaries(Res.get());
+          Expr *Init = Res.takeAs<Expr>();
+          BDRE->setCopyConstructorExpr(Init);
+        }
+      }
+    }
+    return Owned(BDRE);
   }
   // 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);
+  return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
+                          NameInfo, &SS);
 }
 
-Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
+ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
                                                  tok::TokenKind Kind) {
   PredefinedExpr::IdentType IT;
 
@@ -1769,6 +1893,8 @@
   // string.
 
   Decl *currentDecl = getCurFunctionOrMethodDecl();
+  if (!currentDecl && getCurBlock())
+    currentDecl = getCurBlock()->TheDecl;
   if (!currentDecl) {
     Diag(Loc, diag::ext_predef_outside_function);
     currentDecl = Context.getTranslationUnitDecl();
@@ -1787,7 +1913,7 @@
   return Owned(new (Context) PredefinedExpr(Loc, ResTy, IT));
 }
 
-Sema::OwningExprResult Sema::ActOnCharacterConstant(const Token &Tok) {
+ExprResult Sema::ActOnCharacterConstant(const Token &Tok) {
   llvm::SmallString<16> CharBuffer;
   bool Invalid = false;
   llvm::StringRef ThisTok = PP.getSpelling(Tok, CharBuffer, &Invalid);
@@ -1814,13 +1940,13 @@
                                               Ty, Tok.getLocation()));
 }
 
-Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
+ExprResult 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'),
+    return Owned(IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val-'0'),
                     Context.IntTy, Tok.getLocation()));
   }
 
@@ -1878,7 +2004,7 @@
     }
 
     bool isExact = (result == APFloat::opOK);
-    Res = new (Context) FloatingLiteral(Val, isExact, Ty, Tok.getLocation());
+    Res = FloatingLiteral::Create(Context, Val, isExact, Ty, Tok.getLocation());
 
   } else if (!Literal.isIntegerLiteral()) {
     return ExprError();
@@ -1965,7 +2091,7 @@
       if (ResultVal.getBitWidth() != Width)
         ResultVal.trunc(Width);
     }
-    Res = new (Context) IntegerLiteral(ResultVal, Ty, Tok.getLocation());
+    Res = IntegerLiteral::Create(Context, ResultVal, Ty, Tok.getLocation());
   }
 
   // If this is an imaginary literal, create the ImaginaryLiteral wrapper.
@@ -1976,9 +2102,8 @@
   return Owned(Res);
 }
 
-Action::OwningExprResult Sema::ActOnParenExpr(SourceLocation L,
-                                              SourceLocation R, ExprArg Val) {
-  Expr *E = Val.takeAs<Expr>();
+ExprResult Sema::ActOnParenExpr(SourceLocation L,
+                                              SourceLocation R, Expr *E) {
   assert((E != 0) && "ActOnParenExpr() missing expr");
   return Owned(new (Context) ParenExpr(L, R, E));
 }
@@ -2020,12 +2145,18 @@
     return true;
 
   // Reject sizeof(interface) and sizeof(interface<proto>) in 64-bit mode.
-  if (LangOpts.ObjCNonFragileABI && exprType->isObjCInterfaceType()) {
+  if (LangOpts.ObjCNonFragileABI && exprType->isObjCObjectType()) {
     Diag(OpLoc, diag::err_sizeof_nonfragile_interface)
       << exprType << isSizeof << ExprRange;
     return true;
   }
 
+  if (Context.hasSameUnqualifiedType(exprType, Context.OverloadTy)) {
+    Diag(OpLoc, diag::err_sizeof_alignof_overloaded_function_type)
+      << !isSizeof << ExprRange;
+    return true;
+  }
+  
   return false;
 }
 
@@ -2056,7 +2187,7 @@
 }
 
 /// \brief Build a sizeof or alignof expression given a type operand.
-Action::OwningExprResult
+ExprResult
 Sema::CreateSizeOfAlignOfExpr(TypeSourceInfo *TInfo,
                               SourceLocation OpLoc,
                               bool isSizeOf, SourceRange R) {
@@ -2077,7 +2208,7 @@
 
 /// \brief Build a sizeof or alignof expression given an expression
 /// operand.
-Action::OwningExprResult
+ExprResult
 Sema::CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
                               bool isSizeOf, SourceRange R) {
   // Verify that the operand is valid.
@@ -2105,7 +2236,7 @@
 /// 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
+ExprResult
 Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
                              void *TyOrEx, const SourceRange &ArgRange) {
   // If error parsing type, ignore.
@@ -2113,12 +2244,12 @@
 
   if (isType) {
     TypeSourceInfo *TInfo;
-    (void) GetTypeFromParser(TyOrEx, &TInfo);
+    (void) GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrEx), &TInfo);
     return CreateSizeOfAlignOfExpr(TInfo, OpLoc, isSizeof, ArgRange);
   }
 
   Expr *ArgEx = (Expr *)TyOrEx;
-  Action::OwningExprResult Result
+  ExprResult Result
     = CreateSizeOfAlignOfExpr(ArgEx, OpLoc, isSizeof, ArgEx->getSourceRange());
 
   if (Result.isInvalid())
@@ -2147,32 +2278,31 @@
 
 
 
-Action::OwningExprResult
+ExprResult
 Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
-                          tok::TokenKind Kind, ExprArg Input) {
-  UnaryOperator::Opcode Opc;
+                          tok::TokenKind Kind, Expr *Input) {
+  UnaryOperatorKind Opc;
   switch (Kind) {
   default: assert(0 && "Unknown unary op!");
-  case tok::plusplus:   Opc = UnaryOperator::PostInc; break;
-  case tok::minusminus: Opc = UnaryOperator::PostDec; break;
+  case tok::plusplus:   Opc = UO_PostInc; break;
+  case tok::minusminus: Opc = UO_PostDec; break;
   }
 
-  return BuildUnaryOp(S, OpLoc, Opc, move(Input));
+  return BuildUnaryOp(S, OpLoc, Opc, Input);
 }
 
-Action::OwningExprResult
-Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc,
-                              ExprArg Idx, SourceLocation RLoc) {
+ExprResult
+Sema::ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc,
+                              Expr *Idx, SourceLocation RLoc) {
   // Since this might be a postfix expression, get rid of ParenListExprs.
-  Base = MaybeConvertParenListExprToParenExpr(S, move(Base));
+  ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
+  if (Result.isInvalid()) return ExprError();
+  Base = Result.take();
 
-  Expr *LHSExp = static_cast<Expr*>(Base.get()),
-       *RHSExp = static_cast<Expr*>(Idx.get());
+  Expr *LHSExp = Base, *RHSExp = Idx;
 
   if (getLangOptions().CPlusPlus &&
       (LHSExp->isTypeDependent() || RHSExp->isTypeDependent())) {
-    Base.release();
-    Idx.release();
     return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,
                                                   Context.DependentTy, RLoc));
   }
@@ -2182,18 +2312,18 @@
        LHSExp->getType()->isEnumeralType() ||
        RHSExp->getType()->isRecordType() ||
        RHSExp->getType()->isEnumeralType())) {
-    return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, move(Base),move(Idx));
+    return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, Base, Idx);
   }
 
-  return CreateBuiltinArraySubscriptExpr(move(Base), LLoc, move(Idx), RLoc);
+  return CreateBuiltinArraySubscriptExpr(Base, LLoc, 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());
+ExprResult
+Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
+                                     Expr *Idx, SourceLocation RLoc) {
+  Expr *LHSExp = Base;
+  Expr *RHSExp = Idx;
 
   // Perform default conversions.
   if (!LHSExp->getType()->getAs<VectorType>())
@@ -2247,7 +2377,7 @@
     Diag(LHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
         LHSExp->getSourceRange();
     ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy),
-                      CastExpr::CK_ArrayToPointerDecay);
+                      CK_ArrayToPointerDecay);
     LHSTy = LHSExp->getType();
 
     BaseExpr = LHSExp;
@@ -2258,7 +2388,7 @@
     Diag(RHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
         RHSExp->getSourceRange();
     ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy),
-                      CastExpr::CK_ArrayToPointerDecay);
+                      CK_ArrayToPointerDecay);
     RHSTy = RHSExp->getType();
 
     BaseExpr = RHSExp;
@@ -2269,8 +2399,7 @@
        << LHSExp->getSourceRange() << RHSExp->getSourceRange());
   }
   // C99 6.5.2.1p1
-  if (!(IndexExpr->getType()->isIntegerType() &&
-        IndexExpr->getType()->isScalarType()) && !IndexExpr->isTypeDependent())
+  if (!IndexExpr->getType()->isIntegerType() && !IndexExpr->isTypeDependent())
     return ExprError(Diag(LLoc, diag::err_typecheck_subscript_not_integer)
                      << IndexExpr->getSourceRange());
 
@@ -2296,14 +2425,12 @@
     return ExprError();
 
   // Diagnose bad cases where we step over interface counts.
-  if (ResultType->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+  if (ResultType->isObjCObjectType() && 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));
 }
@@ -2350,7 +2477,7 @@
     // 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);
+      << llvm::StringRef(compStr, 1) << SourceRange(CompLoc);
     return QualType();
   }
 
@@ -2443,15 +2570,13 @@
   return GDecl;
 }
 
-Sema::OwningExprResult
-Sema::ActOnDependentMemberExpr(ExprArg Base, QualType BaseType,
+ExprResult
+Sema::ActOnDependentMemberExpr(Expr *BaseExpr, QualType BaseType,
                                bool IsArrow, SourceLocation OpLoc,
                                const CXXScopeSpec &SS,
                                NamedDecl *FirstQualifierInScope,
-                               DeclarationName Name, SourceLocation NameLoc,
+                               const DeclarationNameInfo &NameInfo,
                                const TemplateArgumentListInfo *TemplateArgs) {
-  Expr *BaseExpr = Base.takeAs<Expr>();
-
   // Even in dependent contexts, try to diagnose base expressions with
   // obviously wrong types, e.g.:
   //
@@ -2466,24 +2591,24 @@
     if (PT && (!getLangOptions().ObjC1 ||
                PT->getPointeeType()->isRecordType())) {
       assert(BaseExpr && "cannot happen with implicit member accesses");
-      Diag(NameLoc, diag::err_typecheck_member_reference_struct_union)
+      Diag(NameInfo.getLoc(), diag::err_typecheck_member_reference_struct_union)
         << BaseType << BaseExpr->getSourceRange();
       return ExprError();
     }
   }
 
-  assert(BaseType->isDependentType() || Name.isDependentName() || 
+  assert(BaseType->isDependentType() ||
+         NameInfo.getName().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.getScopeRep(),
                                                    SS.getRange(),
                                                    FirstQualifierInScope,
-                                                   Name, NameLoc,
-                                                   TemplateArgs));
+                                                   NameInfo, TemplateArgs));
 }
 
 /// We know that the given qualified member reference points only to
@@ -2535,12 +2660,15 @@
       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());
+    DeclContext *DC = (*I)->getDeclContext();
+    while (DC->isTransparentContext())
+      DC = DC->getParent();
 
+    if (!DC->isRecord())
+      continue;
+    
     llvm::SmallPtrSet<CXXRecordDecl*,4> MemberRecord;
-    MemberRecord.insert(RecordD->getCanonicalDecl());
+    MemberRecord.insert(cast<CXXRecordDecl>(DC)->getCanonicalDecl());
 
     if (!IsProvablyNotDerivedFrom(*this, BaseRecord, MemberRecord))
       return false;
@@ -2553,20 +2681,30 @@
 static bool
 LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
                          SourceRange BaseRange, const RecordType *RTy,
-                         SourceLocation OpLoc, CXXScopeSpec &SS) {
+                         SourceLocation OpLoc, CXXScopeSpec &SS,
+                         bool HasTemplateArgs) {
   RecordDecl *RDecl = RTy->getDecl();
   if (SemaRef.RequireCompleteType(OpLoc, QualType(RTy, 0),
                               SemaRef.PDiag(diag::err_typecheck_incomplete_tag)
                                     << BaseRange))
     return true;
 
+  if (HasTemplateArgs) {
+    // LookupTemplateName doesn't expect these both to exist simultaneously.
+    QualType ObjectType = SS.isSet() ? QualType() : QualType(RTy, 0);
+
+    bool MOUS;
+    SemaRef.LookupTemplateName(R, 0, SS, ObjectType, false, MOUS);
+    return false;
+  }
+
   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)) {
+    if (SemaRef.RequireCompleteDeclContext(SS, DC)) {
       SemaRef.Diag(SS.getRange().getEnd(), diag::err_typecheck_incomplete_tag)
         << SS.getRange() << DC;
       return true;
@@ -2590,7 +2728,7 @@
   // 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) && 
+  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)
@@ -2603,29 +2741,27 @@
     return false;
   } else {
     R.clear();
+    R.setLookupName(Name);
   }
 
   return false;
 }
 
-Sema::OwningExprResult
-Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType,
+ExprResult
+Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
                                SourceLocation OpLoc, bool IsArrow,
                                CXXScopeSpec &SS,
                                NamedDecl *FirstQualifierInScope,
-                               DeclarationName Name, SourceLocation NameLoc,
+                               const DeclarationNameInfo &NameInfo,
                                const TemplateArgumentListInfo *TemplateArgs) {
-  Expr *Base = BaseArg.takeAs<Expr>();
-
   if (BaseType->isDependentType() ||
       (SS.isSet() && isDependentScopeSpecifier(SS)))
-    return ActOnDependentMemberExpr(ExprArg(*this, Base), BaseType,
+    return ActOnDependentMemberExpr(Base, BaseType,
                                     IsArrow, OpLoc,
                                     SS, FirstQualifierInScope,
-                                    Name, NameLoc,
-                                    TemplateArgs);
+                                    NameInfo, TemplateArgs);
 
-  LookupResult R(*this, Name, NameLoc, LookupMemberName);
+  LookupResult R(*this, NameInfo, LookupMemberName);
 
   // Implicit member accesses.
   if (!Base) {
@@ -2633,14 +2769,14 @@
     if (IsArrow) RecordTy = RecordTy->getAs<PointerType>()->getPointeeType();
     if (LookupMemberExprInRecord(*this, R, SourceRange(),
                                  RecordTy->getAs<RecordType>(),
-                                 OpLoc, SS))
+                                 OpLoc, SS, TemplateArgs != 0))
       return ExprError();
 
   // Explicit member accesses.
   } else {
-    OwningExprResult Result =
+    ExprResult Result =
       LookupMemberExpr(R, Base, IsArrow, OpLoc,
-                       SS, /*ObjCImpDecl*/ DeclPtrTy());
+                       SS, /*ObjCImpDecl*/ 0, TemplateArgs != 0);
 
     if (Result.isInvalid()) {
       Owned(Base);
@@ -2649,21 +2785,24 @@
 
     if (Result.get())
       return move(Result);
+
+    // LookupMemberExpr can modify Base, and thus change BaseType
+    BaseType = Base->getType();
   }
 
-  return BuildMemberReferenceExpr(ExprArg(*this, Base), BaseType,
+  return BuildMemberReferenceExpr(Base, BaseType,
                                   OpLoc, IsArrow, SS, FirstQualifierInScope,
                                   R, TemplateArgs);
 }
 
-Sema::OwningExprResult
-Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
+ExprResult
+Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
                                SourceLocation OpLoc, bool IsArrow,
                                const CXXScopeSpec &SS,
                                NamedDecl *FirstQualifierInScope,
                                LookupResult &R,
-                         const TemplateArgumentListInfo *TemplateArgs) {
-  Expr *BaseExpr = Base.takeAs<Expr>();
+                         const TemplateArgumentListInfo *TemplateArgs,
+                               bool SuppressQualifierCheck) {
   QualType BaseType = BaseExprType;
   if (IsArrow) {
     assert(BaseType->isPointerType());
@@ -2671,10 +2810,10 @@
   }
   R.setBaseObjectType(BaseType);
 
-  NestedNameSpecifier *Qualifier =
-    static_cast<NestedNameSpecifier*>(SS.getScopeRep());
-  DeclarationName MemberName = R.getLookupName();
-  SourceLocation MemberLoc = R.getNameLoc();
+  NestedNameSpecifier *Qualifier = SS.getScopeRep();
+  const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo();
+  DeclarationName MemberName = MemberNameInfo.getName();
+  SourceLocation MemberLoc = MemberNameInfo.getLoc();
 
   if (R.isAmbiguous())
     return ExprError();
@@ -2701,6 +2840,7 @@
   if ((SS.isSet() || !BaseExpr ||
        (isa<CXXThisExpr>(BaseExpr) &&
         cast<CXXThisExpr>(BaseExpr)->isImplicit())) &&
+      !SuppressQualifierCheck &&
       CheckQualifiedMemberReference(BaseExpr, BaseType, SS, R))
     return ExprError();
 
@@ -2722,9 +2862,8 @@
                                      BaseExpr, BaseExprType,
                                      IsArrow, OpLoc,
                                      Qualifier, SS.getRange(),
-                                     MemberName, MemberLoc,
-                                     TemplateArgs);
-    MemExpr->addDecls(R.begin(), R.end());
+                                     MemberNameInfo,
+                                     TemplateArgs, R.begin(), R.end());
 
     return Owned(MemExpr);
   }
@@ -2745,7 +2884,7 @@
   if (!BaseExpr) {
     // If this is not an instance member, convert to a non-member access.
     if (!MemberDecl->isCXXInstanceMember())
-      return BuildDeclarationNameExpr(SS, R.getNameLoc(), MemberDecl);
+      return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), MemberDecl);
 
     SourceLocation Loc = R.getNameLoc();
     if (SS.getRange().isValid())
@@ -2796,34 +2935,36 @@
     if (PerformObjectMemberConversion(BaseExpr, Qualifier, FoundDecl, FD))
       return ExprError();
     return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
-                                 FD, FoundDecl, MemberLoc, MemberType));
+                                 FD, FoundDecl, MemberNameInfo,
+                                 MemberType));
   }
 
   if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
     MarkDeclarationReferenced(MemberLoc, Var);
     return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
-                                 Var, FoundDecl, MemberLoc,
+                                 Var, FoundDecl, MemberNameInfo,
                                  Var->getType().getNonReferenceType()));
   }
 
   if (FunctionDecl *MemberFn = dyn_cast<FunctionDecl>(MemberDecl)) {
     MarkDeclarationReferenced(MemberLoc, MemberDecl);
     return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
-                                 MemberFn, FoundDecl, MemberLoc,
+                                 MemberFn, FoundDecl, MemberNameInfo,
                                  MemberFn->getType()));
   }
 
   if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
     MarkDeclarationReferenced(MemberLoc, MemberDecl);
     return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
-                                 Enum, FoundDecl, MemberLoc, Enum->getType()));
+                                 Enum, FoundDecl, MemberNameInfo,
+                                 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)
+    Diag(MemberLoc, diag::err_typecheck_member_reference_type)
       << MemberName << BaseType << int(IsArrow);
   else
     Diag(MemberLoc, diag::err_typecheck_member_reference_unknown)
@@ -2845,11 +2986,11 @@
 ///
 /// The ObjCImpDecl bit is a gross hack that will need to be properly
 /// fixed for ObjC++.
-Sema::OwningExprResult
+ExprResult
 Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
                        bool &IsArrow, SourceLocation OpLoc,
                        CXXScopeSpec &SS,
-                       DeclPtrTy ObjCImpDecl) {
+                       Decl *ObjCImpDecl, bool HasTemplateArgs) {
   assert(BaseExpr && "no base expression");
 
   // Perform default conversions.
@@ -2879,9 +3020,10 @@
           << QualType(Fun, 0)
           << FixItHint::CreateInsertion(Loc, "()");
 
-        OwningExprResult NewBase
-          = ActOnCallExpr(0, ExprArg(*this, BaseExpr), Loc,
+        ExprResult NewBase
+          = ActOnCallExpr(0, BaseExpr, Loc,
                           MultiExprArg(*this, 0, 0), 0, Loc);
+        BaseExpr = 0;
         if (NewBase.isInvalid())
           return ExprError();
 
@@ -2899,7 +3041,7 @@
       // Handle the following exceptional case PObj->isa.
       if (const ObjCObjectPointerType *OPT =
           BaseType->getAs<ObjCObjectPointerType>()) {
-        if (OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
+        if (OPT->getObjectType()->isObjCId() &&
             MemberName.getAsIdentifierInfo()->isStr("isa"))
           return Owned(new (Context) ObjCIsaExpr(BaseExpr, true, MemberLoc,
                                                  Context.getObjCClassType()));
@@ -2909,7 +3051,7 @@
     // is a reference to 'isa'.
     if (BaseType != Context.ObjCIdRedefinitionType) {
       BaseType = Context.ObjCIdRedefinitionType;
-      ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+      ImpCastExprToType(BaseExpr, BaseType, CK_BitCast);
     }
   }
 
@@ -2920,7 +3062,7 @@
     // is a reference to 'sel_id'.
     if (BaseType != Context.ObjCSelRedefinitionType) {
       BaseType = Context.ObjCSelRedefinitionType;
-      ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+      ImpCastExprToType(BaseExpr, BaseType, CK_BitCast);
     }
   }
 
@@ -2962,7 +3104,7 @@
         QualType PType;
 
         if (Getter)
-          PType = Getter->getResultType();
+          PType = Getter->getSendResultType();
         else
           // Get the expression type from Setter's incoming parameter.
           PType = (*(Setter->param_end() -1))->getType();
@@ -2979,7 +3121,7 @@
   if (BaseType->isObjCClassType() &&
       BaseType != Context.ObjCClassRedefinitionType) {
     BaseType = Context.ObjCClassRedefinitionType;
-    ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+    ImpCastExprToType(BaseExpr, BaseType, CK_BitCast);
   }
 
   if (IsArrow) {
@@ -3023,11 +3165,10 @@
     }
   }
 
-  // Handle field access to simple records.  This also handles access
-  // to fields of the ObjC 'id' struct.
+  // Handle field access to simple records.
   if (const RecordType *RTy = BaseType->getAs<RecordType>()) {
     if (LookupMemberExprInRecord(*this, R, BaseExpr->getSourceRange(),
-                                 RTy, OpLoc, SS))
+                                 RTy, OpLoc, SS, HasTemplateArgs))
       return ExprError();
     return Owned((Expr*) 0);
   }
@@ -3035,14 +3176,14 @@
   // Handle access to Objective-C instance variables, such as "Obj->ivar" and
   // (*Obj).ivar.
   if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
-      (!IsArrow && BaseType->isObjCInterfaceType())) {
+      (!IsArrow && BaseType->isObjCObjectType())) {
     const ObjCObjectPointerType *OPT = BaseType->getAs<ObjCObjectPointerType>();
-    const ObjCInterfaceType *IFaceT =
-      OPT ? OPT->getInterfaceType() : BaseType->getAs<ObjCInterfaceType>();
-    if (IFaceT) {
+    ObjCInterfaceDecl *IDecl =
+      OPT ? OPT->getInterfaceDecl()
+          : BaseType->getAs<ObjCObjectType>()->getInterface();
+    if (IDecl) {
       IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
 
-      ObjCInterfaceDecl *IDecl = IFaceT->getDecl();
       ObjCInterfaceDecl *ClassDeclared;
       ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
 
@@ -3059,6 +3200,9 @@
                                             IV->getNameAsString());
           Diag(IV->getLocation(), diag::note_previous_decl)
             << IV->getDeclName();
+        } else {
+          Res.clear();
+          Res.setLookupName(Member);
         }
       }
 
@@ -3084,12 +3228,11 @@
             // 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))
+                dyn_cast<ObjCImplementationDecl>(ObjCImpDecl))
               ClassOfMethodDecl = IMPD->getClassInterface();
             else if (ObjCCategoryImplDecl* CatImplClass =
-                        dyn_cast<ObjCCategoryImplDecl>(ImplDecl))
+                        dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl))
               ClassOfMethodDecl = CatImplClass->getClassInterface();
           }
 
@@ -3135,8 +3278,8 @@
         if (DiagnoseUseOfDecl(OMD, MemberLoc))
           return ExprError();
 
-        return Owned(ObjCMessageExpr::Create(Context, 
-                                     OMD->getResultType().getNonReferenceType(),
+        return Owned(ObjCMessageExpr::Create(Context,
+                                             OMD->getSendResultType(),
                                              OpLoc, BaseExpr, Sel,
                                              OMD, NULL, 0, MemberLoc));
       }
@@ -3145,7 +3288,7 @@
     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)
@@ -3155,7 +3298,8 @@
 
   // Handle the following exceptional case (*Obj).isa.
   if (!IsArrow &&
-      BaseType->isSpecificBuiltinType(BuiltinType::ObjCId) &&
+      BaseType->isObjCObjectType() &&
+      BaseType->getAs<ObjCObjectType>()->isObjCId() &&
       MemberName.getAsIdentifierInfo()->isStr("isa"))
     return Owned(new (Context) ObjCIsaExpr(BaseExpr, false, MemberLoc,
                                            Context.getObjCClassType()));
@@ -3189,12 +3333,12 @@
 /// \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,
+ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base,
                                                    SourceLocation OpLoc,
                                                    tok::TokenKind OpKind,
                                                    CXXScopeSpec &SS,
                                                    UnqualifiedId &Id,
-                                                   DeclPtrTy ObjCImpDecl,
+                                                   Decl *ObjCImpDecl,
                                                    bool HasTrailingLParen) {
   if (SS.isSet() && SS.isInvalid())
     return ExprError();
@@ -3202,12 +3346,12 @@
   TemplateArgumentListInfo TemplateArgsBuffer;
 
   // Decompose the name into its component parts.
-  DeclarationName Name;
-  SourceLocation NameLoc;
+  DeclarationNameInfo NameInfo;
   const TemplateArgumentListInfo *TemplateArgs;
   DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer,
-                         Name, NameLoc, TemplateArgs);
+                         NameInfo, TemplateArgs);
 
+  DeclarationName Name = NameInfo.getName();
   bool IsArrow = (OpKind == tok::arrow);
 
   NamedDecl *FirstQualifierInScope
@@ -3215,45 +3359,39 @@
                        static_cast<NestedNameSpecifier*>(SS.getScopeRep())));
 
   // This is a postfix expression, so get rid of ParenListExprs.
-  BaseArg = MaybeConvertParenListExprToParenExpr(S, move(BaseArg));
+  ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
+  if (Result.isInvalid()) return ExprError();
+  Base = Result.take();
 
-  Expr *Base = BaseArg.takeAs<Expr>();
-  OwningExprResult Result(*this);
   if (Base->getType()->isDependentType() || Name.isDependentName() ||
       isDependentScopeSpecifier(SS)) {
-    Result = ActOnDependentMemberExpr(ExprArg(*this, Base), Base->getType(),
+    Result = ActOnDependentMemberExpr(Base, Base->getType(),
                                       IsArrow, OpLoc,
                                       SS, FirstQualifierInScope,
-                                      Name, NameLoc,
-                                      TemplateArgs);
+                                      NameInfo, 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);
+    LookupResult R(*this, NameInfo, LookupMemberName);
+    Result = LookupMemberExpr(R, Base, IsArrow, OpLoc,
+                              SS, ObjCImpDecl, TemplateArgs != 0);
 
-      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);
-      }
+    if (Result.isInvalid()) {
+      Owned(Base);
+      return ExprError();
     }
 
-    Result = BuildMemberReferenceExpr(ExprArg(*this, Base), Base->getType(),
+    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(NameInfo.getLoc(), Result.get());
+
+      return move(Result);
+    }
+
+    Result = BuildMemberReferenceExpr(Base, Base->getType(),
                                       OpLoc, IsArrow, SS, FirstQualifierInScope,
                                       R, TemplateArgs);
   }
@@ -3261,7 +3399,7 @@
   return move(Result);
 }
 
-Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
+ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
                                                     FunctionDecl *FD,
                                                     ParmVarDecl *Param) {
   if (Param->hasUnparsedDefaultArg()) {
@@ -3278,11 +3416,12 @@
       MultiLevelTemplateArgumentList ArgList
         = getTemplateInstantiationArgs(FD, 0, /*RelativeToPrimary=*/true);
 
-      InstantiatingTemplate Inst(*this, CallLoc, Param,
-                                 ArgList.getInnermost().getFlatArgumentList(),
-                                 ArgList.getInnermost().flat_size());
+      std::pair<const TemplateArgument *, unsigned> Innermost 
+        = ArgList.getInnermost();
+      InstantiatingTemplate Inst(*this, CallLoc, Param, Innermost.first,
+                                 Innermost.second);
 
-      OwningExprResult Result = SubstExpr(UninstExpr, ArgList);
+      ExprResult Result = SubstExpr(UninstExpr, ArgList);
       if (Result.isInvalid())
         return ExprError();
 
@@ -3296,7 +3435,7 @@
 
       InitializationSequence InitSeq(*this, Entity, Kind, &ResultE, 1);
       Result = InitSeq.Perform(*this, Entity, Kind,
-                               MultiExprArg(*this, (void**)&ResultE, 1));
+                               MultiExprArg(*this, &ResultE, 1));
       if (Result.isInvalid())
         return ExprError();
 
@@ -3340,7 +3479,7 @@
   if (NumArgs < NumArgsInProto) {
     if (!FDecl || NumArgs < FDecl->getMinRequiredArguments())
       return Diag(RParenLoc, diag::err_typecheck_call_too_few_args)
-        << Fn->getType()->isBlockPointerType() 
+        << Fn->getType()->isBlockPointerType()
         << NumArgsInProto << NumArgs << Fn->getSourceRange();
     Call->setNumArgs(Context, NumArgsInProto);
   }
@@ -3351,7 +3490,7 @@
     if (!Proto->isVariadic()) {
       Diag(Args[NumArgsInProto]->getLocStart(),
            diag::err_typecheck_call_too_many_args)
-        << Fn->getType()->isBlockPointerType() 
+        << Fn->getType()->isBlockPointerType()
         << NumArgsInProto << NumArgs << Fn->getSourceRange()
         << SourceRange(Args[NumArgsInProto]->getLocStart(),
                        Args[NumArgs-1]->getLocEnd());
@@ -3415,7 +3554,7 @@
       InitializedEntity Entity =
         Param? InitializedEntity::InitializeParameter(Param)
              : InitializedEntity::InitializeParameter(ProtoArgType);
-      OwningExprResult ArgE = PerformCopyInitialization(Entity,
+      ExprResult ArgE = PerformCopyInitialization(Entity,
                                                         SourceLocation(),
                                                         Owned(Arg));
       if (ArgE.isInvalid())
@@ -3425,7 +3564,7 @@
     } else {
       ParmVarDecl *Param = FDecl->getParamDecl(i);
 
-      OwningExprResult ArgExpr =
+      ExprResult ArgExpr =
         BuildCXXDefaultArgExpr(CallLoc, FDecl, Param);
       if (ArgExpr.isInvalid())
         return true;
@@ -3438,9 +3577,9 @@
   // 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++) {
+    for (unsigned i = ArgIx; i != NumArgs; ++i) {
       Expr *Arg = Args[i];
-      Invalid |= DefaultVariadicArgumentPromotion(Arg, CallType);
+      Invalid |= DefaultVariadicArgumentPromotion(Arg, CallType, FDecl);
       AllArgs.push_back(Arg);
     }
   }
@@ -3450,18 +3589,18 @@
 /// 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,
+ExprResult
+Sema::ActOnCallExpr(Scope *S, Expr *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));
+  ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Fn);
+  if (Result.isInvalid()) return ExprError();
+  Fn = Result.take();
 
-  Expr *Fn = fn.takeAs<Expr>();
-  Expr **Args = reinterpret_cast<Expr**>(args.release());
-  assert(Fn && "no function call expression");
+  Expr **Args = args.release();
 
   if (getLangOptions().CPlusPlus) {
     // If this is a pseudo-destructor expression, build the call immediately.
@@ -3473,9 +3612,6 @@
                                     SourceRange(Args[0]->getLocStart(),
                                                 Args[NumArgs-1]->getLocEnd()));
 
-        for (unsigned I = 0; I != NumArgs; ++I)
-          Args[I]->Destroy(Context);
-
         NumArgs = 0;
       }
 
@@ -3530,27 +3666,27 @@
 
     // 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();
+      if (BO->getOpcode() == BO_PtrMemD ||
+          BO->getOpcode() == BO_PtrMemI) {
+        if (const FunctionProtoType *FPT
+                                = BO->getType()->getAs<FunctionProtoType>()) {
+          QualType ResultTy = FPT->getCallResultType(Context);
 
-          ExprOwningPtr<CXXMemberCallExpr>
-            TheCall(this, new (Context) CXXMemberCallExpr(Context, BO, Args,
-                                                          NumArgs, ResultTy,
-                                                          RParenLoc));
+          CXXMemberCallExpr *TheCall
+            = new (Context) CXXMemberCallExpr(Context, BO, Args,
+                                              NumArgs, ResultTy,
+                                              RParenLoc);
 
           if (CheckCallReturnType(FPT->getResultType(),
                                   BO->getRHS()->getSourceRange().getBegin(),
-                                  TheCall.get(), 0))
+                                  TheCall, 0))
             return ExprError();
 
-          if (ConvertArgumentsForCall(&*TheCall, BO, 0, FPT, Args, NumArgs,
+          if (ConvertArgumentsForCall(TheCall, BO, 0, FPT, Args, NumArgs,
                                       RParenLoc))
             return ExprError();
 
-          return Owned(MaybeBindToTemporary(TheCall.release()).release());
+          return MaybeBindToTemporary(TheCall);
         }
         return ExprError(Diag(Fn->getLocStart(),
                               diag::err_typecheck_call_not_function)
@@ -3583,7 +3719,7 @@
 /// block-pointer type.
 ///
 /// \param NDecl the declaration being called, if available
-Sema::OwningExprResult
+ExprResult
 Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
                             SourceLocation LParenLoc,
                             Expr **Args, unsigned NumArgs,
@@ -3595,10 +3731,10 @@
 
   // 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));
+  CallExpr *TheCall = new (Context) CallExpr(Context, Fn,
+                                             Args, NumArgs,
+                                             Context.BoolTy,
+                                             RParenLoc);
 
   const FunctionType *FuncT;
   if (!Fn->getType()->isBlockPointerType()) {
@@ -3619,15 +3755,15 @@
 
   // Check for a valid return type
   if (CheckCallReturnType(FuncT->getResultType(),
-                          Fn->getSourceRange().getBegin(), TheCall.get(),
+                          Fn->getSourceRange().getBegin(), TheCall,
                           FDecl))
     return ExprError();
 
   // We know the result type of the call, set it.
-  TheCall->setType(FuncT->getResultType().getNonReferenceType());
+  TheCall->setType(FuncT->getCallResultType(Context));
 
   if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT)) {
-    if (ConvertArgumentsForCall(&*TheCall, Fn, FDecl, Proto, Args, NumArgs,
+    if (ConvertArgumentsForCall(TheCall, Fn, FDecl, Proto, Args, NumArgs,
                                 RParenLoc))
       return ExprError();
   } else {
@@ -3637,7 +3773,7 @@
       // 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()) {
+      if (FDecl->hasBody(Def) && NumArgs != Def->param_size()) {
         const FunctionProtoType *Proto =
             Def->getType()->getAs<FunctionProtoType>();
         if (!Proto || !(Proto->isVariadic() && NumArgs >= Def->param_size())) {
@@ -3671,22 +3807,22 @@
 
   // Do special checking on direct calls to functions.
   if (FDecl) {
-    if (CheckFunctionCall(FDecl, TheCall.get()))
+    if (CheckFunctionCall(FDecl, TheCall))
       return ExprError();
 
     if (unsigned BuiltinID = FDecl->getBuiltinID())
-      return CheckBuiltinFunctionCall(BuiltinID, TheCall.take());
+      return CheckBuiltinFunctionCall(BuiltinID, TheCall);
   } else if (NDecl) {
-    if (CheckBlockCall(NDecl, TheCall.get()))
+    if (CheckBlockCall(NDecl, TheCall))
       return ExprError();
   }
 
-  return MaybeBindToTemporary(TheCall.take());
+  return MaybeBindToTemporary(TheCall);
 }
 
-Action::OwningExprResult
-Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
-                           SourceLocation RParenLoc, ExprArg InitExpr) {
+ExprResult
+Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
+                           SourceLocation RParenLoc, Expr *InitExpr) {
   assert((Ty != 0) && "ActOnCompoundLiteral(): missing type");
   // FIXME: put back this assert when initializers are worked out.
   //assert((InitExpr != 0) && "ActOnCompoundLiteral(): missing expression");
@@ -3696,14 +3832,13 @@
   if (!TInfo)
     TInfo = Context.getTrivialTypeSourceInfo(literalType);
 
-  return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, move(InitExpr));
+  return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, InitExpr);
 }
 
-Action::OwningExprResult
+ExprResult
 Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
-                               SourceLocation RParenLoc, ExprArg InitExpr) {
+                               SourceLocation RParenLoc, Expr *literalExpr) {
   QualType literalType = TInfo->getType();
-  Expr *literalExpr = static_cast<Expr*>(InitExpr.get());
 
   if (literalType->isArrayType()) {
     if (literalType->isVariableArrayType())
@@ -3722,13 +3857,12 @@
     = 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),
+  ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                       MultiExprArg(*this, &literalExpr, 1),
                                             &literalType);
   if (Result.isInvalid())
     return ExprError();
-  InitExpr.release();
-  literalExpr = static_cast<Expr*>(Result.get());
+  literalExpr = Result.get();
 
   bool isFileScope = getCurFunctionOrMethodDecl() == 0;
   if (isFileScope) { // 6.5.2.5p3
@@ -3736,17 +3870,15 @@
       return ExprError();
   }
 
-  Result.release();
-
   return Owned(new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
                                                  literalExpr, isFileScope));
 }
 
-Action::OwningExprResult
+ExprResult
 Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
                     SourceLocation RBraceLoc) {
   unsigned NumInit = initlist.size();
-  Expr **InitList = reinterpret_cast<Expr**>(initlist.release());
+  Expr **InitList = initlist.release();
 
   // Semantic analysis for initializers is done by ActOnDeclarator() and
   // CheckInitializer() - it requires knowledge of the object being intialized.
@@ -3757,45 +3889,45 @@
   return Owned(E);
 }
 
-static CastExpr::CastKind getScalarCastKind(ASTContext &Context,
+static CastKind getScalarCastKind(ASTContext &Context,
                                             QualType SrcTy, QualType DestTy) {
   if (Context.hasSameUnqualifiedType(SrcTy, DestTy))
-    return CastExpr::CK_NoOp;
+    return CK_NoOp;
 
   if (SrcTy->hasPointerRepresentation()) {
     if (DestTy->hasPointerRepresentation())
       return DestTy->isObjCObjectPointerType() ?
-                CastExpr::CK_AnyPointerToObjCPointerCast :
-                CastExpr::CK_BitCast;
+                CK_AnyPointerToObjCPointerCast :
+                CK_BitCast;
     if (DestTy->isIntegerType())
-      return CastExpr::CK_PointerToIntegral;
+      return CK_PointerToIntegral;
   }
 
   if (SrcTy->isIntegerType()) {
     if (DestTy->isIntegerType())
-      return CastExpr::CK_IntegralCast;
+      return CK_IntegralCast;
     if (DestTy->hasPointerRepresentation())
-      return CastExpr::CK_IntegralToPointer;
+      return CK_IntegralToPointer;
     if (DestTy->isRealFloatingType())
-      return CastExpr::CK_IntegralToFloating;
+      return CK_IntegralToFloating;
   }
 
   if (SrcTy->isRealFloatingType()) {
     if (DestTy->isRealFloatingType())
-      return CastExpr::CK_FloatingCast;
+      return CK_FloatingCast;
     if (DestTy->isIntegerType())
-      return CastExpr::CK_FloatingToIntegral;
+      return CK_FloatingToIntegral;
   }
 
   // FIXME: Assert here.
   // assert(false && "Unhandled cast combination!");
-  return CastExpr::CK_Unknown;
+  return CK_Unknown;
 }
 
 /// CheckCastTypes - Check type constraints for casting between types.
 bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
-                          CastExpr::CastKind& Kind,
-                          CXXBaseSpecifierArray &BasePath,
+                          CastKind& Kind,
+                          CXXCastPath &BasePath,
                           bool FunctionalStyle) {
   if (getLangOptions().CPlusPlus)
     return CXXCheckCStyleCast(TyR, castType, castExpr, Kind, BasePath,
@@ -3807,10 +3939,14 @@
   // type needs to be scalar.
   if (castType->isVoidType()) {
     // Cast to void allows any expr type.
-    Kind = CastExpr::CK_ToVoid;
+    Kind = CK_ToVoid;
     return false;
   }
 
+  if (RequireCompleteType(TyR.getBegin(), castType,
+                          diag::err_typecheck_cast_to_incomplete))
+    return true;
+
   if (!castType->isScalarType() && !castType->isVectorType()) {
     if (Context.hasSameUnqualifiedType(castType, castExpr->getType()) &&
         (castType->isStructureType() || castType->isUnionType())) {
@@ -3818,7 +3954,7 @@
       // FIXME: Check that the cast destination type is complete.
       Diag(TyR.getBegin(), diag::ext_typecheck_cast_nonscalar)
         << castType << castExpr->getSourceRange();
-      Kind = CastExpr::CK_NoOp;
+      Kind = CK_NoOp;
       return false;
     }
 
@@ -3838,7 +3974,7 @@
       if (Field == FieldEnd)
         return Diag(TyR.getBegin(), diag::err_typecheck_cast_to_union_no_type)
           << castExpr->getType() << castExpr->getSourceRange();
-      Kind = CastExpr::CK_ToUnion;
+      Kind = CK_ToUnion;
       return false;
     }
 
@@ -3867,23 +4003,28 @@
 
   if (!castType->isArithmeticType()) {
     QualType castExprType = castExpr->getType();
-    if (!castExprType->isIntegralType() && castExprType->isArithmeticType())
+    if (!castExprType->isIntegralType(Context) && 
+        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())
+    if (!castType->isIntegralType(Context) && castType->isArithmeticType())
       return Diag(castExpr->getLocStart(),
                   diag::err_cast_pointer_to_non_pointer_int)
         << castType << castExpr->getSourceRange();
   }
 
   Kind = getScalarCastKind(Context, castExpr->getType(), castType);
+
+  if (Kind == CK_Unknown || Kind == CK_BitCast)
+    CheckCastAlign(castExpr, castType, TyR);
+
   return false;
 }
 
 bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
-                           CastExpr::CastKind &Kind) {
+                           CastKind &Kind) {
   assert(VectorTy->isVectorType() && "Not a vector type!");
 
   if (Ty->isVectorType() || Ty->isIntegerType()) {
@@ -3898,12 +4039,12 @@
                 diag::err_invalid_conversion_between_vector_and_scalar)
       << VectorTy << Ty << R;
 
-  Kind = CastExpr::CK_BitCast;
+  Kind = CK_BitCast;
   return false;
 }
 
 bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr,
-                              CastExpr::CastKind &Kind) {
+                              CastKind &Kind) {
   assert(DestTy->isExtVectorType() && "Not an extended vector type!");
 
   QualType SrcTy = CastExpr->getType();
@@ -3914,7 +4055,7 @@
     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;
+    Kind = CK_BitCast;
     return false;
   }
 
@@ -3930,14 +4071,14 @@
   ImpCastExprToType(CastExpr, DestElemTy,
                     getScalarCastKind(Context, SrcTy, DestElemTy));
 
-  Kind = CastExpr::CK_VectorSplat;
+  Kind = CK_VectorSplat;
   return false;
 }
 
-Action::OwningExprResult
-Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty,
-                    SourceLocation RParenLoc, ExprArg Op) {
-  assert((Ty != 0) && (Op.get() != 0) &&
+ExprResult
+Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, ParsedType Ty,
+                    SourceLocation RParenLoc, Expr *castExpr) {
+  assert((Ty != 0) && (castExpr != 0) &&
          "ActOnCastExpr(): missing type or expr");
 
   TypeSourceInfo *castTInfo;
@@ -3946,88 +4087,97 @@
     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),
+    return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, castExpr,
                                     castTInfo);
 
-  return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, move(Op));
+  return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, castExpr);
 }
 
-Action::OwningExprResult
+ExprResult
 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;
+                          SourceLocation RParenLoc, Expr *castExpr) {
+  CastKind Kind = CK_Unknown;
+  CXXCastPath 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));
+  return Owned(CStyleCastExpr::Create(Context,
+                                    Ty->getType().getNonLValueExprType(Context),
+                                      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>();
+ExprResult
+Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *expr) {
   ParenListExpr *E = dyn_cast<ParenListExpr>(expr);
   if (!E)
     return Owned(expr);
 
-  OwningExprResult Result(*this, E->getExpr(0));
+  ExprResult Result(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)));
+    Result = ActOnBinOp(S, E->getExprLoc(), tok::comma, Result.get(),
+                        E->getExpr(i));
 
-  return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), move(Result));
+  if (Result.isInvalid()) return ExprError();
+
+  return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), Result.get());
 }
 
-Action::OwningExprResult
+ExprResult
 Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
-                               SourceLocation RParenLoc, ExprArg Op,
+                               SourceLocation RParenLoc, Expr *Op,
                                TypeSourceInfo *TInfo) {
-  ParenListExpr *PE = (ParenListExpr *)Op.get();
+  ParenListExpr *PE = cast<ParenListExpr>(Op);
   QualType Ty = TInfo->getType();
+  bool isAltiVecLiteral = false;
 
-  // If this is an altivec initializer, '(' type ')' '(' init, ..., init ')'
-  // then handle it as such.
+  // Check for an altivec literal,
+  // i.e. all the elements are integer constants.
   if (getLangOptions().AltiVec && Ty->isVectorType()) {
     if (PE->getNumExprs() == 0) {
       Diag(PE->getExprLoc(), diag::err_altivec_empty_initializer);
       return ExprError();
     }
+    if (PE->getNumExprs() == 1) {
+      if (!PE->getExpr(0)->getType()->isVectorType())
+        isAltiVecLiteral = true;
+    }
+    else
+      isAltiVecLiteral = true;
+  }
 
+  // If this is an altivec initializer, '(' type ')' '(' init, ..., init ')'
+  // then handle it as such.
+  if (isAltiVecLiteral) {
     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));
+    return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, 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));
+    ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Op);
+    if (Result.isInvalid()) return ExprError();
+    return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Result.take());
   }
 }
 
-Action::OwningExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L,
+ExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L,
                                                   SourceLocation R,
                                                   MultiExprArg Val,
-                                                  TypeTy *TypeOfCast) {
+                                                  ParsedType TypeOfCast) {
   unsigned nexprs = Val.size();
   Expr **exprs = reinterpret_cast<Expr**>(Val.release());
   assert((exprs != 0) && "ActOnParenOrParenListExpr() missing expr list");
@@ -4048,8 +4198,6 @@
   if (getLangOptions().CPlusPlus)
     return CXXCheckConditionalOperands(Cond, LHS, RHS, QuestionLoc);
 
-  CheckSignCompare(LHS, RHS, QuestionLoc);
-
   UsualUnaryConversions(Cond);
   UsualUnaryConversions(LHS);
   UsualUnaryConversions(RHS);
@@ -4095,8 +4243,8 @@
     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);
+    ImpCastExprToType(LHS, Context.VoidTy, CK_ToVoid);
+    ImpCastExprToType(RHS, Context.VoidTy, CK_ToVoid);
     return Context.VoidTy;
   }
   // C99 6.5.15p6 - "if one operand is a null pointer constant, the result has
@@ -4104,12 +4252,12 @@
   if ((LHSTy->isAnyPointerType() || LHSTy->isBlockPointerType()) &&
       RHS->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
     // promote the null to a pointer.
-    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_Unknown);
+    ImpCastExprToType(RHS, LHSTy, CK_Unknown);
     return LHSTy;
   }
   if ((RHSTy->isAnyPointerType() || RHSTy->isBlockPointerType()) &&
       LHS->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
-    ImpCastExprToType(LHS, RHSTy, CastExpr::CK_Unknown);
+    ImpCastExprToType(LHS, RHSTy, CK_Unknown);
     return RHSTy;
   }
 
@@ -4125,8 +4273,8 @@
     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);
+        ImpCastExprToType(LHS, destType, CK_BitCast);
+        ImpCastExprToType(RHS, destType, CK_BitCast);
         return destType;
       }
       Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
@@ -4150,13 +4298,13 @@
       // 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);
+      ImpCastExprToType(LHS, incompatTy, CK_BitCast);
+      ImpCastExprToType(RHS, incompatTy, CK_BitCast);
       return incompatTy;
     }
     // The block pointer types are compatible.
-    ImpCastExprToType(LHS, LHSTy, CastExpr::CK_BitCast);
-    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(LHS, LHSTy, CK_BitCast);
+    ImpCastExprToType(RHS, LHSTy, CK_BitCast);
     return LHSTy;
   }
 
@@ -4173,9 +4321,9 @@
         = Context.getQualifiedType(lhptee, rhptee.getQualifiers());
       QualType destType = Context.getPointerType(destPointee);
       // Add qualifiers if necessary.
-      ImpCastExprToType(LHS, destType, CastExpr::CK_NoOp);
+      ImpCastExprToType(LHS, destType, CK_NoOp);
       // Promote to void*.
-      ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast);
+      ImpCastExprToType(RHS, destType, CK_BitCast);
       return destType;
     }
     if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) {
@@ -4183,9 +4331,9 @@
         = Context.getQualifiedType(rhptee, lhptee.getQualifiers());
       QualType destType = Context.getPointerType(destPointee);
       // Add qualifiers if necessary.
-      ImpCastExprToType(RHS, destType, CastExpr::CK_NoOp);
+      ImpCastExprToType(RHS, destType, CK_NoOp);
       // Promote to void*.
-      ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast);
+      ImpCastExprToType(LHS, destType, CK_BitCast);
       return destType;
     }
 
@@ -4201,8 +4349,8 @@
       // 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);
+      ImpCastExprToType(LHS, incompatTy, CK_BitCast);
+      ImpCastExprToType(RHS, incompatTy, CK_BitCast);
       return incompatTy;
     }
     // The pointer types are compatible.
@@ -4212,8 +4360,8 @@
     // 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);
+    ImpCastExprToType(LHS, LHSTy, CK_BitCast);
+    ImpCastExprToType(RHS, LHSTy, CK_BitCast);
     return LHSTy;
   }
 
@@ -4221,13 +4369,13 @@
   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);
+    ImpCastExprToType(LHS, RHSTy, 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);
+    ImpCastExprToType(RHS, LHSTy, CK_IntegralToPointer);
     return LHSTy;
   }
 
@@ -4249,34 +4397,34 @@
   // redefinition type if an attempt is made to access its fields.
   if (LHSTy->isObjCClassType() &&
       (RHSTy.getDesugaredType() == Context.ObjCClassRedefinitionType)) {
-    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(RHS, LHSTy, CK_BitCast);
     return LHSTy;
   }
   if (RHSTy->isObjCClassType() &&
       (LHSTy.getDesugaredType() == Context.ObjCClassRedefinitionType)) {
-    ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(LHS, RHSTy, 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);
+    ImpCastExprToType(RHS, LHSTy, CK_BitCast);
     return LHSTy;
   }
   if (RHSTy->isObjCIdType() &&
       (LHSTy.getDesugaredType() == Context.ObjCIdRedefinitionType)) {
-    ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(LHS, RHSTy, 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);
+    ImpCastExprToType(RHS, LHSTy, CK_BitCast);
     return LHSTy;
   }
   if (Context.isObjCSelType(RHSTy) &&
       (LHSTy.getDesugaredType() == Context.ObjCSelRedefinitionType)) {
-    ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(LHS, RHSTy, CK_BitCast);
     return RHSTy;
   }
   // Check constraints for Objective-C object pointers types.
@@ -4325,13 +4473,13 @@
       << LHSTy << RHSTy
       << LHS->getSourceRange() << RHS->getSourceRange();
       QualType incompatTy = Context.getObjCIdType();
-      ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast);
-      ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast);
+      ImpCastExprToType(LHS, incompatTy, CK_BitCast);
+      ImpCastExprToType(RHS, incompatTy, CK_BitCast);
       return incompatTy;
     }
     // The object pointer types are compatible.
-    ImpCastExprToType(LHS, compositeType, CastExpr::CK_BitCast);
-    ImpCastExprToType(RHS, compositeType, CastExpr::CK_BitCast);
+    ImpCastExprToType(LHS, compositeType, CK_BitCast);
+    ImpCastExprToType(RHS, compositeType, CK_BitCast);
     return compositeType;
   }
   // Check Objective-C object pointer types and 'void *'
@@ -4342,9 +4490,9 @@
     = Context.getQualifiedType(lhptee, rhptee.getQualifiers());
     QualType destType = Context.getPointerType(destPointee);
     // Add qualifiers if necessary.
-    ImpCastExprToType(LHS, destType, CastExpr::CK_NoOp);
+    ImpCastExprToType(LHS, destType, CK_NoOp);
     // Promote to void*.
-    ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast);
+    ImpCastExprToType(RHS, destType, CK_BitCast);
     return destType;
   }
   if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) {
@@ -4354,9 +4502,9 @@
     = Context.getQualifiedType(rhptee, lhptee.getQualifiers());
     QualType destType = Context.getPointerType(destPointee);
     // Add qualifiers if necessary.
-    ImpCastExprToType(RHS, destType, CastExpr::CK_NoOp);
+    ImpCastExprToType(RHS, destType, CK_NoOp);
     // Promote to void*.
-    ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast);
+    ImpCastExprToType(LHS, destType, CK_BitCast);
     return destType;
   }
   return QualType();
@@ -4364,13 +4512,10 @@
 
 /// 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,
+ExprResult 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();
-
+                                                  Expr *CondExpr, Expr *LHSExpr,
+                                                  Expr *RHSExpr) {
   // If this is the gnu "x ?: y" extension, analyze the types as though the LHS
   // was the condition.
   bool isLHSNull = LHSExpr == 0;
@@ -4382,9 +4527,6 @@
   if (result.isNull())
     return ExprError();
 
-  Cond.release();
-  LHS.release();
-  RHS.release();
   return Owned(new (Context) ConditionalOperator(CondExpr, QuestionLoc,
                                                  isLHSNull ? 0 : LHSExpr,
                                                  ColonLoc, RHSExpr, result));
@@ -4453,12 +4595,12 @@
     // "unsigned char" on systems where "char" is unsigned.
     if (lhptee->isCharType())
       lhptee = Context.UnsignedCharTy;
-    else if (lhptee->isSignedIntegerType())
+    else if (lhptee->hasSignedIntegerRepresentation())
       lhptee = Context.getCorrespondingUnsignedType(lhptee);
 
     if (rhptee->isCharType())
       rhptee = Context.UnsignedCharTy;
-    else if (rhptee->isSignedIntegerType())
+    else if (rhptee->hasSignedIntegerRepresentation())
       rhptee = Context.getCorrespondingUnsignedType(rhptee);
 
     if (lhptee == rhptee) {
@@ -4610,23 +4752,29 @@
   if (lhsType->isExtVectorType()) {
     if (rhsType->isExtVectorType())
       return lhsType == rhsType ? Compatible : Incompatible;
-    if (!rhsType->isVectorType() && rhsType->isArithmeticType())
+    if (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))
+    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 &&
+         (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType)))
         return IncompatibleVectors;
+
+      // Allow assignments of an AltiVec vector type to an equivalent GCC
+      // vector type and vice versa
+      if (Context.areCompatibleVectorTypes(lhsType, rhsType))
+        return Compatible;
     }
     return Incompatible;
   }
 
-  if (lhsType->isArithmeticType() && rhsType->isArithmeticType())
+  if (lhsType->isArithmeticType() && rhsType->isArithmeticType() &&
+      !(getLangOptions().CPlusPlus && lhsType->isEnumeralType()))
     return Compatible;
 
   if (isa<PointerType>(lhsType)) {
@@ -4778,14 +4926,14 @@
       // 2) null pointer constant
       if (FromType->isPointerType())
         if (FromType->getAs<PointerType>()->getPointeeType()->isVoidType()) {
-          ImpCastExprToType(rExpr, it->getType(), CastExpr::CK_BitCast);
+          ImpCastExprToType(rExpr, it->getType(), CK_BitCast);
           InitField = *it;
           break;
         }
 
       if (rExpr->isNullPointerConstant(Context,
                                        Expr::NPC_ValueDependentIsNull)) {
-        ImpCastExprToType(rExpr, it->getType(), CastExpr::CK_IntegralToPointer);
+        ImpCastExprToType(rExpr, it->getType(), CK_IntegralToPointer);
         InitField = *it;
         break;
       }
@@ -4829,14 +4977,14 @@
        lhsType->isBlockPointerType())
       && rExpr->isNullPointerConstant(Context,
                                       Expr::NPC_ValueDependentIsNull)) {
-    ImpCastExprToType(rExpr, lhsType, CastExpr::CK_Unknown);
+    ImpCastExprToType(rExpr, lhsType, 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).
+  // expressions that suppress this implicit conversion (&, sizeof).
   //
   // Suppress this for references: C++ 8.5.3p5.
   if (!lhsType->isReferenceType())
@@ -4852,8 +5000,8 @@
   // 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);
+    ImpCastExprToType(rExpr, lhsType.getNonLValueExprType(Context),
+                      CK_Unknown);
   return result;
 }
 
@@ -4879,14 +5027,32 @@
   // 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;
+          if (lhsType->isExtVectorType()) {
+            ImpCastExprToType(rex, lhsType, CK_BitCast);
+            return lhsType;
+          } 
+
+          ImpCastExprToType(lex, rhsType, CK_BitCast);
+          return rhsType;
+        } else if (Context.getTypeSize(lhsType) ==Context.getTypeSize(rhsType)){
+          // 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.
+          ImpCastExprToType(rex, lhsType, CK_BitCast);
+          return lhsType;
         }
-    }
+      }
+  }
+
+  // Handle the case of equivalent AltiVec and GCC vector types
+  if (lhsType->isVectorType() && rhsType->isVectorType() &&
+      Context.areCompatibleVectorTypes(lhsType, rhsType)) {
+    ImpCastExprToType(lex, rhsType, CK_BitCast);
+    return rhsType;
   }
 
   // Canonicalize the ExtVector to the LHS, remember if we swapped so we can
@@ -4901,9 +5067,9 @@
   // 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 (EltTy->isIntegralType(Context) && rhsType->isIntegralType(Context)) {
       if (Context.getIntegerTypeOrder(EltTy, rhsType) >= 0) {
-        ImpCastExprToType(rex, lhsType, CastExpr::CK_IntegralCast);
+        ImpCastExprToType(rex, lhsType, CK_IntegralCast);
         if (swapped) std::swap(rex, lex);
         return lhsType;
       }
@@ -4911,7 +5077,7 @@
     if (EltTy->isRealFloatingType() && rhsType->isScalarType() &&
         rhsType->isRealFloatingType()) {
       if (Context.getFloatingTypeOrder(EltTy, rhsType) >= 0) {
-        ImpCastExprToType(rex, lhsType, CastExpr::CK_FloatingCast);
+        ImpCastExprToType(rex, lhsType, CK_FloatingCast);
         if (swapped) std::swap(rex, lex);
         return lhsType;
       }
@@ -4948,7 +5114,8 @@
 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())
+    if (lex->getType()->hasIntegerRepresentation() && 
+        rex->getType()->hasIntegerRepresentation())
       return CheckVectorOperands(Loc, lex, rex);
     return InvalidOperands(Loc, lex, rex);
   }
@@ -5026,7 +5193,7 @@
           return QualType();
       }
       // Diagnose bad cases where we step over interface counts.
-      if (PointeeTy->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+      if (PointeeTy->isObjCObjectType() && LangOpts.ObjCNonFragileABI) {
         Diag(Loc, diag::err_arithmetic_nonfragile_interface)
           << PointeeTy << PExp->getSourceRange();
         return QualType();
@@ -5102,7 +5269,7 @@
       return QualType();
 
     // Diagnose bad cases where we step over interface counts.
-    if (lpointee->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+    if (lpointee->isObjCObjectType() && LangOpts.ObjCNonFragileABI) {
       Diag(Loc, diag::err_arithmetic_nonfragile_interface)
         << lpointee << lex->getSourceRange();
       return QualType();
@@ -5193,7 +5360,8 @@
 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())
+  if (!lex->getType()->hasIntegerRepresentation() || 
+      !rex->getType()->hasIntegerRepresentation())
     return InvalidOperands(Loc, lex, rex);
 
   // Vector shifts promote their scalar inputs to vector type.
@@ -5209,7 +5377,7 @@
       LHSTy = Context.getPromotedIntegerType(LHSTy);
   }
   if (!isCompAssign)
-    ImpCastExprToType(lex, LHSTy, CastExpr::CK_IntegralCast);
+    ImpCastExprToType(lex, LHSTy, CK_IntegralCast);
 
   UsualUnaryConversions(rex);
 
@@ -5232,41 +5400,74 @@
   return LHSTy;
 }
 
+static bool IsWithinTemplateSpecialization(Decl *D) {
+  if (DeclContext *DC = D->getDeclContext()) {
+    if (isa<ClassTemplateSpecializationDecl>(DC))
+      return true;
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(DC))
+      return FD->isFunctionTemplateSpecialization();
+  }
+  return false;
+}
+
 // 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;
+  BinaryOperatorKind Opc = (BinaryOperatorKind) 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)) {
+  if (!lType->hasFloatingRepresentation() &&
+      !(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.
+    //
+    // NOTE: Don't warn about comparison expressions resulting from macro
+    // expansion. Also don't warn about comparisons which are only self
+    // comparisons within a template specialization. The warnings should catch
+    // obvious cases in the definition of the template anyways. The idea is to
+    // warn when the typed comparison operator will always evaluate to the same
+    // result.
     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 (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(LHSStripped)) {
+      if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RHSStripped)) {
+        if (DRL->getDecl() == DRR->getDecl() && !Loc.isMacroID() &&
+            !IsWithinTemplateSpecialization(DRL->getDecl())) {
+          DiagRuntimeBehavior(Loc, PDiag(diag::warn_comparison_always)
+                              << 0 // self-
+                              << (Opc == BO_EQ
+                                  || Opc == BO_LE
+                                  || Opc == BO_GE));
+        } else if (lType->isArrayType() && rType->isArrayType() &&
+                   !DRL->getDecl()->getType()->isReferenceType() &&
+                   !DRR->getDecl()->getType()->isReferenceType()) {
+            // what is it always going to eval to?
+            char always_evals_to;
+            switch(Opc) {
+            case BO_EQ: // e.g. array1 == array2
+              always_evals_to = 0; // false
+              break;
+            case BO_NE: // e.g. array1 != array2
+              always_evals_to = 1; // true
+              break;
+            default:
+              // best we can say is 'a constant'
+              always_evals_to = 2; // e.g. array1 <= array2
+              break;
+            }
+            DiagRuntimeBehavior(Loc, PDiag(diag::warn_comparison_always)
+                                << 1 // array
+                                << always_evals_to);
+        }
+      }
+    }
 
     if (isa<CastExpr>(LHSStripped))
       LHSStripped = LHSStripped->IgnoreParenCasts();
@@ -5293,12 +5494,12 @@
     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;
+      case BO_LT: resultComparison = ") < 0"; break;
+      case BO_GT: resultComparison = ") > 0"; break;
+      case BO_LE: resultComparison = ") <= 0"; break;
+      case BO_GE: resultComparison = ") >= 0"; break;
+      case BO_EQ: resultComparison = ") == 0"; break;
+      case BO_NE: resultComparison = ") != 0"; break;
       default: assert(false && "Invalid comparison operator");
       }
 
@@ -5309,6 +5510,17 @@
     }
   }
 
+  // C99 6.5.8p3 / C99 6.5.9p4
+  if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
+    UsualArithmeticConversions(lex, rex);
+  else {
+    UsualUnaryConversions(lex);
+    UsualUnaryConversions(rex);
+  }
+
+  lType = lex->getType();
+  rType = rex->getType();
+
   // The result of comparisons is 'bool' in C++, 'int' in C.
   QualType ResultTy = getLangOptions().CPlusPlus ? Context.BoolTy:Context.IntTy;
 
@@ -5317,7 +5529,7 @@
       return ResultTy;
   } else {
     // Check for comparisons of floating point operands using != and ==.
-    if (lType->isFloatingType() && rType->isFloatingType())
+    if (lType->hasFloatingRepresentation())
       CheckFloatComparison(Loc,lex,rex);
 
     if (lType->isArithmeticType() && rType->isArithmeticType())
@@ -5329,9 +5541,8 @@
   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).
+  // All of the following pointer-related warnings are GCC extensions, except
+  // when handling null pointer constants. 
   if (lType->isPointerType() && rType->isPointerType()) { // C99 6.5.8p2
     QualType LCanPointeeTy =
       Context.getCanonicalType(lType->getAs<PointerType>()->getPointeeType());
@@ -5345,11 +5556,20 @@
           (LCanPointeeTy->isVoidType() || RCanPointeeTy->isVoidType())) {
         // Valid unless comparison between non-null pointer and function pointer
         // This is a gcc extension compatibility comparison.
+        // In a SFINAE context, we treat this as a hard error to maintain
+        // conformance with the C++ standard.
         if ((LCanPointeeTy->isFunctionType() || RCanPointeeTy->isFunctionType())
             && !LHSIsNull && !RHSIsNull) {
-          Diag(Loc, diag::ext_typecheck_comparison_of_fptr_to_void)
+          Diag(Loc, 
+               isSFINAEContext()? 
+                   diag::err_typecheck_comparison_of_fptr_to_void
+                 : diag::ext_typecheck_comparison_of_fptr_to_void)
             << lType << rType << lex->getSourceRange() << rex->getSourceRange();
-          ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+          
+          if (isSFINAEContext())
+            return QualType();
+          
+          ImpCastExprToType(rex, lType, CK_BitCast);
           return ResultTy;
         }
       }
@@ -5375,8 +5595,8 @@
           << lex->getSourceRange() << rex->getSourceRange();
       }
 
-      ImpCastExprToType(lex, T, CastExpr::CK_BitCast);
-      ImpCastExprToType(rex, T, CastExpr::CK_BitCast);
+      ImpCastExprToType(lex, T, CK_BitCast);
+      ImpCastExprToType(rex, T, CK_BitCast);
       return ResultTy;
     }
     // C99 6.5.9p2 and C99 6.5.8p2
@@ -5401,7 +5621,7 @@
         << lType << rType << lex->getSourceRange() << rex->getSourceRange();
     }
     if (LCanPointeeTy != RCanPointeeTy)
-      ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+      ImpCastExprToType(rex, lType, CK_BitCast);
     return ResultTy;
   }
 
@@ -5411,13 +5631,19 @@
     if (RHSIsNull &&
         (lType->isPointerType() ||
          (!isRelational && lType->isMemberPointerType()))) {
-      ImpCastExprToType(rex, lType, CastExpr::CK_NullToMemberPointer);
+      ImpCastExprToType(rex, lType, 
+                        lType->isMemberPointerType()
+                          ? CK_NullToMemberPointer
+                          : CK_IntegralToPointer);
       return ResultTy;
     }
     if (LHSIsNull &&
         (rType->isPointerType() ||
          (!isRelational && rType->isMemberPointerType()))) {
-      ImpCastExprToType(lex, rType, CastExpr::CK_NullToMemberPointer);
+      ImpCastExprToType(lex, rType, 
+                        rType->isMemberPointerType()
+                          ? CK_NullToMemberPointer
+                          : CK_IntegralToPointer);
       return ResultTy;
     }
 
@@ -5448,8 +5674,8 @@
           << lex->getSourceRange() << rex->getSourceRange();
       }
 
-      ImpCastExprToType(lex, T, CastExpr::CK_BitCast);
-      ImpCastExprToType(rex, T, CastExpr::CK_BitCast);
+      ImpCastExprToType(lex, T, CK_BitCast);
+      ImpCastExprToType(rex, T, CK_BitCast);
       return ResultTy;
     }
 
@@ -5468,7 +5694,7 @@
       Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks)
         << lType << rType << lex->getSourceRange() << rex->getSourceRange();
     }
-    ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+    ImpCastExprToType(rex, lType, CK_BitCast);
     return ResultTy;
   }
   // Allow block pointers to be compared with null pointer constants.
@@ -5483,7 +5709,7 @@
         Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks)
           << lType << rType << lex->getSourceRange() << rex->getSourceRange();
     }
-    ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+    ImpCastExprToType(rex, lType, CK_BitCast);
     return ResultTy;
   }
 
@@ -5501,60 +5727,56 @@
         Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
           << lType << rType << lex->getSourceRange() << rex->getSourceRange();
       }
-      ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+      ImpCastExprToType(rex, lType, 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);
+      ImpCastExprToType(rex, lType, CK_BitCast);
       return ResultTy;
     }
   }
-  if (lType->isAnyPointerType() && rType->isIntegerType()) {
+  if ((lType->isAnyPointerType() && rType->isIntegerType()) ||
+      (lType->isIntegerType() && rType->isAnyPointerType())) {
     unsigned DiagID = 0;
-    if (RHSIsNull) {
-      if (isRelational)
+    bool isError = false;
+    if ((LHSIsNull && lType->isIntegerType()) ||
+        (RHSIsNull && rType->isIntegerType())) {
+      if (isRelational && !getLangOptions().CPlusPlus)
         DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_and_zero;
-    } else if (isRelational)
+    } else if (isRelational && !getLangOptions().CPlusPlus)
       DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_integer;
-    else
+    else if (getLangOptions().CPlusPlus) {
+      DiagID = diag::err_typecheck_comparison_of_pointer_integer;
+      isError = true;
+    } else
       DiagID = diag::ext_typecheck_comparison_of_pointer_integer;
 
     if (DiagID) {
       Diag(Loc, DiagID)
         << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+      if (isError)
+        return QualType();
     }
-    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;
+    
+    if (lType->isIntegerType())
+      ImpCastExprToType(lex, rType, CK_IntegralToPointer);
     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);
+      ImpCastExprToType(rex, lType, CK_IntegralToPointer);
     return ResultTy;
   }
+  
   // Handle block pointers.
   if (!isRelational && RHSIsNull
       && lType->isBlockPointerType() && rType->isIntegerType()) {
-    ImpCastExprToType(rex, lType, CastExpr::CK_IntegralToPointer);
+    ImpCastExprToType(rex, lType, CK_IntegralToPointer);
     return ResultTy;
   }
   if (!isRelational && LHSIsNull
       && lType->isIntegerType() && rType->isBlockPointerType()) {
-    ImpCastExprToType(lex, rType, CastExpr::CK_IntegralToPointer);
+    ImpCastExprToType(lex, rType, CK_IntegralToPointer);
     return ResultTy;
   }
   return InvalidOperands(Loc, lex, rex);
@@ -5579,23 +5801,27 @@
   // 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 (!lType->hasFloatingRepresentation()) {
     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));
+          DiagRuntimeBehavior(Loc,
+                              PDiag(diag::warn_comparison_always)
+                                << 0 // self-
+                                << 2 // "a constant"
+                              );
   }
 
   // Check for comparisons of floating point operands using != and ==.
-  if (!isRelational && lType->isFloatingType()) {
-    assert (rType->isFloatingType());
+  if (!isRelational && lType->hasFloatingRepresentation()) {
+    assert (rType->hasFloatingRepresentation());
     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())
+  if (lType->hasIntegerRepresentation())
     return lType;
 
   const VectorType *VTy = lType->getAs<VectorType>();
@@ -5612,8 +5838,13 @@
 
 inline QualType Sema::CheckBitwiseOperands(
   Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
-  if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
-    return CheckVectorOperands(Loc, lex, rex);
+  if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
+    if (lex->getType()->hasIntegerRepresentation() &&
+        rex->getType()->hasIntegerRepresentation())
+      return CheckVectorOperands(Loc, lex, rex);
+    
+    return InvalidOperands(Loc, lex, rex);
+  }
 
   QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
 
@@ -5623,7 +5854,28 @@
 }
 
 inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14]
-  Expr *&lex, Expr *&rex, SourceLocation Loc) {
+  Expr *&lex, Expr *&rex, SourceLocation Loc, unsigned Opc) {
+  
+  // Diagnose cases where the user write a logical and/or but probably meant a
+  // bitwise one.  We do this when the LHS is a non-bool integer and the RHS
+  // is a constant.
+  if (lex->getType()->isIntegerType() && !lex->getType()->isBooleanType() &&
+      rex->getType()->isIntegerType() && !rex->isValueDependent() &&
+      // Don't warn in macros.
+      !Loc.isMacroID()) {
+    // If the RHS can be constant folded, and if it constant folds to something
+    // that isn't 0 or 1 (which indicate a potential logical operation that
+    // happened to fold to true/false) then warn.
+    Expr::EvalResult Result;
+    if (rex->Evaluate(Result, Context) && !Result.HasSideEffects &&
+        Result.Val.getInt() != 0 && Result.Val.getInt() != 1) {
+      Diag(Loc, diag::warn_logical_instead_of_bitwise)
+       << rex->getSourceRange()
+        << (Opc == BO_LAnd ? "&&" : "||")
+        << (Opc == BO_LAnd ? "&" : "|");
+    }
+  }
+  
   if (!Context.getLangOptions().CPlusPlus) {
     UsualUnaryConversions(lex);
     UsualUnaryConversions(rex);
@@ -5634,25 +5886,14 @@
     return Context.IntTy;
   }
 
+  // The following is safe because we only use this method for
+  // non-overloadable operands.
+
   // 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))
+  // The operands are both contextually converted to type bool.
+  if (PerformContextuallyConvertToBool(lex) ||
+      PerformContextuallyConvertToBool(rex))
     return InvalidOperands(Loc, lex, rex);
 
   // C++ [expr.log.and]p2
@@ -5757,11 +5998,22 @@
 
   QualType LHSType = LHS->getType();
   QualType RHSType = CompoundType.isNull() ? RHS->getType() : CompoundType;
-
   AssignConvertType ConvTy;
   if (CompoundType.isNull()) {
+    QualType LHSTy(LHSType);
     // Simple assignment "x = y".
-    ConvTy = CheckSingleAssignmentConstraints(LHSType, RHS);
+    if (const ObjCImplicitSetterGetterRefExpr *OISGE = 
+        dyn_cast<ObjCImplicitSetterGetterRefExpr>(LHS)) {
+      // If using property-dot syntax notation for assignment, and there is a
+      // setter, RHS expression is being passed to the setter argument. So,
+      // type conversion (and comparison) is RHS to setter's argument type.
+      if (const ObjCMethodDecl *SetterMD = OISGE->getSetterMethod()) {
+        ObjCMethodDecl::param_iterator P = SetterMD->param_begin();
+        LHSTy = (*P)->getType();
+      }
+    }
+    
+    ConvTy = CheckSingleAssignmentConstraints(LHSTy, RHS);
     // Special case of NSObject attributes on c-style pointer types.
     if (ConvTy == IncompatiblePointer &&
         ((Context.isObjCNSObjectType(LHSType) &&
@@ -5777,8 +6029,8 @@
     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) &&
+      if ((UO->getOpcode() == UO_Plus ||
+           UO->getOpcode() == UO_Minus) &&
           Loc.isFileID() && UO->getOperatorLoc().isFileID() &&
           // Only if the two operators are exactly adjacent.
           Loc.getFileLocWithOffset(1) == UO->getOperatorLoc() &&
@@ -5787,7 +6039,7 @@
           Loc.getFileLocWithOffset(2) != UO->getSubExpr()->getLocStart() &&
           UO->getSubExpr()->getLocStart().isFileID()) {
         Diag(Loc, diag::warn_not_compound_assign)
-          << (UO->getOpcode() == UnaryOperator::Plus ? "+" : "-")
+          << (UO->getOpcode() == UO_Plus ? "+" : "-")
           << SourceRange(UO->getOperatorLoc(), UO->getOperatorLoc());
       }
     }
@@ -5800,6 +6052,23 @@
                                RHS, AA_Assigning))
     return QualType();
 
+  
+  // Check to see if the destination operand is a dereferenced null pointer.  If
+  // so, and if not volatile-qualified, this is undefined behavior that the
+  // optimizer will delete, so warn about it.  People sometimes try to use this
+  // to get a deterministic trap and are surprised by clang's behavior.  This
+  // only handles the pattern "*null = whatever", which is a very syntactic
+  // check.
+  if (UnaryOperator *UO = dyn_cast<UnaryOperator>(LHS->IgnoreParenCasts()))
+    if (UO->getOpcode() == UO_Deref &&
+        UO->getSubExpr()->IgnoreParenCasts()->
+          isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull) &&
+        !UO->getType().isVolatileQualified()) {
+    Diag(UO->getOperatorLoc(), diag::warn_indirection_through_null)
+        << UO->getSubExpr()->getSourceRange();
+    Diag(UO->getOperatorLoc(), diag::note_indirection_through_null);
+  }
+  
   // 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.
@@ -5812,6 +6081,8 @@
 
 // C99 6.5.17
 QualType Sema::CheckCommaOperands(Expr *LHS, Expr *&RHS, SourceLocation Loc) {
+  DiagnoseUnusedExprResult(LHS);
+
   // 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)
@@ -5826,7 +6097,7 @@
 /// CheckIncrementDecrementOperand - unlike most "Check" methods, this routine
 /// doesn't need to call UsualUnaryConversions or UsualArithmeticConversions.
 QualType Sema::CheckIncrementDecrementOperand(Expr *Op, SourceLocation OpLoc,
-                                              bool isInc) {
+                                              bool isInc, bool isPrefix) {
   if (Op->isTypeDependent())
     return Context.DependentTy;
 
@@ -5871,7 +6142,7 @@
                              << ResType))
       return QualType();
     // Diagnose bad cases where we step over interface counts.
-    else if (PointeeTy->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+    else if (PointeeTy->isObjCObjectType() && LangOpts.ObjCNonFragileABI) {
       Diag(OpLoc, diag::err_arithmetic_nonfragile_interface)
         << PointeeTy << Op->getSourceRange();
       return QualType();
@@ -5889,7 +6160,11 @@
   // Now make sure the operand is a modifiable lvalue.
   if (CheckForModifiableLvalue(Op, OpLoc, *this))
     return QualType();
-  return ResType;
+  // In C++, a prefix increment is the same type as the operand. Otherwise
+  // (in C or with postfix), the increment is the unqualified type of the
+  // operand.
+  return isPrefix && getLangOptions().CPlusPlus
+    ? ResType : ResType.getUnqualifiedType();
 }
 
 /// getPrimaryDecl - Helper function for CheckAddressOfOperand().
@@ -5930,9 +6205,9 @@
     UnaryOperator *UO = cast<UnaryOperator>(E);
 
     switch(UO->getOpcode()) {
-    case UnaryOperator::Real:
-    case UnaryOperator::Imag:
-    case UnaryOperator::Extension:
+    case UO_Real:
+    case UO_Imag:
+    case UO_Extension:
       return getPrimaryDecl(UO->getSubExpr());
     default:
       return 0;
@@ -5956,17 +6231,19 @@
 /// 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())
+QualType Sema::CheckAddressOfOperand(Expr *OrigOp, SourceLocation OpLoc) {
+  if (OrigOp->isTypeDependent())
     return Context.DependentTy;
+  if (OrigOp->getType() == Context.OverloadTy)
+    return Context.OverloadTy;
+
+  // Make sure to ignore parentheses in subsequent checks
+  Expr *op = OrigOp->IgnoreParens();
 
   if (getLangOptions().C99) {
     // Implement C99-only parts of addressof rules.
     if (UnaryOperator* uOp = dyn_cast<UnaryOperator>(op)) {
-      if (uOp->getOpcode() == UnaryOperator::Deref)
+      if (uOp->getOpcode() == UO_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();
@@ -5977,27 +6254,40 @@
   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) {
+  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 (isa<ObjCSelectorExpr>(op)) {
+    return Context.getPointerType(op->getType());
+  } else if (lval == Expr::LV_MemberFunction) {
+    // If it's an instance method, make a member pointer.
+    // The expression must have exactly the form &A::foo.
+
+    // If the underlying expression isn't a decl ref, give up.
+    if (!isa<DeclRefExpr>(op)) {
+      Diag(OpLoc, diag::err_invalid_form_pointer_member_function)
+        << OrigOp->getSourceRange();
+      return QualType();
+    }
+    DeclRefExpr *DRE = cast<DeclRefExpr>(op);
+    CXXMethodDecl *MD = cast<CXXMethodDecl>(DRE->getDecl());
+
+    // The id-expression was parenthesized.
+    if (OrigOp != DRE) {
+      Diag(OpLoc, diag::err_parens_pointer_member_function)
+        << OrigOp->getSourceRange();
+
+    // The method was named without a qualifier.
+    } else if (!DRE->getQualifier()) {
+      Diag(OpLoc, diag::err_unqualified_pointer_member_function)
+        << op->getSourceRange();
+    }
+
+    return Context.getMemberPointerType(op->getType(),
+              Context.getTypeDeclType(MD->getParent()).getTypePtr());
   } 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
@@ -6026,13 +6316,14 @@
     // 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) {
+      // in C++ it is not error to take address of a register
+      // variable (c++03 7.1.1P3)
+      if (vd->getStorageClass() == SC_Register &&
+          !getLangOptions().CPlusPlus) {
         Diag(OpLoc, diag::err_typecheck_address_of)
           << "register variable" << op->getSourceRange();
         return QualType();
@@ -6057,13 +6348,6 @@
                 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");
   }
@@ -6076,88 +6360,96 @@
   }
 
   // If the operand has type "type", the result has type "pointer to type".
+  if (op->getType()->isObjCObjectType())
+    return Context.getObjCObjectPointerType(op->getType());
   return Context.getPointerType(op->getType());
 }
 
+/// CheckIndirectionOperand - Type check unary indirection (prefix '*').
 QualType Sema::CheckIndirectionOperand(Expr *Op, SourceLocation OpLoc) {
   if (Op->isTypeDependent())
     return Context.DependentTy;
 
   UsualUnaryConversions(Op);
-  QualType Ty = Op->getType();
+  QualType OpTy = Op->getType();
+  QualType Result;
+  
+  // Note that per both C89 and C99, indirection is always legal, even if OpTy
+  // 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 = OpTy->getAs<PointerType>())
+    Result = PT->getPointeeType();
+  else if (const ObjCObjectPointerType *OPT =
+             OpTy->getAs<ObjCObjectPointerType>())
+    Result = OPT->getPointeeType();
 
-  // 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();
+  if (Result.isNull()) {
+    Diag(OpLoc, diag::err_typecheck_indirection_requires_pointer)
+      << OpTy << Op->getSourceRange();
+    return QualType();
+  }
+  
+  return Result;
 }
 
-static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode(
+static inline BinaryOperatorKind ConvertTokenKindToBinaryOpcode(
   tok::TokenKind Kind) {
-  BinaryOperator::Opcode Opc;
+  BinaryOperatorKind 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;
+  case tok::periodstar:           Opc = BO_PtrMemD; break;
+  case tok::arrowstar:            Opc = BO_PtrMemI; break;
+  case tok::star:                 Opc = BO_Mul; break;
+  case tok::slash:                Opc = BO_Div; break;
+  case tok::percent:              Opc = BO_Rem; break;
+  case tok::plus:                 Opc = BO_Add; break;
+  case tok::minus:                Opc = BO_Sub; break;
+  case tok::lessless:             Opc = BO_Shl; break;
+  case tok::greatergreater:       Opc = BO_Shr; break;
+  case tok::lessequal:            Opc = BO_LE; break;
+  case tok::less:                 Opc = BO_LT; break;
+  case tok::greaterequal:         Opc = BO_GE; break;
+  case tok::greater:              Opc = BO_GT; break;
+  case tok::exclaimequal:         Opc = BO_NE; break;
+  case tok::equalequal:           Opc = BO_EQ; break;
+  case tok::amp:                  Opc = BO_And; break;
+  case tok::caret:                Opc = BO_Xor; break;
+  case tok::pipe:                 Opc = BO_Or; break;
+  case tok::ampamp:               Opc = BO_LAnd; break;
+  case tok::pipepipe:             Opc = BO_LOr; break;
+  case tok::equal:                Opc = BO_Assign; break;
+  case tok::starequal:            Opc = BO_MulAssign; break;
+  case tok::slashequal:           Opc = BO_DivAssign; break;
+  case tok::percentequal:         Opc = BO_RemAssign; break;
+  case tok::plusequal:            Opc = BO_AddAssign; break;
+  case tok::minusequal:           Opc = BO_SubAssign; break;
+  case tok::lesslessequal:        Opc = BO_ShlAssign; break;
+  case tok::greatergreaterequal:  Opc = BO_ShrAssign; break;
+  case tok::ampequal:             Opc = BO_AndAssign; break;
+  case tok::caretequal:           Opc = BO_XorAssign; break;
+  case tok::pipeequal:            Opc = BO_OrAssign; break;
+  case tok::comma:                Opc = BO_Comma; break;
   }
   return Opc;
 }
 
-static inline UnaryOperator::Opcode ConvertTokenKindToUnaryOpcode(
+static inline UnaryOperatorKind ConvertTokenKindToUnaryOpcode(
   tok::TokenKind Kind) {
-  UnaryOperator::Opcode Opc;
+  UnaryOperatorKind 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;
+  case tok::plusplus:     Opc = UO_PreInc; break;
+  case tok::minusminus:   Opc = UO_PreDec; break;
+  case tok::amp:          Opc = UO_AddrOf; break;
+  case tok::star:         Opc = UO_Deref; break;
+  case tok::plus:         Opc = UO_Plus; break;
+  case tok::minus:        Opc = UO_Minus; break;
+  case tok::tilde:        Opc = UO_Not; break;
+  case tok::exclaim:      Opc = UO_LNot; break;
+  case tok::kw___real:    Opc = UO_Real; break;
+  case tok::kw___imag:    Opc = UO_Imag; break;
+  case tok::kw___extension__: Opc = UO_Extension; break;
   }
   return Opc;
 }
@@ -6165,106 +6457,111 @@
 /// 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) {
+ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
+                                    unsigned Op,
+                                    Expr *lhs, Expr *rhs) {
   QualType ResultTy;     // Result type of the binary operator.
-  BinaryOperator::Opcode Opc = (BinaryOperator::Opcode)Op;
+  BinaryOperatorKind Opc = (BinaryOperatorKind) 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:
+  case BO_Assign:
     ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, QualType());
     break;
-  case BinaryOperator::PtrMemD:
-  case BinaryOperator::PtrMemI:
+  case BO_PtrMemD:
+  case BO_PtrMemI:
     ResultTy = CheckPointerToMemberOperands(lhs, rhs, OpLoc,
-                                            Opc == BinaryOperator::PtrMemI);
+                                            Opc == BO_PtrMemI);
     break;
-  case BinaryOperator::Mul:
-  case BinaryOperator::Div:
+  case BO_Mul:
+  case BO_Div:
     ResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, false,
-                                           Opc == BinaryOperator::Div);
+                                           Opc == BO_Div);
     break;
-  case BinaryOperator::Rem:
+  case BO_Rem:
     ResultTy = CheckRemainderOperands(lhs, rhs, OpLoc);
     break;
-  case BinaryOperator::Add:
+  case BO_Add:
     ResultTy = CheckAdditionOperands(lhs, rhs, OpLoc);
     break;
-  case BinaryOperator::Sub:
+  case BO_Sub:
     ResultTy = CheckSubtractionOperands(lhs, rhs, OpLoc);
     break;
-  case BinaryOperator::Shl:
-  case BinaryOperator::Shr:
+  case BO_Shl:
+  case BO_Shr:
     ResultTy = CheckShiftOperands(lhs, rhs, OpLoc);
     break;
-  case BinaryOperator::LE:
-  case BinaryOperator::LT:
-  case BinaryOperator::GE:
-  case BinaryOperator::GT:
+  case BO_LE:
+  case BO_LT:
+  case BO_GE:
+  case BO_GT:
     ResultTy = CheckCompareOperands(lhs, rhs, OpLoc, Opc, true);
     break;
-  case BinaryOperator::EQ:
-  case BinaryOperator::NE:
+  case BO_EQ:
+  case BO_NE:
     ResultTy = CheckCompareOperands(lhs, rhs, OpLoc, Opc, false);
     break;
-  case BinaryOperator::And:
-  case BinaryOperator::Xor:
-  case BinaryOperator::Or:
+  case BO_And:
+  case BO_Xor:
+  case BO_Or:
     ResultTy = CheckBitwiseOperands(lhs, rhs, OpLoc);
     break;
-  case BinaryOperator::LAnd:
-  case BinaryOperator::LOr:
-    ResultTy = CheckLogicalOperands(lhs, rhs, OpLoc);
+  case BO_LAnd:
+  case BO_LOr:
+    ResultTy = CheckLogicalOperands(lhs, rhs, OpLoc, Opc);
     break;
-  case BinaryOperator::MulAssign:
-  case BinaryOperator::DivAssign:
+  case BO_MulAssign:
+  case BO_DivAssign:
     CompResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, true,
-                                              Opc == BinaryOperator::DivAssign);
+                                              Opc == BO_DivAssign);
     CompLHSTy = CompResultTy;
     if (!CompResultTy.isNull())
       ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
     break;
-  case BinaryOperator::RemAssign:
+  case BO_RemAssign:
     CompResultTy = CheckRemainderOperands(lhs, rhs, OpLoc, true);
     CompLHSTy = CompResultTy;
     if (!CompResultTy.isNull())
       ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
     break;
-  case BinaryOperator::AddAssign:
+  case BO_AddAssign:
     CompResultTy = CheckAdditionOperands(lhs, rhs, OpLoc, &CompLHSTy);
     if (!CompResultTy.isNull())
       ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
     break;
-  case BinaryOperator::SubAssign:
+  case BO_SubAssign:
     CompResultTy = CheckSubtractionOperands(lhs, rhs, OpLoc, &CompLHSTy);
     if (!CompResultTy.isNull())
       ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
     break;
-  case BinaryOperator::ShlAssign:
-  case BinaryOperator::ShrAssign:
+  case BO_ShlAssign:
+  case BO_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:
+  case BO_AndAssign:
+  case BO_XorAssign:
+  case BO_OrAssign:
     CompResultTy = CheckBitwiseOperands(lhs, rhs, OpLoc, true);
     CompLHSTy = CompResultTy;
     if (!CompResultTy.isNull())
       ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
     break;
-  case BinaryOperator::Comma:
+  case BO_Comma:
     ResultTy = CheckCommaOperands(lhs, rhs, OpLoc);
     break;
   }
   if (ResultTy.isNull())
     return ExprError();
+  if (ResultTy->isObjCObjectType() && LangOpts.ObjCNonFragileABI) {
+    if (Opc >= BO_Assign && Opc <= BO_OrAssign) 
+          Diag(OpLoc, diag::err_assignment_requires_nonfragile_object)
+                << ResultTy;
+  }
   if (CompResultTy.isNull())
     return Owned(new (Context) BinaryOperator(lhs, rhs, Opc, ResultTy, OpLoc));
   else
@@ -6316,7 +6613,7 @@
 /// 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,
+static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc,
                                       SourceLocation OpLoc,Expr *lhs,Expr *rhs){
   typedef BinaryOperator BinOp;
   BinOp::Opcode lhsopc = static_cast<BinOp::Opcode>(-1),
@@ -6363,19 +6660,17 @@
 /// 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,
+static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind 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>();
-
+ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
+                            tok::TokenKind Kind,
+                            Expr *lhs, Expr *rhs) {
+  BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Kind);
   assert((lhs != 0) && "ActOnBinOp(): missing left expression");
   assert((rhs != 0) && "ActOnBinOp(): missing right expression");
 
@@ -6385,9 +6680,9 @@
   return BuildBinOp(S, TokLoc, Opc, lhs, rhs);
 }
 
-Action::OwningExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
-                                          BinaryOperator::Opcode Opc,
-                                          Expr *lhs, Expr *rhs) {
+ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
+                            BinaryOperatorKind Opc,
+                            Expr *lhs, Expr *rhs) {
   if (getLangOptions().CPlusPlus &&
       (lhs->getType()->isOverloadableType() ||
        rhs->getType()->isOverloadableType())) {
@@ -6410,53 +6705,50 @@
   return CreateBuiltinBinOp(OpLoc, Opc, lhs, rhs);
 }
 
-Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
+ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
                                                     unsigned OpcIn,
-                                                    ExprArg InputArg) {
-  UnaryOperator::Opcode Opc = static_cast<UnaryOperator::Opcode>(OpcIn);
+                                                    Expr *Input) {
+  UnaryOperatorKind Opc = static_cast<UnaryOperatorKind>(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:
+  case UO_PreInc:
+  case UO_PreDec:
+  case UO_PostInc:
+  case UO_PostDec:
     resultType = CheckIncrementDecrementOperand(Input, OpLoc,
-                                                Opc == UnaryOperator::PreInc ||
-                                                Opc == UnaryOperator::PostInc);
+                                                Opc == UO_PreInc ||
+                                                Opc == UO_PostInc,
+                                                Opc == UO_PreInc ||
+                                                Opc == UO_PreDec);
     break;
-  case UnaryOperator::AddrOf:
+  case UO_AddrOf:
     resultType = CheckAddressOfOperand(Input, OpLoc);
     break;
-  case UnaryOperator::Deref:
+  case UO_Deref:
     DefaultFunctionArrayLvalueConversion(Input);
     resultType = CheckIndirectionOperand(Input, OpLoc);
     break;
-  case UnaryOperator::Plus:
-  case UnaryOperator::Minus:
+  case UO_Plus:
+  case UO_Minus:
     UsualUnaryConversions(Input);
     resultType = Input->getType();
     if (resultType->isDependentType())
       break;
-    if (resultType->isArithmeticType()) // C99 6.5.3.3p1
+    if (resultType->isArithmeticType() || // C99 6.5.3.3p1
+        resultType->isVectorType()) 
       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 &&
+             Opc == UO_Plus &&
              resultType->isPointerType())
       break;
 
     return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
       << resultType << Input->getSourceRange());
-  case UnaryOperator::Not: // bitwise complement
+  case UO_Not: // bitwise complement
     UsualUnaryConversions(Input);
     resultType = Input->getType();
     if (resultType->isDependentType())
@@ -6466,11 +6758,11 @@
       // C99 does not support '~' for complex conjugation.
       Diag(OpLoc, diag::ext_integer_complement_complex)
         << resultType << Input->getSourceRange();
-    else if (!resultType->isIntegerType())
+    else if (!resultType->hasIntegerRepresentation())
       return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
         << resultType << Input->getSourceRange());
     break;
-  case UnaryOperator::LNot: // logical negation
+  case UO_LNot: // logical negation
     // Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
     DefaultFunctionArrayLvalueConversion(Input);
     resultType = Input->getType();
@@ -6483,27 +6775,25 @@
     // 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);
+  case UO_Real:
+  case UO_Imag:
+    resultType = CheckRealImagOperand(Input, OpLoc, Opc == UO_Real);
     break;
-  case UnaryOperator::Extension:
+  case UO_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();
+ExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
+                              UnaryOperatorKind Opc,
+                              Expr *Input) {
   if (getLangOptions().CPlusPlus && Input->getType()->isOverloadableType() &&
-      Opc != UnaryOperator::Extension) {
+      Opc != UO_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
@@ -6514,24 +6804,24 @@
       LookupOverloadedOperatorName(OverOp, S, Input->getType(), QualType(),
                                    Functions);
 
-    return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(input));
+    return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, Input);
   }
 
-  return CreateBuiltinUnaryOp(OpLoc, Opc, move(input));
+  return CreateBuiltinUnaryOp(OpLoc, Opc, 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));
+ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
+                                            tok::TokenKind Op, Expr *Input) {
+  return BuildUnaryOp(S, OpLoc, ConvertTokenKindToUnaryOpcode(Op), Input);
 }
 
 /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
-Sema::OwningExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
+ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
                                             SourceLocation LabLoc,
                                             IdentifierInfo *LabelII) {
   // Look up the record for this label identifier.
-  LabelStmt *&LabelDecl = getLabelMap()[LabelII];
+  LabelStmt *&LabelDecl = getCurFunction()->LabelMap[LabelII];
 
   // If we haven't seen this label yet, create a forward reference. It
   // will be validated and/or cleaned up in ActOnFinishFunctionBody.
@@ -6543,10 +6833,9 @@
                                        Context.getPointerType(Context.VoidTy)));
 }
 
-Sema::OwningExprResult
-Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtArg substmt,
+ExprResult
+Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
                     SourceLocation RPLoc) { // "({..})"
-  Stmt *SubStmt = static_cast<Stmt*>(substmt.get());
   assert(SubStmt && isa<CompoundStmt>(SubStmt) && "Invalid action invocation!");
   CompoundStmt *Compound = cast<CompoundStmt>(SubStmt);
 
@@ -6576,41 +6865,33 @@
   // 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,
+ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
+                                                  TypeSourceInfo *TInfo,
                                                   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!");
-
+                                                  SourceLocation RParenLoc) {
+  QualType ArgTy = TInfo->getType();
   bool Dependent = ArgTy->isDependentType();
-
+  SourceRange TypeRange = TInfo->getTypeLoc().getLocalSourceRange();
+  
   // 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());
-
+    return ExprError(Diag(BuiltinLoc, diag::err_offsetof_record_type) 
+                       << ArgTy << TypeRange);
+  
+  // Type must be complete per C99 7.17p3 because a declaring a variable
+  // with an incomplete type would be ill-formed.
+  if (!Dependent 
+      && RequireCompleteType(BuiltinLoc, ArgTy,
+                             PDiag(diag::err_offsetof_incomplete_type)
+                               << TypeRange))
+    return ExprError();
+  
   // 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
@@ -6618,103 +6899,170 @@
   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(),
+  
+  bool DidWarnAboutNonPOD = false;
+  QualType CurrentType = ArgTy;
+  typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
+  llvm::SmallVector<OffsetOfNode, 4> Comps;
+  llvm::SmallVector<Expr*, 4> Exprs;
+  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?
+      if (!CurrentType->isDependentType()) {
+        const ArrayType *AT = Context.getAsArrayType(CurrentType);
+        if(!AT)
+          return ExprError(Diag(OC.LocEnd, diag::err_offsetof_array_type)
+                           << CurrentType);
+        CurrentType = AT->getElementType();
+      } else
+        CurrentType = Context.DependentTy;
+      
+      // The expression must be an integral expression.
+      // FIXME: An integral constant expression?
+      Expr *Idx = static_cast<Expr*>(OC.U.E);
+      if (!Idx->isTypeDependent() && !Idx->isValueDependent() &&
+          !Idx->getType()->isIntegerType())
+        return ExprError(Diag(Idx->getLocStart(),
+                              diag::err_typecheck_subscript_not_integer)
+                         << Idx->getSourceRange());
+      
+      // Record this array index.
+      Comps.push_back(OffsetOfNode(OC.LocStart, Exprs.size(), OC.LocEnd));
+      Exprs.push_back(Idx);
+      continue;
+    }
+    
+    // Offset of a field.
+    if (CurrentType->isDependentType()) {
+      // We have the offset of a field, but we can't look into the dependent
+      // type. Just record the identifier of the field.
+      Comps.push_back(OffsetOfNode(OC.LocStart, OC.U.IdentInfo, OC.LocEnd));
+      CurrentType = Context.DependentTy;
+      continue;
+    }
+    
+    // We need to have a complete type to look into.
+    if (RequireCompleteType(OC.LocStart, CurrentType,
                             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());
-      }
+    
+    // Look for the designated field.
+    const RecordType *RC = CurrentType->getAs<RecordType>();
+    if (!RC) 
+      return ExprError(Diag(OC.LocEnd, diag::err_offsetof_record_type)
+                       << CurrentType);
+    RecordDecl *RD = RC->getDecl();
+    
+    // C++ [lib.support.types]p5:
+    //   The macro offsetof accepts a restricted set of type arguments in this
+    //   International Standard. type shall be a POD structure or a POD union
+    //   (clause 9).
+    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)
+                              << CurrentType))
+        DidWarnAboutNonPOD = true;
     }
-  }
+    
+    // Look for the field.
+    LookupResult R(*this, OC.U.IdentInfo, OC.LocStart, LookupMemberName);
+    LookupQualifiedName(R, RD);
+    FieldDecl *MemberDecl = R.getAsSingle<FieldDecl>();
+    if (!MemberDecl)
+      return ExprError(Diag(BuiltinLoc, diag::err_no_member)
+                       << OC.U.IdentInfo << RD << SourceRange(OC.LocStart, 
+                                                              OC.LocEnd));
+    
+    // C99 7.17p3:
+    //   (If the specified member is a bit-field, the behavior is undefined.)
+    //
+    // We diagnose this as an error.
+    if (MemberDecl->getBitWidth()) {
+      Diag(OC.LocEnd, diag::err_offsetof_bitfield)
+        << MemberDecl->getDeclName()
+        << SourceRange(BuiltinLoc, RParenLoc);
+      Diag(MemberDecl->getLocation(), diag::note_bitfield_decl);
+      return ExprError();
+    }
 
-  return Owned(new (Context) UnaryOperator(Res, UnaryOperator::OffsetOf,
-                                           Context.getSizeType(), BuiltinLoc));
+    RecordDecl *Parent = MemberDecl->getParent();
+    bool AnonStructUnion = Parent->isAnonymousStructOrUnion();
+    if (AnonStructUnion) {
+      do {
+        Parent = cast<RecordDecl>(Parent->getParent());
+      } while (Parent->isAnonymousStructOrUnion());
+    }
+
+    // If the member was found in a base class, introduce OffsetOfNodes for
+    // the base class indirections.
+    CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+                       /*DetectVirtual=*/false);
+    if (IsDerivedFrom(CurrentType, Context.getTypeDeclType(Parent), Paths)) {
+      CXXBasePath &Path = Paths.front();
+      for (CXXBasePath::iterator B = Path.begin(), BEnd = Path.end();
+           B != BEnd; ++B)
+        Comps.push_back(OffsetOfNode(B->Base));
+    }
+
+    if (AnonStructUnion) {
+      llvm::SmallVector<FieldDecl*, 4> Path;
+      BuildAnonymousStructUnionMemberPath(MemberDecl, Path);
+      unsigned n = Path.size();
+      for (int j = n - 1; j > -1; --j)
+        Comps.push_back(OffsetOfNode(OC.LocStart, Path[j], OC.LocEnd));
+    } else {
+      Comps.push_back(OffsetOfNode(OC.LocStart, MemberDecl, OC.LocEnd));
+    }
+    CurrentType = MemberDecl->getType().getNonReferenceType(); 
+  }
+  
+  return Owned(OffsetOfExpr::Create(Context, Context.getSizeType(), BuiltinLoc, 
+                                    TInfo, Comps.data(), Comps.size(),
+                                    Exprs.data(), Exprs.size(), RParenLoc));  
+}
+
+ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
+                                                  SourceLocation BuiltinLoc,
+                                                  SourceLocation TypeLoc,
+                                                  ParsedType argty,
+                                                  OffsetOfComponent *CompPtr,
+                                                  unsigned NumComponents,
+                                                  SourceLocation RPLoc) {
+
+  TypeSourceInfo *ArgTInfo;
+  QualType ArgTy = GetTypeFromParser(argty, &ArgTInfo);
+  if (ArgTy.isNull())
+    return ExprError();
+
+  if (!ArgTInfo)
+    ArgTInfo = Context.getTrivialTypeSourceInfo(ArgTy, TypeLoc);
+
+  return BuildBuiltinOffsetOf(BuiltinLoc, ArgTInfo, CompPtr, NumComponents, 
+                              RPLoc);
 }
 
 
-Sema::OwningExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
-                                                      TypeTy *arg1,TypeTy *arg2,
+ExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
+                                                      ParsedType arg1,ParsedType arg2,
                                                       SourceLocation RPLoc) {
-  // FIXME: Preserve type source info.
-  QualType argT1 = GetTypeFromParser(arg1);
-  QualType argT2 = GetTypeFromParser(arg2);
+  TypeSourceInfo *argTInfo1;
+  QualType argT1 = GetTypeFromParser(arg1, &argTInfo1);
+  TypeSourceInfo *argTInfo2;
+  QualType argT2 = GetTypeFromParser(arg2, &argTInfo2);
 
   assert((!argT1.isNull() && !argT2.isNull()) && "Missing type argument(s)");
 
+  return BuildTypesCompatibleExpr(BuiltinLoc, argTInfo1, argTInfo2, RPLoc);
+}
+
+ExprResult
+Sema::BuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
+                               TypeSourceInfo *argTInfo1,
+                               TypeSourceInfo *argTInfo2,
+                               SourceLocation RPLoc) {
   if (getLangOptions().CPlusPlus) {
     Diag(BuiltinLoc, diag::err_types_compatible_p_in_cplusplus)
       << SourceRange(BuiltinLoc, RPLoc);
@@ -6722,17 +7070,14 @@
   }
 
   return Owned(new (Context) TypesCompatibleExpr(Context.IntTy, BuiltinLoc,
-                                                 argT1, argT2, RPLoc));
+                                                 argTInfo1, argTInfo2, 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());
 
+ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
+                                             Expr *CondExpr,
+                                             Expr *LHSExpr, Expr *RHSExpr,
+                                             SourceLocation RPLoc) {
   assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)");
 
   QualType resType;
@@ -6755,7 +7100,6 @@
                                              : RHSExpr->isValueDependent();
   }
 
-  cond.release(); expr1.release(); expr2.release();
   return Owned(new (Context) ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr,
                                         resType, RPLoc,
                                         resType->isDependentType(),
@@ -6771,83 +7115,99 @@
   BlockDecl *Block = BlockDecl::Create(Context, CurContext, CaretLoc);
   PushBlockScope(BlockScope, Block);
   CurContext->addDecl(Block);
-  PushDeclContext(BlockScope, Block);
+  if (BlockScope)
+    PushDeclContext(BlockScope, Block);
+  else
+    CurContext = 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);
+  TypeSourceInfo *Sig = GetTypeForDeclarator(ParamInfo, CurScope);
+  CurBlock->TheDecl->setSignatureAsWritten(Sig);
+  QualType T = Sig->getType();
 
-    if (T->isArrayType()) {
-      Diag(ParamInfo.getSourceRange().getBegin(),
-           diag::err_block_returns_array);
-      return;
-    }
+  bool isVariadic;
+  QualType RetTy;
+  if (const FunctionType *Fn = T->getAs<FunctionType>()) {
+    CurBlock->FunctionType = T;
+    RetTy = Fn->getResultType();
+    isVariadic =
+      !isa<FunctionProtoType>(Fn) || cast<FunctionProtoType>(Fn)->isVariadic();
+  } else {
+    RetTy = T;
+    isVariadic = false;
+  }
 
-    // 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->TheDecl->setIsVariadic(isVariadic);
 
-    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;
+  // Don't allow returning an array by value.
+  if (RetTy->isArrayType()) {
+    Diag(ParamInfo.getSourceRange().getBegin(), diag::err_block_returns_array);
     return;
   }
 
-  // Analyze arguments to block.
-  assert(ParamInfo.getTypeObject(0).Kind == DeclaratorChunk::Function &&
-         "Not a function declarator!");
-  DeclaratorChunk::FunctionTypeInfo &FTI = ParamInfo.getTypeObject(0).Fun;
+  // Don't allow returning a objc interface by value.
+  if (RetTy->isObjCObjectType()) {
+    Diag(ParamInfo.getSourceRange().getBegin(),
+         diag::err_object_cannot_be_passed_returned_by_value) << 0 << RetTy;
+    return;
+  }
 
-  CurBlock->hasPrototype = FTI.hasPrototype;
-  CurBlock->isVariadic = true;
+  // Context.DependentTy is used as a placeholder for a missing block
+  // return type.  TODO:  what should we do with declarators like:
+  //   ^ * { ... }
+  // If the answer is "apply template argument deduction"....
+  if (RetTy != Context.DependentTy)
+    CurBlock->ReturnType = RetTy;
 
-  // 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>();
+  // Push block parameters from the declarator if we had them.
+  llvm::SmallVector<ParmVarDecl*, 8> Params;
+  if (isa<FunctionProtoType>(T)) {
+    FunctionProtoTypeLoc TL = cast<FunctionProtoTypeLoc>(Sig->getTypeLoc());
+    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+      ParmVarDecl *Param = TL.getArg(I);
       if (Param->getIdentifier() == 0 &&
           !Param->isImplicit() &&
           !Param->isInvalidDecl() &&
           !getLangOptions().CPlusPlus)
         Diag(Param->getLocation(), diag::err_parameter_name_omitted);
-      CurBlock->Params.push_back(Param);
+      Params.push_back(Param);
     }
-    CurBlock->isVariadic = FTI.isVariadic;
+
+  // Fake up parameter variables if we have a typedef, like
+  //   ^ fntype { ... }
+  } else if (const FunctionProtoType *Fn = T->getAs<FunctionProtoType>()) {
+    for (FunctionProtoType::arg_type_iterator
+           I = Fn->arg_type_begin(), E = Fn->arg_type_end(); I != E; ++I) {
+      ParmVarDecl *Param =
+        BuildParmVarDeclForTypedef(CurBlock->TheDecl,
+                                   ParamInfo.getSourceRange().getBegin(),
+                                   *I);
+      Params.push_back(Param);
+    }
   }
-  CurBlock->TheDecl->setParams(CurBlock->Params.data(),
-                               CurBlock->Params.size());
-  CurBlock->TheDecl->setIsVariadic(CurBlock->isVariadic);
+
+  // Set the parameters on the block decl.
+  if (!Params.empty())
+    CurBlock->TheDecl->setParams(Params.data(), Params.size());
+
+  // Finally we can process decl attributes.
   ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo);
 
+  if (!isVariadic && CurBlock->TheDecl->getAttr<SentinelAttr>()) {
+    Diag(ParamInfo.getAttributes()->getLoc(),
+         diag::warn_attribute_sentinel_not_variadic) << 1;
+    // FIXME: remove the attribute.
+  }
+
+  // Put the parameter variables in scope.  We can bail out immediately
+  // if we don't have any.
+  if (Params.empty())
+    return;
+
   bool ShouldCheckShadow =
     Diags.getDiagnosticLevel(diag::warn_decl_shadow) != Diagnostic::Ignored;
 
@@ -6863,25 +7223,6 @@
       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
@@ -6895,43 +7236,73 @@
 
 /// 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) {
+ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
+                                                Stmt *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));
+
+  // If the user wrote a function type in some form, try to use that.
+  if (!BSI->FunctionType.isNull()) {
+    const FunctionType *FTy = BSI->FunctionType->getAs<FunctionType>();
+
+    FunctionType::ExtInfo Ext = FTy->getExtInfo();
+    if (NoReturn && !Ext.getNoReturn()) Ext = Ext.withNoReturn(true);
+    
+    // Turn protoless block types into nullary block types.
+    if (isa<FunctionNoProtoType>(FTy)) {
+      BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 0,
+                                        false, false, 0, 0, Ext);
+
+    // Otherwise, if we don't need to change anything about the function type,
+    // preserve its sugar structure.
+    } else if (FTy->getResultType() == RetTy &&
+               (!NoReturn || FTy->getNoReturnAttr())) {
+      BlockTy = BSI->FunctionType;
+
+    // Otherwise, make the minimal modifications to the function type.
+    } else {
+      const FunctionProtoType *FPT = cast<FunctionProtoType>(FTy);
+      BlockTy = Context.getFunctionType(RetTy,
+                                        FPT->arg_type_begin(),
+                                        FPT->getNumArgs(),
+                                        FPT->isVariadic(),
+                                        /*quals*/ 0,
+                                        FPT->hasExceptionSpec(),
+                                        FPT->hasAnyExceptionSpec(),
+                                        FPT->getNumExceptions(),
+                                        FPT->exception_begin(),
+                                        Ext);
+    }
+
+  // If we don't have a function type, just build one from nothing.
+  } else {
+    BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 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());
+  DiagnoseUnusedParameters(BSI->TheDecl->param_begin(),
+                           BSI->TheDecl->param_end());
   BlockTy = Context.getBlockPointerType(BlockTy);
 
   // If needed, diagnose invalid gotos and switches in the block.
-  if (FunctionNeedsScopeChecking() && !hasAnyErrorsInThisFunction())
-    DiagnoseInvalidJumps(static_cast<CompoundStmt*>(body.get()));
+  if (getCurFunction()->NeedsScopeChecking() && !hasAnyErrorsInThisFunction())
+    DiagnoseInvalidJumps(cast<CompoundStmt>(Body));
 
-  BSI->TheDecl->setBody(body.takeAs<CompoundStmt>());
+  BSI->TheDecl->setBody(cast<CompoundStmt>(Body));
 
   bool Good = true;
   // Check goto/label use.
@@ -6953,22 +7324,29 @@
     return ExprError();
   }
 
+  BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy,
+                                              BSI->hasBlockDeclRefExprs);
+
   // Issue any analysis-based warnings.
   const sema::AnalysisBasedWarnings::Policy &WP =
     AnalysisWarnings.getDefaultPolicy();
-  AnalysisWarnings.IssueWarnings(WP, BSI->TheDecl, BlockTy);
+  AnalysisWarnings.IssueWarnings(WP, Result);
 
-  Expr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy,
-                                         BSI->hasBlockDeclRefExprs);
   PopFunctionOrBlockScope();
   return Owned(Result);
 }
 
-Sema::OwningExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
-                                        ExprArg expr, TypeTy *type,
+ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
+                                        Expr *expr, ParsedType type,
                                         SourceLocation RPLoc) {
-  QualType T = GetTypeFromParser(type);
-  Expr *E = static_cast<Expr*>(expr.get());
+  TypeSourceInfo *TInfo;
+  QualType T = GetTypeFromParser(type, &TInfo);
+  return BuildVAArgExpr(BuiltinLoc, expr, TInfo, RPLoc);
+}
+
+ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
+                                            Expr *E, TypeSourceInfo *TInfo,
+                                            SourceLocation RPLoc) {
   Expr *OrigExpr = E;
 
   InitBuiltinVaListType();
@@ -7000,12 +7378,11 @@
   // 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));
+  QualType T = TInfo->getType().getNonLValueExprType(Context);
+  return Owned(new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T));
 }
 
-Sema::OwningExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
+ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
   // The type of __null will be int or long, depending on the size of
   // pointers on the target.
   QualType Ty;
@@ -7017,7 +7394,7 @@
   return Owned(new (Context) GNUNullExpr(Ty, TokenLoc));
 }
 
-static void MakeObjCStringLiteralFixItHint(Sema& SemaRef, QualType DstType, 
+static void MakeObjCStringLiteralFixItHint(Sema& SemaRef, QualType DstType,
                                            Expr *SrcExpr, FixItHint &Hint) {
   if (!SemaRef.getLangOptions().ObjC1)
     return;
@@ -7120,7 +7497,7 @@
     FirstType = DstType;
     SecondType = SrcType;
     break;
-      
+
   case AA_Returning:
   case AA_Passing:
   case AA_Converting:
@@ -7131,7 +7508,7 @@
     SecondType = DstType;
     break;
   }
-  
+
   Diag(Loc, DiagKind) << FirstType << SecondType << Action
     << SrcExpr->getSourceRange() << Hint;
   if (Complained)
@@ -7236,7 +7613,7 @@
 void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
   assert(D && "No declaration?");
 
-  if (D->isUsed())
+  if (D->isUsed(false))
     return;
 
   // Mark a parameter or variable declaration "used", regardless of whether we're in a
@@ -7248,10 +7625,10 @@
     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())
@@ -7279,30 +7656,34 @@
   if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
     unsigned TypeQuals;
     if (Constructor->isImplicit() && Constructor->isDefaultConstructor()) {
-        if (!Constructor->isUsed())
-          DefineImplicitDefaultConstructor(Loc, Constructor);
+      if (Constructor->getParent()->hasTrivialConstructor())
+        return;
+      if (!Constructor->isUsed(false))
+        DefineImplicitDefaultConstructor(Loc, Constructor);
     } else if (Constructor->isImplicit() &&
                Constructor->isCopyConstructor(TypeQuals)) {
-      if (!Constructor->isUsed())
+      if (!Constructor->isUsed(false))
         DefineImplicitCopyConstructor(Loc, Constructor, TypeQuals);
     }
 
-    MaybeMarkVirtualMembersReferenced(Loc, Constructor);
+    MarkVTableUsed(Loc, Constructor->getParent());
   } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
-    if (Destructor->isImplicit() && !Destructor->isUsed())
+    if (Destructor->isImplicit() && !Destructor->isUsed(false))
       DefineImplicitDestructor(Loc, Destructor);
-
+    if (Destructor->isVirtual())
+      MarkVTableUsed(Loc, Destructor->getParent());
   } else if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) {
     if (MethodDecl->isImplicit() && MethodDecl->isOverloadedOperator() &&
         MethodDecl->getOverloadedOperator() == OO_Equal) {
-      if (!MethodDecl->isUsed())
-        DefineImplicitOverloadedAssign(Loc, MethodDecl);
-    }
+      if (!MethodDecl->isUsed(false))
+        DefineImplicitCopyAssignment(Loc, MethodDecl);
+    } else if (MethodDecl->isVirtual())
+      MarkVTableUsed(Loc, MethodDecl->getParent());
   }
   if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
     // Implicit instantiation of function templates and member functions of
     // class templates.
-    if (!Function->getBody() && Function->isImplicitlyInstantiable()) {
+    if (Function->isImplicitlyInstantiable()) {
       bool AlreadyInstantiated = false;
       if (FunctionTemplateSpecializationInfo *SpecInfo
                                 = Function->getTemplateSpecializationInfo()) {
@@ -7326,13 +7707,20 @@
           PendingLocalImplicitInstantiations.push_back(std::make_pair(Function,
                                                                       Loc));
         else
-          PendingImplicitInstantiations.push_back(std::make_pair(Function,
-                                                                 Loc));
+          PendingInstantiations.push_back(std::make_pair(Function, Loc));
       }
-    }
+    } else // Walk redefinitions, as some of them may be instantiable.
+      for (FunctionDecl::redecl_iterator i(Function->redecls_begin()),
+           e(Function->redecls_end()); i != e; ++i) {
+        if (!i->isUsed(false) && i->isImplicitlyInstantiable())
+          MarkDeclarationReferenced(Loc, *i);
+      }
 
     // FIXME: keep track of references to static functions
-    Function->setUsed(true);
+
+    // Recursive functions should be marked when used from another function.
+    if (CurContext != Function)
+      Function->setUsed(true);
 
     return;
   }
@@ -7346,7 +7734,7 @@
       if (MSInfo->getPointOfInstantiation().isInvalid() &&
           MSInfo->getTemplateSpecializationKind()== TSK_ImplicitInstantiation) {
         MSInfo->setPointOfInstantiation(Loc);
-        PendingImplicitInstantiations.push_back(std::make_pair(Var, Loc));
+        PendingInstantiations.push_back(std::make_pair(Var, Loc));
       }
     }
 
@@ -7357,6 +7745,49 @@
   }
 }
 
+namespace {
+  // Mark all of the declarations referenced
+  // FIXME: Not fully implemented yet! We need to have a better understanding
+  // of when we're entering
+  class MarkReferencedDecls : public RecursiveASTVisitor<MarkReferencedDecls> {
+    Sema &S;
+    SourceLocation Loc;
+
+  public:
+    typedef RecursiveASTVisitor<MarkReferencedDecls> Inherited;
+
+    MarkReferencedDecls(Sema &S, SourceLocation Loc) : S(S), Loc(Loc) { }
+
+    bool TraverseTemplateArgument(const TemplateArgument &Arg);
+    bool TraverseRecordType(RecordType *T);
+  };
+}
+
+bool MarkReferencedDecls::TraverseTemplateArgument(
+  const TemplateArgument &Arg) {
+  if (Arg.getKind() == TemplateArgument::Declaration) {
+    S.MarkDeclarationReferenced(Loc, Arg.getAsDecl());
+  }
+
+  return Inherited::TraverseTemplateArgument(Arg);
+}
+
+bool MarkReferencedDecls::TraverseRecordType(RecordType *T) {
+  if (ClassTemplateSpecializationDecl *Spec
+                  = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) {
+    const TemplateArgumentList &Args = Spec->getTemplateArgs();
+    return TraverseTemplateArguments(Args.getFlatArgumentList(),
+                                     Args.flat_size());
+  }
+
+  return true;
+}
+
+void Sema::MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T) {
+  MarkReferencedDecls Marker(*this, Loc);
+  Marker.TraverseType(Context.getCanonicalType(T));
+}
+
 /// \brief Emit a diagnostic that describes an effect on the run-time behavior
 /// of the program being compiled.
 ///
@@ -7423,7 +7854,7 @@
 
   if (isa<BinaryOperator>(E)) {
     BinaryOperator *Op = cast<BinaryOperator>(E);
-    if (Op->getOpcode() != BinaryOperator::Assign)
+    if (Op->getOpcode() != BO_Assign)
       return;
 
     // Greylist some idioms by putting them into a warning subcategory.
@@ -7485,3 +7916,14 @@
 
   return false;
 }
+
+ExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,
+                                       Expr *Sub) {
+  if (!Sub)
+    return ExprError();
+  
+  if (CheckBooleanCondition(Sub, Loc))
+    return ExprError();
+  
+  return Owned(Sub);
+}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 7c32423..5720d93 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -11,27 +11,31 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Sema/TemplateDeduction.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.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;
+using namespace sema;
 
-Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
-                                        IdentifierInfo &II, 
-                                        SourceLocation NameLoc,
-                                        Scope *S, CXXScopeSpec &SS,
-                                        TypeTy *ObjectTypePtr,
-                                        bool EnteringContext) {
+ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
+                                   IdentifierInfo &II, 
+                                   SourceLocation NameLoc,
+                                   Scope *S, CXXScopeSpec &SS,
+                                   ParsedType ObjectTypePtr,
+                                   bool EnteringContext) {
   // Determine where to perform name lookup.
 
   // FIXME: This area of the standard is very messy, and the current
@@ -52,6 +56,8 @@
   //   }
   //
   // See also PR6358 and PR6359.
+  // For this reason, we're currently only doing the C++03 version of this
+  // code; the C++0x version has to wait until we get a proper spec.
   QualType SearchType;
   DeclContext *LookupCtx = 0;
   bool isDependent = false;
@@ -68,50 +74,33 @@
     
     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 
+    // 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[opt] class-name :: ~class-name 
+    //     ::opt nested-name-specifier class-name ::  ̃ class-name 
     //
-    //   the second class-name is looked up in the same scope as the first.
+    //   the class-names are looked up as types in the scope designated by 
+    //   the nested-name-specifier.
     //
-    // 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.
+    // 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.
+    DeclContext *DC = computeDeclContext(SS, EnteringContext);
+    if (DC && DC->isFileContext()) {
+      AlreadySearched = true;
+      LookupCtx = DC;
+      isDependent = false;
+    } else if (DC && isa<CXXRecordDecl>(DC))
+      LookAtPrefix = false;
+    
+    // The second case from the C++03 rules quoted further above.
     NestedNameSpecifier *Prefix = 0;
     if (AlreadySearched) {
       // Nothing left to do.
@@ -120,11 +109,6 @@
       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();
@@ -168,7 +152,7 @@
 
     // FIXME: Should we be suppressing ambiguities here?
     if (Found.isAmbiguous())
-      return 0;
+      return ParsedType();
 
     if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) {
       QualType T = Context.getTypeDeclType(Type);
@@ -177,7 +161,7 @@
           Context.hasSameUnqualifiedType(T, SearchType)) {
         // We found our type!
 
-        return T.getAsOpaquePtr();
+        return ParsedType::make(T);
       }
     }
 
@@ -210,7 +194,7 @@
               = dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) {
           if (Spec->getSpecializedTemplate()->getCanonicalDecl() ==
                 Template->getCanonicalDecl())
-            return MemberOfType.getAsOpaquePtr();
+            return ParsedType::make(MemberOfType);
         }
 
         continue;
@@ -229,7 +213,7 @@
         // specialized.
         if (TemplateDecl *SpecTemplate = SpecName.getAsTemplateDecl()) {
           if (SpecTemplate->getCanonicalDecl() == Template->getCanonicalDecl())
-            return MemberOfType.getAsOpaquePtr();
+            return ParsedType::make(MemberOfType);
 
           continue;
         }
@@ -240,7 +224,7 @@
                                     = SpecName.getAsDependentTemplateName()) {
           if (DepTemplate->isIdentifier() &&
               DepTemplate->getIdentifier() == Template->getIdentifier())
-            return MemberOfType.getAsOpaquePtr();
+            return ParsedType::make(MemberOfType);
 
           continue;
         }
@@ -261,7 +245,10 @@
       Range = SourceRange(NameLoc);
     }
 
-    return CheckTypenameType(ETK_None, NNS, II, Range).getAsOpaquePtr();
+    QualType T = CheckTypenameType(ETK_None, NNS, II,
+                                   SourceLocation(),
+                                   Range, NameLoc);
+    return ParsedType::make(T);
   }
 
   if (ObjectTypePtr)
@@ -270,11 +257,11 @@
   else
     Diag(NameLoc, diag::err_destructor_class_name);
 
-  return 0;
+  return ParsedType();
 }
 
 /// \brief Build a C++ typeid expression with a type operand.
-Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
+ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
                                             SourceLocation TypeidLoc,
                                             TypeSourceInfo *Operand,
                                             SourceLocation RParenLoc) {
@@ -283,7 +270,10 @@
   //   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();
+  Qualifiers Quals;
+  QualType T
+    = Context.getUnqualifiedArrayType(Operand->getType().getNonReferenceType(),
+                                      Quals);
   if (T->getAs<RecordType>() &&
       RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
     return ExprError();
@@ -294,12 +284,11 @@
 }
 
 /// \brief Build a C++ typeid expression with an expression operand.
-Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
+ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
                                             SourceLocation TypeidLoc,
-                                            ExprArg Operand,
+                                            Expr *E,
                                             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>()) {
@@ -311,11 +300,15 @@
         return ExprError();
       
       // C++ [expr.typeid]p3:
-      //   When typeid is applied to an expression other than an lvalue of a
+      //   When typeid is applied to an expression other than an glvalue of a
       //   polymorphic class type [...] [the] expression is an unevaluated
       //   operand. [...]
-      if (RecordD->isPolymorphic() && E->isLvalue(Context) == Expr::LV_Valid)
+      if (RecordD->isPolymorphic() && E->Classify(Context).isGLValue()) {
         isUnevaluatedOperand = false;
+
+        // We require a vtable to query the type at run time.
+        MarkVTableUsed(TypeidLoc, RecordD);
+      }
     }
     
     // C++ [expr.typeid]p4:
@@ -323,11 +316,11 @@
     //   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);
+    Qualifiers Quals;
+    QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals);
+    if (!Context.hasSameType(T, UnqualT)) {
+      T = UnqualT;
+      ImpCastExprToType(E, UnqualT, CK_NoOp, CastCategory(E));
     }
   }
   
@@ -338,12 +331,12 @@
     ExprEvalContexts.back().Context = Unevaluated;
   
   return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(),
-                                           Operand.takeAs<Expr>(),
+                                           E,
                                            SourceRange(TypeidLoc, RParenLoc)));  
 }
 
 /// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression);
-Action::OwningExprResult
+ExprResult
 Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
                      bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
   // Find the std::type_info type.
@@ -352,7 +345,7 @@
 
   IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
   LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName);
-  LookupQualifiedName(R, StdNamespace);
+  LookupQualifiedName(R, getStdNamespace());
   RecordDecl *TypeInfoRecordDecl = R.getAsSingle<RecordDecl>();
   if (!TypeInfoRecordDecl)
     return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
@@ -362,7 +355,8 @@
   if (isType) {
     // The operand is a type; handle it as such.
     TypeSourceInfo *TInfo = 0;
-    QualType T = GetTypeFromParser(TyOrExpr, &TInfo);
+    QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr),
+                                   &TInfo);
     if (T.isNull())
       return ExprError();
     
@@ -373,11 +367,11 @@
   }
 
   // The operand is an expression.  
-  return BuildCXXTypeId(TypeInfoType, OpLoc, Owned((Expr*)TyOrExpr), RParenLoc);
+  return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
 }
 
 /// ActOnCXXBoolLiteral - Parse {true,false} literals.
-Action::OwningExprResult
+ExprResult
 Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
   assert((Kind == tok::kw_true || Kind == tok::kw_false) &&
          "Unknown C++ Boolean value!");
@@ -386,15 +380,14 @@
 }
 
 /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
-Action::OwningExprResult
+ExprResult
 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>();
+ExprResult
+Sema::ActOnCXXThrow(SourceLocation OpLoc, Expr *Ex) {
   if (Ex && !Ex->isTypeDependent() && CheckCXXThrowOperand(OpLoc, Ex))
     return ExprError();
   return Owned(new (Context) CXXThrowExpr(Ex, Context.VoidTy, OpLoc));
@@ -409,8 +402,8 @@
   //   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);
+    ImpCastExprToType(E, E->getType().getUnqualifiedType(), CK_NoOp,
+                      CastCategory(E));
   
   DefaultFunctionArrayConversion(E);
 
@@ -437,26 +430,49 @@
 
   // Initialize the exception result.  This implicitly weeds out
   // abstract types or types with inaccessible copy constructors.
+  // FIXME: Determine whether we can elide this copy per C++0x [class.copy]p34.
   InitializedEntity Entity =
-    InitializedEntity::InitializeException(ThrowLoc, E->getType());
-  OwningExprResult Res = PerformCopyInitialization(Entity,
+    InitializedEntity::InitializeException(ThrowLoc, E->getType(),
+                                           /*NRVO=*/false);
+  ExprResult Res = PerformCopyInitialization(Entity,
                                                    SourceLocation(),
                                                    Owned(E));
   if (Res.isInvalid())
     return true;
   E = Res.takeAs<Expr>();
+
+  // If the exception has class type, we need additional handling.
+  const RecordType *RecordTy = Ty->getAs<RecordType>();
+  if (!RecordTy)
+    return false;
+  CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
+
+  // If we are throwing a polymorphic class type or pointer thereof,
+  // exception handling will make use of the vtable.
+  MarkVTableUsed(ThrowLoc, RD);
+
+  // If the class has a non-trivial destructor, we must be able to call it.
+  if (RD->hasTrivialDestructor())
+    return false;
+
+  CXXDestructorDecl *Destructor 
+    = const_cast<CXXDestructorDecl*>(LookupDestructor(RD));
+  if (!Destructor)
+    return false;
+
+  MarkDeclarationReferenced(E->getExprLoc(), Destructor);
+  CheckDestructorAccess(E->getExprLoc(), Destructor,
+                        PDiag(diag::err_access_dtor_exception) << Ty);
   return false;
 }
 
-Action::OwningExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
+ExprResult 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))
+  DeclContext *DC = getFunctionLevelDeclContext();
+  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC))
     if (MD->isInstance())
       return Owned(new (Context) CXXThisExpr(ThisLoc,
                                              MD->getThisType(Context),
@@ -469,8 +485,8 @@
 /// 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,
+ExprResult
+Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, ParsedType TypeRep,
                                 SourceLocation LParenLoc,
                                 MultiExprArg exprs,
                                 SourceLocation *CommaLocs,
@@ -518,41 +534,34 @@
   // corresponding cast expression.
   //
   if (NumExprs == 1) {
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CastKind Kind = CK_Unknown;
+    CXXCastPath 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));
+    return Owned(CXXFunctionalCastExpr::Create(Context,
+                                              Ty.getNonLValueExprType(Context),
+                                               TInfo, TyBeginLoc, Kind,
+                                               Exprs[0], &BasePath,
+                                               RParenLoc));
   }
 
-  if (const RecordType *RT = Ty->getAs<RecordType>()) {
-    CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
+  if (Ty->isRecordType()) {
+    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);
+    ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                              move(exprs));
 
-    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.
+    // FIXME: Improve AST representation?
+    return move(Result);
   }
 
   // C++ [expr.type.conv]p1:
@@ -571,7 +580,7 @@
   // rvalue of the specified type, which is value-initialized.
   //
   exprs.release();
-  return Owned(new (Context) CXXZeroInitValueExpr(Ty, TyBeginLoc, RParenLoc));
+  return Owned(new (Context) CXXScalarValueInitExpr(Ty, TyBeginLoc, RParenLoc));
 }
 
 
@@ -580,10 +589,10 @@
 /// or
 /// @code ::new Foo(23, "hello") @endcode
 /// For the interpretation of this heap of arguments, consult the base version.
-Action::OwningExprResult
+ExprResult
 Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
                   SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
-                  SourceLocation PlacementRParen, bool ParenTypeId,
+                  SourceLocation PlacementRParen, SourceRange TypeIdParens, 
                   Declarator &D, SourceLocation ConstructorLParen,
                   MultiExprArg ConstructorArgs,
                   SourceLocation ConstructorRParen) {
@@ -599,17 +608,6 @@
       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();
   }
@@ -633,55 +631,81 @@
   }
 
   //FIXME: Store TypeSourceInfo in CXXNew expression.
-  TypeSourceInfo *TInfo = 0;
-  QualType AllocType = GetTypeForDeclarator(D, /*Scope=*/0, &TInfo);
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, /*Scope=*/0);
+  QualType AllocType = TInfo->getType();
   if (D.isInvalidType())
     return ExprError();
-    
+  
+  SourceRange R = TInfo->getTypeLoc().getSourceRange();    
   return BuildCXXNew(StartLoc, UseGlobal,
                      PlacementLParen,
                      move(PlacementArgs),
                      PlacementRParen,
-                     ParenTypeId,
+                     TypeIdParens,
                      AllocType,
                      D.getSourceRange().getBegin(),
-                     D.getSourceRange(),
-                     Owned(ArraySize),
+                     R,
+                     ArraySize,
                      ConstructorLParen,
                      move(ConstructorArgs),
                      ConstructorRParen);
 }
 
-Sema::OwningExprResult
+ExprResult
 Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
                   SourceLocation PlacementLParen,
                   MultiExprArg PlacementArgs,
                   SourceLocation PlacementRParen,
-                  bool ParenTypeId,
+                  SourceRange TypeIdParens,
                   QualType AllocType,
                   SourceLocation TypeLoc,
                   SourceRange TypeRange,
-                  ExprArg ArraySizeE,
+                  Expr *ArraySize,
                   SourceLocation ConstructorLParen,
                   MultiExprArg ConstructorArgs,
                   SourceLocation ConstructorRParen) {
   if (CheckAllocatedType(AllocType, TypeLoc, TypeRange))
     return ExprError();
 
-  QualType ResultType = Context.getPointerType(AllocType);
+  // Per C++0x [expr.new]p5, the type being constructed may be a
+  // typedef of an array type.
+  if (!ArraySize) {
+    if (const ConstantArrayType *Array
+                              = Context.getAsConstantArrayType(AllocType)) {
+      ArraySize = IntegerLiteral::Create(Context, Array->getSize(),
+                                         Context.getSizeType(),
+                                         TypeRange.getEnd());
+      AllocType = Array->getElementType();
+    }
+  }
 
-  // That every array dimension except the first is constant was already
-  // checked by the type check above.
+  QualType ResultType = Context.getPointerType(AllocType);
 
   // 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());
+    
+    ExprResult ConvertedSize
+      = ConvertToIntegralOrEnumerationType(StartLoc, ArraySize,
+                                       PDiag(diag::err_array_size_not_integral),
+                                     PDiag(diag::err_array_size_incomplete_type)
+                                       << ArraySize->getSourceRange(),
+                               PDiag(diag::err_array_size_explicit_conversion),
+                                       PDiag(diag::note_array_size_conversion),
+                               PDiag(diag::err_array_size_ambiguous_conversion),
+                                       PDiag(diag::note_array_size_conversion),
+                          PDiag(getLangOptions().CPlusPlus0x? 0 
+                                            : diag::ext_array_size_conversion));
+    if (ConvertedSize.isInvalid())
+      return ExprError();
+    
+    ArraySize = ConvertedSize.take();
+    SizeType = ArraySize->getType();
+    if (!SizeType->isIntegralOrEnumerationType())
+      return ExprError();
+    
     // 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.
@@ -692,13 +716,33 @@
                         llvm::APInt::getNullValue(Value.getBitWidth()), 
                                  Value.isUnsigned()))
           return ExprError(Diag(ArraySize->getSourceRange().getBegin(),
-                           diag::err_typecheck_negative_array_size)
+                                diag::err_typecheck_negative_array_size)
             << ArraySize->getSourceRange());
+        
+        if (!AllocType->isDependentType()) {
+          unsigned ActiveSizeBits
+            = ConstantArrayType::getNumAddressingBits(Context, AllocType, Value);
+          if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) {
+            Diag(ArraySize->getSourceRange().getBegin(), 
+                 diag::err_array_too_large)
+              << Value.toString(10)
+              << ArraySize->getSourceRange();
+            return ExprError();
+          }
+        }
+      } else if (TypeIdParens.isValid()) {
+        // Can't have dynamic array size when the type-id is in parentheses.
+        Diag(ArraySize->getLocStart(), diag::ext_new_paren_array_nonconst)
+          << ArraySize->getSourceRange()
+          << FixItHint::CreateRemoval(TypeIdParens.getBegin())
+          << FixItHint::CreateRemoval(TypeIdParens.getEnd());
+          
+        TypeIdParens = SourceRange();
       }
     }
     
     ImpCastExprToType(ArraySize, Context.getSizeType(),
-                      CastExpr::CK_IntegralCast);
+                      CK_IntegralCast);
   }
 
   FunctionDecl *OperatorNew = 0;
@@ -720,10 +764,10 @@
       OperatorNew->getType()->getAs<FunctionProtoType>();
     VariadicCallType CallType = 
       Proto->isVariadic() ? VariadicFunction : VariadicDoesNotApply;
-    bool Invalid = GatherArgumentsForCall(PlacementLParen, OperatorNew,
-                                          Proto, 1, PlaceArgs, NumPlaceArgs, 
-                                          AllPlaceArgs, CallType);
-    if (Invalid)
+    
+    if (GatherArgumentsForCall(PlacementLParen, OperatorNew,
+                               Proto, 1, PlaceArgs, NumPlaceArgs, 
+                               AllPlaceArgs, CallType))
       return ExprError();
     
     NumPlaceArgs = AllPlaceArgs.size();
@@ -736,7 +780,16 @@
   CXXConstructorDecl *Constructor = 0;
   Expr **ConsArgs = (Expr**)ConstructorArgs.get();
   unsigned NumConsArgs = ConstructorArgs.size();
-  ASTOwningVector<&ActionBase::DeleteExpr> ConvertedConstructorArgs(*this);
+  ASTOwningVector<Expr*> ConvertedConstructorArgs(*this);
+
+  // Array 'new' can't have any initializers.
+  if (NumConsArgs && (ResultType->isArrayType() || ArraySize)) {
+    SourceRange InitRange(ConsArgs[0]->getLocStart(),
+                          ConsArgs[NumConsArgs - 1]->getLocEnd());
+    
+    Diag(StartLoc, diag::err_new_array_init_args) << InitRange;
+    return ExprError();
+  }
 
   if (!AllocType->isDependentType() &&
       !Expr::hasAnyTypeDependentArguments(ConsArgs, NumConsArgs)) {
@@ -757,7 +810,7 @@
     InitializedEntity Entity
       = InitializedEntity::InitializeNew(StartLoc, AllocType);
     InitializationSequence InitSeq(*this, Entity, Kind, ConsArgs, NumConsArgs);
-    OwningExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, 
+    ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, 
                                                 move(ConstructorArgs));
     if (FullInit.isInvalid())
       return ExprError();
@@ -798,14 +851,15 @@
   
   PlacementArgs.release();
   ConstructorArgs.release();
-  ArraySizeE.release();
+  
+  // FIXME: The TypeSourceInfo should also be included in CXXNewExpr.
   return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
-                                        PlaceArgs, NumPlaceArgs, ParenTypeId,
+                                        PlaceArgs, NumPlaceArgs, TypeIdParens,
                                         ArraySize, Constructor, Init,
                                         ConsArgs, NumConsArgs, OperatorDelete,
                                         ResultType, StartLoc,
                                         Init ? ConstructorRParen :
-                                               SourceLocation()));
+                                               TypeRange.getEnd()));
 }
 
 /// CheckAllocatedType - Checks that a type is suitable as the allocated type
@@ -868,7 +922,7 @@
   // 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(
+  IntegerLiteral Size(Context, llvm::APInt::getNullValue(
                       Context.Target.getPointerWidth(0)),
                       Context.getSizeType(),
                       SourceLocation());
@@ -886,9 +940,11 @@
   DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
                                         IsArray ? OO_Array_Delete : OO_Delete);
 
-  if (AllocType->isRecordType() && !UseGlobal) {
+  QualType AllocElemType = Context.getBaseElementType(AllocType);
+
+  if (AllocElemType->isRecordType() && !UseGlobal) {
     CXXRecordDecl *Record
-      = cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl());
+      = cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl());
     if (FindAllocationOverload(StartLoc, Range, NewName, &AllocArgs[0],
                           AllocArgs.size(), Record, /*AllowMissing=*/true,
                           OperatorNew))
@@ -926,9 +982,9 @@
   //   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) {
+  if (AllocElemType->isRecordType() && !UseGlobal) {
     CXXRecordDecl *RD
-      = cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl());
+      = cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl());
     LookupQualifiedName(FoundDelete, RD);
   }
   if (FoundDelete.isAmbiguous())
@@ -1072,7 +1128,7 @@
 
   // Do the resolution.
   OverloadCandidateSet::iterator Best;
-  switch(BestViableFunction(Candidates, StartLoc, Best)) {
+  switch (Candidates.BestViableFunction(*this, StartLoc, Best)) {
   case OR_Success: {
     // Got one!
     FunctionDecl *FnDecl = Best->Function;
@@ -1082,7 +1138,7 @@
     // Watch out for variadic allocator function.
     unsigned NumArgsInFnDecl = FnDecl->getNumParams();
     for (unsigned i = 0; (i < NumArgs && i < NumArgsInFnDecl); ++i) {
-      OwningExprResult Result
+      ExprResult Result
         = PerformCopyInitialization(InitializedEntity::InitializeParameter(
                                                        FnDecl->getParamDecl(i)),
                                     SourceLocation(),
@@ -1100,20 +1156,20 @@
   case OR_No_Viable_Function:
     Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
       << Name << Range;
-    PrintOverloadCandidates(Candidates, OCD_AllCandidates, Args, NumArgs);
+    Candidates.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
     return true;
 
   case OR_Ambiguous:
     Diag(StartLoc, diag::err_ovl_ambiguous_call)
       << Name << Range;
-    PrintOverloadCandidates(Candidates, OCD_ViableCandidates, Args, NumArgs);
+    Candidates.NoteCandidates(*this, 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);
+    Candidates.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
     return true;
   }
   assert(false && "Unreachable, bad result from BestViableFunction");
@@ -1152,24 +1208,15 @@
   // "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, 
+    StdBadAlloc = CXXRecordDecl::Create(Context, TTK_Class, 
+                                        getOrCreateStdNamespace(), 
                                         SourceLocation(), 
                                       &PP.getIdentifierTable().get("bad_alloc"), 
                                         SourceLocation(), 0);
-    StdBadAlloc->setImplicit(true);
+    getStdBadAlloc()->setImplicit(true);
   }
   
   GlobalNewDeleteDeclared = true;
@@ -1211,8 +1258,11 @@
           Context.getCanonicalType(
             Func->getParamDecl(0)->getType().getUnqualifiedType());
         // FIXME: Do we need to check for default arguments here?
-        if (Func->getNumParams() == 1 && InitialParamType == Argument)
+        if (Func->getNumParams() == 1 && InitialParamType == Argument) {
+          if(AddMallocAttr && !Func->hasAttr<MallocAttr>())
+            Func->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
           return;
+        }
       }
     }
   }
@@ -1223,7 +1273,7 @@
        Name.getCXXOverloadedOperator() == OO_Array_New);
   if (HasBadAllocExceptionSpec) {
     assert(StdBadAlloc && "Must have std::bad_alloc declared");
-    BadAllocType = Context.getTypeDeclType(StdBadAlloc);
+    BadAllocType = Context.getTypeDeclType(getStdBadAlloc());
   }
   
   QualType FnType = Context.getFunctionType(Return, &Argument, 1, false, 0,
@@ -1233,23 +1283,23 @@
                                             FunctionType::ExtInfo());
   FunctionDecl *Alloc =
     FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), Name,
-                         FnType, /*TInfo=*/0, FunctionDecl::None,
-                         FunctionDecl::None, false, true);
+                         FnType, /*TInfo=*/0, SC_None,
+                         SC_None, false, true);
   Alloc->setImplicit();
   
   if (AddMallocAttr)
-    Alloc->addAttr(::new (Context) MallocAttr());
+    Alloc->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
   
   ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(),
                                            0, Argument, /*TInfo=*/0,
-                                           VarDecl::None,
-                                           VarDecl::None, 0);
+                                           SC_None,
+                                           SC_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);
+  Context.getTranslationUnitDecl()->addDecl(Alloc);
 }
 
 bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
@@ -1262,13 +1312,39 @@
   if (Found.isAmbiguous())
     return true;
 
+  Found.suppressDiagnostics();
+
+  llvm::SmallVector<DeclAccessPair,4> Matches;
   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;
-      }
+    NamedDecl *ND = (*F)->getUnderlyingDecl();
+
+    // Ignore template operator delete members from the check for a usual
+    // deallocation function.
+    if (isa<FunctionTemplateDecl>(ND))
+      continue;
+
+    if (cast<CXXMethodDecl>(ND)->isUsualDeallocationFunction())
+      Matches.push_back(F.getPair());
+  }
+
+  // There's exactly one suitable operator;  pick it.
+  if (Matches.size() == 1) {
+    Operator = cast<CXXMethodDecl>(Matches[0]->getUnderlyingDecl());
+    CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
+                          Matches[0]);
+    return false;
+
+  // We found multiple suitable operators;  complain about the ambiguity.
+  } else if (!Matches.empty()) {
+    Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found)
+      << Name << RD;
+
+    for (llvm::SmallVectorImpl<DeclAccessPair>::iterator
+           F = Matches.begin(), FEnd = Matches.end(); F != FEnd; ++F)
+      Diag((*F)->getUnderlyingDecl()->getLocation(),
+           diag::note_member_declared_here) << Name;
+    return true;
   }
 
   // We did find operator delete/operator delete[] declarations, but
@@ -1278,10 +1354,9 @@
       << Name << RD;
         
     for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
-         F != FEnd; ++F) {
-      Diag((*F)->getLocation(), diag::note_member_declared_here)
-        << Name;
-    }
+         F != FEnd; ++F)
+      Diag((*F)->getUnderlyingDecl()->getLocation(),
+           diag::note_member_declared_here) << Name;
 
     return true;
   }
@@ -1306,9 +1381,9 @@
 /// @code ::delete ptr; @endcode
 /// or
 /// @code delete [] ptr; @endcode
-Action::OwningExprResult
+ExprResult
 Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
-                     bool ArrayForm, ExprArg Operand) {
+                     bool ArrayForm, Expr *Ex) {
   // 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.
@@ -1317,11 +1392,14 @@
 
   FunctionDecl *OperatorDelete = 0;
 
-  Expr *Ex = (Expr *)Operand.get();
   if (!Ex->isTypeDependent()) {
     QualType Type = Ex->getType();
 
     if (const RecordType *Record = Type->getAs<RecordType>()) {
+      if (RequireCompleteType(StartLoc, Type, 
+                              PDiag(diag::err_delete_incomplete_class_type)))
+        return ExprError();
+      
       llvm::SmallVector<CXXConversionDecl*, 4> ObjectPtrConversions;
 
       CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
@@ -1340,18 +1418,16 @@
         
         QualType ConvType = Conv->getConversionType().getNonReferenceType();
         if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
-          if (ConvPtrType->getPointeeType()->isObjectType())
+          if (ConvPtrType->getPointeeType()->isIncompleteOrObjectType())
             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();
         }
       }
@@ -1369,7 +1445,13 @@
         << Type << Ex->getSourceRange());
 
     QualType Pointee = Type->getAs<PointerType>()->getPointeeType();
-    if (Pointee->isFunctionType() || Pointee->isVoidType())
+    if (Pointee->isVoidType() && !isSFINAEContext()) {
+      // The C++ standard bans deleting a pointer to a non-object type, which 
+      // effectively bans deletion of "void*". However, most compilers support
+      // this, so we treat it as a warning unless we're in a SFINAE context.
+      Diag(StartLoc, diag::ext_delete_void_ptr_operand)
+        << Type << Ex->getSourceRange();
+    } else if (Pointee->isFunctionType() || Pointee->isVoidType())
       return ExprError(Diag(StartLoc, diag::err_delete_operand)
         << Type << Ex->getSourceRange());
     else if (!Pointee->isDependentType() &&
@@ -1384,16 +1466,13 @@
     //   (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);
+                      CK_NoOp);
     
     DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
                                       ArrayForm ? OO_Array_Delete : OO_Delete);
 
-    if (const RecordType *RT = Pointee->getAs<RecordType>()) {
+    QualType PointeeElem = Context.getBaseElementType(Pointee);
+    if (const RecordType *RT = PointeeElem->getAs<RecordType>()) {
       CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
 
       if (!UseGlobal && 
@@ -1401,7 +1480,7 @@
         return ExprError();
       
       if (!RD->hasTrivialDestructor())
-        if (const CXXDestructorDecl *Dtor = RD->getDestructor(Context))
+        if (const CXXDestructorDecl *Dtor = LookupDestructor(RD))
           MarkDeclarationReferenced(StartLoc,
                                     const_cast<CXXDestructorDecl*>(Dtor));
     }
@@ -1421,14 +1500,15 @@
     // 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) {
+ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
+                                                      SourceLocation StmtLoc,
+                                                      bool ConvertToBoolean) {
   QualType T = ConditionVar->getType();
   
   // C++ [stmt.select]p2:
@@ -1442,9 +1522,13 @@
                           diag::err_invalid_use_of_array_type)
                      << ConditionVar->getSourceRange());
 
-  return Owned(DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar,
-                                   ConditionVar->getLocation(), 
-                                ConditionVar->getType().getNonReferenceType()));
+  Expr *Condition = DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar,
+                                        ConditionVar->getLocation(), 
+                                 ConditionVar->getType().getNonReferenceType());
+  if (ConvertToBoolean && CheckBooleanCondition(Condition, StmtLoc))
+    return ExprError();
+  
+  return Owned(Condition);
 }
 
 /// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid.
@@ -1474,7 +1558,7 @@
   // 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 (StringLiteral *StrLit = dyn_cast<StringLiteral>(From->IgnoreParens()))
     if (const PointerType *ToPtrType = ToType->getAs<PointerType>())
       if (const BuiltinType *ToPointeeType
           = ToPtrType->getPointeeType()->getAs<BuiltinType>()) {
@@ -1491,34 +1575,33 @@
   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>();
-  
+static ExprResult BuildCXXCastArgument(Sema &S, 
+                                       SourceLocation CastLoc,
+                                       QualType Ty,
+                                       CastKind Kind,
+                                       CXXMethodDecl *Method,
+                                       Expr *From) {
   switch (Kind) {
   default: assert(0 && "Unhandled cast kind!");
-  case CastExpr::CK_ConstructorConversion: {
-    ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+  case CK_ConstructorConversion: {
+    ASTOwningVector<Expr*> ConstructorArgs(S);
     
     if (S.CompleteConstructorCall(cast<CXXConstructorDecl>(Method),
-                                  Sema::MultiExprArg(S, (void **)&From, 1),
+                                  MultiExprArg(&From, 1),
                                   CastLoc, ConstructorArgs))
-      return S.ExprError();
+      return ExprError();
     
-    Sema::OwningExprResult Result = 
+    ExprResult Result = 
     S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method), 
-                            move_arg(ConstructorArgs));
+                            move_arg(ConstructorArgs),
+                            /*ZeroInit*/ false, CXXConstructExpr::CK_Complete);
     if (Result.isInvalid())
-      return S.ExprError();
+      return ExprError();
     
     return S.MaybeBindToTemporary(Result.takeAs<Expr>());
   }
     
-  case CastExpr::CK_UserDefinedConversion: {
+  case CK_UserDefinedConversion: {
     assert(!From->getType()->isPointerType() && "Arg can't have pointer type!");
     
     // Create an implicit call expr that calls it.
@@ -1549,10 +1632,10 @@
   case ImplicitConversionSequence::UserDefinedConversion: {
     
       FunctionDecl *FD = ICS.UserDefined.ConversionFunction;
-      CastExpr::CastKind CastKind = CastExpr::CK_Unknown;
+      CastKind CastKind = CK_Unknown;
       QualType BeforeToType;
       if (const CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(FD)) {
-        CastKind = CastExpr::CK_UserDefinedConversion;
+        CastKind = CK_UserDefinedConversion;
         
         // If the user-defined conversion is specified by a conversion function,
         // the initial standard conversion sequence converts the source type to
@@ -1560,7 +1643,7 @@
         BeforeToType = Context.getTagDeclType(Conv->getParent());
       } else if (const CXXConstructorDecl *Ctor = 
                   dyn_cast<CXXConstructorDecl>(FD)) {
-        CastKind = CastExpr::CK_ConstructorConversion;
+        CastKind = 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 
@@ -1579,12 +1662,12 @@
           return true;
       }
     
-      OwningExprResult CastArg 
+      ExprResult CastArg 
         = BuildCXXCastArgument(*this,
                                From->getLocStart(),
                                ToType.getNonReferenceType(),
                                CastKind, cast<CXXMethodDecl>(FD), 
-                               Owned(From));
+                               From);
 
       if (CastArg.isInvalid())
         return true;
@@ -1596,7 +1679,7 @@
   }
 
   case ImplicitConversionSequence::AmbiguousConversion:
-    DiagnoseAmbiguousConversion(ICS, From->getExprLoc(),
+    ICS.DiagnoseAmbiguousConversion(*this, From->getExprLoc(),
                           PDiag(diag::err_typecheck_ambiguous_condition)
                             << From->getSourceRange());
      return true;
@@ -1633,25 +1716,29 @@
     // FIXME: When can ToType be a reference type?
     assert(!ToType->isReferenceType());
     if (SCS.Second == ICK_Derived_To_Base) {
-      ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(*this);
+      ASTOwningVector<Expr*> ConstructorArgs(*this);
       if (CompleteConstructorCall(cast<CXXConstructorDecl>(SCS.CopyConstructor),
-                                  MultiExprArg(*this, (void **)&From, 1),
+                                  MultiExprArg(*this, &From, 1),
                                   /*FIXME:ConstructLoc*/SourceLocation(), 
                                   ConstructorArgs))
         return true;
-      OwningExprResult FromResult =
+      ExprResult FromResult =
         BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
                               ToType, SCS.CopyConstructor,
-                              move_arg(ConstructorArgs));
+                              move_arg(ConstructorArgs),
+                              /*ZeroInit*/ false,
+                              CXXConstructExpr::CK_Complete);
       if (FromResult.isInvalid())
         return true;
       From = FromResult.takeAs<Expr>();
       return false;
     }
-    OwningExprResult FromResult =
+    ExprResult FromResult =
       BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
                             ToType, SCS.CopyConstructor,
-                            MultiExprArg(*this, (void**)&From, 1));
+                            MultiExprArg(*this, &From, 1),
+                            /*ZeroInit*/ false,
+                            CXXConstructExpr::CK_Complete);
 
     if (FromResult.isInvalid())
       return true;
@@ -1660,6 +1747,21 @@
     return false;
   }
 
+  // Resolve overloaded function references.
+  if (Context.hasSameType(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();
+  }
+
   // Perform the first implicit conversion.
   switch (SCS.First) {
   case ICK_Identity:
@@ -1669,31 +1771,12 @@
 
   case ICK_Array_To_Pointer:
     FromType = Context.getArrayDecayedType(FromType);
-    ImpCastExprToType(From, FromType, CastExpr::CK_ArrayToPointerDecay);
+    ImpCastExprToType(From, FromType, 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);
+    ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay);
     break;
 
   default:
@@ -1718,37 +1801,33 @@
       return true;      
       
     ImpCastExprToType(From, Context.getNoReturnType(From->getType(), false),
-                      CastExpr::CK_NoOp);
+                      CK_NoOp);
     break;
       
   case ICK_Integral_Promotion:
   case ICK_Integral_Conversion:
-    ImpCastExprToType(From, ToType, CastExpr::CK_IntegralCast);
+    ImpCastExprToType(From, ToType, CK_IntegralCast);
     break;
 
   case ICK_Floating_Promotion:
   case ICK_Floating_Conversion:
-    ImpCastExprToType(From, ToType, CastExpr::CK_FloatingCast);
+    ImpCastExprToType(From, ToType, CK_FloatingCast);
     break;
 
   case ICK_Complex_Promotion:
   case ICK_Complex_Conversion:
-    ImpCastExprToType(From, ToType, CastExpr::CK_Unknown);
+    ImpCastExprToType(From, ToType, CK_Unknown);
     break;
 
   case ICK_Floating_Integral:
-    if (ToType->isFloatingType())
-      ImpCastExprToType(From, ToType, CastExpr::CK_IntegralToFloating);
+    if (ToType->isRealFloatingType())
+      ImpCastExprToType(From, ToType, CK_IntegralToFloating);
     else
-      ImpCastExprToType(From, ToType, CastExpr::CK_FloatingToIntegral);
-    break;
-
-  case ICK_Complex_Real:
-    ImpCastExprToType(From, ToType, CastExpr::CK_Unknown);
+      ImpCastExprToType(From, ToType, CK_FloatingToIntegral);
     break;
 
   case ICK_Compatible_Conversion:
-    ImpCastExprToType(From, ToType, CastExpr::CK_NoOp);
+    ImpCastExprToType(From, ToType, CK_NoOp);
     break;
 
   case ICK_Pointer_Conversion: {
@@ -1761,46 +1840,67 @@
     }
 
     
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CastKind Kind = CK_Unknown;
+    CXXCastPath BasePath;
     if (CheckPointerConversion(From, ToType, Kind, BasePath, IgnoreBaseAccess))
       return true;
-    ImpCastExprToType(From, ToType, Kind, /*isLvalue=*/false, BasePath);
+    ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath);
     break;
   }
   
   case ICK_Pointer_Member: {
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CastKind Kind = CK_Unknown;
+    CXXCastPath BasePath;
     if (CheckMemberPointerConversion(From, ToType, Kind, BasePath,
                                      IgnoreBaseAccess))
       return true;
     if (CheckExceptionSpecCompatibility(From, ToType))
       return true;
-    ImpCastExprToType(From, ToType, Kind, /*isLvalue=*/false, BasePath);
+    ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath);
     break;
   }
   case ICK_Boolean_Conversion: {
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+    CastKind Kind = CK_Unknown;
     if (FromType->isMemberPointerType())
-      Kind = CastExpr::CK_MemberPointerToBoolean;
+      Kind = CK_MemberPointerToBoolean;
     
     ImpCastExprToType(From, Context.BoolTy, Kind);
     break;
   }
 
-  case ICK_Derived_To_Base:
+  case ICK_Derived_To_Base: {
+    CXXCastPath BasePath;
     if (CheckDerivedToBaseConversion(From->getType(), 
                                      ToType.getNonReferenceType(),
                                      From->getLocStart(),
-                                     From->getSourceRange(), 0,
+                                     From->getSourceRange(), 
+                                     &BasePath,
                                      IgnoreBaseAccess))
       return true;
-    ImpCastExprToType(From, ToType.getNonReferenceType(), 
-                      CastExpr::CK_DerivedToBase);
+
+    ImpCastExprToType(From, ToType.getNonReferenceType(),
+                      CK_DerivedToBase, CastCategory(From),
+                      &BasePath);
+    break;
+  }
+
+  case ICK_Vector_Conversion:
+    ImpCastExprToType(From, ToType, CK_BitCast);
+    break;
+
+  case ICK_Vector_Splat:
+    ImpCastExprToType(From, ToType, CK_VectorSplat);
     break;
       
-  default:
+  case ICK_Complex_Real:
+    ImpCastExprToType(From, ToType, CK_Unknown);
+    break;
+      
+  case ICK_Lvalue_To_Rvalue:
+  case ICK_Array_To_Pointer:
+  case ICK_Function_To_Pointer:
+  case ICK_Qualification:
+  case ICK_Num_Conversion_Kinds:
     assert(false && "Improper second standard conversion");
     break;
   }
@@ -1810,30 +1910,33 @@
     // 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());
+  case ICK_Qualification: {
+    // The qualification keeps the category of the inner expression, unless the
+    // target type isn't a reference.
+    ExprValueKind VK = ToType->isReferenceType() ?
+                                  CastCategory(From) : VK_RValue;
+    ImpCastExprToType(From, ToType.getNonLValueExprType(Context),
+                      CK_NoOp, VK);
 
     if (SCS.DeprecatedStringLiteralToCharPtr)
       Diag(From->getLocStart(), diag::warn_deprecated_string_literal_conversion)
         << ToType.getNonReferenceType();
 
     break;
-      
+    }
+
   default:
-    assert(false && "Improper second standard conversion");
+    assert(false && "Improper third standard conversion");
     break;
   }
 
   return false;
 }
 
-Sema::OwningExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
+ExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
                                                  SourceLocation KWLoc,
                                                  SourceLocation LParen,
-                                                 TypeTy *Ty,
+                                                 ParsedType Ty,
                                                  SourceLocation RParen) {
   QualType T = GetTypeFromParser(Ty);
 
@@ -1907,15 +2010,15 @@
     }
     // Cast LHS to type of use.
     QualType UseType = isIndirect ? Context.getPointerType(Class) : Class;
-    bool isLValue = !isIndirect && lex->isLvalue(Context) == Expr::LV_Valid;
-    
-    CXXBaseSpecifierArray BasePath;
+    ExprValueKind VK =
+        isIndirect ? VK_RValue : CastCategory(lex);
+
+    CXXCastPath BasePath;
     BuildBasePathArray(Paths, BasePath);
-    ImpCastExprToType(lex, UseType, CastExpr::CK_DerivedToBase, isLValue,
-                      BasePath);
+    ImpCastExprToType(lex, UseType, CK_DerivedToBase, VK, &BasePath);
   }
 
-  if (isa<CXXZeroInitValueExpr>(rex->IgnoreParens())) {
+  if (isa<CXXScalarValueInitExpr>(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;
@@ -2041,7 +2144,7 @@
   Self.AddBuiltinOperatorCandidates(OO_Conditional, Loc, Args, 2, CandidateSet);
 
   OverloadCandidateSet::iterator Best;
-  switch (Self.BestViableFunction(CandidateSet, Loc, Best)) {
+  switch (CandidateSet.BestViableFunction(Self, 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],
@@ -2079,8 +2182,7 @@
   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));
+  ExprResult Result = InitSeq.Perform(Self, Entity, Kind, MultiExprArg(&E, 1));
   if (Result.isInvalid())
     return true;
   
@@ -2108,8 +2210,6 @@
   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();
@@ -2213,9 +2313,36 @@
 
   //   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))
+  //      is of that type. If the operands have class type, the result
+  //      is a prvalue temporary of the result type, which is
+  //      copy-initialized from either the second operand or the third
+  //      operand depending on the value of the first operand.
+  if (Context.getCanonicalType(LTy) == Context.getCanonicalType(RTy)) {
+    if (LTy->isRecordType()) {
+      // The operands have class type. Make a temporary copy.
+      InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy);
+      ExprResult LHSCopy = PerformCopyInitialization(Entity, 
+                                                           SourceLocation(), 
+                                                           Owned(LHS));
+      if (LHSCopy.isInvalid())
+        return QualType();
+        
+      ExprResult RHSCopy = PerformCopyInitialization(Entity, 
+                                                           SourceLocation(), 
+                                                           Owned(RHS));
+      if (RHSCopy.isInvalid())
+        return QualType();
+      
+      LHS = LHSCopy.takeAs<Expr>();
+      RHS = RHSCopy.takeAs<Expr>();
+    }
+
     return LTy;
+  }
+
+  // Extension: conditional operator involving vector types.
+  if (LTy->isVectorType() || RTy->isVectorType()) 
+    return CheckVectorOperands(QuestionLoc, LHS, RHS);
 
   //   -- The second and third operands have arithmetic or enumeration type;
   //      the usual arithmetic conversions are performed to bring them to a
@@ -2293,16 +2420,16 @@
   //   the type of the other operand.
   if (E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
     if (T2->isMemberPointerType())
-      ImpCastExprToType(E1, T2, CastExpr::CK_NullToMemberPointer);
+      ImpCastExprToType(E1, T2, CK_NullToMemberPointer);
     else
-      ImpCastExprToType(E1, T2, CastExpr::CK_IntegralToPointer);
+      ImpCastExprToType(E1, T2, CK_IntegralToPointer);
     return T2;
   }
   if (E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
     if (T1->isMemberPointerType())
-      ImpCastExprToType(E2, T1, CastExpr::CK_NullToMemberPointer);
+      ImpCastExprToType(E2, T1, CK_NullToMemberPointer);
     else
-      ImpCastExprToType(E2, T1, CastExpr::CK_IntegralToPointer);
+      ImpCastExprToType(E2, T1, CK_IntegralToPointer);
     return T1;
   }
 
@@ -2436,15 +2563,15 @@
     }
 
     // Convert E1 to Composite1
-    OwningExprResult E1Result
-      = E1ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,(void**)&E1,1));
+    ExprResult E1Result
+      = E1ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,&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));
+    ExprResult E2Result
+      = E2ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,&E2,1));
     if (E2Result.isInvalid())
       return QualType();
     E2 = E2Result.takeAs<Expr>();
@@ -2461,15 +2588,15 @@
     return QualType();
   
   // Convert E1 to Composite2
-  OwningExprResult E1Result
-    = E1ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, (void**)&E1, 1));
+  ExprResult E1Result
+    = E1ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, &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));
+  ExprResult E2Result
+    = E2ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, &E2, 1));
   if (E2Result.isInvalid())
     return QualType();
   E2 = E2Result.takeAs<Expr>();
@@ -2477,7 +2604,7 @@
   return Composite2;
 }
 
-Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {
+ExprResult Sema::MaybeBindToTemporary(Expr *E) {
   if (!Context.getLangOptions().CPlusPlus)
     return Owned(E);
 
@@ -2487,31 +2614,27 @@
   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 this is the result of a call or an Objective-C message send 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())
+    if (CE->getCallReturnType()->isReferenceType())
       return Owned(E);
+  } else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
+    if (const ObjCMethodDecl *MD = ME->getMethodDecl()) {
+      if (MD->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())
+  if (RD->isInvalidDecl() || RD->hasTrivialDestructor())
     return Owned(E);
 
-  CXXTemporary *Temp = CXXTemporary::Create(Context,
-                                            RD->getDestructor(Context));
+  CXXTemporary *Temp = CXXTemporary::Create(Context, LookupDestructor(RD));
   ExprTemporaries.push_back(Temp);
-  if (CXXDestructorDecl *Destructor =
-        const_cast<CXXDestructorDecl*>(RD->getDestructor(Context))) {
+  if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) {
     MarkDeclarationReferenced(E->getExprLoc(), Destructor);
     CheckDestructorAccess(E->getExprLoc(), Destructor,
                           PDiag(diag::err_access_dtor_temp)
@@ -2524,6 +2647,9 @@
 Expr *Sema::MaybeCreateCXXExprWithTemporaries(Expr *SubExpr) {
   assert(SubExpr && "sub expression can't be null!");
 
+  // Check any implicit conversions within the expression.
+  CheckImplicitConversions(SubExpr);
+
   unsigned FirstTemporary = ExprEvalContexts.back().NumTemporaries;
   assert(ExprTemporaries.size() >= FirstTemporary);
   if (ExprTemporaries.size() == FirstTemporary)
@@ -2538,8 +2664,8 @@
   return E;
 }
 
-Sema::OwningExprResult 
-Sema::MaybeCreateCXXExprWithTemporaries(OwningExprResult SubExpr) {
+ExprResult 
+Sema::MaybeCreateCXXExprWithTemporaries(ExprResult SubExpr) {
   if (SubExpr.isInvalid())
     return ExprError();
   
@@ -2562,17 +2688,16 @@
   return E;
 }
 
-Sema::OwningExprResult
-Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
-                                   tok::TokenKind OpKind, TypeTy *&ObjectType,
+ExprResult
+Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc,
+                                   tok::TokenKind OpKind, ParsedType &ObjectType,
                                    bool &MayBePseudoDestructor) {
   // Since this might be a postfix expression, get rid of ParenListExprs.
-  Base = MaybeConvertParenListExprToParenExpr(S, move(Base));
+  ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
+  if (Result.isInvalid()) return ExprError();
+  Base = Result.get();
 
-  Expr *BaseExpr = (Expr*)Base.get();
-  assert(BaseExpr && "no record expansion");
-
-  QualType BaseType = BaseExpr->getType();
+  QualType BaseType = Base->getType();
   MayBePseudoDestructor = false;
   if (BaseType->isDependentType()) {
     // If we have a pointer to a dependent type and are using the -> operator,
@@ -2582,9 +2707,9 @@
       if (const PointerType *Ptr = BaseType->getAs<PointerType>())
         BaseType = Ptr->getPointeeType();
     
-    ObjectType = BaseType.getAsOpaquePtr();
+    ObjectType = ParsedType::make(BaseType);
     MayBePseudoDestructor = true;
-    return move(Base);
+    return Owned(Base);
   }
 
   // C++ [over.match.oper]p8:
@@ -2597,13 +2722,13 @@
     CTypes.insert(Context.getCanonicalType(BaseType));
     
     while (BaseType->isRecordType()) {
-      Base = BuildOverloadedArrowExpr(S, move(Base), OpLoc);
-      BaseExpr = (Expr*)Base.get();
-      if (BaseExpr == NULL)
+      Result = BuildOverloadedArrowExpr(S, Base, OpLoc);
+      if (Result.isInvalid())
         return ExprError();
-      if (CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(BaseExpr))
+      Base = Result.get();
+      if (CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(Base))
         Locations.push_back(OpCall->getDirectCallee()->getLocation());
-      BaseType = BaseExpr->getType();
+      BaseType = Base->getType();
       CanQualType CBaseType = Context.getCanonicalType(BaseType);
       if (!CTypes.insert(CBaseType)) {
         Diag(OpLoc, diag::err_operator_arrow_circular);
@@ -2628,9 +2753,9 @@
     //
     // This also indicates that we should be parsing a
     // pseudo-destructor-name.
-    ObjectType = 0;
+    ObjectType = ParsedType();
     MayBePseudoDestructor = true;
-    return move(Base);
+    return Owned(Base);
   }
 
   // The object type must be complete (or dependent).
@@ -2644,27 +2769,26 @@
   //   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();
+  ObjectType = ParsedType::make(BaseType);
   return move(Base);
 }
 
-Sema::OwningExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc,
-                                                   ExprArg MemExpr) {
-  Expr *E = (Expr *) MemExpr.get();
+ExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc,
+                                                   Expr *MemExpr) {
   SourceLocation ExpectedLParenLoc = PP.getLocForEndOfToken(NameLoc);
-  Diag(E->getLocStart(), diag::err_dtor_expr_without_call)
-    << isa<CXXPseudoDestructorExpr>(E)
+  Diag(MemExpr->getLocStart(), diag::err_dtor_expr_without_call)
+    << isa<CXXPseudoDestructorExpr>(MemExpr)
     << FixItHint::CreateInsertion(ExpectedLParenLoc, "()");
   
   return ActOnCallExpr(/*Scope*/ 0,
-                       move(MemExpr),
+                       MemExpr,
                        /*LPLoc*/ ExpectedLParenLoc,
-                       Sema::MultiExprArg(*this, 0, 0),
+                       MultiExprArg(),
                        /*CommaLocs*/ 0,
                        /*RPLoc*/ ExpectedLParenLoc);
 }
 
-Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
+ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base,
                                                        SourceLocation OpLoc,
                                                        tok::TokenKind OpKind,
                                                        const CXXScopeSpec &SS,
@@ -2679,12 +2803,11 @@
   //   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();
+  QualType ObjectType = Base->getType();
   if (OpKind == tok::arrow) {
     if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
       ObjectType = Ptr->getPointeeType();
-    } else if (!BaseE->isTypeDependent()) {
+    } else if (!Base->isTypeDependent()) {
       // The user wrote "p->" when she probably meant "p."; fix it.
       Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
         << ObjectType << true
@@ -2698,7 +2821,7 @@
   
   if (!ObjectType->isDependentType() && !ObjectType->isScalarType()) {
     Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar)
-      << ObjectType << BaseE->getSourceRange();
+      << ObjectType << Base->getSourceRange();
     return ExprError();
   }
 
@@ -2708,12 +2831,12 @@
   if (DestructedTypeInfo) {
     QualType DestructedType = DestructedTypeInfo->getType();
     SourceLocation DestructedTypeStart
-      = DestructedTypeInfo->getTypeLoc().getSourceRange().getBegin();
+      = DestructedTypeInfo->getTypeLoc().getLocalSourceRange().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();
+        << ObjectType << DestructedType << Base->getSourceRange()
+        << DestructedTypeInfo->getTypeLoc().getLocalSourceRange();
       
       // Recover by setting the destructed type to the object type.
       DestructedType = ObjectType;
@@ -2733,37 +2856,34 @@
   if (ScopeTypeInfo) {
     QualType ScopeType = ScopeTypeInfo->getType();
     if (!ScopeType->isDependentType() && !ObjectType->isDependentType() &&
-        !Context.hasSameType(ScopeType, ObjectType)) {
+        !Context.hasSameUnqualifiedType(ScopeType, ObjectType)) {
       
-      Diag(ScopeTypeInfo->getTypeLoc().getSourceRange().getBegin(),
+      Diag(ScopeTypeInfo->getTypeLoc().getLocalSourceRange().getBegin(),
            diag::err_pseudo_dtor_type_mismatch)
-        << ObjectType << ScopeType << BaseE->getSourceRange()
-        << ScopeTypeInfo->getTypeLoc().getSourceRange();
+        << ObjectType << ScopeType << Base->getSourceRange()
+        << ScopeTypeInfo->getTypeLoc().getLocalSourceRange();
   
       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));
+  Expr *Result
+    = new (Context) CXXPseudoDestructorExpr(Context, Base,
+                                            OpKind == tok::arrow, OpLoc,
+                                            SS.getScopeRep(), SS.getRange(),
+                                            ScopeTypeInfo,
+                                            CCLoc,
+                                            TildeLoc,
+                                            Destructed);
             
   if (HasTrailingLParen)
-    return move(Result);
+    return Owned(Result);
   
-  return DiagnoseDtorReference(Destructed.getLocation(), move(Result));
+  return DiagnoseDtorReference(Destructed.getLocation(), Result);
 }
 
-Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
+ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
                                                        SourceLocation OpLoc,
                                                        tok::TokenKind OpKind,
                                                        CXXScopeSpec &SS,
@@ -2779,13 +2899,11 @@
           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();
+  QualType ObjectType = Base->getType();
   if (OpKind == tok::arrow) {
     if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
       ObjectType = Ptr->getPointeeType();
@@ -2803,11 +2921,12 @@
 
   // Compute the object type that we should use for name lookup purposes. Only
   // record types and dependent types matter.
-  void *ObjectTypePtrForLookup = 0;
+  ParsedType ObjectTypePtrForLookup;
   if (!SS.isSet()) {
-    ObjectTypePtrForLookup = (void *)ObjectType->getAs<RecordType>();
-    if (!ObjectTypePtrForLookup && ObjectType->isDependentType())
-      ObjectTypePtrForLookup = Context.DependentTy.getAsOpaquePtr();
+    if (const Type *T = ObjectType->getAs<RecordType>())
+      ObjectTypePtrForLookup = ParsedType::make(QualType(T, 0));
+    else if (ObjectType->isDependentType())
+      ObjectTypePtrForLookup = ParsedType::make(Context.DependentTy);
   }
   
   // Convert the name of the type being destructed (following the ~) into a 
@@ -2816,9 +2935,9 @@
   TypeSourceInfo *DestructedTypeInfo = 0;
   PseudoDestructorTypeStorage Destructed;
   if (SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) {
-    TypeTy *T = getTypeName(*SecondTypeName.Identifier, 
-                            SecondTypeName.StartLocation,
-                            S, &SS, true, ObjectTypePtrForLookup);
+    ParsedType T = getTypeName(*SecondTypeName.Identifier, 
+                               SecondTypeName.StartLocation,
+                               S, &SS, true, ObjectTypePtrForLookup);
     if (!T && 
         ((SS.isSet() && !computeDeclContext(SS, false)) ||
          (!SS.isSet() && ObjectType->isDependentType()))) {
@@ -2845,7 +2964,7 @@
     ASTTemplateArgsPtr TemplateArgsPtr(*this,
                                        TemplateId->getTemplateArgs(),
                                        TemplateId->NumArgs);
-    TypeResult T = ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+    TypeResult T = ActOnTemplateIdType(TemplateId->Template,
                                        TemplateId->TemplateNameLoc,
                                        TemplateId->LAngleLoc,
                                        TemplateArgsPtr,
@@ -2872,9 +2991,9 @@
   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);
+      ParsedType T = getTypeName(*FirstTypeName.Identifier, 
+                                 FirstTypeName.StartLocation,
+                                 S, &SS, false, ObjectTypePtrForLookup);
       if (!T) {
         Diag(FirstTypeName.StartLocation, 
              diag::err_pseudo_dtor_destructor_non_type)
@@ -2893,7 +3012,7 @@
       ASTTemplateArgsPtr TemplateArgsPtr(*this,
                                          TemplateId->getTemplateArgs(),
                                          TemplateId->NumArgs);
-      TypeResult T = ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+      TypeResult T = ActOnTemplateIdType(TemplateId->Template,
                                          TemplateId->TemplateNameLoc,
                                          TemplateId->LAngleLoc,
                                          TemplateArgsPtr,
@@ -2911,7 +3030,7 @@
                                                   FirstTypeName.StartLocation);
 
     
-  return BuildPseudoDestructorExpr(move(Base), OpLoc, OpKind, SS,
+  return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, SS,
                                    ScopeTypeInfo, CCLoc, TildeLoc,
                                    Destructed, HasTrailingLParen);
 }
@@ -2924,9 +3043,9 @@
     assert(0 && "Calling BuildCXXMemberCallExpr with invalid call?");
 
   MemberExpr *ME = 
-      new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method, 
+      new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method,
                                SourceLocation(), Method->getType());
-  QualType ResultType = Method->getResultType().getNonReferenceType();
+  QualType ResultType = Method->getCallResultType();
   MarkDeclarationReferenced(Exp->getLocStart(), Method);
   CXXMemberCallExpr *CE =
     new (Context) CXXMemberCallExpr(Context, ME, 0, 0, ResultType,
@@ -2934,10 +3053,7 @@
   return CE;
 }
 
-Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) {
-  Expr *FullExpr = Arg.takeAs<Expr>();
-  if (FullExpr)
-    FullExpr = MaybeCreateCXXExprWithTemporaries(FullExpr);
-
-  return Owned(FullExpr);
+ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) {
+  if (!FullExpr) return ExprError();
+  return MaybeCreateCXXExprWithTemporaries(FullExpr);
 }
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index db9a2e2..b56159c 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -11,9 +11,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "Lookup.h"
-#include "SemaInit.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/Initialization.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprObjC.h"
@@ -23,9 +24,9 @@
 
 using namespace clang;
 
-Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
-                                              ExprTy **strings,
-                                              unsigned NumStrings) {
+ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
+                                        Expr **strings,
+                                        unsigned NumStrings) {
   StringLiteral **Strings = reinterpret_cast<StringLiteral**>(strings);
 
   // Most ObjC strings are formed out of a single piece.  However, we *can*
@@ -50,14 +51,11 @@
         return true;
       }
 
-      // Get the string data.
-      StrBuf.append(S->getStrData(), S->getStrData()+S->getByteLength());
+      // Append the string.
+      StrBuf += S->getString();
 
       // 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
@@ -135,11 +133,11 @@
   return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);
 }
 
-Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
-                                                 SourceLocation EncodeLoc,
-                                                 SourceLocation LParenLoc,
-                                                 TypeTy *ty,
-                                                 SourceLocation RParenLoc) {
+ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
+                                           SourceLocation EncodeLoc,
+                                           SourceLocation LParenLoc,
+                                           ParsedType ty,
+                                           SourceLocation RParenLoc) {
   // FIXME: Preserve type source info ?
   TypeSourceInfo *TInfo;
   QualType EncodedType = GetTypeFromParser(ty, &TInfo);
@@ -150,28 +148,33 @@
   return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc);
 }
 
-Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
-                                                   SourceLocation AtLoc,
-                                                   SourceLocation SelLoc,
-                                                   SourceLocation LParenLoc,
-                                                   SourceLocation RParenLoc) {
+ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
+                                             SourceLocation AtLoc,
+                                             SourceLocation SelLoc,
+                                             SourceLocation LParenLoc,
+                                             SourceLocation RParenLoc) {
   ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
-                             SourceRange(LParenLoc, RParenLoc), false);
+                             SourceRange(LParenLoc, RParenLoc), false, false);
   if (!Method)
     Method = LookupFactoryMethodInGlobalPool(Sel,
                                           SourceRange(LParenLoc, RParenLoc));
   if (!Method)
     Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
 
+  llvm::DenseMap<Selector, SourceLocation>::iterator Pos
+    = ReferencedSelectors.find(Sel);
+  if (Pos == ReferencedSelectors.end())
+    ReferencedSelectors.insert(std::make_pair(Sel, SelLoc));
+
   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) {
+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;
@@ -207,7 +210,7 @@
     return false;
   }
 
-  ReturnType = Method->getResultType().getNonReferenceType();
+  ReturnType = Method->getSendResultType();
 
   unsigned NumNamedArgs = Sel.getNumArgs();
   // Method might have more arguments than selector indicates. This is due
@@ -239,7 +242,7 @@
       return true;
 
     InitializedEntity Entity = InitializedEntity::InitializeParameter(Param);
-    OwningExprResult ArgE = PerformCopyInitialization(Entity,
+    ExprResult ArgE = PerformCopyInitialization(Entity,
                                                       SourceLocation(),
                                                       Owned(argExpr->Retain()));
     if (ArgE.isInvalid())
@@ -254,7 +257,7 @@
       if (Args[i]->isTypeDependent())
         continue;
 
-      IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
+      IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, 0);
     }
   } else {
     // Check for extra arguments to non-variadic methods.
@@ -329,7 +332,7 @@
 
 /// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an
 /// objective C interface.  This is a property reference expression.
-Action::OwningExprResult Sema::
+ExprResult Sema::
 HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
                           Expr *BaseExpr, DeclarationName MemberName,
                           SourceLocation MemberLoc) {
@@ -346,7 +349,7 @@
     Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
     ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
     if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc))
-      ResTy = Getter->getResultType();
+      ResTy = Getter->getSendResultType();
     return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
                                                    MemberLoc, BaseExpr));
   }
@@ -402,7 +405,7 @@
 
   if (Getter) {
     QualType PType;
-    PType = Getter->getResultType();
+    PType = Getter->getSendResultType();
     return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType,
                                     Setter, MemberLoc, BaseExpr));
   }
@@ -431,7 +434,7 @@
 
 
 
-Action::OwningExprResult Sema::
+ExprResult Sema::
 ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
                           IdentifierInfo &propertyName,
                           SourceLocation receiverNameLoc,
@@ -510,7 +513,7 @@
     QualType PType;
 
     if (Getter)
-      PType = Getter->getResultType();
+      PType = Getter->getSendResultType();
     else {
       for (ObjCMethodDecl::param_iterator PI = Setter->param_begin(),
            E = Setter->param_end(); PI != E; ++PI)
@@ -529,8 +532,8 @@
                                                SourceLocation NameLoc,
                                                bool IsSuper,
                                                bool HasTrailingDot,
-                                               TypeTy *&ReceiverType) {
-  ReceiverType = 0;
+                                               ParsedType &ReceiverType) {
+  ReceiverType = ParsedType();
 
   // If the identifier is "super" and there is no trailing dot, we're
   // messaging super.
@@ -577,7 +580,7 @@
     //  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();
+    ReceiverType = CreateParsedType(T, TSInfo);
     return ObjCClassMessage;
   }
   }
@@ -604,7 +607,7 @@
 
         QualType T = Context.getObjCInterfaceType(Class);
         TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
-        ReceiverType = CreateLocInfoType(T, TSInfo).getAsOpaquePtr();
+        ReceiverType = CreateParsedType(T, TSInfo);
         return ObjCClassMessage;
       }
     } else if (Result.empty() && Corrected.getAsIdentifierInfo() &&
@@ -622,7 +625,7 @@
   return ObjCInstanceMessage;
 }
 
-Sema::OwningExprResult Sema::ActOnSuperMessage(Scope *S, 
+ExprResult Sema::ActOnSuperMessage(Scope *S, 
                                                SourceLocation SuperLoc,
                                                Selector Sel,
                                                SourceLocation LBracLoc,
@@ -657,7 +660,7 @@
     // message to the superclass instance.
     QualType SuperTy = Context.getObjCInterfaceType(Super);
     SuperTy = Context.getObjCObjectPointerType(SuperTy);
-    return BuildInstanceMessage(ExprArg(*this), SuperTy, SuperLoc,
+    return BuildInstanceMessage(0, SuperTy, SuperLoc,
                                 Sel, /*Method=*/0, LBracLoc, RBracLoc, 
                                 move(Args));
   }
@@ -698,7 +701,7 @@
 /// \param RBrac The location of the closing square bracket ']'.
 ///
 /// \param Args The message arguments.
-Sema::OwningExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
+ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
                                                QualType ReceiverType,
                                                SourceLocation SuperLoc,
                                                Selector Sel,
@@ -718,14 +721,12 @@
   }
   
   SourceLocation Loc = SuperLoc.isValid()? SuperLoc
-             : ReceiverTypeInfo->getTypeLoc().getSourceRange().getBegin();
+             : ReceiverTypeInfo->getTypeLoc().getLocalSourceRange().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 {
+  const ObjCObjectType *ClassType = ReceiverType->getAs<ObjCObjectType>();
+  if (!ClassType || !(Class = ClassType->getInterface())) {
     Diag(Loc, diag::err_invalid_receiver_class_message)
       << ReceiverType;
     return ExprError();
@@ -759,29 +760,28 @@
   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);
+                                LBracLoc, RBracLoc, ReturnType))
     return ExprError();
-  }
 
   // Construct the appropriate ObjCMessageExpr.
+  Expr *Result;
   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));
+    Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, 
+                                     SuperLoc, /*IsInstanceSuper=*/false, 
+                                     ReceiverType, Sel, Method, Args, 
+                                     NumArgs, RBracLoc);
+  else
+    Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, 
+                                     ReceiverTypeInfo, Sel, Method, Args, 
+                                     NumArgs, RBracLoc);
+  return MaybeBindToTemporary(Result);
 }
 
 // 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,
+ExprResult Sema::ActOnClassMessage(Scope *S, 
+                                               ParsedType Receiver,
                                                Selector Sel,
                                                SourceLocation LBracLoc,
                                                SourceLocation SelectorLoc,
@@ -829,7 +829,7 @@
 /// \param RBrac The location of the closing square bracket ']'.
 ///
 /// \param Args The message arguments.
-Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
+ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
                                                   QualType ReceiverType,
                                                   SourceLocation SuperLoc,
                                                   Selector Sel,
@@ -839,7 +839,6 @@
                                                   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
@@ -864,13 +863,16 @@
 
   if (!Method) {
     // Handle messages to id.
-    if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType() ||
+    bool receiverIsId = ReceiverType->isObjCIdType();
+    if (receiverIsId || ReceiverType->isBlockPointerType() ||
         (Receiver && Context.isObjCNSObjectType(Receiver->getType()))) {
       Method = LookupInstanceMethodInGlobalPool(Sel, 
-                                              SourceRange(LBracLoc, RBracLoc));
+                                                SourceRange(LBracLoc, RBracLoc),
+                                                receiverIsId);
       if (!Method)
         Method = LookupFactoryMethodInGlobalPool(Sel, 
-                                               SourceRange(LBracLoc, RBracLoc));
+                                                 SourceRange(LBracLoc, RBracLoc),
+                                                 receiverIsId);
     } else if (ReceiverType->isObjCClassType() ||
                ReceiverType->isObjCQualifiedClassType()) {
       // Handle messages to Class.
@@ -892,12 +894,14 @@
         // If not messaging 'self', look for any factory method named 'Sel'.
         if (!Receiver || !isSelfExpr(Receiver)) {
           Method = LookupFactoryMethodInGlobalPool(Sel, 
-                                               SourceRange(LBracLoc, RBracLoc));
+                                               SourceRange(LBracLoc, RBracLoc),
+                                                   true);
           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));
+                                               SourceRange(LBracLoc, RBracLoc),
+                                                      true);
             if (Method)
                 if (const ObjCInterfaceDecl *ID =
                   dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
@@ -931,7 +935,7 @@
         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.
+        // The idea is to add class info to MethodPool.
         Method = ClassDecl->lookupInstanceMethod(Sel);
 
         if (!Method) {
@@ -952,7 +956,7 @@
             // compatibility. FIXME: should we deviate??
             if (OCIType->qual_empty()) {
               Method = LookupInstanceMethodInGlobalPool(Sel,
-                                                 SourceRange(LBracLoc, RBracLoc));
+                                                 SourceRange(LBracLoc, RBracLoc)); 
               if (Method && !OCIType->getInterfaceDecl()->isForwardDecl())
                 Diag(Loc, diag::warn_maynot_respond)
                   << OCIType->getInterfaceDecl()->getIdentifier() << Sel;
@@ -962,20 +966,34 @@
         if (Method && DiagnoseUseOfDecl(Method, Loc))
           return ExprError();
       } else if (!Context.getObjCIdType().isNull() &&
-                 (ReceiverType->isPointerType() ||
-                  (ReceiverType->isIntegerType() &&
-                   ReceiverType->isScalarType()))) {
+                 (ReceiverType->isPointerType() || 
+                  ReceiverType->isIntegerType())) {
         // 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);
+                            CK_BitCast);
         else
           ImpCastExprToType(Receiver, Context.getObjCIdType(),
-                            CastExpr::CK_IntegralToPointer);
+                            CK_IntegralToPointer);
         ReceiverType = Receiver->getType();
+      } 
+      else if (getLangOptions().CPlusPlus &&
+               !PerformContextuallyConvertToObjCId(Receiver)) {
+        if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Receiver)) {
+          Receiver = ICE->getSubExpr();
+          ReceiverType = Receiver->getType();
+        }
+        return BuildInstanceMessage(Receiver,
+                                    ReceiverType,
+                                    SuperLoc,
+                                    Sel,
+                                    Method,
+                                    LBracLoc, 
+                                    RBracLoc,
+                                    move(ArgsIn));
       } else {
         // Reject other random receiver types (e.g. structs).
         Diag(Loc, diag::err_bad_receiver_type)
@@ -992,33 +1010,40 @@
   if (CheckMessageArgumentTypes(Args, NumArgs, Sel, Method, false,
                                 LBracLoc, RBracLoc, ReturnType))
     return ExprError();
+  
+  if (!ReturnType->isVoidType()) {
+    if (RequireCompleteType(LBracLoc, ReturnType, 
+                            diag::err_illegal_message_expr_incomplete_type))
+      return ExprError();
+  }
 
   // Construct the appropriate ObjCMessageExpr instance.
+  Expr *Result;
   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));
+    Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc,
+                                     SuperLoc,  /*IsInstanceSuper=*/true,
+                                     ReceiverType, Sel, Method, 
+                                     Args, NumArgs, RBracLoc);
+  else
+    Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, Receiver, 
+                                     Sel, Method, Args, NumArgs, RBracLoc);
+  return MaybeBindToTemporary(Result);
 }
 
 // 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());
+ExprResult Sema::ActOnInstanceMessage(Scope *S,
+                                      Expr *Receiver, 
+                                      Selector Sel,
+                                      SourceLocation LBracLoc,
+                                      SourceLocation SelectorLoc,
+                                      SourceLocation RBracLoc,
+                                      MultiExprArg Args) {
   if (!Receiver)
     return ExprError();
 
-  return BuildInstanceMessage(move(ReceiverE), Receiver->getType(),
+  return BuildInstanceMessage(Receiver, Receiver->getType(),
                               /*SuperLoc=*/SourceLocation(), Sel, /*Method=*/0, 
                               LBracLoc, RBracLoc, move(Args));
 }
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 1caa94b..a719590 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -15,12 +15,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "SemaInit.h"
-#include "Lookup.h"
-#include "Sema.h"
+#include "clang/Sema/Designator.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/SemaInternal.h"
 #include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/Designator.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/TypeLoc.h"
@@ -263,9 +264,8 @@
       return;
     }
     
-    Sema::OwningExprResult MemberInit
-      = InitSeq.Perform(SemaRef, MemberEntity, Kind, 
-                        Sema::MultiExprArg(SemaRef, 0, 0));
+    ExprResult MemberInit
+      = InitSeq.Perform(SemaRef, MemberEntity, Kind, MultiExprArg());
     if (MemberInit.isInvalid()) {
       hadError = true;
       return;
@@ -373,9 +373,8 @@
         return;
       }
 
-      Sema::OwningExprResult ElementInit
-        = InitSeq.Perform(SemaRef, ElementEntity, Kind, 
-                          Sema::MultiExprArg(SemaRef, 0, 0));
+      ExprResult ElementInit
+        = InitSeq.Perform(SemaRef, ElementEntity, Kind, MultiExprArg());
       if (ElementInit.isInvalid()) {
         hadError = true;
         return;
@@ -523,8 +522,9 @@
   StructuredList->setSyntacticForm(IList);
   CheckListElementTypes(Entity, IList, T, /*SubobjectIsDesignatorContext=*/true, 
                         Index, StructuredList, StructuredIndex, TopLevelObject);
-  IList->setType(T.getNonReferenceType());
-  StructuredList->setType(T.getNonReferenceType());
+  QualType ExprTy = T.getNonLValueExprType(SemaRef.Context);
+  IList->setType(ExprTy);
+  StructuredList->setType(ExprTy);
   if (hadError)
     return;
 
@@ -624,10 +624,14 @@
   } else if (DeclType->isReferenceType()) {
     CheckReferenceType(Entity, IList, DeclType, Index,
                        StructuredList, StructuredIndex);
+  } else if (DeclType->isObjCObjectType()) {
+    SemaRef.Diag(IList->getLocStart(), diag::err_init_objc_class)
+      << DeclType;
+    hadError = true;
   } 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");
+    SemaRef.Diag(IList->getLocStart(), diag::err_illegal_initializer_type)
+      << DeclType;
+    hadError = true;
   }
 }
 
@@ -673,9 +677,8 @@
       InitializationSequence Seq(SemaRef, Entity, Kind, &expr, 1);
       
       if (Seq) {
-        Sema::OwningExprResult Result = 
-          Seq.Perform(SemaRef, Entity, Kind,
-                      Sema::MultiExprArg(SemaRef, (void **)&expr, 1));
+        ExprResult Result = 
+          Seq.Perform(SemaRef, Entity, Kind, MultiExprArg(&expr, 1));
         if (Result.isInvalid())
           hadError = true;
         
@@ -735,13 +738,13 @@
                                       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;
+    if (InitListExpr *SubIList = dyn_cast<InitListExpr>(expr)) {
+      SemaRef.Diag(SubIList->getLocStart(),
+                    diag::warn_many_braces_around_scalar_init)
+        << SubIList->getSourceRange();
+
+      CheckScalarType(Entity, SubIList, DeclType, Index, StructuredList,
+                      StructuredIndex);
       return;
     } else if (isa<DesignatedInitExpr>(expr)) {
       SemaRef.Diag(expr->getSourceRange().getBegin(),
@@ -753,7 +756,7 @@
       return;
     }
 
-    Sema::OwningExprResult Result =
+    ExprResult Result =
       SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(),
                                         SemaRef.Owned(expr));
 
@@ -800,7 +803,7 @@
       return;
     }
 
-    Sema::OwningExprResult Result =
+    ExprResult Result =
       SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(),
                                         SemaRef.Owned(expr));
 
@@ -873,10 +876,15 @@
                               StructuredList, StructuredIndex);
           ++numEltsInit;
         } else {
+          QualType VecType;
           const VectorType *IVT = IType->getAs<VectorType>();
           unsigned numIElts = IVT->getNumElements();
-          QualType VecType = SemaRef.Context.getExtVectorType(elementType,
-                                                              numIElts);
+          
+          if (IType->isExtVectorType())
+            VecType = SemaRef.Context.getExtVectorType(elementType, numIElts);
+          else
+            VecType = SemaRef.Context.getVectorType(elementType, numIElts,
+                                                    IVT->getAltiVecSpecific());
           CheckSubElementType(ElementEntity, IList, VecType, Index,
                               StructuredList, StructuredIndex);
           numEltsInit += numIElts;
@@ -1110,7 +1118,7 @@
   }
 
   // Emit warnings for missing struct field initializers.
-  if (CheckForMissingFields && Field != FieldEnd && 
+  if (InitializedSomething && 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.
@@ -1707,7 +1715,7 @@
                                          InitRange.getBegin(), 0, 0,
                                          InitRange.getEnd());
 
-  Result->setType(CurrentObjectType.getNonReferenceType());
+  Result->setType(CurrentObjectType.getNonLValueExprType(SemaRef.Context));
 
   // Pre-allocate storage for the structured initializer list.
   unsigned NumElements = 0;
@@ -1803,10 +1811,10 @@
   return false;
 }
 
-Sema::OwningExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
+ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
                                                         SourceLocation Loc,
                                                         bool GNUSyntax,
-                                                        OwningExprResult Init) {
+                                                        ExprResult Init) {
   typedef DesignatedInitExpr::Designator ASTDesignator;
 
   bool Invalid = false;
@@ -1952,6 +1960,7 @@
   case EK_Base:
   case EK_ArrayElement:
   case EK_VectorElement:
+  case EK_BlockElement:
     return DeclarationName();
   }
   
@@ -1973,6 +1982,7 @@
   case EK_Base:
   case EK_ArrayElement:
   case EK_VectorElement:
+  case EK_BlockElement:
     return 0;
   }
   
@@ -1980,6 +1990,27 @@
   return 0;
 }
 
+bool InitializedEntity::allowsNRVO() const {
+  switch (getKind()) {
+  case EK_Result:
+  case EK_Exception:
+    return LocAndNRVO.NRVO;
+    
+  case EK_Variable:
+  case EK_Parameter:
+  case EK_Member:
+  case EK_New:
+  case EK_Temporary:
+  case EK_Base:
+  case EK_ArrayElement:
+  case EK_VectorElement:
+  case EK_BlockElement:
+    break;
+  }
+
+  return false;
+}
+
 //===----------------------------------------------------------------------===//
 // Initialization sequence
 //===----------------------------------------------------------------------===//
@@ -1988,18 +2019,21 @@
   switch (Kind) {
   case SK_ResolveAddressOfOverloadedFunction:
   case SK_CastDerivedToBaseRValue:
+  case SK_CastDerivedToBaseXValue:
   case SK_CastDerivedToBaseLValue:
   case SK_BindReference:
   case SK_BindReferenceToTemporary:
   case SK_ExtraneousCopyToTemporary:
   case SK_UserConversion:
   case SK_QualificationConversionRValue:
+  case SK_QualificationConversionXValue:
   case SK_QualificationConversionLValue:
   case SK_ListInitialization:
   case SK_ConstructorInitialization:
   case SK_ZeroInitialization:
   case SK_CAssignment:
   case SK_StringInit:
+  case SK_ObjCObjectConversion:
     break;
     
   case SK_ConversionSequence:
@@ -2030,6 +2064,7 @@
   case FK_ReferenceBindingToInitList:
   case FK_InitListBadDestinationType:
   case FK_DefaultInitOfConst:
+  case FK_Incomplete:
     return false;
     
   case FK_ReferenceInitOverloadFailed:
@@ -2057,9 +2092,14 @@
 }
 
 void InitializationSequence::AddDerivedToBaseCastStep(QualType BaseType, 
-                                                      bool IsLValue) {
+                                                      ExprValueKind VK) {
   Step S;
-  S.Kind = IsLValue? SK_CastDerivedToBaseLValue : SK_CastDerivedToBaseRValue;
+  switch (VK) {
+  case VK_RValue: S.Kind = SK_CastDerivedToBaseRValue; break;
+  case VK_XValue: S.Kind = SK_CastDerivedToBaseXValue; break;
+  case VK_LValue: S.Kind = SK_CastDerivedToBaseLValue; break;
+  default: llvm_unreachable("No such category");
+  }
   S.Type = BaseType;
   Steps.push_back(S);
 }
@@ -2091,10 +2131,20 @@
 }
 
 void InitializationSequence::AddQualificationConversionStep(QualType Ty,
-                                                            bool IsLValue) {
+                                                            ExprValueKind VK) {
   Step S;
-  S.Kind = IsLValue? SK_QualificationConversionLValue 
-                   : SK_QualificationConversionRValue;
+  S.Kind = SK_QualificationConversionRValue; // work around a gcc warning
+  switch (VK) {
+  case VK_RValue:
+    S.Kind = SK_QualificationConversionRValue;
+    break;
+  case VK_XValue:
+    S.Kind = SK_QualificationConversionXValue;
+    break;
+  case VK_LValue:
+    S.Kind = SK_QualificationConversionLValue;
+    break;
+  }
   S.Type = Ty;
   Steps.push_back(S);
 }
@@ -2150,6 +2200,13 @@
   Steps.push_back(S);
 }
 
+void InitializationSequence::AddObjCObjectConversionStep(QualType T) {
+  Step S;
+  S.Kind = SK_ObjCObjectConversion;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
 void InitializationSequence::SetOverloadFailure(FailureKind Failure, 
                                                 OverloadingResult Result) {
   SequenceKind = FailedSequence;
@@ -2170,7 +2227,7 @@
   // 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
+  // well-formed. When 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);
@@ -2211,8 +2268,6 @@
 
 /// \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,
@@ -2226,10 +2281,13 @@
   QualType T2 = cv2T2.getUnqualifiedType();
 
   bool DerivedToBase;
+  bool ObjCConversion;
   assert(!S.CompareReferenceRelationship(Initializer->getLocStart(), 
-                                         T1, T2, DerivedToBase) &&
+                                         T1, T2, DerivedToBase,
+                                         ObjCConversion) &&
          "Must have incompatible references when binding via conversion");
   (void)DerivedToBase;
+  (void)ObjCConversion;
 
   // Build the candidate set directly in the initialization sequence
   // structure, so that it will persist if we fail.
@@ -2241,16 +2299,14 @@
   bool AllowExplicit = Kind.getKind() == InitializationKind::IK_Direct;
   
   const RecordType *T1RecordType = 0;
-  if (AllowRValues && (T1RecordType = T1->getAs<RecordType>())) {
+  if (AllowRValues && (T1RecordType = T1->getAs<RecordType>()) &&
+      !S.RequireCompleteType(Kind.getLocation(), T1, 0)) {
     // 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);
+    for (llvm::tie(Con, ConEnd) = S.LookupConstructors(T1RecordDecl);
          Con != ConEnd; ++Con) {
       NamedDecl *D = *Con;
       DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
@@ -2276,8 +2332,12 @@
       }
     }    
   }
+  if (T1RecordType && T1RecordType->getDecl()->isInvalidDecl())
+    return OR_No_Viable_Function;
   
-  if (const RecordType *T2RecordType = T2->getAs<RecordType>()) {
+  const RecordType *T2RecordType = 0;
+  if ((T2RecordType = T2->getAs<RecordType>()) &&
+      !S.RequireCompleteType(Kind.getLocation(), T2, 0)) {
     // The type we're converting from is a class type, enumerate its conversion
     // functions.
     CXXRecordDecl *T2RecordDecl = cast<CXXRecordDecl>(T2RecordType->getDecl());
@@ -2301,7 +2361,7 @@
       if (ConvTemplate)
         Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
       else
-        Conv = cast<CXXConversionDecl>(*I);
+        Conv = cast<CXXConversionDecl>(D);
       
       // If the conversion function doesn't return a reference type,
       // it can't be considered for this conversion unless we're allowed to
@@ -2321,13 +2381,15 @@
       }
     }
   }
+  if (T2RecordType && T2RecordType->getDecl()->isInvalidDecl())
+    return OR_No_Viable_Function;
   
   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))
+        = CandidateSet.BestViableFunction(S, DeclLoc, Best))
     return Result;
 
   FunctionDecl *Function = Best->Function;
@@ -2340,14 +2402,22 @@
 
   // Add the user-defined conversion step.
   Sequence.AddUserConversionStep(Function, Best->FoundDecl,
-                                 T2.getNonReferenceType());
+                                 T2.getNonLValueExprType(S.Context));
 
   // Determine whether we need to perform derived-to-base or 
   // cv-qualification adjustments.
+  ExprValueKind VK = VK_RValue;
+  if (T2->isLValueReferenceType())
+    VK = VK_LValue;
+  else if (const RValueReferenceType *RRef = T2->getAs<RValueReferenceType>())
+    VK = RRef->getPointeeType()->isFunctionType() ? VK_LValue : VK_XValue;
+
   bool NewDerivedToBase = false;
+  bool NewObjCConversion = false;
   Sema::ReferenceCompareResult NewRefRelationship
-    = S.CompareReferenceRelationship(DeclLoc, T1, T2.getNonReferenceType(),
-                                     NewDerivedToBase);
+    = S.CompareReferenceRelationship(DeclLoc, T1, 
+                                     T2.getNonLValueExprType(S.Context),
+                                     NewDerivedToBase, NewObjCConversion);
   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
@@ -2362,23 +2432,27 @@
     Sequence.AddDerivedToBaseCastStep(
                                 S.Context.getQualifiedType(T1,
                                   T2.getNonReferenceType().getQualifiers()), 
-                                  /*isLValue=*/true);
-  
+                                      VK);
+  else if (NewObjCConversion)
+    Sequence.AddObjCObjectConversionStep(
+                                S.Context.getQualifiedType(T1,
+                                  T2.getNonReferenceType().getQualifiers()));
+
   if (cv1T1.getQualifiers() != T2.getNonReferenceType().getQualifiers())
-    Sequence.AddQualificationConversionStep(cv1T1, T2->isReferenceType());
+    Sequence.AddQualificationConversionStep(cv1T1, VK);
   
   Sequence.AddReferenceBindingStep(cv1T1, !T2->isReferenceType());
   return OR_Success;
 }
   
-/// \brief Attempt reference initialization (C++0x [dcl.init.list]) 
+/// \brief Attempt reference initialization (C++0x [dcl.init.ref]) 
 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;
@@ -2387,7 +2461,7 @@
   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.
@@ -2401,29 +2475,35 @@
       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);
+  bool ObjCConversion = false;
+  Expr::Classification InitCategory = Initializer->Classify(S.Context);
   Sema::ReferenceCompareResult RefRelationship
-    = S.CompareReferenceRelationship(DeclLoc, cv1T1, cv2T2, DerivedToBase);
-  
+    = S.CompareReferenceRelationship(DeclLoc, cv1T1, cv2T2, DerivedToBase,
+                                     ObjCConversion);
+
   // 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
+  // Note the analogous bullet points for rvlaue refs to functions. Because
+  // there are no function rvalues in C++, rvalue refs to functions are treated
+  // like lvalue refs.
   OverloadingResult ConvOvlResult = OR_Success;
-  if (isLValueRef) {
-    if (InitLvalue == Expr::LV_Valid && 
+  bool T1Function = T1->isFunctionType();
+  if (isLValueRef || T1Function) {
+    if (InitCategory.isLValue() && 
         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
@@ -2436,9 +2516,13 @@
       if (DerivedToBase)
         Sequence.AddDerivedToBaseCastStep(
                          S.Context.getQualifiedType(T1, T2Quals), 
-                         /*isLValue=*/true);
+                         VK_LValue);
+      else if (ObjCConversion)
+        Sequence.AddObjCObjectConversionStep(
+                                     S.Context.getQualifiedType(T1, T2Quals));
+
       if (T1Quals != T2Quals)
-        Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/true);
+        Sequence.AddQualificationConversionStep(cv1T1, VK_LValue);
       bool BindingTemporary = T1Quals.hasConst() && !T1Quals.hasVolatile() &&
         (Initializer->getBitField() || Initializer->refersToVectorElement());
       Sequence.AddReferenceBindingStep(cv1T1, BindingTemporary);
@@ -2451,10 +2535,13 @@
     //       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()) {
+    // If we have an rvalue ref to function type here, the rhs must be
+    // an rvalue.
+    if (RefRelationship == Sema::Ref_Incompatible && T2->isRecordType() &&
+        (isLValueRef || InitCategory.isRValue())) {
       ConvOvlResult = TryRefInitWithConversionFunction(S, Entity, Kind, 
                                                        Initializer,
-                                                       /*AllowRValues=*/false,
+                                                   /*AllowRValues=*/isRValueRef,
                                                        Sequence);
       if (ConvOvlResult == OR_Success)
         return;
@@ -2465,19 +2552,20 @@
       }
     }
   }
-  
+
   //     - 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.
+  //       be an rvalue or have a function type.
+  // We handled the function type stuff above.
   if (!((isLValueRef && T1Quals.hasConst() && !T1Quals.hasVolatile()) ||
-        (isRValueRef && InitLvalue != Expr::LV_Valid))) {
+        (isRValueRef && InitCategory.isRValue()))) {
     if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty())
       Sequence.SetOverloadFailure(
                         InitializationSequence::FK_ReferenceInitOverloadFailed,
                                   ConvOvlResult);
     else if (isLValueRef)
-      Sequence.SetFailed(InitLvalue == Expr::LV_Valid
+      Sequence.SetFailed(InitCategory.isLValue()
         ? (RefRelationship == Sema::Ref_Related
              ? InitializationSequence::FK_ReferenceInitDropsQualifiers
              : InitializationSequence::FK_NonConstLValueReferenceBindingToUnrelated)
@@ -2485,15 +2573,16 @@
     else
       Sequence.SetFailed(
                     InitializationSequence::FK_RValueReferenceBindingToLValue);
-    
+
     return;
   }
-  
-  //       - If T1 and T2 are class types and
-  if (T1->isRecordType() && T2->isRecordType()) {
+
+  //       - [If T1 is not a function type], if T2 is a class type and
+  if (!T1Function && T2->isRecordType()) {
+    bool isXValue = InitCategory.isXValue();
     //       - the initializer expression is an rvalue and "cv1 T1" is 
     //         reference-compatible with "cv2 T2", or
-    if (InitLvalue != Expr::LV_Valid && 
+    if (InitCategory.isRValue() && 
         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
@@ -2510,13 +2599,18 @@
       if (DerivedToBase)
         Sequence.AddDerivedToBaseCastStep(
                          S.Context.getQualifiedType(T1, T2Quals), 
-                         /*isLValue=*/false);
+                         isXValue ? VK_XValue : VK_RValue);
+      else if (ObjCConversion)
+        Sequence.AddObjCObjectConversionStep(
+                                     S.Context.getQualifiedType(T1, T2Quals));
+
       if (T1Quals != T2Quals)
-        Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/false);
-      Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true);
+        Sequence.AddQualificationConversionStep(cv1T1,
+                                            isXValue ? VK_XValue : VK_RValue);
+      Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/!isXValue);
       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
@@ -2549,15 +2643,17 @@
   //        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()) {
+
+  InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(cv1T1);
+
+  if (S.TryImplicitConversion(Sequence, TempEntity, Initializer,
+                              /*SuppressUserConversions*/ false,
+                              AllowExplicit,
+                              /*FIXME:InOverloadResolution=*/false)) {
     // 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
@@ -2582,8 +2678,6 @@
     return;
   }
 
-  // Perform the actual conversion.
-  Sequence.AddConversionSequenceStep(ICS, cv1T1);
   Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true);
   return;
 }
@@ -2623,7 +2717,7 @@
 
   // The type we're constructing needs to be complete.
   if (S.RequireCompleteType(Kind.getLocation(), DestType, 0)) {
-    Sequence.SetFailed(InitializationSequence::FK_ConversionFailed);
+    Sequence.SetFailed(InitializationSequence::FK_Incomplete);
     return;
   }
   
@@ -2634,11 +2728,8 @@
   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);
+  for (llvm::tie(Con, ConEnd) = S.LookupConstructors(DestRecordDecl);
        Con != ConEnd; ++Con) {
     NamedDecl *D = *Con;
     DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
@@ -2680,7 +2771,7 @@
   // Perform overload resolution. If it fails, return the failed result.  
   OverloadCandidateSet::iterator Best;
   if (OverloadingResult Result 
-        = S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
+        = CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
     Sequence.SetOverloadFailure(
                           InitializationSequence::FK_ConstructorOverloadFailed, 
                                 Result);
@@ -2736,9 +2827,8 @@
       //    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()) {
+      if ((ClassDecl->getTagKind() == TTK_Class ||
+           ClassDecl->getTagKind() == TTK_Struct)) {
         Sequence.AddZeroInitializationStep(Entity.getType());
         return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence);        
       }
@@ -2767,8 +2857,8 @@
   //       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);
+    TryConstructorInitialization(S, Entity, Kind, 0, 0, DestType, Sequence);
+    return;
   }
   
   //     - otherwise, no initialization is performed.
@@ -2814,15 +2904,11 @@
     
     // 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);
+      for (llvm::tie(Con, ConEnd) = S.LookupConstructors(DestRecordDecl);
            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;
@@ -2831,17 +2917,8 @@
         if (ConstructorTmpl)
           Constructor = cast<CXXConstructorDecl>(
                                            ConstructorTmpl->getTemplatedDecl());
-        else {
+        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)) {
@@ -2849,11 +2926,11 @@
             S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
                                            /*ExplicitArgs*/ 0,
                                            &Initializer, 1, CandidateSet,
-                                           SuppressUserConversions);
+                                           /*SuppressUserConversions=*/true);
           else
             S.AddOverloadCandidate(Constructor, FoundDecl,
                                    &Initializer, 1, CandidateSet,
-                                   SuppressUserConversions);
+                                   /*SuppressUserConversions=*/true);
         }
       }    
     }
@@ -2904,7 +2981,7 @@
   // Perform overload resolution. If it fails, return the failed result.  
   OverloadCandidateSet::iterator Best;
   if (OverloadingResult Result
-        = S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
+        = CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
     Sequence.SetOverloadFailure(
                         InitializationSequence::FK_UserConversionOverloadFailed, 
                                 Result);
@@ -2921,7 +2998,7 @@
   }
 
   // Add the user-defined conversion step that calls the conversion function.
-  QualType ConvType = Function->getResultType().getNonReferenceType();
+  QualType ConvType = Function->getCallResultType();
   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
@@ -2946,27 +3023,6 @@
   }
 }
 
-/// \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,
@@ -3098,8 +3154,13 @@
   //      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);
+  if (S.TryImplicitConversion(*this, Entity, Initializer,
+                              /*SuppressUserConversions*/ true,
+                              /*AllowExplicitConversions*/ false,
+                              /*InOverloadResolution*/ false))
+    SetFailed(InitializationSequence::FK_ConversionFailed);
+  else
+    setSequenceKind(StandardConversion);
 }
 
 InitializationSequence::~InitializationSequence() {
@@ -3141,6 +3202,7 @@
   case InitializedEntity::EK_Member:
   case InitializedEntity::EK_ArrayElement:
   case InitializedEntity::EK_VectorElement:
+  case InitializedEntity::EK_BlockElement:
     return Sema::AA_Initializing;
   }
 
@@ -3159,6 +3221,7 @@
   case InitializedEntity::EK_Base:
   case InitializedEntity::EK_VectorElement:
   case InitializedEntity::EK_Exception:
+  case InitializedEntity::EK_BlockElement:
     return false;
     
   case InitializedEntity::EK_Parameter:
@@ -3178,6 +3241,7 @@
     case InitializedEntity::EK_New:
     case InitializedEntity::EK_Base:
     case InitializedEntity::EK_VectorElement:
+    case InitializedEntity::EK_BlockElement:
       return false;
       
     case InitializedEntity::EK_Variable:
@@ -3211,10 +3275,10 @@
 /// \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,
+static ExprResult CopyObject(Sema &S,
                                          QualType T,
                                          const InitializedEntity &Entity,
-                                         Sema::OwningExprResult CurInit,
+                                         ExprResult CurInit,
                                          bool IsExtraneousCopy) {
   // Determine which class type we're copying to.
   Expr *CurInitExpr = (Expr *)CurInit.get();
@@ -3236,9 +3300,9 @@
   //       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.
+  // elision for return statements and throw expressions are 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;
@@ -3262,6 +3326,7 @@
   case InitializedEntity::EK_New:
   case InitializedEntity::EK_Base:
   case InitializedEntity::EK_VectorElement:
+  case InitializedEntity::EK_BlockElement:
     Loc = CurInitExpr->getLocStart();
     break;
   }
@@ -3271,12 +3336,9 @@
     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);
+  for (llvm::tie(Con, ConEnd) = S.LookupConstructors(Class);
        Con != ConEnd; ++Con) {
     // Only consider copy constructors.
     CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(*Con);
@@ -3292,25 +3354,27 @@
   }
   
   OverloadCandidateSet::iterator Best;
-  switch (S.BestViableFunction(CandidateSet, Loc, Best)) {
+  switch (CandidateSet.BestViableFunction(S, Loc, Best)) {
   case OR_Success:
     break;
       
   case OR_No_Viable_Function:
-    S.Diag(Loc, diag::err_temp_copy_no_viable)
+    S.Diag(Loc, IsExtraneousCopy && !S.isSFINAEContext()
+           ? diag::ext_rvalue_to_reference_temp_copy_no_viable
+           : diag::err_temp_copy_no_viable)
       << (int)Entity.getKind() << CurInitExpr->getType()
       << CurInitExpr->getSourceRange();
-    S.PrintOverloadCandidates(CandidateSet, Sema::OCD_AllCandidates,
-                              &CurInitExpr, 1);
-    return S.ExprError();
+    CandidateSet.NoteCandidates(S, OCD_AllCandidates, &CurInitExpr, 1);
+    if (!IsExtraneousCopy || S.isSFINAEContext())
+      return ExprError();
+    return move(CurInit);
       
   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();
+    CandidateSet.NoteCandidates(S, OCD_ViableCandidates, &CurInitExpr, 1);
+    return ExprError();
     
   case OR_Deleted:
     S.Diag(Loc, diag::err_temp_copy_deleted)
@@ -3318,15 +3382,15 @@
       << CurInitExpr->getSourceRange();
     S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
       << Best->Function->isDeleted();
-    return S.ExprError();
+    return ExprError();
   }
 
   CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Best->Function);
-  ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+  ASTOwningVector<Expr*> ConstructorArgs(S);
   CurInit.release(); // Ownership transferred into MultiExprArg, below.
 
   S.CheckConstructorAccess(Loc, Constructor, Entity,
-                           Best->FoundDecl.getAccess());
+                           Best->FoundDecl.getAccess(), IsExtraneousCopy);
 
   if (IsExtraneousCopy) {
     // If this is a totally extraneous copy for C++03 reference
@@ -3357,16 +3421,15 @@
   // 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),
+  if (S.CompleteConstructorCall(Constructor, MultiExprArg(&CurInitExpr, 1),
                                 Loc, ConstructorArgs))
-    return S.ExprError();
+    return ExprError();
 
   // Actually perform the constructor call.
   CurInit = S.BuildCXXConstructExpr(Loc, T, Constructor, Elidable,
-                                    move_arg(ConstructorArgs));
+                                    move_arg(ConstructorArgs),
+                                    /*ZeroInit*/ false,
+                                    CXXConstructExpr::CK_Complete);
   
   // If we're supposed to bind temporaries, do so.
   if (!CurInit.isInvalid() && shouldBindAsTemporary(Entity))
@@ -3388,16 +3451,16 @@
   }
 }
 
-Action::OwningExprResult 
+ExprResult 
 InitializationSequence::Perform(Sema &S,
                                 const InitializedEntity &Entity,
                                 const InitializationKind &Kind,
-                                Action::MultiExprArg Args,
+                                MultiExprArg Args,
                                 QualType *ResultType) {
   if (SequenceKind == FailedSequence) {
     unsigned NumArgs = Args.size();
     Diagnose(S, Entity, Kind, (Expr **)Args.release(), NumArgs);
-    return S.ExprError();
+    return ExprError();
   }
   
   if (SequenceKind == DependentSequence) {
@@ -3441,7 +3504,7 @@
     }
 
     if (Kind.getKind() == InitializationKind::IK_Copy || Kind.isExplicitCast())
-      return Sema::OwningExprResult(S, Args.release()[0]);
+      return ExprResult(Args.release()[0]);
 
     if (Args.size() == 0)
       return S.Owned((Expr *)0);
@@ -3465,7 +3528,7 @@
     *ResultType = Entity.getDecl() ? Entity.getDecl()->getType() :
                                      Entity.getType();
 
-  Sema::OwningExprResult CurInit = S.Owned((Expr *)0);
+  ExprResult CurInit = S.Owned((Expr *)0);
   
   assert(!Steps.empty() && "Cannot have an empty initialization sequence");
   
@@ -3475,21 +3538,24 @@
   switch (Steps.front().Kind) {
   case SK_ResolveAddressOfOverloadedFunction:
   case SK_CastDerivedToBaseRValue:
+  case SK_CastDerivedToBaseXValue:
   case SK_CastDerivedToBaseLValue:
   case SK_BindReference:
   case SK_BindReferenceToTemporary:
   case SK_ExtraneousCopyToTemporary:
   case SK_UserConversion:
   case SK_QualificationConversionLValue:
+  case SK_QualificationConversionXValue:
   case SK_QualificationConversionRValue:
   case SK_ConversionSequence:
   case SK_ListInitialization:
   case SK_CAssignment:
   case SK_StringInit:
+  case SK_ObjCObjectConversion:
     assert(Args.size() == 1);
-    CurInit = Sema::OwningExprResult(S, ((Expr **)(Args.get()))[0]->Retain());
+    CurInit = ExprResult(((Expr **)(Args.get()))[0]->Retain());
     if (CurInit.isInvalid())
-      return S.ExprError();
+      return ExprError();
     break;
     
   case SK_ConstructorInitialization:
@@ -3503,7 +3569,7 @@
   for (step_iterator Step = step_begin(), StepEnd = step_end();
        Step != StepEnd; ++Step) {
     if (CurInit.isInvalid())
-      return S.ExprError();
+      return ExprError();
     
     Expr *CurInitExpr = (Expr *)CurInit.get();
     QualType SourceType = CurInitExpr? CurInitExpr->getType() : QualType();
@@ -3513,17 +3579,19 @@
       // Overload resolution determined which function invoke; update the 
       // initializer to reflect that choice.
       S.CheckAddressOfMemberAccess(CurInitExpr, Step->Function.FoundDecl);
+      S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Kind.getLocation());
       CurInit = S.FixOverloadedFunctionReference(move(CurInit),
                                                  Step->Function.FoundDecl,
                                                  Step->Function.Function);
       break;
         
     case SK_CastDerivedToBaseRValue:
+    case SK_CastDerivedToBaseXValue:
     case SK_CastDerivedToBaseLValue: {
       // We have a derived-to-base cast that produces either an rvalue or an
       // lvalue. Perform that cast.
       
-      CXXBaseSpecifierArray BasePath;
+      CXXCastPath BasePath;
 
       // Casts to inaccessible base classes are allowed with C-style casts.
       bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast();
@@ -3531,13 +3599,28 @@
                                          CurInitExpr->getLocStart(),
                                          CurInitExpr->getSourceRange(), 
                                          &BasePath, IgnoreBaseAccess))
-        return S.ExprError();
+        return ExprError();
         
-      CurInit = S.Owned(new (S.Context) ImplicitCastExpr(Step->Type,
-                                                    CastExpr::CK_DerivedToBase,
-                                                    (Expr*)CurInit.release(),
-                                                    BasePath,
-                                     Step->Kind == SK_CastDerivedToBaseLValue));
+      if (S.BasePathInvolvesVirtualBase(BasePath)) {
+        QualType T = SourceType;
+        if (const PointerType *Pointer = T->getAs<PointerType>())
+          T = Pointer->getPointeeType();
+        if (const RecordType *RecordTy = T->getAs<RecordType>())
+          S.MarkVTableUsed(CurInitExpr->getLocStart(), 
+                           cast<CXXRecordDecl>(RecordTy->getDecl()));
+      }
+
+      ExprValueKind VK =
+          Step->Kind == SK_CastDerivedToBaseLValue ?
+              VK_LValue :
+              (Step->Kind == SK_CastDerivedToBaseXValue ?
+                   VK_XValue :
+                   VK_RValue);
+      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
+                                                 Step->Type,
+                                                 CK_DerivedToBase,
+                                                 CurInit.get(),
+                                                 &BasePath, VK));
       break;
     }
         
@@ -3549,7 +3632,7 @@
           << BitField->getDeclName()
           << CurInitExpr->getSourceRange();
         S.Diag(BitField->getLocation(), diag::note_bitfield_decl);
-        return S.ExprError();
+        return ExprError();
       }
 
       if (CurInitExpr->refersToVectorElement()) {
@@ -3558,14 +3641,14 @@
           << Entity.getType().isVolatileQualified()
           << CurInitExpr->getSourceRange();
         PrintInitLocationNote(S, Entity);
-        return S.ExprError();
+        return ExprError();
       }
         
       // Reference binding does not have any corresponding ASTs.
 
       // Check exception specifications
       if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType))
-        return S.ExprError();
+        return ExprError();
 
       break;
 
@@ -3574,7 +3657,7 @@
 
       // Check exception specifications
       if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType))
-        return S.ExprError();
+        return ExprError();
 
       break;
         
@@ -3586,7 +3669,7 @@
     case SK_UserConversion: {
       // We have a user-defined conversion that invokes either a constructor
       // or a conversion function.
-      CastExpr::CastKind CastKind = CastExpr::CK_Unknown;
+      CastKind CastKind = CK_Unknown;
       bool IsCopy = false;
       FunctionDecl *Fn = Step->Function.Function;
       DeclAccessPair FoundFn = Step->Function.FoundDecl;
@@ -3594,29 +3677,30 @@
       bool IsLvalue = false;
       if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Fn)) {
         // Build a call to the selected constructor.
-        ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+        ASTOwningVector<Expr*> 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),
+                                      MultiExprArg(&CurInitExpr, 1),
                                       Loc, ConstructorArgs))
-          return S.ExprError();
+          return ExprError();
         
         // Build the an expression that constructs a temporary.
         CurInit = S.BuildCXXConstructExpr(Loc, Step->Type, Constructor, 
-                                          move_arg(ConstructorArgs));
+                                          move_arg(ConstructorArgs),
+                                          /*ZeroInit*/ false,
+                                          CXXConstructExpr::CK_Complete);
         if (CurInit.isInvalid())
-          return S.ExprError();
+          return ExprError();
 
         S.CheckConstructorAccess(Kind.getLocation(), Constructor, Entity,
                                  FoundFn.getAccess());
+        S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation());
         
-        CastKind = CastExpr::CK_ConstructorConversion;
+        CastKind = CK_ConstructorConversion;
         QualType Class = S.Context.getTypeDeclType(Constructor->getParent());
         if (S.Context.hasSameUnqualifiedType(SourceType, Class) ||
             S.IsDerivedFrom(SourceType, Class))
@@ -3629,13 +3713,14 @@
         IsLvalue = Conversion->getResultType()->isLValueReferenceType();
         S.CheckMemberOperatorAccess(Kind.getLocation(), CurInitExpr, 0,
                                     FoundFn);
+        S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation());
         
         // 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();
+          return ExprError();
 
         // Do a little dance to make sure that CurInit has the proper
         // pointer.
@@ -3645,9 +3730,9 @@
         CurInit = S.Owned(S.BuildCXXMemberCallExpr(CurInitExpr, FoundFn,
                                                    Conversion));
         if (CurInit.isInvalid() || !CurInit.get())
-          return S.ExprError();
+          return ExprError();
         
-        CastKind = CastExpr::CK_UserDefinedConversion;
+        CastKind = CK_UserDefinedConversion;
         
         CreatedObject = Conversion->getResultType()->isRecordType();
       }
@@ -3660,8 +3745,8 @@
         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);
+          CXXDestructorDecl *Destructor 
+            = S.LookupDestructor(cast<CXXRecordDecl>(Record->getDecl()));
           S.CheckDestructorAccess(CurInitExpr->getLocStart(), Destructor, 
                                   S.PDiag(diag::err_access_dtor_temp) << T);
           S.MarkDeclarationReferenced(CurInitExpr->getLocStart(), Destructor);
@@ -3669,35 +3754,41 @@
       }
       
       CurInitExpr = CurInit.takeAs<Expr>();
-      CurInit = S.Owned(new (S.Context) ImplicitCastExpr(CurInitExpr->getType(),
-                                                         CastKind, 
-                                                         CurInitExpr,
-                                                        CXXBaseSpecifierArray(),
-                                                         IsLvalue));
+      // FIXME: xvalues
+      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
+                                                 CurInitExpr->getType(),
+                                                 CastKind, CurInitExpr, 0,
+                                           IsLvalue ? VK_LValue : VK_RValue));
       
       if (RequiresCopy)
         CurInit = CopyObject(S, Entity.getType().getNonReferenceType(), Entity,
                              move(CurInit), /*IsExtraneousCopy=*/false);
-      
+
       break;
     }
-        
+
     case SK_QualificationConversionLValue:
-    case SK_QualificationConversionRValue:
+    case SK_QualificationConversionXValue:
+    case SK_QualificationConversionRValue: {
       // Perform a qualification conversion; these can never go wrong.
-      S.ImpCastExprToType(CurInitExpr, Step->Type,
-                          CastExpr::CK_NoOp,
-                          Step->Kind == SK_QualificationConversionLValue);
+      ExprValueKind VK =
+          Step->Kind == SK_QualificationConversionLValue ?
+              VK_LValue :
+              (Step->Kind == SK_QualificationConversionXValue ?
+                   VK_XValue :
+                   VK_RValue);
+      S.ImpCastExprToType(CurInitExpr, Step->Type, CK_NoOp, VK);
       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();
+        return ExprError();
         
       CurInit.release();
       CurInit = S.Owned(CurInitExpr);
@@ -3708,7 +3799,7 @@
       InitListExpr *InitList = cast<InitListExpr>(CurInitExpr);
       QualType Ty = Step->Type;
       if (S.CheckInitList(Entity, InitList, ResultType? *ResultType : Ty))
-        return S.ExprError();
+        return ExprError();
 
       CurInit.release();
       CurInit = S.Owned(InitList);
@@ -3719,18 +3810,31 @@
       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();
-          
+      ASTOwningVector<Expr*> ConstructorArgs(S);
+      SourceLocation Loc = (Kind.isCopyInit() && Kind.getEqualLoc().isValid())
+                             ? Kind.getEqualLoc()
+                             : Kind.getLocation();
+
+      if (Kind.getKind() == InitializationKind::IK_Default) {
+        // Force even a trivial, implicit default constructor to be
+        // semantically checked. We do this explicitly because we don't build
+        // the definition for completely trivial constructors.
+        CXXRecordDecl *ClassDecl = Constructor->getParent();
+        assert(ClassDecl && "No parent class for constructor.");
+        if (Constructor->isImplicit() && Constructor->isDefaultConstructor() &&
+            ClassDecl->hasTrivialConstructor() && !Constructor->isUsed(false))
+          S.DefineImplicitDefaultConstructor(Loc, Constructor);
+      }
+
       // Determine the arguments required to actually perform the constructor
       // call.
       if (S.CompleteConstructorCall(Constructor, move(Args), 
                                     Loc, ConstructorArgs))
-        return S.ExprError();
+        return 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 ||
@@ -3738,26 +3842,47 @@
         // An explicitly-constructed temporary, e.g., X(1, 2).
         unsigned NumExprs = ConstructorArgs.size();
         Expr **Exprs = (Expr **)ConstructorArgs.take();
-        S.MarkDeclarationReferenced(Kind.getLocation(), Constructor);
+        S.MarkDeclarationReferenced(Loc, Constructor);
         CurInit = S.Owned(new (S.Context) CXXTemporaryObjectExpr(S.Context,
                                                                  Constructor,
                                                               Entity.getType(),
-                                                            Kind.getLocation(),
+                                                                 Loc,
                                                                  Exprs, 
                                                                  NumExprs,
-                                                Kind.getParenRange().getEnd()));
-      } else
-        CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
-                                          Constructor, 
-                                          move_arg(ConstructorArgs),
-                                          ConstructorInitRequiresZeroInit,
-                               Entity.getKind() == InitializedEntity::EK_Base);
+                                                Kind.getParenRange().getEnd(),
+                                             ConstructorInitRequiresZeroInit));
+      } else {
+        CXXConstructExpr::ConstructionKind ConstructKind =
+          CXXConstructExpr::CK_Complete;
+        
+        if (Entity.getKind() == InitializedEntity::EK_Base) {
+          ConstructKind = Entity.getBaseSpecifier()->isVirtual() ?
+            CXXConstructExpr::CK_VirtualBase : 
+            CXXConstructExpr::CK_NonVirtualBase;
+        }    
+        
+        // If the entity allows NRVO, mark the construction as elidable
+        // unconditionally.
+        if (Entity.allowsNRVO())
+          CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
+                                            Constructor, /*Elidable=*/true,
+                                            move_arg(ConstructorArgs),
+                                            ConstructorInitRequiresZeroInit,
+                                            ConstructKind);
+        else
+          CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
+                                            Constructor, 
+                                            move_arg(ConstructorArgs),
+                                            ConstructorInitRequiresZeroInit,
+                                            ConstructKind);
+      }
       if (CurInit.isInvalid())
-        return S.ExprError();
+        return ExprError();
 
       // Only check access if all of that succeeded.
       S.CheckConstructorAccess(Loc, Constructor, Entity,
                                Step->Function.FoundDecl.getAccess());
+      S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Loc);
       
       if (shouldBindAsTemporary(Entity))
         CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
@@ -3776,7 +3901,7 @@
       } else if (Kind.getKind() == InitializationKind::IK_Value &&
                  S.getLangOptions().CPlusPlus &&
                  !Kind.isImplicitValueInit()) {
-        CurInit = S.Owned(new (S.Context) CXXZeroInitValueExpr(Step->Type,
+        CurInit = S.Owned(new (S.Context) CXXScalarValueInitExpr(Step->Type,
                                                    Kind.getRange().getBegin(),
                                                     Kind.getRange().getEnd()));
       } else {
@@ -3804,7 +3929,7 @@
                                      getAssignmentAction(Entity),
                                      &Complained)) {
         PrintInitLocationNote(S, Entity);
-        return S.ExprError();
+        return ExprError();
       } else if (Complained)
         PrintInitLocationNote(S, Entity);
 
@@ -3818,6 +3943,14 @@
       CheckStringInit(CurInitExpr, ResultType ? *ResultType : Ty, S);
       break;
     }
+
+    case SK_ObjCObjectConversion:
+      S.ImpCastExprToType(CurInitExpr, Step->Type, 
+                          CK_ObjCObjectLValueCast,
+                          S.CastCategory(CurInitExpr));
+      CurInit.release();
+      CurInit = S.Owned(CurInitExpr);
+      break;
     }
   }
   
@@ -3874,16 +4007,14 @@
           << DestType << Args[0]->getType()
           << Args[0]->getSourceRange();
 
-      S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_ViableCandidates,
-                                Args, NumArgs);
+      FailedCandidateSet.NoteCandidates(S, 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);
+      FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args, NumArgs);
       break;
         
     case OR_Deleted: {
@@ -3891,9 +4022,8 @@
         << Args[0]->getType() << DestType.getNonReferenceType()
         << Args[0]->getSourceRange();
       OverloadCandidateSet::iterator Best;
-      OverloadingResult Ovl = S.BestViableFunction(FailedCandidateSet,
-                                                   Kind.getLocation(),
-                                                   Best);
+      OverloadingResult Ovl
+        = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
       if (Ovl == OR_Deleted) {
         S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
           << Best->Function->isDeleted();
@@ -3986,8 +4116,8 @@
       case OR_Ambiguous:
         S.Diag(Kind.getLocation(), diag::err_ovl_ambiguous_init)
           << DestType << ArgsRange;
-        S.PrintOverloadCandidates(FailedCandidateSet,
-                                  Sema::OCD_ViableCandidates, Args, NumArgs);
+        FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates,
+                                          Args, NumArgs);
         break;
         
       case OR_No_Viable_Function:
@@ -4032,17 +4162,15 @@
 
         S.Diag(Kind.getLocation(), diag::err_ovl_no_viable_function_in_init)
           << DestType << ArgsRange;
-        S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_AllCandidates,
-                                  Args, NumArgs);
+        FailedCandidateSet.NoteCandidates(S, 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);
+        OverloadingResult Ovl
+          = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
         if (Ovl == OR_Deleted) {
           S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
             << Best->Function->isDeleted();
@@ -4078,6 +4206,11 @@
         << DestType << (bool)DestType->getAs<RecordType>();
     }
     break;
+      
+    case FK_Incomplete:
+      S.RequireCompleteType(Kind.getLocation(), DestType, 
+                            diag::err_init_incomplete_type);
+      break;      
   }
   
   PrintInitLocationNote(S, Entity);
@@ -4156,6 +4289,10 @@
     case FK_DefaultInitOfConst:
       OS << "default initialization of a const variable";
       break;
+        
+    case FK_Incomplete:
+      OS << "initialization of incomplete type";
+      break;
     }   
     OS << '\n';
     return;
@@ -4216,6 +4353,10 @@
       OS << "derived-to-base case (rvalue" << S->Type.getAsString() << ")";
       break;
       
+    case SK_CastDerivedToBaseXValue:
+      OS << "derived-to-base case (xvalue" << S->Type.getAsString() << ")";
+      break;
+      
     case SK_CastDerivedToBaseLValue:
       OS << "derived-to-base case (lvalue" << S->Type.getAsString() << ")";
       break;
@@ -4235,10 +4376,13 @@
     case SK_UserConversion:
       OS << "user-defined conversion via " << S->Function.Function;
       break;
-      
+
     case SK_QualificationConversionRValue:
       OS << "qualification conversion (rvalue)";
 
+    case SK_QualificationConversionXValue:
+      OS << "qualification conversion (xvalue)";
+
     case SK_QualificationConversionLValue:
       OS << "qualification conversion (lvalue)";
       break;
@@ -4268,6 +4412,10 @@
     case SK_StringInit:
       OS << "string initialization";
       break;
+
+    case SK_ObjCObjectConversion:
+      OS << "Objective-C object conversion";
+      break;
     }
   }
 }
@@ -4279,10 +4427,10 @@
 //===----------------------------------------------------------------------===//
 // Initialization helper functions
 //===----------------------------------------------------------------------===//
-Sema::OwningExprResult 
+ExprResult 
 Sema::PerformCopyInitialization(const InitializedEntity &Entity,
                                 SourceLocation EqualLoc,
-                                OwningExprResult Init) {
+                                ExprResult Init) {
   if (Init.isInvalid())
     return ExprError();
 
@@ -4296,6 +4444,5 @@
                                                            EqualLoc);
   InitializationSequence Seq(*this, Entity, Kind, &InitE, 1);
   Init.release();
-  return Seq.Perform(*this, Entity, Kind, 
-                     MultiExprArg(*this, (void**)&InitE, 1));
+  return Seq.Perform(*this, Entity, Kind, MultiExprArg(&InitE, 1));
 }
diff --git a/lib/Sema/SemaInit.h b/lib/Sema/SemaInit.h
deleted file mode 100644
index 5f2592f..0000000
--- a/lib/Sema/SemaInit.h
+++ /dev/null
@@ -1,741 +0,0 @@
-//===--- 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
index 1b2401a..bb267e3 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -11,8 +11,13 @@
 //  Objective-C++.
 //
 //===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/TemplateDeduction.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Decl.h"
@@ -21,9 +26,9 @@
 #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/DenseSet.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -35,6 +40,7 @@
 #include <algorithm>
 
 using namespace clang;
+using namespace sema;
 
 namespace {
   class UnqualUsingEntry {
@@ -100,7 +106,7 @@
                              End = S->using_directives_end();
           
           for (; I != End; ++I)
-            visit(I->getAs<UsingDirectiveDecl>(), InnermostFileDC);
+            visit(*I, InnermostFileDC);
         }
       }
     }
@@ -254,6 +260,12 @@
   case Sema::LookupObjCProtocolName:
     IDNS = Decl::IDNS_ObjCProtocol;
     break;
+      
+  case Sema::LookupAnyName:
+    IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member 
+      | Decl::IDNS_Using | Decl::IDNS_Namespace | Decl::IDNS_ObjCProtocol
+      | Decl::IDNS_Type;
+    break;
   }
   return IDNS;
 }
@@ -267,7 +279,7 @@
   // operators, make sure that the implicitly-declared new and delete
   // operators can be found.
   if (!isForRedeclaration()) {
-    switch (Name.getCXXOverloadedOperator()) {
+    switch (NameInfo.getName().getCXXOverloadedOperator()) {
     case OO_New:
     case OO_Delete:
     case OO_Array_New:
@@ -281,6 +293,22 @@
   }
 }
 
+#ifndef NDEBUG
+void LookupResult::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)));
+}
+#endif
+
 // Necessary because CXXBasePaths is not complete in Sema.h
 void LookupResult::deletePaths(CXXBasePaths *Paths) {
   delete Paths;
@@ -311,7 +339,8 @@
   if (ResultKind == Ambiguous) return;
 
   llvm::SmallPtrSet<NamedDecl*, 16> Unique;
-
+  llvm::SmallPtrSet<QualType, 16> UniqueTypes;
+  
   bool Ambiguous = false;
   bool HasTag = false, HasFunction = false, HasNonFunction = false;
   bool HasFunctionTemplate = false, HasUnresolved = false;
@@ -323,32 +352,49 @@
     NamedDecl *D = Decls[I]->getUnderlyingDecl();
     D = cast<NamedDecl>(D->getCanonicalDecl());
 
+    // Redeclarations of types via typedef can occur both within a scope
+    // and, through using declarations and directives, across scopes. There is
+    // no ambiguity if they all refer to the same type, so unique based on the
+    // canonical type.
+    if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
+      if (!TD->getDeclContext()->isRecord()) {
+        QualType T = SemaRef.Context.getTypeDeclType(TD);
+        if (!UniqueTypes.insert(SemaRef.Context.getCanonicalType(T))) {
+          // The type is not unique; pull something off the back and continue
+          // at this index.
+          Decls[I] = Decls[--N];
+          continue;
+        }
+      }
+    }
+    
     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.
+      continue;
+    } 
+    
+    // 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++;
+    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:
@@ -447,11 +493,118 @@
   return false;
 }
 
+/// \brief Determine whether we can declare a special member function within
+/// the class at this point.
+static bool CanDeclareSpecialMemberFunction(ASTContext &Context,
+                                            const CXXRecordDecl *Class) {
+  // Don't do it if the class is invalid.
+  if (Class->isInvalidDecl())
+    return false;
+  
+  // We need to have a definition for the class.
+  if (!Class->getDefinition() || Class->isDependentContext())
+    return false;
+  
+  // We can't be in the middle of defining the class.
+  if (const RecordType *RecordTy
+                        = Context.getTypeDeclType(Class)->getAs<RecordType>())
+    return !RecordTy->isBeingDefined();
+    
+  return false;
+}
+
+void Sema::ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class) {
+  if (!CanDeclareSpecialMemberFunction(Context, Class))
+    return;
+
+  // If the default constructor has not yet been declared, do so now.
+  if (!Class->hasDeclaredDefaultConstructor())
+    DeclareImplicitDefaultConstructor(Class);
+  
+  // If the copy constructor has not yet been declared, do so now.
+  if (!Class->hasDeclaredCopyConstructor())
+    DeclareImplicitCopyConstructor(Class);
+  
+  // If the copy assignment operator has not yet been declared, do so now.
+  if (!Class->hasDeclaredCopyAssignment())
+    DeclareImplicitCopyAssignment(Class);
+
+  // If the destructor has not yet been declared, do so now.
+  if (!Class->hasDeclaredDestructor())
+    DeclareImplicitDestructor(Class);  
+}
+
+/// \brief Determine whether this is the name of an implicitly-declared 
+/// special member function.
+static bool isImplicitlyDeclaredMemberFunctionName(DeclarationName Name) {
+  switch (Name.getNameKind()) {
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+    return true;
+    
+  case DeclarationName::CXXOperatorName:
+    return Name.getCXXOverloadedOperator() == OO_Equal;
+    
+  default:
+    break;      
+  }
+  
+  return false;
+}
+
+/// \brief If there are any implicit member functions with the given name
+/// that need to be declared in the given declaration context, do so.
+static void DeclareImplicitMemberFunctionsWithName(Sema &S, 
+                                                   DeclarationName Name,
+                                                   const DeclContext *DC) {
+  if (!DC)
+    return;
+  
+  switch (Name.getNameKind()) {
+  case DeclarationName::CXXConstructorName:
+    if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC))
+      if (Record->getDefinition() &&
+          CanDeclareSpecialMemberFunction(S.Context, Record)) {
+        if (!Record->hasDeclaredDefaultConstructor())
+          S.DeclareImplicitDefaultConstructor(
+                                           const_cast<CXXRecordDecl *>(Record));
+        if (!Record->hasDeclaredCopyConstructor())
+          S.DeclareImplicitCopyConstructor(const_cast<CXXRecordDecl *>(Record));
+      }
+    break;
+      
+  case DeclarationName::CXXDestructorName:
+    if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC))
+      if (Record->getDefinition() && !Record->hasDeclaredDestructor() &&
+          CanDeclareSpecialMemberFunction(S.Context, Record))
+        S.DeclareImplicitDestructor(const_cast<CXXRecordDecl *>(Record));
+    break;
+    
+  case DeclarationName::CXXOperatorName:
+    if (Name.getCXXOverloadedOperator() != OO_Equal)
+      break;
+    
+    if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC))
+      if (Record->getDefinition() && !Record->hasDeclaredCopyAssignment() &&
+          CanDeclareSpecialMemberFunction(S.Context, Record))
+        S.DeclareImplicitCopyAssignment(const_cast<CXXRecordDecl *>(Record));
+    break;
+    
+  default:
+    break;      
+  }
+}
+
 // 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;
 
+  // Lazily declare C++ special member functions.
+  if (S.getLangOptions().CPlusPlus)
+    DeclareImplicitMemberFunctionsWithName(S, R.getLookupName(), DC);
+  
+  // Perform lookup into this declaration context.
   DeclContext::lookup_const_iterator I, E;
   for (llvm::tie(I, E) = DC->lookup(R.getLookupName()); I != E; ++I) {
     NamedDecl *D = *I;
@@ -505,7 +658,7 @@
     // 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());
+    TemplateDeductionInfo Info(R.getSema().Context, R.getNameLoc());
     FunctionDecl *Specialization = 0;
     
     const FunctionProtoType *ConvProto        
@@ -640,6 +793,17 @@
 
   DeclarationName Name = R.getLookupName();
 
+  // If this is the name of an implicitly-declared special member function,
+  // go through the scope stack to implicitly declare
+  if (isImplicitlyDeclaredMemberFunctionName(Name)) {
+    for (Scope *PreS = S; PreS; PreS = PreS->getParent())
+      if (DeclContext *DC = static_cast<DeclContext *>(PreS->getEntity()))
+        DeclareImplicitMemberFunctionsWithName(*this, Name, DC);
+  }
+    
+  // Implicitly declare member functions with the name we're looking for, if in
+  // fact we are in a scope where it matters.
+
   Scope *Initial = S;
   IdentifierResolver::iterator
     I = IdResolver.begin(Name),
@@ -665,9 +829,11 @@
   //
   DeclContext *OutsideOfTemplateParamDC = 0;
   for (; S && !isNamespaceOrTranslationUnitScope(S); S = S->getParent()) {
+    DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity());
+
     // Check whether the IdResolver has anything in this scope.
     bool Found = false;
-    for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) {
+    for (; I != IEnd && S->isDeclScope(*I); ++I) {
       if (R.isAcceptableDecl(*I)) {
         Found = true;
         R.addDecl(*I);
@@ -675,10 +841,12 @@
     }
     if (Found) {
       R.resolveKind();
+      if (S->isClassScope())
+        if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(Ctx))
+          R.setNamingClass(Record);
       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
@@ -761,13 +929,9 @@
   // 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) {
+    for (; I != IEnd && S->isDeclScope(*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
@@ -778,23 +942,59 @@
       }
     }
 
-    // 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) {
+    if (Found && S->isTemplateParamScope()) {
       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;
+        
+        // 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 (!(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->isTransparentContext())
+          return false;
+      }
+    }
+
     if (R.isForRedeclaration() && Ctx && !Ctx->isTransparentContext())
       return false;
   }
@@ -867,7 +1067,7 @@
         if (NameKind == LookupRedeclarationWithLinkage) {
           // Determine whether this (or a previous) declaration is
           // out-of-scope.
-          if (!LeftStartingScope && !S->isDeclScope(DeclPtrTy::make(*I)))
+          if (!LeftStartingScope && !S->isDeclScope(*I))
             LeftStartingScope = true;
 
           // If we found something outside of our starting scope that
@@ -884,14 +1084,14 @@
 
           // Figure out what scope the identifier is in.
           while (!(S->getFlags() & Scope::DeclScope) ||
-                 !S->isDeclScope(DeclPtrTy::make(*I)))
+                 !S->isDeclScope(*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)))
+            if (!S->isDeclScope(*LastI))
               break;
             R.addDecl(*LastI);
           }
@@ -1027,6 +1227,17 @@
   return Found;
 }
 
+/// \brief Callback that looks for any member of a class with the given name.
+static bool LookupAnyMember(const CXXBaseSpecifier *Specifier, 
+                            CXXBasePath &Path,
+                            void *Name) {
+  RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
+  
+  DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
+  Path.Decls = BaseRecord->lookup(N);
+  return Path.Decls.first != Path.Decls.second;
+}
+
 /// \brief Perform qualified name lookup into a given context.
 ///
 /// Qualified name lookup (C++ [basic.lookup.qual]) is used to find
@@ -1091,7 +1302,7 @@
   // 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)
+  if (!LookupRec || !LookupRec->getDefinition())
     return false;
 
   // If we're performing qualified name lookup into a dependent class,
@@ -1122,6 +1333,10 @@
       BaseCallback = &CXXRecordDecl::FindTagMember;
       break;
 
+    case LookupAnyName:
+      BaseCallback = &LookupAnyMember;
+      break;
+      
     case LookupUsingDeclName:
       // This lookup is for redeclarations only.
       
@@ -1261,7 +1476,7 @@
     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))
+      if (!DC->isDependentContext() && RequireCompleteDeclContext(*SS, DC))
         return false;
 
       R.setContextRange(SS->getRange());
@@ -1380,25 +1595,42 @@
   return true;
 }
 
-static void
-addAssociatedClassesAndNamespaces(QualType T,
-                                  ASTContext &Context,
-                          Sema::AssociatedNamespaceSet &AssociatedNamespaces,
-                                  Sema::AssociatedClassSet &AssociatedClasses);
+namespace {
+  struct AssociatedLookup {
+    AssociatedLookup(Sema &S,
+                     Sema::AssociatedNamespaceSet &Namespaces,
+                     Sema::AssociatedClassSet &Classes)
+      : S(S), Namespaces(Namespaces), Classes(Classes) {
+    }
 
-static void CollectNamespace(Sema::AssociatedNamespaceSet &Namespaces,
-                             DeclContext *Ctx) {
+    Sema &S;
+    Sema::AssociatedNamespaceSet &Namespaces;
+    Sema::AssociatedClassSet &Classes;
+  };
+}
+
+static void
+addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType T);
+
+static void CollectEnclosingNamespace(Sema::AssociatedNamespaceSet &Namespaces,
+                                      DeclContext *Ctx) {
+  // Add the associated namespace for this class.
+
+  // We don't use DeclContext::getEnclosingNamespaceContext() as this may
+  // be a locally scoped record.
+
+  while (Ctx->isRecord() || Ctx->isTransparentContext())
+    Ctx = Ctx->getParent();
+
   if (Ctx->isFileContext())
-    Namespaces.insert(Ctx);
+    Namespaces.insert(Ctx->getPrimaryContext());
 }
 
 // \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) {
+addAssociatedClassesAndNamespaces(AssociatedLookup &Result,
+                                  const TemplateArgument &Arg) {
   // C++ [basic.lookup.koenig]p2, last bullet:
   //   -- [...] ;
   switch (Arg.getKind()) {
@@ -1409,9 +1641,7 @@
       // [...] 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);
+      addAssociatedClassesAndNamespaces(Result, Arg.getAsType());
       break;
 
     case TemplateArgument::Template: {
@@ -1423,11 +1653,9 @@
                  = dyn_cast<ClassTemplateDecl>(Template.getAsTemplateDecl())) {
         DeclContext *Ctx = ClassTemplate->getDeclContext();
         if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
-          AssociatedClasses.insert(EnclosingClass);
+          Result.Classes.insert(EnclosingClass);
         // Add the associated namespace for this class.
-        while (Ctx->isRecord())
-          Ctx = Ctx->getParent();
-        CollectNamespace(AssociatedNamespaces, Ctx);
+        CollectEnclosingNamespace(Result.Namespaces, Ctx);
       }
       break;
     }
@@ -1443,9 +1671,7 @@
       for (TemplateArgument::pack_iterator P = Arg.pack_begin(),
                                         PEnd = Arg.pack_end();
            P != PEnd; ++P)
-        addAssociatedClassesAndNamespaces(*P, Context,
-                                          AssociatedNamespaces,
-                                          AssociatedClasses);
+        addAssociatedClassesAndNamespaces(Result, *P);
       break;
   }
 }
@@ -1454,10 +1680,13 @@
 // 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) {
+addAssociatedClassesAndNamespaces(AssociatedLookup &Result,
+                                  CXXRecordDecl *Class) {
+
+  // Just silently ignore anything whose name is __va_list_tag.
+  if (Class->getDeclName() == Result.S.VAListTagName)
+    return;
+
   // C++ [basic.lookup.koenig]p2:
   //   [...]
   //     -- If T is a class type (including unions), its associated
@@ -1469,15 +1698,13 @@
   // 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);
+    Result.Classes.insert(EnclosingClass);
   // Add the associated namespace for this class.
-  while (Ctx->isRecord())
-    Ctx = Ctx->getParent();
-  CollectNamespace(AssociatedNamespaces, Ctx);
+  CollectEnclosingNamespace(Result.Namespaces, Ctx);
 
   // Add the class itself. If we've already seen this class, we don't
   // need to visit base classes.
-  if (!AssociatedClasses.insert(Class))
+  if (!Result.Classes.insert(Class))
     return;
 
   // -- If T is a template-id, its associated namespaces and classes are
@@ -1493,17 +1720,13 @@
         = dyn_cast<ClassTemplateSpecializationDecl>(Class)) {
     DeclContext *Ctx = Spec->getSpecializedTemplate()->getDeclContext();
     if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
-      AssociatedClasses.insert(EnclosingClass);
+      Result.Classes.insert(EnclosingClass);
     // Add the associated namespace for this class.
-    while (Ctx->isRecord())
-      Ctx = Ctx->getParent();
-    CollectNamespace(AssociatedNamespaces, Ctx);
+    CollectEnclosingNamespace(Result.Namespaces, Ctx);
 
     const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
     for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
-      addAssociatedClassesAndNamespaces(TemplateArgs[I], Context,
-                                        AssociatedNamespaces,
-                                        AssociatedClasses);
+      addAssociatedClassesAndNamespaces(Result, TemplateArgs[I]);
   }
 
   // Only recurse into base classes for complete types.
@@ -1535,12 +1758,10 @@
       if (!BaseType)
         continue;
       CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(BaseType->getDecl());
-      if (AssociatedClasses.insert(BaseDecl)) {
+      if (Result.Classes.insert(BaseDecl)) {
         // Find the associated namespace for this base class.
         DeclContext *BaseCtx = BaseDecl->getDeclContext();
-        while (BaseCtx->isRecord())
-          BaseCtx = BaseCtx->getParent();
-        CollectNamespace(AssociatedNamespaces, BaseCtx);
+        CollectEnclosingNamespace(Result.Namespaces, BaseCtx);
 
         // Make sure we visit the bases of this base class.
         if (BaseDecl->bases_begin() != BaseDecl->bases_end())
@@ -1554,10 +1775,7 @@
 // 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) {
+addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
   // C++ [basic.lookup.koenig]p2:
   //
   //   For each argument type T in the function call, there is a set
@@ -1568,111 +1786,137 @@
   //   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.
+  llvm::SmallVector<const Type *, 16> Queue;
+  const Type *T = Ty->getCanonicalTypeInternal().getTypePtr();
+
   while (true) {
-    if (const PointerType *Ptr = T->getAs<PointerType>())
-      T = Ptr->getPointeeType();
-    else if (const ArrayType *Ptr = Context.getAsArrayType(T))
-      T = Ptr->getElementType();
-    else
+    switch (T->getTypeClass()) {
+
+#define TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define ABSTRACT_TYPE(Class, Base)
+#include "clang/AST/TypeNodes.def"
+      // T is canonical.  We can also ignore dependent types because
+      // we don't need to do ADL at the definition point, but if we
+      // wanted to implement template export (or if we find some other
+      // use for associated classes and namespaces...) this would be
+      // wrong.
       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 pointer to U or an array of U, its associated
+    //       namespaces and classes are those associated with U.
+    case Type::Pointer:
+      T = cast<PointerType>(T)->getPointeeType().getTypePtr();
+      continue;
+    case Type::ConstantArray:
+    case Type::IncompleteArray:
+    case Type::VariableArray:
+      T = cast<ArrayType>(T)->getElementType().getTypePtr();
+      continue;
 
-  //     -- 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 a fundamental type, its associated sets of
+    //        namespaces and classes are both empty.
+    case Type::Builtin:
+      break;
+
+    //     -- 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.
+    case Type::Record: {
+      CXXRecordDecl *Class
+        = cast<CXXRecordDecl>(cast<RecordType>(T)->getDecl());
+      addAssociatedClassesAndNamespaces(Result, Class);
+      break;
     }
 
-  //     -- 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();
+    //     -- 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.
+    case Type::Enum: {
+      EnumDecl *Enum = cast<EnumType>(T)->getDecl();
 
-    DeclContext *Ctx = Enum->getDeclContext();
-    if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
-      AssociatedClasses.insert(EnclosingClass);
+      DeclContext *Ctx = Enum->getDeclContext();
+      if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
+        Result.Classes.insert(EnclosingClass);
 
-    // Add the associated namespace for this class.
-    while (Ctx->isRecord())
-      Ctx = Ctx->getParent();
-    CollectNamespace(AssociatedNamespaces, Ctx);
+      // Add the associated namespace for this class.
+      CollectEnclosingNamespace(Result.Namespaces, Ctx);
 
-    return;
+      break;
+    }
+
+    //     -- 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.
+    case Type::FunctionProto: {
+      const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
+      for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
+                                             ArgEnd = Proto->arg_type_end();
+             Arg != ArgEnd; ++Arg)
+        Queue.push_back(Arg->getTypePtr());
+      // fallthrough
+    }
+    case Type::FunctionNoProto: {
+      const FunctionType *FnType = cast<FunctionType>(T);
+      T = FnType->getResultType().getTypePtr();
+      continue;
+    }
+
+    //     -- 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.
+    case Type::MemberPointer: {
+      const MemberPointerType *MemberPtr = cast<MemberPointerType>(T);
+
+      // Queue up the class type into which this points.
+      Queue.push_back(MemberPtr->getClass());
+
+      // And directly continue with the pointee type.
+      T = MemberPtr->getPointeeType().getTypePtr();
+      continue;
+    }
+
+    // As an extension, treat this like a normal pointer.
+    case Type::BlockPointer:
+      T = cast<BlockPointerType>(T)->getPointeeType().getTypePtr();
+      continue;
+
+    // References aren't covered by the standard, but that's such an
+    // obvious defect that we cover them anyway.
+    case Type::LValueReference:
+    case Type::RValueReference:
+      T = cast<ReferenceType>(T)->getPointeeType().getTypePtr();
+      continue;
+
+    // These are fundamental types.
+    case Type::Vector:
+    case Type::ExtVector:
+    case Type::Complex:
+      break;
+
+    // These are ignored by ADL.
+    case Type::ObjCObject:
+    case Type::ObjCInterface:
+    case Type::ObjCObjectPointer:
+      break;
+    }
+
+    if (Queue.empty()) break;
+    T = Queue.back();
+    Queue.pop_back();
   }
-
-  //     -- 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
@@ -1689,6 +1933,8 @@
   AssociatedNamespaces.clear();
   AssociatedClasses.clear();
 
+  AssociatedLookup Result(*this, AssociatedNamespaces, 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
@@ -1700,9 +1946,7 @@
     Expr *Arg = Args[ArgIdx];
 
     if (Arg->getType() != Context.OverloadTy) {
-      addAssociatedClassesAndNamespaces(Arg->getType(), Context,
-                                        AssociatedNamespaces,
-                                        AssociatedClasses);
+      addAssociatedClassesAndNamespaces(Result, Arg->getType());
       continue;
     }
 
@@ -1715,20 +1959,14 @@
     // parameter types and return type.
     Arg = Arg->IgnoreParens();
     if (UnaryOperator *unaryOp = dyn_cast<UnaryOperator>(Arg))
-      if (unaryOp->getOpcode() == UnaryOperator::AddrOf)
+      if (unaryOp->getOpcode() == UO_AddrOf)
         Arg = unaryOp->getSubExpr();
 
-    // TODO: avoid the copies.  This should be easy when the cases
-    // share a storage implementation.
-    llvm::SmallVector<NamedDecl*, 8> Functions;
+    UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg);
+    if (!ULE) continue;
 
-    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) {
+    for (UnresolvedSetIterator I = ULE->decls_begin(), E = ULE->decls_end();
+           I != E; ++I) {
       // Look through any using declarations to find the underlying function.
       NamedDecl *Fn = (*I)->getUnderlyingDecl();
 
@@ -1738,9 +1976,7 @@
 
       // Add the classes and namespaces associated with the parameter
       // types and return type of this function.
-      addAssociatedClassesAndNamespaces(FDecl->getType(), Context,
-                                        AssociatedNamespaces,
-                                        AssociatedClasses);
+      addAssociatedClassesAndNamespaces(Result, FDecl->getType());
     }
   }
 }
@@ -1840,6 +2076,36 @@
   }
 }
 
+/// \brief Look up the constructors for the given class.
+DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) {
+  // If the copy constructor has not yet been declared, do so now.
+  if (CanDeclareSpecialMemberFunction(Context, Class)) {
+    if (!Class->hasDeclaredDefaultConstructor())
+      DeclareImplicitDefaultConstructor(Class);
+    if (!Class->hasDeclaredCopyConstructor())
+      DeclareImplicitCopyConstructor(Class);
+  }
+  
+  CanQualType T = Context.getCanonicalType(Context.getTypeDeclType(Class));
+  DeclarationName Name = Context.DeclarationNames.getCXXConstructorName(T);
+  return Class->lookup(Name);
+}
+
+/// \brief Look for the destructor of the given class.
+///
+/// During semantic analysis, this routine should be used in lieu of 
+/// CXXRecordDecl::getDestructor().
+///
+/// \returns The destructor for this class.
+CXXDestructorDecl *Sema::LookupDestructor(CXXRecordDecl *Class) {
+  // If the destructor has not yet been declared, do so now.
+  if (CanDeclareSpecialMemberFunction(Context, Class) &&
+      !Class->hasDeclaredDestructor())
+    DeclareImplicitDestructor(Class);
+
+  return Class->getDestructor();
+}
+
 void ADLResult::insert(NamedDecl *New) {
   NamedDecl *&Old = Decls[cast<NamedDecl>(New->getCanonicalDecl())];
 
@@ -2000,6 +2266,10 @@
     return !VisitedContexts.insert(Ctx);
   }
 
+  bool alreadyVisitedContext(DeclContext *Ctx) {
+    return VisitedContexts.count(Ctx);
+  }
+
   /// \brief Determine whether the given declaration is hidden in the
   /// current scope.
   ///
@@ -2138,6 +2408,9 @@
   if (Visited.visitedContext(Ctx->getPrimaryContext()))
     return;
   
+  if (CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(Ctx))
+    Result.getSema().ForceDeclarationOfImplicitMembers(Class);
+
   // Enumerate all of the results in this context.
   for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx; 
        CurCtx = CurCtx->getNextContext()) {
@@ -2277,12 +2550,14 @@
   if (!S)
     return;
 
-  if (!S->getEntity() || !S->getParent() ||
+  if (!S->getEntity() || 
+      (!S->getParent() && 
+       !Visited.alreadyVisitedContext((DeclContext *)S->getEntity())) ||
       ((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 (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
         if (Result.isAcceptableDecl(ND)) {
           Consumer.FoundDecl(ND, Visited.checkHidden(ND), false);
           Visited.add(ND);
@@ -2355,7 +2630,8 @@
 }
 
 void Sema::LookupVisibleDecls(Scope *S, LookupNameKind Kind,
-                              VisibleDeclConsumer &Consumer) {
+                              VisibleDeclConsumer &Consumer,
+                              bool IncludeGlobalScope) {
   // Determine the set of using directives available during
   // unqualified name lookup.
   Scope *Initial = S;
@@ -2372,14 +2648,19 @@
   // Look for visible declarations.
   LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind);
   VisibleDeclsRecord Visited;
+  if (!IncludeGlobalScope)
+    Visited.visitedContext(Context.getTranslationUnitDecl());
   ShadowContextRAII Shadow(Visited);
   ::LookupVisibleDecls(Initial, Result, UDirs, Consumer, Visited);
 }
 
 void Sema::LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
-                              VisibleDeclConsumer &Consumer) {
+                              VisibleDeclConsumer &Consumer,
+                              bool IncludeGlobalScope) {
   LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind);
   VisibleDeclsRecord Visited;
+  if (!IncludeGlobalScope)
+    Visited.visitedContext(Context.getTranslationUnitDecl());
   ShadowContextRAII Shadow(Visited);
   ::LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/true, 
                        /*InBaseClass=*/false, Consumer, Visited);
@@ -2522,7 +2803,7 @@
                                   bool EnteringContext,
                                   CorrectTypoContext CTC,
                                   const ObjCObjectPointerType *OPT) {
-  if (Diags.hasFatalErrorOccurred())
+  if (Diags.hasFatalErrorOccurred() || !getLangOptions().SpellChecking)
     return DeclarationName();
 
   // Provide a stop gap for files that are just seriously broken.  Trying
@@ -2582,6 +2863,12 @@
       WantExpressionKeywords = true;
       WantCXXNamedCasts = true;
       WantRemainingKeywords = true;
+      
+      if (ObjCMethodDecl *Method = getCurMethodDecl())
+        if (Method->getClassInterface() &&
+            Method->getClassInterface()->getSuperClass())
+          Consumer.addKeywordResult(Context, "super");
+      
       break;
   
     case CTC_NoKeywords:
@@ -2648,7 +2935,7 @@
       Consumer.addKeywordResult(Context, "typeof");
   }
   
-  if (WantCXXNamedCasts) {
+  if (WantCXXNamedCasts && getLangOptions().CPlusPlus) {
     Consumer.addKeywordResult(Context, "const_cast");
     Consumer.addKeywordResult(Context, "dynamic_cast");
     Consumer.addKeywordResult(Context, "reinterpret_cast");
@@ -2701,7 +2988,7 @@
       if (S && S->getContinueParent())
         Consumer.addKeywordResult(Context, "continue");
       
-      if (!getSwitchStack().empty()) {
+      if (!getCurFunction()->SwitchStack.empty()) {
         Consumer.addKeywordResult(Context, "case");
         Consumer.addKeywordResult(Context, "default");
       }
@@ -2778,6 +3065,25 @@
         BestIvarOrPropertyDecl = 0;
         FoundIvarOrPropertyDecl = false;
         Consumer.clear_decls();
+      } else if (CTC == CTC_ObjCMessageReceiver &&
+                 (*Consumer.keyword_begin())->isStr("super")) {
+        // In an Objective-C message send, give the "super" keyword a slight
+        // edge over entities not in function or method scope.
+        for (TypoCorrectionConsumer::iterator I = Consumer.begin(), 
+                                           IEnd = Consumer.end();
+             I != IEnd; ++I) {
+          if ((*I)->getDeclName() == BestName) {
+            if ((*I)->getDeclContext()->isFunctionOrMethod())
+              return DeclarationName();
+          }
+        }
+        
+        // Everything found was outside a function or method; the 'super'
+        // keyword takes precedence.
+        BestIvarOrPropertyDecl = 0;
+        FoundIvarOrPropertyDecl = false;
+        Consumer.clear_decls();        
+        BestName = *Consumer.keyword_begin();
       } else {
         // Name collision; we will not correct typos.
         return DeclarationName();
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 1d27e44..7c3918a 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -12,7 +12,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/ExprObjC.h"
+#include "llvm/ADT/DenseSet.h"
 
 using namespace clang;
 
@@ -20,14 +24,14 @@
 // 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) {
+Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
+                          FieldDeclarator &FD,
+                          ObjCDeclSpec &ODS,
+                          Selector GetterSel,
+                          Selector SetterSel,
+                          Decl *ClassCategory,
+                          bool *isOverridingProperty,
+                          tok::ObjCKeywordKind MethodImplKind) {
   unsigned Attributes = ODS.getPropertyAttributes();
   bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
                       // default is readwrite!
@@ -39,34 +43,39 @@
                     !(Attributes & ObjCDeclSpec::DQ_PR_retain) &&
                     !(Attributes & ObjCDeclSpec::DQ_PR_copy)));
 
-  QualType T = GetTypeForDeclarator(FD.D, S);
+  TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S);
+  QualType T = TSI->getType();
   if (T->isReferenceType()) {
     Diag(AtLoc, diag::error_reference_property);
-    return DeclPtrTy();
+    return 0;
   }
   // Proceed with constructing the ObjCPropertDecls.
   ObjCContainerDecl *ClassDecl =
-    cast<ObjCContainerDecl>(ClassCategory.getAs<Decl>());
+    cast<ObjCContainerDecl>(ClassCategory);
 
   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));
+    if (CDecl->IsClassExtension()) {
+      Decl *Res = HandlePropertyInClassExtension(S, CDecl, AtLoc,
+                                           FD, GetterSel, SetterSel,
+                                           isAssign, isReadWrite,
+                                           Attributes,
+                                           isOverridingProperty, TSI,
+                                           MethodImplKind);
+      if (Res)
+        CheckObjCPropertyAttributes(Res, AtLoc, Attributes);
+      return Res;
+    }
+  
+  Decl *Res = CreatePropertyDecl(S, ClassDecl, AtLoc, FD,
+                                 GetterSel, SetterSel,
+                                 isAssign, isReadWrite,
+                                 Attributes, TSI, MethodImplKind);
   // Validate the attributes on the @property.
   CheckObjCPropertyAttributes(Res, AtLoc, Attributes);
   return Res;
 }
 
-Sema::DeclPtrTy
+Decl *
 Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
                                      SourceLocation AtLoc, FieldDeclarator &FD,
                                      Selector GetterSel, Selector SetterSel,
@@ -74,7 +83,7 @@
                                      const bool isReadWrite,
                                      const unsigned Attributes,
                                      bool *isOverridingProperty,
-                                     QualType T,
+                                     TypeSourceInfo *T,
                                      tok::ObjCKeywordKind MethodImplKind) {
 
   // Diagnose if this property is already in continuation class.
@@ -85,7 +94,7 @@
         ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) {
     Diag(AtLoc, diag::err_duplicate_property);
     Diag(prevDecl->getLocation(), diag::note_property_declare);
-    return DeclPtrTy();
+    return 0;
   }
 
   // Create a new ObjCPropertyDecl with the DeclContext being
@@ -106,7 +115,7 @@
   if (!CCPrimary) {
     Diag(CDecl->getLocation(), diag::err_continuation_class);
     *isOverridingProperty = true;
-    return DeclPtrTy();
+    return 0;
   }
 
   // Find the property in continuation class's primary class only.
@@ -119,19 +128,23 @@
     ObjCPropertyDecl *PDecl =
       CreatePropertyDecl(S, CCPrimary, AtLoc,
                          FD, GetterSel, SetterSel, isAssign, isReadWrite,
-                         Attributes, T, MethodImplKind);
+                         Attributes, T, MethodImplKind, DC);
+    // Mark written attribute as having no attribute because
+    // this is not a user-written property declaration in primary
+    // class.
+    PDecl->setPropertyAttributesAsWritten(ObjCPropertyDecl::OBJC_PR_noattr);
 
     // 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);
+    return PDecl;
 
   }
 
   // The property 'PIDecl's readonly attribute will be over-ridden
   // with continuation class's readwrite property attribute!
-  unsigned PIkind = PIDecl->getPropertyAttributes();
+  unsigned PIkind = PIDecl->getPropertyAttributesAsWritten();
   if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
     unsigned retainCopyNonatomic =
     (ObjCPropertyDecl::OBJC_PR_retain |
@@ -154,13 +167,13 @@
       setPropertyAttributes((ObjCDeclSpec::ObjCPropertyAttributeKind)
                             PIkind);
 
-      DeclPtrTy ProtocolPtrTy =
+      Decl *ProtocolPtrTy =
         ActOnProperty(S, AtLoc, FD, ProtocolPropertyODS,
                       PIDecl->getGetterName(),
                       PIDecl->getSetterName(),
-                      DeclPtrTy::make(CCPrimary), isOverridingProperty,
+                      CCPrimary, isOverridingProperty,
                       MethodImplKind);
-      PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy.getAs<Decl>());
+      PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy);
     }
     PIDecl->makeitReadWriteAttribute();
     if (Attributes & ObjCDeclSpec::DQ_PR_retain)
@@ -176,7 +189,7 @@
   *isOverridingProperty = true;
   // Make sure setter decl is synthesized, and added to primary class's list.
   ProcessPropertyDecl(PIDecl, CCPrimary);
-  return DeclPtrTy();
+  return 0;
 }
 
 ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
@@ -188,34 +201,32 @@
                                            const bool isAssign,
                                            const bool isReadWrite,
                                            const unsigned Attributes,
-                                           QualType T,
-                                           tok::ObjCKeywordKind MethodImplKind){
-
+                                           TypeSourceInfo *TInfo,
+                                           tok::ObjCKeywordKind MethodImplKind,
+                                           DeclContext *lexicalDC){
   IdentifierInfo *PropertyId = FD.D.getIdentifier();
+  QualType T = TInfo->getType();
 
   // 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 (const ObjCObjectPointerType *ObjPtrTy =
+          T->getAs<ObjCObjectPointerType>()) {
+      ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
+      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())
+  if (T->isObjCObjectType())
     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);
+                                                     PropertyId, AtLoc, TInfo);
 
   if (ObjCPropertyDecl *prevDecl =
         ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) {
@@ -223,8 +234,11 @@
     Diag(prevDecl->getLocation(), diag::note_property_declare);
     PDecl->setInvalidDecl();
   }
-  else
+  else {
     DC->addDecl(PDecl);
+    if (lexicalDC)
+      PDecl->setLexicalDeclContext(lexicalDC);
+  }
 
   if (T->isArrayType() || T->isFunctionType()) {
     Diag(AtLoc, diag::err_property_type) << T;
@@ -262,6 +276,8 @@
   if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
 
+  PDecl->setPropertyAttributesAsWritten(PDecl->getPropertyAttributes());
+  
   if (MethodImplKind == tok::objc_required)
     PDecl->setPropertyImplementation(ObjCPropertyDecl::Required);
   else if (MethodImplKind == tok::objc_optional)
@@ -275,18 +291,19 @@
 /// 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) {
+Decl *Sema::ActOnPropertyImplDecl(Scope *S,
+                                  SourceLocation AtLoc,
+                                  SourceLocation PropertyLoc,
+                                  bool Synthesize,
+                                  Decl *ClassCatImpDecl,
+                                  IdentifierInfo *PropertyId,
+                                  IdentifierInfo *PropertyIvar) {
   ObjCContainerDecl *ClassImpDecl =
-    cast_or_null<ObjCContainerDecl>(ClassCatImpDecl.getAs<Decl>());
+    cast_or_null<ObjCContainerDecl>(ClassCatImpDecl);
   // Make sure we have a context for the property implementation declaration.
   if (!ClassImpDecl) {
     Diag(AtLoc, diag::error_missing_property_context);
-    return DeclPtrTy();
+    return 0;
   }
   ObjCPropertyDecl *property = 0;
   ObjCInterfaceDecl* IDecl = 0;
@@ -305,25 +322,25 @@
     property = IDecl->FindPropertyDeclaration(PropertyId);
     if (!property) {
       Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName();
-      return DeclPtrTy();
+      return 0;
     }
     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();
+        return 0;
       }
     }
   } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
     if (Synthesize) {
       Diag(AtLoc, diag::error_synthesize_category_decl);
-      return DeclPtrTy();
+      return 0;
     }
     IDecl = CatImplClass->getClassInterface();
     if (!IDecl) {
       Diag(AtLoc, diag::error_missing_property_interface);
-      return DeclPtrTy();
+      return 0;
     }
     ObjCCategoryDecl *Category =
     IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier());
@@ -331,17 +348,17 @@
     // If category for this implementation not found, it is an error which
     // has already been reported eralier.
     if (!Category)
-      return DeclPtrTy();
+      return 0;
     // 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();
+      return 0;
     }
   } else {
     Diag(AtLoc, diag::error_bad_property_context);
-    return DeclPtrTy();
+    return 0;
   }
   ObjCIvarDecl *Ivar = 0;
   // Check that we have a valid, previously declared ivar for @synthesize
@@ -357,7 +374,7 @@
       Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, PropertyLoc,
                                   PropertyIvar, PropType, /*Dinfo=*/0,
                                   ObjCIvarDecl::Protected,
-                                  (Expr *)0);
+                                  (Expr *)0, true);
       ClassImpDecl->addDecl(Ivar);
       IDecl->makeDeclVisibleInContext(Ivar, false);
       property->setPropertyIvarDecl(Ivar);
@@ -372,14 +389,23 @@
       << property->getDeclName() << Ivar->getDeclName()
       << ClassDeclared->getDeclName();
       Diag(Ivar->getLocation(), diag::note_previous_access_declaration)
-      << Ivar << Ivar->getNameAsCString();
+      << Ivar << Ivar->getName();
       // 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) {
+      bool compat = false;
+      if (isa<ObjCObjectPointerType>(PropType) 
+            && isa<ObjCObjectPointerType>(IvarType))
+        compat = 
+          Context.canAssignObjCInterfaces(
+                                  PropType->getAs<ObjCObjectPointerType>(),
+                                  IvarType->getAs<ObjCObjectPointerType>());
+      else 
+        compat = (CheckAssignmentConstraints(PropType, IvarType) == Compatible);
+      if (!compat) {
         Diag(PropertyLoc, diag::error_property_ivar_type)
           << property->getDeclName() << PropType
           << Ivar->getDeclName() << IvarType;
@@ -427,6 +453,55 @@
                                 ObjCPropertyImplDecl::Synthesize
                                 : ObjCPropertyImplDecl::Dynamic),
                                Ivar);
+  if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
+    getterMethod->createImplicitParams(Context, IDecl);
+    if (getLangOptions().CPlusPlus && Synthesize) {
+      // For Objective-C++, need to synthesize the AST for the IVAR object to be
+      // returned by the getter as it must conform to C++'s copy-return rules.
+      // FIXME. Eventually we want to do this for Objective-C as well.
+      ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl();
+      DeclRefExpr *SelfExpr = 
+        new (Context) DeclRefExpr(SelfDecl,SelfDecl->getType(),
+                                  SourceLocation());
+      Expr *IvarRefExpr =
+        new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc,
+                                      SelfExpr, true, true);
+      ExprResult Res = 
+        PerformCopyInitialization(InitializedEntity::InitializeResult(
+                                    SourceLocation(),
+                                    getterMethod->getResultType(),
+                                    /*NRVO=*/false),
+                                  SourceLocation(),
+                                  Owned(IvarRefExpr));
+      if (!Res.isInvalid()) {
+        Expr *ResExpr = Res.takeAs<Expr>();
+        if (ResExpr)
+          ResExpr = MaybeCreateCXXExprWithTemporaries(ResExpr);
+        PIDecl->setGetterCXXConstructor(ResExpr);
+      }
+    }
+  }
+  if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
+    setterMethod->createImplicitParams(Context, IDecl);
+    if (getLangOptions().CPlusPlus && Synthesize) {
+      // FIXME. Eventually we want to do this for Objective-C as well.
+      ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl();
+      DeclRefExpr *SelfExpr = 
+        new (Context) DeclRefExpr(SelfDecl,SelfDecl->getType(),
+                                  SourceLocation());
+      Expr *lhs =
+        new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc,
+                                      SelfExpr, true, true);
+      ObjCMethodDecl::param_iterator P = setterMethod->param_begin();
+      ParmVarDecl *Param = (*P);
+      Expr *rhs = new (Context) DeclRefExpr(Param,Param->getType(),
+                                            SourceLocation());
+      ExprResult Res = BuildBinOp(S, SourceLocation(), 
+                                  BO_Assign, lhs, rhs);
+      PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>());
+    }
+  }
+  
   if (IC) {
     if (Synthesize)
       if (ObjCPropertyImplDecl *PPIDecl =
@@ -441,9 +516,29 @@
         = IC->FindPropertyImplDecl(PropertyId)) {
       Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
       Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
-      return DeclPtrTy();
+      return 0;
     }
     IC->addPropertyImplementation(PIDecl);
+    if (getLangOptions().ObjCNonFragileABI2) {
+      // Diagnose if an ivar was lazily synthesdized due to a previous
+      // use and if 1) property is @dynamic or 2) property is synthesized
+      // but it requires an ivar of different name.
+      ObjCInterfaceDecl *ClassDeclared;
+      ObjCIvarDecl *Ivar = 0;
+      if (!Synthesize)
+        Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
+      else {
+        if (PropertyIvar && PropertyIvar != PropertyId)
+          Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
+      }
+      // Issue diagnostics only if Ivar belongs to current class.
+      if (Ivar && Ivar->getSynthesize() && 
+          IC->getClassInterface() == ClassDeclared) {
+        Diag(Ivar->getLocation(), diag::err_undeclared_var_use) 
+        << PropertyId;
+        Ivar->setInvalidDecl();
+      }
+    }
   } else {
     if (Synthesize)
       if (ObjCPropertyImplDecl *PPIDecl =
@@ -458,12 +553,12 @@
         CatImplClass->FindPropertyImplDecl(PropertyId)) {
       Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
       Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
-      return DeclPtrTy();
+      return 0;
     }
     CatImplClass->addPropertyImplementation(PIDecl);
   }
 
-  return DeclPtrTy::make(PIDecl);
+  return PIDecl;
 }
 
 //===----------------------------------------------------------------------===//
@@ -607,9 +702,8 @@
 /// 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>();
+void Sema::CompareProperties(Decl *CDecl, Decl *ClassOrProtocol) {
+  Decl *ClassDecl = ClassOrProtocol;
   ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl);
 
   if (!IDecl) {
@@ -626,7 +720,7 @@
       // 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));
+        CompareProperties(CatDecl, *P);
     } else {
       ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
       for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
@@ -646,7 +740,7 @@
     // 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));
+      CompareProperties(IDecl, *P);
   } else {
     ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
     for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
@@ -709,7 +803,8 @@
 /// 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) {
+            llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap,
+            llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap) {
   if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
     for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(),
          E = IDecl->prop_end(); P != E; ++P) {
@@ -719,7 +814,7 @@
     // scan through class's protocols.
     for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
          E = IDecl->protocol_end(); PI != E; ++PI)
-      CollectImmediateProperties((*PI), PropMap);
+        CollectImmediateProperties((*PI), PropMap, SuperPropMap);
   }
   if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
     if (!CATDecl->IsClassExtension())
@@ -731,20 +826,66 @@
     // scan through class's protocols.
     for (ObjCInterfaceDecl::protocol_iterator PI = CATDecl->protocol_begin(),
          E = CATDecl->protocol_end(); PI != E; ++PI)
-      CollectImmediateProperties((*PI), PropMap);
+      CollectImmediateProperties((*PI), PropMap, SuperPropMap);
   }
   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;
+      ObjCPropertyDecl *PropertyFromSuper = SuperPropMap[Prop->getIdentifier()];
+      // Exclude property for protocols which conform to class's super-class, 
+      // as super-class has to implement the property.
+      if (!PropertyFromSuper || PropertyFromSuper != Prop) {
+        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);
+      CollectImmediateProperties((*PI), PropMap, SuperPropMap);
+  }
+}
+
+/// CollectClassPropertyImplementations - This routine collects list of
+/// properties to be implemented in the class. This includes, class's
+/// and its conforming protocols' properties.
+static void CollectClassPropertyImplementations(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;
+    }
+    for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
+         E = IDecl->protocol_end(); PI != E; ++PI)
+      CollectClassPropertyImplementations((*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);
+      PropMap[Prop->getIdentifier()] = Prop;
+    }
+    // scan through protocol's protocols.
+    for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
+         E = PDecl->protocol_end(); PI != E; ++PI)
+      CollectClassPropertyImplementations((*PI), PropMap);
+  }
+}
+
+/// CollectSuperClassPropertyImplementations - This routine collects list of
+/// properties to be implemented in super class(s) and also coming from their
+/// conforming protocols.
+static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl,
+                llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) {
+  if (ObjCInterfaceDecl *SDecl = CDecl->getSuperClass()) {
+    while (SDecl) {
+      CollectClassPropertyImplementations(SDecl, PropMap);
+      SDecl = SDecl->getSuperClass();
+    }
   }
 }
 
@@ -787,12 +928,54 @@
   return 0;
 }
 
+/// DefaultSynthesizeProperties - This routine default synthesizes all
+/// properties which must be synthesized in class's @implementation.
+void Sema::DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
+                                        ObjCInterfaceDecl *IDecl) {
+  
+  llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap;
+  CollectClassPropertyImplementations(IDecl, PropMap);
+  if (PropMap.empty())
+    return;
+  llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap;
+  CollectSuperClassPropertyImplementations(IDecl, SuperPropMap);
+  
+  for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator
+       P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
+    ObjCPropertyDecl *Prop = P->second;
+    // If property to be implemented in the super class, ignore.
+    if (SuperPropMap[Prop->getIdentifier()])
+      continue;
+    // Is there a matching propery synthesize/dynamic?
+    if (Prop->isInvalidDecl() ||
+        Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional ||
+        IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier()))
+      continue;
+    // Property may have been synthesized by user.
+    if (IMPDecl->FindPropertyImplDecl(Prop->getIdentifier()))
+      continue;
+    if (IMPDecl->getInstanceMethod(Prop->getGetterName())) {
+      if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly)
+        continue;
+      if (IMPDecl->getInstanceMethod(Prop->getSetterName()))
+        continue;
+    }
 
-void Sema::DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
+    ActOnPropertyImplDecl(S, IMPDecl->getLocation(), IMPDecl->getLocation(),
+                          true, IMPDecl,
+                          Prop->getIdentifier(), Prop->getIdentifier());
+  }    
+}
+
+void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
                                       ObjCContainerDecl *CDecl,
                                       const llvm::DenseSet<Selector>& InsMap) {
+  llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap;
+  if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl))
+    CollectSuperClassPropertyImplementations(IDecl, SuperPropMap);
+  
   llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap;
-  CollectImmediateProperties(CDecl, PropMap);
+  CollectImmediateProperties(CDecl, PropMap, SuperPropMap);
   if (PropMap.empty())
     return;
 
@@ -810,14 +993,6 @@
         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) ?
@@ -918,12 +1093,18 @@
     // for this class.
     GetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
                              property->getLocation(), property->getGetterName(),
-                             property->getType(), 0, CD, true, false, true,
+                             property->getType(), 0, CD, true, false, true, 
+                             false,
                              (property->getPropertyImplementation() ==
                               ObjCPropertyDecl::Optional) ?
                              ObjCMethodDecl::Optional :
                              ObjCMethodDecl::Required);
     CD->addDecl(GetterMethod);
+    // FIXME: Eventually this shouldn't be needed, as the lexical context
+    // and the real context should be the same.
+    if (DeclContext *lexicalDC = property->getLexicalDeclContext())
+      GetterMethod->setLexicalDeclContext(lexicalDC);
+
   } else
     // A user declared getter will be synthesize when @synthesize of
     // the property with the same name is seen in the @implementation
@@ -941,6 +1122,7 @@
                                property->getLocation(),
                                property->getSetterName(),
                                Context.VoidTy, 0, CD, true, false, true,
+                               false,
                                (property->getPropertyImplementation() ==
                                 ObjCPropertyDecl::Optional) ?
                                ObjCMethodDecl::Optional :
@@ -952,11 +1134,15 @@
                                                   property->getIdentifier(),
                                                   property->getType(),
                                                   /*TInfo=*/0,
-                                                  VarDecl::None,
-                                                  VarDecl::None,
+                                                  SC_None,
+                                                  SC_None,
                                                   0);
       SetterMethod->setMethodParams(Context, &Argument, 1, 1);
       CD->addDecl(SetterMethod);
+      // FIXME: Eventually this shouldn't be needed, as the lexical context
+      // and the real context should be the same.
+      if (DeclContext *lexicalDC = property->getLexicalDeclContext())
+        SetterMethod->setLexicalDeclContext(lexicalDC);
     } else
       // A user declared setter will be synthesize when @synthesize of
       // the property with the same name is seen in the @implementation
@@ -981,11 +1167,10 @@
     AddInstanceMethodToGlobalPool(SetterMethod);
 }
 
-void Sema::CheckObjCPropertyAttributes(DeclPtrTy PropertyPtrTy,
+void Sema::CheckObjCPropertyAttributes(Decl *PDecl,
                                        SourceLocation Loc,
                                        unsigned &Attributes) {
   // FIXME: Improve the reported location.
-  Decl *PDecl = PropertyPtrTy.getAs<Decl>();
   if (!PDecl)
     return;
 
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 06b5fcb..11b4bb3 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -11,13 +11,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "Lookup.h"
-#include "SemaInit.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Template.h"
+#include "clang/Sema/TemplateDeduction.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/TypeOrdering.h"
@@ -27,6 +30,34 @@
 #include <algorithm>
 
 namespace clang {
+using namespace sema;
+
+static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
+                                 bool InOverloadResolution,
+                                 StandardConversionSequence &SCS);
+static OverloadingResult
+IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
+                        UserDefinedConversionSequence& User,
+                        OverloadCandidateSet& Conversions,
+                        bool AllowExplicit);
+
+
+static ImplicitConversionSequence::CompareKind
+CompareStandardConversionSequences(Sema &S,
+                                   const StandardConversionSequence& SCS1,
+                                   const StandardConversionSequence& SCS2);
+
+static ImplicitConversionSequence::CompareKind
+CompareQualificationConversions(Sema &S,
+                                const StandardConversionSequence& SCS1,
+                                const StandardConversionSequence& SCS2);
+
+static ImplicitConversionSequence::CompareKind
+CompareDerivedToBaseConversions(Sema &S,
+                                const StandardConversionSequence& SCS1,
+                                const StandardConversionSequence& SCS2);
+
+
 
 /// GetConversionCategory - Retrieve the implicit conversion
 /// category corresponding to the given implicit conversion kind.
@@ -52,6 +83,8 @@
     ICC_Conversion,
     ICC_Conversion,
     ICC_Conversion,
+    ICC_Conversion,
+    ICC_Conversion,
     ICC_Conversion
   };
   return Category[(int)Kind];
@@ -80,6 +113,8 @@
     ICR_Conversion,
     ICR_Conversion,
     ICR_Conversion,
+    ICR_Conversion,
+    ICR_Conversion,
     ICR_Complex_Real_Conversion
   };
   return Rank[(int)Kind];
@@ -102,12 +137,14 @@
     "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"
+    "Derived-to-base conversion",
+    "Vector conversion",
+    "Vector splat",
+    "Complex-real conversion"
   };
   return Name[Kind];
 }
@@ -149,7 +186,9 @@
   // check for their presence as well as checking whether FromType is
   // a pointer.
   if (getToType(1)->isBooleanType() &&
-      (getFromType()->isPointerType() || getFromType()->isBlockPointerType() ||
+      (getFromType()->isPointerType() ||
+       getFromType()->isObjCObjectPointerType() ||
+       getFromType()->isBlockPointerType() ||
        First == ICK_Array_To_Pointer || First == ICK_Function_To_Pointer))
     return true;
 
@@ -275,7 +314,194 @@
   new (&conversions()) ConversionSet(O.conversions());
 }
 
+namespace {
+  // Structure used by OverloadCandidate::DeductionFailureInfo to store
+  // template parameter and template argument information.
+  struct DFIParamWithArguments {
+    TemplateParameter Param;
+    TemplateArgument FirstArg;
+    TemplateArgument SecondArg;
+  };
+}
+  
+/// \brief Convert from Sema's representation of template deduction information
+/// to the form used in overload-candidate information.
+OverloadCandidate::DeductionFailureInfo
+static MakeDeductionFailureInfo(ASTContext &Context,
+                                Sema::TemplateDeductionResult TDK,
+                                TemplateDeductionInfo &Info) {
+  OverloadCandidate::DeductionFailureInfo Result;
+  Result.Result = static_cast<unsigned>(TDK);
+  Result.Data = 0;
+  switch (TDK) {
+  case Sema::TDK_Success:
+  case Sema::TDK_InstantiationDepth:
+  case Sema::TDK_TooManyArguments:
+  case Sema::TDK_TooFewArguments:
+    break;
+      
+  case Sema::TDK_Incomplete:
+  case Sema::TDK_InvalidExplicitArguments:
+    Result.Data = Info.Param.getOpaqueValue();
+    break;
+      
+  case Sema::TDK_Inconsistent:
+  case Sema::TDK_Underqualified: {
+    // FIXME: Should allocate from normal heap so that we can free this later.
+    DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments;
+    Saved->Param = Info.Param;
+    Saved->FirstArg = Info.FirstArg;
+    Saved->SecondArg = Info.SecondArg;
+    Result.Data = Saved;
+    break;
+  }
+      
+  case Sema::TDK_SubstitutionFailure:
+    Result.Data = Info.take();
+    break;
+      
+  case Sema::TDK_NonDeducedMismatch:
+  case Sema::TDK_FailedOverloadResolution:
+    break;  
+  }
+  
+  return Result;
+}
 
+void OverloadCandidate::DeductionFailureInfo::Destroy() {
+  switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
+  case Sema::TDK_Success:
+  case Sema::TDK_InstantiationDepth:
+  case Sema::TDK_Incomplete:
+  case Sema::TDK_TooManyArguments:
+  case Sema::TDK_TooFewArguments:
+  case Sema::TDK_InvalidExplicitArguments:
+    break;
+      
+  case Sema::TDK_Inconsistent:
+  case Sema::TDK_Underqualified:
+    // FIXME: Destroy the data?
+    Data = 0;
+    break;
+
+  case Sema::TDK_SubstitutionFailure:
+    // FIXME: Destroy the template arugment list?
+    Data = 0;
+    break;
+      
+  // Unhandled
+  case Sema::TDK_NonDeducedMismatch:
+  case Sema::TDK_FailedOverloadResolution:
+    break;
+  }
+}
+  
+TemplateParameter 
+OverloadCandidate::DeductionFailureInfo::getTemplateParameter() {
+  switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
+  case Sema::TDK_Success:
+  case Sema::TDK_InstantiationDepth:
+  case Sema::TDK_TooManyArguments:
+  case Sema::TDK_TooFewArguments:
+  case Sema::TDK_SubstitutionFailure:
+    return TemplateParameter();
+    
+  case Sema::TDK_Incomplete:
+  case Sema::TDK_InvalidExplicitArguments:
+    return TemplateParameter::getFromOpaqueValue(Data);    
+
+  case Sema::TDK_Inconsistent:
+  case Sema::TDK_Underqualified:
+    return static_cast<DFIParamWithArguments*>(Data)->Param;
+      
+  // Unhandled
+  case Sema::TDK_NonDeducedMismatch:
+  case Sema::TDK_FailedOverloadResolution:
+    break;
+  }
+  
+  return TemplateParameter();
+}
+ 
+TemplateArgumentList *
+OverloadCandidate::DeductionFailureInfo::getTemplateArgumentList() {
+  switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
+    case Sema::TDK_Success:
+    case Sema::TDK_InstantiationDepth:
+    case Sema::TDK_TooManyArguments:
+    case Sema::TDK_TooFewArguments:
+    case Sema::TDK_Incomplete:
+    case Sema::TDK_InvalidExplicitArguments:
+    case Sema::TDK_Inconsistent:
+    case Sema::TDK_Underqualified:
+      return 0;
+
+    case Sema::TDK_SubstitutionFailure:
+      return static_cast<TemplateArgumentList*>(Data);
+      
+    // Unhandled
+    case Sema::TDK_NonDeducedMismatch:
+    case Sema::TDK_FailedOverloadResolution:
+      break;
+  }
+
+  return 0;
+}
+
+const TemplateArgument *OverloadCandidate::DeductionFailureInfo::getFirstArg() {
+  switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
+  case Sema::TDK_Success:
+  case Sema::TDK_InstantiationDepth:
+  case Sema::TDK_Incomplete:
+  case Sema::TDK_TooManyArguments:
+  case Sema::TDK_TooFewArguments:
+  case Sema::TDK_InvalidExplicitArguments:
+  case Sema::TDK_SubstitutionFailure:
+    return 0;
+
+  case Sema::TDK_Inconsistent:
+  case Sema::TDK_Underqualified:
+    return &static_cast<DFIParamWithArguments*>(Data)->FirstArg;      
+
+  // Unhandled
+  case Sema::TDK_NonDeducedMismatch:
+  case Sema::TDK_FailedOverloadResolution:
+    break;
+  }
+  
+  return 0;
+}    
+
+const TemplateArgument *
+OverloadCandidate::DeductionFailureInfo::getSecondArg() {
+  switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
+  case Sema::TDK_Success:
+  case Sema::TDK_InstantiationDepth:
+  case Sema::TDK_Incomplete:
+  case Sema::TDK_TooManyArguments:
+  case Sema::TDK_TooFewArguments:
+  case Sema::TDK_InvalidExplicitArguments:
+  case Sema::TDK_SubstitutionFailure:
+    return 0;
+
+  case Sema::TDK_Inconsistent:
+  case Sema::TDK_Underqualified:
+    return &static_cast<DFIParamWithArguments*>(Data)->SecondArg;
+
+  // Unhandled
+  case Sema::TDK_NonDeducedMismatch:
+  case Sema::TDK_FailedOverloadResolution:
+    break;
+  }
+  
+  return 0;
+}
+
+void OverloadCandidateSet::clear() {
+  inherited::clear();
+  Functions.clear();
+}
+  
 // 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
@@ -305,19 +531,54 @@
 // 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.
+//
+// 'NewIsUsingShadowDecl' indicates that 'New' is being introduced
+// into a class by a using declaration.  The rules for whether to hide
+// shadow declarations ignore some properties which otherwise figure
+// into a function template's signature.
 Sema::OverloadKind
-Sema::CheckOverload(FunctionDecl *New, const LookupResult &Old,
-                    NamedDecl *&Match) {
+Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
+                    NamedDecl *&Match, bool NewIsUsingDecl) {
   for (LookupResult::iterator I = Old.begin(), E = Old.end();
          I != E; ++I) {
-    NamedDecl *OldD = (*I)->getUnderlyingDecl();
+    NamedDecl *OldD = *I;
+
+    bool OldIsUsingDecl = false;
+    if (isa<UsingShadowDecl>(OldD)) {
+      OldIsUsingDecl = true;
+
+      // We can always introduce two using declarations into the same
+      // context, even if they have identical signatures.
+      if (NewIsUsingDecl) continue;
+
+      OldD = cast<UsingShadowDecl>(OldD)->getTargetDecl();
+    }
+
+    // If either declaration was introduced by a using declaration,
+    // we'll need to use slightly different rules for matching.
+    // Essentially, these rules are the normal rules, except that
+    // function templates hide function templates with different
+    // return types or template parameter lists.
+    bool UseMemberUsingDeclRules =
+      (OldIsUsingDecl || NewIsUsingDecl) && CurContext->isRecord();
+
     if (FunctionTemplateDecl *OldT = dyn_cast<FunctionTemplateDecl>(OldD)) {
-      if (!IsOverload(New, OldT->getTemplatedDecl())) {
+      if (!IsOverload(New, OldT->getTemplatedDecl(), UseMemberUsingDeclRules)) {
+        if (UseMemberUsingDeclRules && OldIsUsingDecl) {
+          HideUsingShadowDecl(S, cast<UsingShadowDecl>(*I));
+          continue;
+        }
+
         Match = *I;
         return Ovl_Match;
       }
     } else if (FunctionDecl *OldF = dyn_cast<FunctionDecl>(OldD)) {
-      if (!IsOverload(New, OldF)) {
+      if (!IsOverload(New, OldF, UseMemberUsingDeclRules)) {
+        if (UseMemberUsingDeclRules && OldIsUsingDecl) {
+          HideUsingShadowDecl(S, cast<UsingShadowDecl>(*I));
+          continue;
+        }
+
         Match = *I;
         return Ovl_Match;
       }
@@ -341,7 +602,13 @@
   return Ovl_Overload;
 }
 
-bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old) {
+bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
+                      bool UseUsingDeclRules) {
+  // If both of the functions are extern "C", then they are not
+  // overloads.
+  if (Old->isExternC() && New->isExternC())
+    return false;
+
   FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate();
   FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate();
 
@@ -374,8 +641,7 @@
   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())))
+       !FunctionArgTypesAreEqual(OldType, NewType)))
     return true;
 
   // C++ [temp.over.link]p4:
@@ -387,7 +653,10 @@
   //
   // We check the return type and template parameter lists for function
   // templates first; the remaining checks follow.
-  if (NewTemplate &&
+  //
+  // However, we don't consider either of these when deciding whether
+  // a member introduced by a shadow declaration is hidden.
+  if (!UseUsingDeclRules && NewTemplate &&
       (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
                                        OldTemplate->getTemplateParameters(),
                                        false, TPL_TemplateMatch) ||
@@ -436,40 +705,34 @@
 /// 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) {
+static ImplicitConversionSequence
+TryImplicitConversion(Sema &S, Expr *From, QualType ToType,
+                      bool SuppressUserConversions,
+                      bool AllowExplicit, 
+                      bool InOverloadResolution) {
   ImplicitConversionSequence ICS;
-  if (IsStandardConversion(From, ToType, InOverloadResolution, ICS.Standard)) {
+  if (IsStandardConversion(S, From, ToType, InOverloadResolution,
+                           ICS.Standard)) {
     ICS.setStandard();
     return ICS;
   }
 
-  if (!getLangOptions().CPlusPlus) {
+  if (!S.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;
-    }
-
+  // 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>() &&
+      (S.Context.hasSameUnqualifiedType(FromType, ToType) ||
+       S.IsDerivedFrom(FromType, ToType))) {
     ICS.setStandard();
     ICS.Standard.setAsIdentityConversion();
     ICS.Standard.setFromType(FromType);
@@ -480,18 +743,25 @@
     // 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))
+    if (!S.Context.hasSameUnqualifiedType(FromType, ToType))
       ICS.Standard.Second = ICK_Derived_To_Base;
-
+    
+    return ICS;
+  }
+  
+  if (SuppressUserConversions) {
+    // 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;
   }
 
   // Attempt user-defined conversion.
   OverloadCandidateSet Conversions(From->getExprLoc());
   OverloadingResult UserDefResult
-    = IsUserDefinedConversion(From, ToType, ICS.UserDefined, Conversions,
+    = IsUserDefinedConversion(S, From, ToType, ICS.UserDefined, Conversions,
                               AllowExplicit);
 
   if (UserDefResult == OR_Success) {
@@ -506,10 +776,11 @@
     if (CXXConstructorDecl *Constructor
           = dyn_cast<CXXConstructorDecl>(ICS.UserDefined.ConversionFunction)) {
       QualType FromCanon
-        = Context.getCanonicalType(From->getType().getUnqualifiedType());
-      QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType();
+        = S.Context.getCanonicalType(From->getType().getUnqualifiedType());
+      QualType ToCanon
+        = S.Context.getCanonicalType(ToType).getUnqualifiedType();
       if (Constructor->isCopyConstructor() &&
-          (FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon))) {
+          (FromCanon == ToCanon || S.IsDerivedFrom(FromCanon, ToCanon))) {
         // Turn this into a "standard" conversion sequence, so that it
         // gets ranked with standard conversion sequences.
         ICS.setStandard();
@@ -547,6 +818,24 @@
   return ICS;
 }
 
+bool Sema::TryImplicitConversion(InitializationSequence &Sequence,
+                                 const InitializedEntity &Entity,
+                                 Expr *Initializer,
+                                 bool SuppressUserConversions,
+                                 bool AllowExplicitConversions,
+                                 bool InOverloadResolution) {
+  ImplicitConversionSequence ICS
+    = clang::TryImplicitConversion(*this, Initializer, Entity.getType(),
+                                   SuppressUserConversions,
+                                   AllowExplicitConversions, 
+                                   InOverloadResolution);
+  if (ICS.isBad()) return true;
+
+  // Perform the actual conversion.
+  Sequence.AddConversionSequenceStep(ICS, Entity.getType());
+  return false;
+}
+
 /// 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
@@ -564,10 +853,10 @@
 Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
                                 AssignmentAction Action, bool AllowExplicit,
                                 ImplicitConversionSequence& ICS) {
-  ICS = TryImplicitConversion(From, ToType,
-                              /*SuppressUserConversions=*/false,
-                              AllowExplicit,
-                              /*InOverloadResolution=*/false);
+  ICS = clang::TryImplicitConversion(*this, From, ToType,
+                                     /*SuppressUserConversions=*/false,
+                                     AllowExplicit,
+                                     /*InOverloadResolution=*/false);
   return PerformImplicitConversion(From, ToType, ICS, Action);
 }
   
@@ -587,6 +876,52 @@
   ResultTy = FromType;
   return true;
 }
+ 
+/// \brief Determine whether the conversion from FromType to ToType is a valid
+/// vector conversion.
+///
+/// \param ICK Will be set to the vector conversion kind, if this is a vector
+/// conversion.
+static bool IsVectorConversion(ASTContext &Context, QualType FromType, 
+                               QualType ToType, ImplicitConversionKind &ICK) {  
+  // We need at least one of these types to be a vector type to have a vector
+  // conversion.
+  if (!ToType->isVectorType() && !FromType->isVectorType())
+    return false;
+
+  // Identical types require no conversions.
+  if (Context.hasSameUnqualifiedType(FromType, ToType))
+    return false;
+
+  // There are no conversions between extended vector types, only identity.
+  if (ToType->isExtVectorType()) {
+    // There are no conversions between extended vector types other than the
+    // identity conversion.
+    if (FromType->isExtVectorType())
+      return false;
+   
+    // Vector splat from any arithmetic type to a vector.
+    if (FromType->isArithmeticType()) {
+      ICK = ICK_Vector_Splat;
+      return true;
+    }
+  }
+
+  // We can perform the conversion between vector types in the following cases:
+  // 1)vector types are equivalent AltiVec and GCC vector types
+  // 2)lax vector conversions are permitted and the vector types are of the
+  //   same size
+  if (ToType->isVectorType() && FromType->isVectorType()) {
+    if (Context.areCompatibleVectorTypes(FromType, ToType) ||
+        (Context.getLangOptions().LaxVectorConversions &&
+         (Context.getTypeSize(FromType) == Context.getTypeSize(ToType)))) {
+      ICK = ICK_Vector_Conversion;
+      return true;
+    }
+  }
+
+  return false;
+}
   
 /// IsStandardConversion - Determines whether there is a standard
 /// conversion sequence (C++ [conv], C++ [over.ics.scs]) from the
@@ -596,12 +931,11 @@
 /// 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) {
+static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
+                                 bool InOverloadResolution,
+                                 StandardConversionSequence &SCS) {
   QualType FromType = From->getType();
-
+  
   // Standard conversions (C++ [conv])
   SCS.setAsIdentityConversion();
   SCS.DeprecatedStringLiteralToCharPtr = false;
@@ -612,7 +946,7 @@
   // 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)
+    if (S.getLangOptions().CPlusPlus)
       return false;
 
     // When we're overloading in C, we allow, as standard conversions,
@@ -622,15 +956,43 @@
   // array-to-pointer conversion, or function-to-pointer conversion
   // (C++ 4p1).
 
-  DeclAccessPair AccessPair;
-
+  if (FromType == S.Context.OverloadTy) {
+    DeclAccessPair AccessPair;
+    if (FunctionDecl *Fn
+          = S.ResolveAddressOfOverloadedFunction(From, ToType, false, 
+                                                 AccessPair)) {
+      // 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 (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
+        if (!Method->isStatic()) {
+          Type *ClassType 
+            = S.Context.getTypeDeclType(Method->getParent()).getTypePtr();
+          FromType = S.Context.getMemberPointerType(FromType, ClassType);
+        }
+      }
+      
+      // If the "from" expression takes the address of the overloaded
+      // function, update the type of the resulting expression accordingly.
+      if (FromType->getAs<FunctionType>())
+        if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(From->IgnoreParens()))
+          if (UnOp->getOpcode() == UO_AddrOf)
+            FromType = S.Context.getPointerType(FromType);
+ 
+      // Check that we've computed the proper type after overload resolution.
+      assert(S.Context.hasSameType(FromType,
+            S.FixOverloadedFunctionReference(From, AccessPair, Fn)->getType()));
+    } else {
+      return false;
+    }
+  } 
   // 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);
+  Expr::isLvalueResult argIsLvalue = From->isLvalue(S.Context);
   if (argIsLvalue == Expr::LV_Valid &&
       !FromType->isFunctionType() && !FromType->isArrayType() &&
-      Context.getCanonicalType(FromType) != Context.OverloadTy) {
+      S.Context.getCanonicalType(FromType) != S.Context.OverloadTy) {
     SCS.First = ICK_Lvalue_To_Rvalue;
 
     // If T is a non-class type, the type of the rvalue is the
@@ -645,9 +1007,9 @@
     // 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);
+    FromType = S.Context.getArrayDecayedType(FromType);
 
-    if (IsStringLiteralToNonConstPointerConversion(From, ToType)) {
+    if (S.IsStringLiteralToNonConstPointerConversion(From, ToType)) {
       // This conversion is deprecated. (C++ D.4).
       SCS.DeprecatedStringLiteralToCharPtr = true;
 
@@ -667,37 +1029,7 @@
     // 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;
-    }
+    FromType = S.Context.getPointerType(FromType);
   } else {
     // We don't require any conversions for the first step.
     SCS.First = ICK_Identity;
@@ -711,24 +1043,25 @@
   // For overloading in C, this can also be a "compatible-type"
   // conversion.
   bool IncompatibleObjC = false;
-  if (Context.hasSameUnqualifiedType(FromType, ToType)) {
+  ImplicitConversionKind SecondICK = ICK_Identity;
+  if (S.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)) {
+  } else if (S.IsIntegralPromotion(From, FromType, ToType)) {
     // Integral promotion (C++ 4.5).
     SCS.Second = ICK_Integral_Promotion;
     FromType = ToType.getUnqualifiedType();
-  } else if (IsFloatingPointPromotion(FromType, ToType)) {
+  } else if (S.IsFloatingPointPromotion(FromType, ToType)) {
     // Floating point promotion (C++ 4.6).
     SCS.Second = ICK_Floating_Promotion;
     FromType = ToType.getUnqualifiedType();
-  } else if (IsComplexPromotion(FromType, ToType)) {
+  } else if (S.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())) {
+  } else if (FromType->isIntegralOrEnumerationType() &&
+             ToType->isIntegralType(S.Context)) {
     // Integral conversions (C++ 4.7).
     SCS.Second = ICK_Integral_Conversion;
     FromType = ToType.getUnqualifiedType();
@@ -741,25 +1074,24 @@
     // Complex-real conversions (C99 6.3.1.7)
     SCS.Second = ICK_Complex_Real;
     FromType = ToType.getUnqualifiedType();
-  } else if (FromType->isFloatingType() && ToType->isFloatingType()) {
+  } else if (FromType->isRealFloatingType() && ToType->isRealFloatingType()) {
     // 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())) {
+  } else if ((FromType->isRealFloatingType() && 
+              ToType->isIntegralType(S.Context) && !ToType->isBooleanType()) ||
+             (FromType->isIntegralOrEnumerationType() &&
+              ToType->isRealFloatingType())) {
     // Floating-integral conversions (C++ 4.9).
     SCS.Second = ICK_Floating_Integral;
     FromType = ToType.getUnqualifiedType();
-  } else if (IsPointerConversion(From, FromType, ToType, InOverloadResolution,
-                                 FromType, IncompatibleObjC)) {
+  } else if (S.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)) {
+  } else if (S.IsMemberPointerConversion(From, FromType, ToType, 
+                                         InOverloadResolution, FromType)) {
     // Pointer to member conversions (4.11).
     SCS.Second = ICK_Pointer_Member;
   } else if (ToType->isBooleanType() &&
@@ -771,12 +1103,16 @@
               FromType->isNullPtrType())) {
     // Boolean conversions (C++ 4.12).
     SCS.Second = ICK_Boolean_Conversion;
-    FromType = Context.BoolTy;
-  } else if (!getLangOptions().CPlusPlus &&
-             Context.typesAreCompatible(ToType, FromType)) {
+    FromType = S.Context.BoolTy;
+  } else if (IsVectorConversion(S.Context, FromType, ToType, SecondICK)) {
+    SCS.Second = SecondICK;
+    FromType = ToType.getUnqualifiedType();
+  } else if (!S.getLangOptions().CPlusPlus &&
+             S.Context.typesAreCompatible(ToType, FromType)) {
     // Compatible conversions (Clang extension for C function overloading)
     SCS.Second = ICK_Compatible_Conversion;
-  } else if (IsNoReturnConversion(Context, FromType, ToType, FromType)) {
+    FromType = ToType.getUnqualifiedType();
+  } else if (IsNoReturnConversion(S.Context, FromType, ToType, FromType)) {
     // Treat a conversion that strips "noreturn" as an identity conversion.
     SCS.Second = ICK_NoReturn_Adjustment;
   } else {
@@ -788,11 +1124,11 @@
   QualType CanonFrom;
   QualType CanonTo;
   // The third conversion can be a qualification conversion (C++ 4p1).
-  if (IsQualificationConversion(FromType, ToType)) {
+  if (S.IsQualificationConversion(FromType, ToType)) {
     SCS.Third = ICK_Qualification;
     FromType = ToType;
-    CanonFrom = Context.getCanonicalType(FromType);
-    CanonTo = Context.getCanonicalType(ToType);
+    CanonFrom = S.Context.getCanonicalType(FromType);
+    CanonTo = S.Context.getCanonicalType(ToType);
   } else {
     // No conversion required
     SCS.Third = ICK_Identity;
@@ -801,11 +1137,12 @@
     //   [...] 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);
+    CanonFrom = S.Context.getCanonicalType(FromType);
+    CanonTo = S.Context.getCanonicalType(ToType);
     if (CanonFrom.getLocalUnqualifiedType() 
                                        == CanonTo.getLocalUnqualifiedType() &&
-        CanonFrom.getLocalCVRQualifiers() != CanonTo.getLocalCVRQualifiers()) {
+        (CanonFrom.getLocalCVRQualifiers() != CanonTo.getLocalCVRQualifiers()
+         || CanonFrom.getObjCGCAttr() != CanonTo.getObjCGCAttr())) {
       FromType = ToType;
       CanonFrom = CanonTo;
     }
@@ -903,7 +1240,7 @@
   if (From)
     if (FieldDecl *MemberDecl = From->getBitField()) {
       APSInt BitWidth;
-      if (FromType->isIntegralType() && !FromType->isEnumeralType() &&
+      if (FromType->isIntegralType(Context) &&
           MemberDecl->getBitWidth()->isIntegerConstantExpr(BitWidth, Context)) {
         APSInt ToSize(BitWidth.getBitWidth(), BitWidth.isUnsigned());
         ToSize = Context.getTypeSize(ToType);
@@ -995,7 +1332,7 @@
   if (CanonToPointee.getLocalQualifiers() == Quals) {
     // ToType is exactly what we need. Return it.
     if (!ToType.isNull())
-      return ToType;
+      return ToType.getUnqualifiedType();
 
     // Build a pointer to ToPointee. It has the right qualifiers
     // already.
@@ -1033,7 +1370,7 @@
   // 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())
+      Expr->getType()->isIntegerType() && !Expr->getType()->isEnumeralType())
     return !InOverloadResolution;
 
   return Expr->isNullPointerConstant(Context,
@@ -1119,10 +1456,16 @@
 
   QualType FromPointeeType = FromTypePtr->getPointeeType();
 
+  // If the unqualified pointee types are the same, this can't be a 
+  // pointer conversion, so don't do all of the work below.
+  if (Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType))
+    return false;
+
   // 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()) {
+  if (FromPointeeType->isIncompleteOrObjectType() &&
+      ToPointeeType->isVoidType()) {
     ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
                                                        ToPointeeType,
                                                        ToType, Context);
@@ -1334,6 +1677,43 @@
 
   return false;
 }
+ 
+/// FunctionArgTypesAreEqual - This routine checks two function proto types
+/// for equlity of their argument types. Caller has already checked that
+/// they have same number of arguments. This routine assumes that Objective-C
+/// pointer types which only differ in their protocol qualifiers are equal.
+bool Sema::FunctionArgTypesAreEqual(FunctionProtoType*  OldType, 
+                            FunctionProtoType*  NewType){
+  if (!getLangOptions().ObjC1)
+    return std::equal(OldType->arg_type_begin(), OldType->arg_type_end(),
+                      NewType->arg_type_begin());
+  
+  for (FunctionProtoType::arg_type_iterator O = OldType->arg_type_begin(),
+       N = NewType->arg_type_begin(),
+       E = OldType->arg_type_end(); O && (O != E); ++O, ++N) {
+    QualType ToType = (*O);
+    QualType FromType = (*N);
+    if (ToType != FromType) {
+      if (const PointerType *PTTo = ToType->getAs<PointerType>()) {
+        if (const PointerType *PTFr = FromType->getAs<PointerType>())
+          if ((PTTo->getPointeeType()->isObjCQualifiedIdType() &&
+               PTFr->getPointeeType()->isObjCQualifiedIdType()) ||
+              (PTTo->getPointeeType()->isObjCQualifiedClassType() &&
+               PTFr->getPointeeType()->isObjCQualifiedClassType()))
+            continue;
+      }
+      else if (const ObjCObjectPointerType *PTTo =
+                 ToType->getAs<ObjCObjectPointerType>()) {
+        if (const ObjCObjectPointerType *PTFr = 
+              FromType->getAs<ObjCObjectPointerType>())
+          if (PTTo->getInterfaceDecl() == PTFr->getInterfaceDecl())
+            continue;
+      }
+      return false;  
+    }
+  }
+  return true;
+}
 
 /// CheckPointerConversion - Check the pointer conversion from the
 /// expression From to the type ToType. This routine checks for
@@ -1342,11 +1722,17 @@
 /// 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,
+                                  CastKind &Kind,
+                                  CXXCastPath& BasePath,
                                   bool IgnoreBaseAccess) {
   QualType FromType = From->getType();
 
+  if (CXXBoolLiteralExpr* LitBool
+                          = dyn_cast<CXXBoolLiteralExpr>(From->IgnoreParens()))
+    if (LitBool->getValue() == false)
+      Diag(LitBool->getExprLoc(), diag::warn_init_pointer_from_false)
+        << ToType;
+
   if (const PointerType *FromPtrType = FromType->getAs<PointerType>())
     if (const PointerType *ToPtrType = ToType->getAs<PointerType>()) {
       QualType FromPointeeType = FromPtrType->getPointeeType(),
@@ -1363,7 +1749,7 @@
           return true;
         
         // The conversion was successful.
-        Kind = CastExpr::CK_DerivedToBase;
+        Kind = CK_DerivedToBase;
       }
     }
   if (const ObjCObjectPointerType *FromPtrType =
@@ -1428,8 +1814,8 @@
 /// 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,
+                                        CastKind &Kind,
+                                        CXXCastPath &BasePath,
                                         bool IgnoreBaseAccess) {
   QualType FromType = From->getType();
   const MemberPointerType *FromPtrType = FromType->getAs<MemberPointerType>();
@@ -1438,7 +1824,7 @@
     assert(From->isNullPointerConstant(Context, 
                                        Expr::NPC_ValueDependentIsNull) &&
            "Expr must be null pointer constant!");
-    Kind = CastExpr::CK_NullToMemberPointer;
+    Kind = CK_NullToMemberPointer;
     return false;
   }
 
@@ -1482,7 +1868,7 @@
 
   // Must be a base to derived member conversion.
   BuildBasePathArray(Paths, BasePath);
-  Kind = CastExpr::CK_BaseToDerivedMemberPointer;
+  Kind = CK_BaseToDerivedMemberPointer;
   return false;
 }
 
@@ -1504,7 +1890,7 @@
   //   in multi-level pointers, subject to the following rules: [...]
   bool PreviousToQualsIncludeConst = true;
   bool UnwrappedAnyPointer = false;
-  while (UnwrapSimilarPointerTypes(FromType, ToType)) {
+  while (Context.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
@@ -1548,10 +1934,11 @@
 /// \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) {
+static OverloadingResult
+IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
+                        UserDefinedConversionSequence& User,
+                        OverloadCandidateSet& CandidateSet,
+                        bool AllowExplicit) {
   // Whether we will only visit constructors.
   bool ConstructorsOnly = false;
 
@@ -1566,21 +1953,17 @@
     //   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()) ||
+    if (S.Context.hasSameUnqualifiedType(ToType, From->getType()) ||
         (From->getType()->getAs<RecordType>() &&
-         IsDerivedFrom(From->getType(), ToType)))
+         S.IsDerivedFrom(From->getType(), ToType)))
       ConstructorsOnly = true;
 
-    if (RequireCompleteType(From->getLocStart(), ToType, PDiag())) {
+    if (S.RequireCompleteType(From->getLocStart(), ToType, S.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);
+      for (llvm::tie(Con, ConEnd) = S.LookupConstructors(ToRecordDecl);
            Con != ConEnd; ++Con) {
         NamedDecl *D = *Con;
         DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
@@ -1598,16 +1981,18 @@
         if (!Constructor->isInvalidDecl() &&
             Constructor->isConvertingConstructor(AllowExplicit)) {
           if (ConstructorTmpl)
-            AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
-                                         /*ExplicitArgs*/ 0,
-                                         &From, 1, CandidateSet, 
-                                 /*SuppressUserConversions=*/!ConstructorsOnly);
+            S.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);
+            S.AddOverloadCandidate(Constructor, FoundDecl,
+                                   &From, 1, CandidateSet,
+                                   /*SuppressUserConversions=*/
+                                     !ConstructorsOnly);
         }
       }
     }
@@ -1615,8 +2000,8 @@
 
   // Enumerate conversion functions, if we're allowed to.
   if (ConstructorsOnly) {
-  } else if (RequireCompleteType(From->getLocStart(), From->getType(),
-                          PDiag(0) << From->getSourceRange())) {
+  } else if (S.RequireCompleteType(From->getLocStart(), From->getType(),
+                                   S.PDiag(0) << From->getSourceRange())) {
     // No conversion functions from incomplete types.
   } else if (const RecordType *FromRecordType
                                    = From->getType()->getAs<RecordType>()) {
@@ -1642,80 +2027,79 @@
 
         if (AllowExplicit || !Conv->isExplicit()) {
           if (ConvTemplate)
-            AddTemplateConversionCandidate(ConvTemplate, FoundDecl,
-                                           ActingContext, From, ToType,
-                                           CandidateSet);
+            S.AddTemplateConversionCandidate(ConvTemplate, FoundDecl,
+                                             ActingContext, From, ToType,
+                                             CandidateSet);
           else
-            AddConversionCandidate(Conv, FoundDecl, ActingContext,
-                                   From, ToType, CandidateSet);
+            S.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.
+  switch (CandidateSet.BestViableFunction(S, 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(S.Context);
+      if (Best->Conversions[0].isEllipsis())
+        User.EllipsisConversion = true;
+      else {
         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;
       }
+      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;
 
-    case OR_No_Viable_Function:
+      // 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 {
+      llvm_unreachable("Not a constructor or conversion function?");
       return OR_No_Viable_Function;
-    case OR_Deleted:
-      // No conversion here! We're done.
-      return OR_Deleted;
-
-    case OR_Ambiguous:
-      return OR_Ambiguous;
     }
 
+  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;
 }
   
@@ -1724,7 +2108,7 @@
   ImplicitConversionSequence ICS;
   OverloadCandidateSet CandidateSet(From->getExprLoc());
   OverloadingResult OvResult = 
-    IsUserDefinedConversion(From, ToType, ICS.UserDefined,
+    IsUserDefinedConversion(*this, From, ToType, ICS.UserDefined,
                             CandidateSet, false);
   if (OvResult == OR_Ambiguous)
     Diag(From->getSourceRange().getBegin(),
@@ -1736,16 +2120,17 @@
     << From->getType() << ToType << From->getSourceRange();
   else
     return false;
-  PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, &From, 1);
+  CandidateSet.NoteCandidates(*this, 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)
+static ImplicitConversionSequence::CompareKind
+CompareImplicitConversionSequences(Sema &S,
+                                   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)
@@ -1775,7 +2160,7 @@
   // indistinguishable conversion sequences unless one of the
   // following rules apply: (C++ 13.3.3.2p3):
   if (ICS1.isStandard())
-    return CompareStandardConversionSequences(ICS1.Standard, ICS2.Standard);
+    return CompareStandardConversionSequences(S, 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
@@ -1785,13 +2170,24 @@
     // U2 (C++ 13.3.3.2p3).
     if (ICS1.UserDefined.ConversionFunction ==
           ICS2.UserDefined.ConversionFunction)
-      return CompareStandardConversionSequences(ICS1.UserDefined.After,
+      return CompareStandardConversionSequences(S,
+                                                ICS1.UserDefined.After,
                                                 ICS2.UserDefined.After);
   }
 
   return ImplicitConversionSequence::Indistinguishable;
 }
 
+static bool hasSimilarType(ASTContext &Context, QualType T1, QualType T2) {
+  while (Context.UnwrapSimilarPointerTypes(T1, T2)) {
+    Qualifiers Quals;
+    T1 = Context.getUnqualifiedArrayType(T1, Quals);
+    T2 = Context.getUnqualifiedArrayType(T2, Quals);    
+  }
+  
+  return Context.hasSameUnqualifiedType(T1, T2);
+}
+  
 // 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
@@ -1801,6 +2197,15 @@
   ImplicitConversionSequence::CompareKind Result
     = ImplicitConversionSequence::Indistinguishable;
 
+  // the identity conversion sequence is considered to be a subsequence of 
+  // any non-identity conversion sequence
+  if (SCS1.ReferenceBinding == SCS2.ReferenceBinding) {
+    if (SCS1.isIdentityConversion() && !SCS2.isIdentityConversion())
+      return ImplicitConversionSequence::Better;
+    else if (!SCS1.isIdentityConversion() && SCS2.isIdentityConversion())
+      return ImplicitConversionSequence::Worse;
+  }
+    
   if (SCS1.Second != SCS2.Second) {
     if (SCS1.Second == ICK_Identity)
       Result = ImplicitConversionSequence::Better;
@@ -1808,7 +2213,7 @@
       Result = ImplicitConversionSequence::Worse;
     else
       return ImplicitConversionSequence::Indistinguishable;
-  } else if (!Context.hasSameType(SCS1.getToType(1), SCS2.getToType(1)))
+  } else if (!hasSimilarType(Context, SCS1.getToType(1), SCS2.getToType(1)))
     return ImplicitConversionSequence::Indistinguishable;
 
   if (SCS1.Third == SCS2.Third) {
@@ -1832,9 +2237,10 @@
 /// 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)
+static ImplicitConversionSequence::CompareKind
+CompareStandardConversionSequences(Sema &S,
+                                   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):
@@ -1845,7 +2251,7 @@
   //     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))
+        = compareStandardConversionSubsets(S.Context, SCS1, SCS2))
     return CK;
 
   //  -- the rank of S1 is better than the rank of S2 (by the rules
@@ -1876,9 +2282,9 @@
   //   void*, and conversion of A* to void* is better than conversion
   //   of B* to void*.
   bool SCS1ConvertsToVoid
-    = SCS1.isPointerConversionToVoidPointer(Context);
+    = SCS1.isPointerConversionToVoidPointer(S.Context);
   bool SCS2ConvertsToVoid
-    = SCS2.isPointerConversionToVoidPointer(Context);
+    = SCS2.isPointerConversionToVoidPointer(S.Context);
   if (SCS1ConvertsToVoid != SCS2ConvertsToVoid) {
     // Exactly one of the conversion sequences is a conversion to
     // a void pointer; it's the worse conversion.
@@ -1888,7 +2294,7 @@
     // Neither conversion sequence converts to a void pointer; compare
     // their derived-to-base conversions.
     if (ImplicitConversionSequence::CompareKind DerivedCK
-          = CompareDerivedToBaseConversions(SCS1, SCS2))
+          = CompareDerivedToBaseConversions(S, SCS1, SCS2))
       return DerivedCK;
   } else if (SCS1ConvertsToVoid && SCS2ConvertsToVoid) {
     // Both conversion sequences are conversions to void
@@ -1900,28 +2306,28 @@
     // 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);
+      FromType1 = S.Context.getArrayDecayedType(FromType1);
     if (SCS2.First == ICK_Array_To_Pointer)
-      FromType2 = Context.getArrayDecayedType(FromType2);
+      FromType2 = S.Context.getArrayDecayedType(FromType2);
 
     QualType FromPointee1
       = FromType1->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
     QualType FromPointee2
       = FromType2->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
 
-    if (IsDerivedFrom(FromPointee2, FromPointee1))
+    if (S.IsDerivedFrom(FromPointee2, FromPointee1))
       return ImplicitConversionSequence::Better;
-    else if (IsDerivedFrom(FromPointee1, FromPointee2))
+    else if (S.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>();
+    const ObjCObjectType* FromIface1 = FromPointee1->getAs<ObjCObjectType>();
+    const ObjCObjectType* FromIface2 = FromPointee2->getAs<ObjCObjectType>();
     if (FromIface1 && FromIface1) {
-      if (Context.canAssignObjCInterfaces(FromIface2, FromIface1))
+      if (S.Context.canAssignObjCInterfaces(FromIface2, FromIface1))
         return ImplicitConversionSequence::Better;
-      else if (Context.canAssignObjCInterfaces(FromIface1, FromIface2))
+      else if (S.Context.canAssignObjCInterfaces(FromIface1, FromIface2))
         return ImplicitConversionSequence::Worse;
     }
   }
@@ -1929,7 +2335,7 @@
   // Compare based on qualification conversions (C++ 13.3.3.2p3,
   // bullet 3).
   if (ImplicitConversionSequence::CompareKind QualCK
-        = CompareQualificationConversions(SCS1, SCS2))
+        = CompareQualificationConversions(S, SCS1, SCS2))
     return QualCK;
 
   if (SCS1.ReferenceBinding && SCS2.ReferenceBinding) {
@@ -1953,18 +2359,18 @@
     //      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);
+    T1 = S.Context.getCanonicalType(T1);
+    T2 = S.Context.getCanonicalType(T2);
     Qualifiers T1Quals, T2Quals;
-    QualType UnqualT1 = Context.getUnqualifiedArrayType(T1, T1Quals);
-    QualType UnqualT2 = Context.getUnqualifiedArrayType(T2, T2Quals);
+    QualType UnqualT1 = S.Context.getUnqualifiedArrayType(T1, T1Quals);
+    QualType UnqualT2 = S.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);
+        T1 = S.Context.getQualifiedType(UnqualT1, T1Quals);
       if (isa<ArrayType>(T2) && T2Quals)
-        T2 = Context.getQualifiedType(UnqualT2, T2Quals);
+        T2 = S.Context.getQualifiedType(UnqualT2, T2Quals);
       if (T2.isMoreQualifiedThan(T1))
         return ImplicitConversionSequence::Better;
       else if (T1.isMoreQualifiedThan(T2))
@@ -1979,8 +2385,9 @@
 /// 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) {
+CompareQualificationConversions(Sema &S,
+                                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
@@ -1995,11 +2402,11 @@
   // conversion (!)
   QualType T1 = SCS1.getToType(2);
   QualType T2 = SCS2.getToType(2);
-  T1 = Context.getCanonicalType(T1);
-  T2 = Context.getCanonicalType(T2);
+  T1 = S.Context.getCanonicalType(T1);
+  T2 = S.Context.getCanonicalType(T2);
   Qualifiers T1Quals, T2Quals;
-  QualType UnqualT1 = Context.getUnqualifiedArrayType(T1, T1Quals);
-  QualType UnqualT2 = Context.getUnqualifiedArrayType(T2, T2Quals);
+  QualType UnqualT1 = S.Context.getUnqualifiedArrayType(T1, T1Quals);
+  QualType UnqualT2 = S.Context.getUnqualifiedArrayType(T2, T2Quals);
 
   // If the types are the same, we won't learn anything by unwrapped
   // them.
@@ -2009,13 +2416,13 @@
   // 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);
+    T1 = S.Context.getQualifiedType(UnqualT1, T1Quals);
   if (isa<ArrayType>(T2) && T2Quals)
-    T2 = Context.getQualifiedType(UnqualT2, T2Quals);
+    T2 = S.Context.getQualifiedType(UnqualT2, T2Quals);
 
   ImplicitConversionSequence::CompareKind Result
     = ImplicitConversionSequence::Indistinguishable;
-  while (UnwrapSimilarPointerTypes(T1, T2)) {
+  while (S.Context.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
@@ -2050,7 +2457,7 @@
     }
 
     // If the types after this point are equivalent, we're done.
-    if (Context.hasSameUnqualifiedType(T1, T2))
+    if (S.Context.hasSameUnqualifiedType(T1, T2))
       break;
   }
 
@@ -2080,8 +2487,9 @@
 /// [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) {
+CompareDerivedToBaseConversions(Sema &S,
+                                const StandardConversionSequence& SCS1,
+                                const StandardConversionSequence& SCS2) {
   QualType FromType1 = SCS1.getFromType();
   QualType ToType1 = SCS1.getToType(1);
   QualType FromType2 = SCS2.getFromType();
@@ -2090,15 +2498,15 @@
   // 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);
+    FromType1 = S.Context.getArrayDecayedType(FromType1);
   if (SCS2.First == ICK_Array_To_Pointer)
-    FromType2 = Context.getArrayDecayedType(FromType2);
+    FromType2 = S.Context.getArrayDecayedType(FromType2);
 
   // Canonicalize all of the types.
-  FromType1 = Context.getCanonicalType(FromType1);
-  ToType1 = Context.getCanonicalType(ToType1);
-  FromType2 = Context.getCanonicalType(FromType2);
-  ToType2 = Context.getCanonicalType(ToType2);
+  FromType1 = S.Context.getCanonicalType(FromType1);
+  ToType1 = S.Context.getCanonicalType(ToType1);
+  FromType2 = S.Context.getCanonicalType(FromType2);
+  ToType2 = S.Context.getCanonicalType(ToType2);
 
   // C++ [over.ics.rank]p4b3:
   //
@@ -2123,37 +2531,37 @@
     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>();
+    const ObjCObjectType* FromIface1 = FromPointee1->getAs<ObjCObjectType>();
+    const ObjCObjectType* FromIface2 = FromPointee2->getAs<ObjCObjectType>();
+    const ObjCObjectType* ToIface1 = ToPointee1->getAs<ObjCObjectType>();
+    const ObjCObjectType* ToIface2 = ToPointee2->getAs<ObjCObjectType>();
 
     //   -- conversion of C* to B* is better than conversion of C* to A*,
     if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) {
-      if (IsDerivedFrom(ToPointee1, ToPointee2))
+      if (S.IsDerivedFrom(ToPointee1, ToPointee2))
         return ImplicitConversionSequence::Better;
-      else if (IsDerivedFrom(ToPointee2, ToPointee1))
+      else if (S.IsDerivedFrom(ToPointee2, ToPointee1))
         return ImplicitConversionSequence::Worse;
 
       if (ToIface1 && ToIface2) {
-        if (Context.canAssignObjCInterfaces(ToIface2, ToIface1))
+        if (S.Context.canAssignObjCInterfaces(ToIface2, ToIface1))
           return ImplicitConversionSequence::Better;
-        else if (Context.canAssignObjCInterfaces(ToIface1, ToIface2))
+        else if (S.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))
+      if (S.IsDerivedFrom(FromPointee2, FromPointee1))
         return ImplicitConversionSequence::Better;
-      else if (IsDerivedFrom(FromPointee1, FromPointee2))
+      else if (S.IsDerivedFrom(FromPointee1, FromPointee2))
         return ImplicitConversionSequence::Worse;
 
       if (FromIface1 && FromIface2) {
-        if (Context.canAssignObjCInterfaces(FromIface1, FromIface2))
+        if (S.Context.canAssignObjCInterfaces(FromIface1, FromIface2))
           return ImplicitConversionSequence::Better;
-        else if (Context.canAssignObjCInterfaces(FromIface2, FromIface1))
+        else if (S.Context.canAssignObjCInterfaces(FromIface2, FromIface1))
           return ImplicitConversionSequence::Worse;
       }
     }
@@ -2181,16 +2589,16 @@
     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))
+      if (S.IsDerivedFrom(ToPointee1, ToPointee2))
         return ImplicitConversionSequence::Worse;
-      else if (IsDerivedFrom(ToPointee2, ToPointee1))
+      else if (S.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))
+      if (S.IsDerivedFrom(FromPointee1, FromPointee2))
         return ImplicitConversionSequence::Better;
-      else if (IsDerivedFrom(FromPointee2, FromPointee1))
+      else if (S.IsDerivedFrom(FromPointee2, FromPointee1))
         return ImplicitConversionSequence::Worse;
     }
   }
@@ -2200,11 +2608,11 @@
     //   -- 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))
+    if (S.Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+        !S.Context.hasSameUnqualifiedType(ToType1, ToType2)) {
+      if (S.IsDerivedFrom(ToType1, ToType2))
         return ImplicitConversionSequence::Better;
-      else if (IsDerivedFrom(ToType2, ToType1))
+      else if (S.IsDerivedFrom(ToType2, ToType1))
         return ImplicitConversionSequence::Worse;
     }
 
@@ -2212,11 +2620,11 @@
     //   -- 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))
+    if (!S.Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+        S.Context.hasSameUnqualifiedType(ToType1, ToType2)) {
+      if (S.IsDerivedFrom(FromType2, FromType1))
         return ImplicitConversionSequence::Better;
-      else if (IsDerivedFrom(FromType1, FromType2))
+      else if (S.IsDerivedFrom(FromType1, FromType2))
         return ImplicitConversionSequence::Worse;
     }
   }
@@ -2234,7 +2642,8 @@
 Sema::ReferenceCompareResult
 Sema::CompareReferenceRelationship(SourceLocation Loc,
                                    QualType OrigT1, QualType OrigT2,
-                                   bool& DerivedToBase) {
+                                   bool &DerivedToBase,
+                                   bool &ObjCConversion) {
   assert(!OrigT1->isReferenceType() &&
     "T1 must be the pointee type of the reference type");
   assert(!OrigT2->isReferenceType() && "T2 cannot be a reference type");
@@ -2249,12 +2658,17 @@
   //   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()) &&
+  DerivedToBase = false;
+  ObjCConversion = false;
+  if (UnqualT1 == UnqualT2) {
+    // Nothing to do.
+  } else if (!RequireCompleteType(Loc, OrigT2, PDiag()) &&
            IsDerivedFrom(UnqualT2, UnqualT1))
     DerivedToBase = true;
+  else if (UnqualT1->isObjCObjectOrInterfaceType() &&
+           UnqualT2->isObjCObjectOrInterfaceType() &&
+           Context.canBindObjCObjectType(UnqualT1, UnqualT2))
+    ObjCConversion = true;
   else
     return Ref_Incompatible;
 
@@ -2283,6 +2697,119 @@
     return Ref_Related;
 }
 
+/// \brief Look for a user-defined conversion to an value reference-compatible
+///        with DeclType. Return true if something definite is found.
+static bool
+FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
+                         QualType DeclType, SourceLocation DeclLoc,
+                         Expr *Init, QualType T2, bool AllowRvalues,
+                         bool AllowExplicit) {
+  assert(T2->isRecordType() && "Can only find conversions of record types.");
+  CXXRecordDecl *T2RecordDecl
+    = dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
+
+  QualType ToType
+    = AllowRvalues? DeclType->getAs<ReferenceType>()->getPointeeType()
+                  : DeclType;
+
+  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 this is an explicit conversion, and we're not allowed to consider 
+    // explicit conversions, skip it.
+    if (!AllowExplicit && Conv->isExplicit())
+      continue;
+    
+    if (AllowRvalues) {
+      bool DerivedToBase = false;
+      bool ObjCConversion = false;
+      if (!ConvTemplate &&
+          S.CompareReferenceRelationship(DeclLoc,
+                                         Conv->getConversionType().getNonReferenceType().getUnqualifiedType(),
+                                         DeclType.getNonReferenceType().getUnqualifiedType(),
+                                         DerivedToBase, ObjCConversion)
+            == Sema::Ref_Incompatible)
+        continue;
+    } else {
+      // If the conversion function doesn't return a reference type,
+      // it can't be considered for this conversion. An rvalue reference
+      // is only acceptable if its referencee is a function type.
+
+      const ReferenceType *RefType =
+        Conv->getConversionType()->getAs<ReferenceType>();
+      if (!RefType ||
+          (!RefType->isLValueReferenceType() &&
+           !RefType->getPointeeType()->isFunctionType()))
+        continue;
+    }
+    
+    if (ConvTemplate)
+      S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC,
+                                       Init, ToType, CandidateSet);
+    else
+      S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Init,
+                               ToType, CandidateSet);
+  }
+
+  OverloadCandidateSet::iterator Best;
+  switch (CandidateSet.BestViableFunction(S, 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)
+      return false;
+
+    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 true;
+
+  case OR_Ambiguous:
+    ICS.setAmbiguous();
+    for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
+         Cand != CandidateSet.end(); ++Cand)
+      if (Cand->Viable)
+        ICS.Ambiguous.addConversion(Cand->Function);
+    return true;
+
+  case OR_No_Viable_Function:
+  case OR_Deleted:
+    // There was no suitable conversion, or we found a deleted
+    // conversion; continue with other checks.
+    return false;
+  }
+  
+  return false;
+}
+
 /// \brief Compute an implicit conversion sequence for reference
 /// initialization.
 static ImplicitConversionSequence
@@ -2312,149 +2839,77 @@
   // Compute some basic properties of the types and the initializer.
   bool isRValRef = DeclType->isRValueReferenceType();
   bool DerivedToBase = false;
-  Expr::isLvalueResult InitLvalue = Init->isLvalue(S.Context);
+  bool ObjCConversion = false;
+  Expr::Classification InitCategory = Init->Classify(S.Context);
   Sema::ReferenceCompareResult RefRelationship
-    = S.CompareReferenceRelationship(DeclLoc, T1, T2, DerivedToBase);
+    = S.CompareReferenceRelationship(DeclLoc, T1, T2, DerivedToBase,
+                                     ObjCConversion);
 
 
-  // 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:
+  // 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 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:
+  //     -- If reference is an lvalue reference and the initializer expression
+  // The next bullet point (T1 is a function) is pretty much equivalent to this
+  // one, so it's handled here.
+  if (!isRValRef || T1->isFunctionType()) {
+    //     -- 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 (InitCategory.isLValue() &&
+        RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
       // 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;
+      //   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
+                         : ObjCConversion? ICK_Compatible_Conversion
+                         : 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 = isRValRef;
+      ICS.Standard.CopyConstructor = 0;
 
-      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!");
+      // 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;
+    }
 
-    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;
+    //       -- 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 (!SuppressUserConversions && T2->isRecordType() &&
+        !S.RequireCompleteType(DeclLoc, T2, 0) && 
+        RefRelationship == Sema::Ref_Incompatible) {
+      if (FindConversionForRefInit(S, ICS, DeclType, DeclLoc,
+                                   Init, T2, /*AllowRvalues=*/false,
+                                   AllowExplicit))
+        return ICS;
     }
   }
 
-  //     -- 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.
+  //     -- 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 or have a function type.
   // 
   // We actually handle one oddity of C++ [over.ics.ref] at this
   // point, which is that, due to p2 (which short-circuits reference
@@ -2463,10 +2918,26 @@
   // 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())
+  // This is also the point where rvalue references and lvalue inits no longer
+  // go together.
+  if ((!isRValRef && !T1.isConstQualified()) ||
+      (isRValRef && InitCategory.isLValue()))
     return ICS;
 
-  //       -- if T2 is a class type and
+  //       -- If T1 is a function type, then
+  //          -- if T2 is the same type as T1, the reference is bound to the
+  //             initializer expression lvalue;
+  //          -- if T2 is a class type and the initializer expression can be
+  //             implicitly converted to an lvalue of type T1 [...], the
+  //             reference is bound to the function lvalue that is the result
+  //             of the conversion;
+  // This is the same as for the lvalue case above, so it was handled there.
+  //          -- otherwise, the program is ill-formed.
+  // This is the one difference to the lvalue case.
+  if (T1->isFunctionType())
+    return ICS;
+
+  //       -- Otherwise, if T2 is a class type and
   //          -- the initializer expression is an rvalue and "cv1 T1"
   //             is reference-compatible with "cv2 T2," or
   //
@@ -2482,26 +2953,37 @@
   //          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;
+  if (T2->isRecordType()) {
+    // First case: "cv1 T1" is reference-compatible with "cv2 T2". This is a
+    // direct binding in C++0x but not in C++03.
+    if (InitCategory.isRValue() && 
+        RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
+      ICS.setStandard();
+      ICS.Standard.First = ICK_Identity;
+      ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base 
+                          : ObjCConversion? ICK_Compatible_Conversion
+                          : 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;
+    }
+    
+    // Second case: not reference-related.
+    if (RefRelationship == Sema::Ref_Incompatible &&
+        !S.RequireCompleteType(DeclLoc, T2, 0) && 
+        FindConversionForRefInit(S, ICS, DeclType, DeclLoc,
+                                 Init, T2, /*AllowRvalues=*/true,
+                                 AllowExplicit))
+      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
@@ -2536,9 +3018,9 @@
   //   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);
+  ICS = TryImplicitConversion(S, Init, T1, SuppressUserConversions,
+                              /*AllowExplicit=*/false,
+                              /*InOverloadResolution=*/false);
 
   // Of course, that's still a reference binding.
   if (ICS.isStandard()) {
@@ -2567,25 +3049,25 @@
                             SuppressUserConversions,
                             /*AllowExplicit=*/false);
 
-  return S.TryImplicitConversion(From, ToType,
-                                 SuppressUserConversions,
-                                 /*AllowExplicit=*/false,
-                                 InOverloadResolution);
+  return TryImplicitConversion(S, 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);
+static ImplicitConversionSequence
+TryObjectArgumentInitialization(Sema &S, QualType OrigFromType,
+                                CXXMethodDecl *Method,
+                                CXXRecordDecl *ActingContext) {
+  QualType ClassType = S.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);
+  QualType ImplicitParamType =  S.Context.getCVRQualifiedType(ClassType, Quals);
 
   // Set up the conversion sequence as a "bad" conversion, to allow us
   // to exit early.
@@ -2609,7 +3091,7 @@
 
   // 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);
+  QualType FromTypeCanon = S.Context.getCanonicalType(FromType);
   if (ImplicitParamType.getCVRQualifiers() 
                                     != FromTypeCanon.getLocalCVRQualifiers() &&
       !ImplicitParamType.isAtLeastAsQualifiedAs(FromTypeCanon)) {
@@ -2620,11 +3102,11 @@
 
   // Check that we have either the same type or a derived type. It
   // affects the conversion rank.
-  QualType ClassTypeCanon = Context.getCanonicalType(ClassType);
+  QualType ClassTypeCanon = S.Context.getCanonicalType(ClassType);
   ImplicitConversionKind SecondKind;
   if (ClassTypeCanon == FromTypeCanon.getLocalUnqualifiedType()) {
     SecondKind = ICK_Identity;
-  } else if (IsDerivedFrom(FromType, ClassType))
+  } else if (S.IsDerivedFrom(FromType, ClassType))
     SecondKind = ICK_Derived_To_Base;
   else {
     ICS.setBad(BadConversionSequence::unrelated_class,
@@ -2667,7 +3149,7 @@
   // Note that we always use the true parent context when performing
   // the actual argument initialization.
   ImplicitConversionSequence ICS
-    = TryObjectArgumentInitialization(From->getType(), Method,
+    = TryObjectArgumentInitialization(*this, From->getType(), Method,
                                       Method->getParent());
   if (ICS.isBad())
     return Diag(From->getSourceRange().getBegin(),
@@ -2678,15 +3160,17 @@
     return PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method);
 
   if (!Context.hasSameType(From->getType(), DestType))
-    ImpCastExprToType(From, DestType, CastExpr::CK_NoOp,
-                      /*isLvalue=*/!From->getType()->isPointerType());
+    ImpCastExprToType(From, DestType, CK_NoOp,
+                      From->getType()->isPointerType() ? VK_RValue : VK_LValue);
   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,
+static ImplicitConversionSequence
+TryContextuallyConvertToBool(Sema &S, Expr *From) {
+  // FIXME: This is pretty broken.
+  return TryImplicitConversion(S, From, S.Context.BoolTy,
                                // FIXME: Are these flags correct?
                                /*SuppressUserConversions=*/false,
                                /*AllowExplicit=*/true,
@@ -2696,7 +3180,7 @@
 /// PerformContextuallyConvertToBool - Perform a contextual conversion
 /// of the expression From to bool (C++0x [conv]p3).
 bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
-  ImplicitConversionSequence ICS = TryContextuallyConvertToBool(From);
+  ImplicitConversionSequence ICS = TryContextuallyConvertToBool(*this, From);
   if (!ICS.isBad())
     return PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting);
   
@@ -2706,6 +3190,195 @@
                   << From->getType() << From->getSourceRange();
   return true;
 }
+  
+/// TryContextuallyConvertToObjCId - Attempt to contextually convert the
+/// expression From to 'id'.
+static ImplicitConversionSequence
+TryContextuallyConvertToObjCId(Sema &S, Expr *From) {
+  QualType Ty = S.Context.getObjCIdType();
+  return TryImplicitConversion(S, From, Ty,
+                               // FIXME: Are these flags correct?
+                               /*SuppressUserConversions=*/false,
+                               /*AllowExplicit=*/true,
+                               /*InOverloadResolution=*/false);
+}
+
+/// PerformContextuallyConvertToObjCId - Perform a contextual conversion
+/// of the expression From to 'id'.
+bool Sema::PerformContextuallyConvertToObjCId(Expr *&From) {
+  QualType Ty = Context.getObjCIdType();
+  ImplicitConversionSequence ICS = TryContextuallyConvertToObjCId(*this, From);
+  if (!ICS.isBad())
+    return PerformImplicitConversion(From, Ty, ICS, AA_Converting);
+  return true;
+}
+
+/// \brief Attempt to convert the given expression to an integral or 
+/// enumeration type.
+///
+/// This routine will attempt to convert an expression of class type to an
+/// integral or enumeration type, if that class type only has a single
+/// conversion to an integral or enumeration type.
+///
+/// \param Loc The source location of the construct that requires the
+/// conversion.
+///
+/// \param FromE The expression we're converting from.
+///
+/// \param NotIntDiag The diagnostic to be emitted if the expression does not
+/// have integral or enumeration type.
+///
+/// \param IncompleteDiag The diagnostic to be emitted if the expression has
+/// incomplete class type.
+///
+/// \param ExplicitConvDiag The diagnostic to be emitted if we're calling an
+/// explicit conversion function (because no implicit conversion functions
+/// were available). This is a recovery mode.
+///
+/// \param ExplicitConvNote The note to be emitted with \p ExplicitConvDiag,
+/// showing which conversion was picked.
+///
+/// \param AmbigDiag The diagnostic to be emitted if there is more than one
+/// conversion function that could convert to integral or enumeration type.
+///
+/// \param AmbigNote The note to be emitted with \p AmbigDiag for each 
+/// usable conversion function.
+///
+/// \param ConvDiag The diagnostic to be emitted if we are calling a conversion
+/// function, which may be an extension in this case.
+///
+/// \returns The expression, converted to an integral or enumeration type if
+/// successful.
+ExprResult 
+Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
+                                         const PartialDiagnostic &NotIntDiag,
+                                       const PartialDiagnostic &IncompleteDiag,
+                                     const PartialDiagnostic &ExplicitConvDiag,
+                                     const PartialDiagnostic &ExplicitConvNote,
+                                         const PartialDiagnostic &AmbigDiag,
+                                         const PartialDiagnostic &AmbigNote,
+                                         const PartialDiagnostic &ConvDiag) {
+  // We can't perform any more checking for type-dependent expressions.
+  if (From->isTypeDependent())
+    return Owned(From);
+  
+  // If the expression already has integral or enumeration type, we're golden.
+  QualType T = From->getType();
+  if (T->isIntegralOrEnumerationType())
+    return Owned(From);
+
+  // FIXME: Check for missing '()' if T is a function type?
+
+  // If we don't have a class type in C++, there's no way we can get an 
+  // expression of integral or enumeration type.
+  const RecordType *RecordTy = T->getAs<RecordType>();
+  if (!RecordTy || !getLangOptions().CPlusPlus) {
+    Diag(Loc, NotIntDiag)
+      << T << From->getSourceRange();
+    return Owned(From);
+  }
+    
+  // We must have a complete class type.
+  if (RequireCompleteType(Loc, T, IncompleteDiag))
+    return Owned(From);
+  
+  // Look for a conversion to an integral or enumeration type.
+  UnresolvedSet<4> ViableConversions;
+  UnresolvedSet<4> ExplicitConversions;
+  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()
+            ->isIntegralOrEnumerationType()) {
+        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, Context.PrintingPolicy);
+      
+      Diag(Loc, ExplicitConvDiag)
+        << T << ConvTy
+        << FixItHint::CreateInsertion(From->getLocStart(),
+                                      "static_cast<" + TypeStr + ">(")
+        << FixItHint::CreateInsertion(PP.getLocForEndOfToken(From->getLocEnd()),
+                                      ")");
+      Diag(Conversion->getLocation(), ExplicitConvNote)
+        << ConvTy->isEnumeralType() << ConvTy;
+      
+      // If we aren't in a SFINAE context, build a call to the 
+      // explicit conversion function.
+      if (isSFINAEContext())
+        return ExprError();
+      
+      CheckMemberOperatorAccess(From->getExprLoc(), From, 0, Found);
+      From = BuildCXXMemberCallExpr(From, Found, Conversion);
+    }
+    
+    // We'll complain below about a non-integral condition type.
+    break;
+      
+  case 1: {
+    // Apply this conversion.
+    DeclAccessPair Found = ViableConversions[0];
+    CheckMemberOperatorAccess(From->getExprLoc(), From, 0, Found);
+    
+    CXXConversionDecl *Conversion
+      = cast<CXXConversionDecl>(Found->getUnderlyingDecl());
+    QualType ConvTy
+      = Conversion->getConversionType().getNonReferenceType();    
+    if (ConvDiag.getDiagID()) {
+      if (isSFINAEContext())
+        return ExprError();
+      
+      Diag(Loc, ConvDiag)
+        << T << ConvTy->isEnumeralType() << ConvTy << From->getSourceRange();
+    }
+    
+    From = BuildCXXMemberCallExpr(From, Found,
+                          cast<CXXConversionDecl>(Found->getUnderlyingDecl()));
+    break;
+  }
+    
+  default:
+    Diag(Loc, AmbigDiag)
+      << T << From->getSourceRange();
+    for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) {
+      CXXConversionDecl *Conv
+        = cast<CXXConversionDecl>(ViableConversions[I]->getUnderlyingDecl());
+      QualType ConvTy = Conv->getConversionType().getNonReferenceType();
+      Diag(Conv->getLocation(), AmbigNote)
+        << ConvTy->isEnumeralType() << ConvTy;
+    }
+    return Owned(From);
+  }
+  
+  if (!From->getType()->isIntegralOrEnumerationType())
+    Diag(Loc, NotIntDiag)
+      << From->getType() << From->getSourceRange();
+
+  return Owned(From);
+}
 
 /// AddOverloadCandidate - Adds the given function to the set of
 /// candidate functions, using the given function call arguments.  If
@@ -2750,7 +3423,7 @@
     return;
 
   // Overload resolution is always an unevaluated context.
-  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
 
   if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Function)){
     // C++ [class.copy]p3:
@@ -2913,7 +3586,7 @@
     return;
 
   // Overload resolution is always an unevaluated context.
-  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
 
   // Add this candidate
   CandidateSet.push_back(OverloadCandidate());
@@ -2957,7 +3630,8 @@
     // Determine the implicit conversion sequence for the object
     // parameter.
     Candidate.Conversions[0]
-      = TryObjectArgumentInitialization(ObjectType, Method, ActingContext);
+      = TryObjectArgumentInitialization(*this, ObjectType, Method,
+                                        ActingContext);
     if (Candidate.Conversions[0].isBad()) {
       Candidate.Viable = false;
       Candidate.FailureKind = ovl_fail_bad_conversion;
@@ -2991,7 +3665,7 @@
     }
   }
 }
-
+  
 /// \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.
@@ -3021,11 +3695,18 @@
   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;
-      }
+    CandidateSet.push_back(OverloadCandidate());
+    OverloadCandidate &Candidate = CandidateSet.back();
+    Candidate.FoundDecl = FoundDecl;
+    Candidate.Function = MethodTmpl->getTemplatedDecl();
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_bad_deduction;
+    Candidate.IsSurrogate = false;
+    Candidate.IgnoreObjectArgument = false;
+    Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, 
+                                                          Info);
+    return;
+  }
 
   // Add the function template specialization produced by template argument
   // deduction as a candidate.
@@ -3072,10 +3753,8 @@
     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();
+    Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, 
+                                                          Info);
     return;
   }
 
@@ -3105,7 +3784,7 @@
     return;
 
   // Overload resolution is always an unevaluated context.
-  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
 
   // Add this candidate
   CandidateSet.push_back(OverloadCandidate());
@@ -3117,25 +3796,32 @@
   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);
+
+  // C++ [over.match.funcs]p4:
+  //   For conversion functions, the function is considered to be a member of 
+  //   the class of the implicit implied object argument for the purpose of 
+  //   defining the type of the implicit object parameter.
+  //
+  // Determine the implicit conversion sequence for the implicit
+  // object parameter.
+  QualType ImplicitParamType = From->getType();
+  if (const PointerType *FromPtrType = ImplicitParamType->getAs<PointerType>())
+    ImplicitParamType = FromPtrType->getPointeeType();
+  CXXRecordDecl *ConversionContext
+    = cast<CXXRecordDecl>(ImplicitParamType->getAs<RecordType>()->getDecl());
+  
   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;
+    = TryObjectArgumentInitialization(*this, From->getType(), Conversion,
+                                      ConversionContext);
+  
   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]
@@ -3158,15 +3844,16 @@
   // well-formed.
   DeclRefExpr ConversionRef(Conversion, Conversion->getType(),
                             From->getLocStart());
-  ImplicitCastExpr ConversionFn(Context.getPointerType(Conversion->getType()),
-                                CastExpr::CK_FunctionToPointerDecay,
-                                &ConversionRef, CXXBaseSpecifierArray(), false);
+  ImplicitCastExpr ConversionFn(ImplicitCastExpr::OnStack,
+                                Context.getPointerType(Conversion->getType()),
+                                CK_FunctionToPointerDecay,
+                                &ConversionRef, VK_RValue);
 
   // 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(),
+                Conversion->getConversionType().getNonLValueExprType(Context),
                 From->getLocStart());
   ImplicitConversionSequence ICS =
     TryCopyInitialization(*this, &Call, ToType,
@@ -3222,9 +3909,16 @@
   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;
+    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;
+    Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, 
+                                                          Info);
     return;
   }
 
@@ -3251,7 +3945,7 @@
     return;
 
   // Overload resolution is always an unevaluated context.
-  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
 
   CandidateSet.push_back(OverloadCandidate());
   OverloadCandidate& Candidate = CandidateSet.back();
@@ -3266,7 +3960,8 @@
   // Determine the implicit conversion sequence for the implicit
   // object parameter.
   ImplicitConversionSequence ObjectInit
-    = TryObjectArgumentInitialization(ObjectType, Conversion, ActingContext);
+    = TryObjectArgumentInitialization(*this, ObjectType, Conversion,
+                                      ActingContext);
   if (ObjectInit.isBad()) {
     Candidate.Viable = false;
     Candidate.FailureKind = ovl_fail_bad_conversion;
@@ -3357,9 +4052,6 @@
   //   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@
@@ -3398,7 +4090,7 @@
                                bool IsAssignmentOperator,
                                unsigned NumContextualBoolArguments) {
   // Overload resolution is always an unevaluated context.
-  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
 
   // Add this candidate
   CandidateSet.push_back(OverloadCandidate());
@@ -3431,7 +4123,8 @@
     if (ArgIdx < NumContextualBoolArguments) {
       assert(ParamTys[ArgIdx] == Context.BoolTy &&
              "Contextual conversion to bool requires bool type");
-      Candidate.Conversions[ArgIdx] = TryContextuallyConvertToBool(Args[ArgIdx]);
+      Candidate.Conversions[ArgIdx]
+        = TryContextuallyConvertToBool(*this, Args[ArgIdx]);
     } else {
       Candidate.Conversions[ArgIdx]
         = TryCopyInitialization(*this, Args[ArgIdx], ParamTys[ArgIdx],
@@ -3466,6 +4159,10 @@
   /// used in the built-in candidates.
   TypeSet EnumerationTypes;
 
+  /// \brief The set of vector types that will be used in the built-in 
+  /// candidates.
+  TypeSet VectorTypes;
+  
   /// Sema - The semantic analysis instance where we are building the
   /// candidate type set.
   Sema &SemaRef;
@@ -3507,6 +4204,9 @@
 
   /// enumeration_end - Past the last enumeration type found;
   iterator enumeration_end() { return EnumerationTypes.end(); }
+  
+  iterator vector_begin() { return VectorTypes.begin(); }
+  iterator vector_end() { return VectorTypes.end(); }
 };
 
 /// AddPointerWithMoreQualifiedTypeVariants - Add the pointer type @p Ty to
@@ -3525,11 +4225,21 @@
   // Insert this type.
   if (!PointerTypes.insert(Ty))
     return false;
-
+    
+  QualType PointeeTy;
   const PointerType *PointerTy = Ty->getAs<PointerType>();
-  assert(PointerTy && "type was not a pointer type!");
-
-  QualType PointeeTy = PointerTy->getPointeeType();
+  bool buildObjCPtr = false;
+  if (!PointerTy) {
+    if (const ObjCObjectPointerType *PTy = Ty->getAs<ObjCObjectPointerType>()) {
+      PointeeTy = PTy->getPointeeType();
+      buildObjCPtr = true;
+    }
+    else
+      assert(false && "type was not a pointer type!");
+  }
+  else
+    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,
@@ -3550,7 +4260,10 @@
     if ((CVR & Qualifiers::Volatile) && !hasVolatile) continue;
     if ((CVR & Qualifiers::Restrict) && !hasRestrict) continue;
     QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR);
-    PointerTypes.insert(Context.getPointerType(QPointeeTy));
+    if (!buildObjCPtr)
+      PointerTypes.insert(Context.getPointerType(QPointeeTy));
+    else
+      PointerTypes.insert(Context.getObjCObjectPointerType(QPointeeTy));
   }
 
   return true;
@@ -3625,10 +4338,9 @@
   // 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();
-
+  if (Ty->isObjCIdType() || Ty->isObjCClassType())
+    PointerTypes.insert(Ty);
+  else if (Ty->getAs<PointerType>() || Ty->getAs<ObjCObjectPointerType>()) {
     // Insert our type, and its more-qualified variants, into the set
     // of types.
     if (!AddPointerWithMoreQualifiedTypeVariants(Ty, VisibleQuals))
@@ -3639,6 +4351,8 @@
       return;
   } else if (Ty->isEnumeralType()) {
     EnumerationTypes.insert(Ty);
+  } else if (Ty->isVectorType()) {
+    VectorTypes.insert(Ty);
   } else if (AllowUserConversions) {
     if (const RecordType *TyRec = Ty->getAs<RecordType>()) {
       if (SemaRef.RequireCompleteType(Loc, Ty, 0)) {
@@ -3803,21 +4517,14 @@
     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);
-  }
+  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) {
@@ -3909,7 +4616,7 @@
     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())
+      if (!(*Ptr)->getPointeeType()->isIncompleteOrObjectType())
         continue;
 
       QualType ParamTypes[2] = {
@@ -3949,7 +4656,7 @@
     for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
          Ptr != CandidateTypes.pointer_end(); ++Ptr) {
       QualType ParamTy = *Ptr;
-      QualType PointeeTy = ParamTy->getAs<PointerType>()->getPointeeType();
+      QualType PointeeTy = ParamTy->getPointeeType();
       AddBuiltinCandidate(Context.getLValueReferenceType(PointeeTy),
                           &ParamTy, Args, 1, CandidateSet);
     }
@@ -3981,6 +4688,14 @@
       QualType ArithTy = ArithmeticTypes[Arith];
       AddBuiltinCandidate(ArithTy, &ArithTy, Args, 1, CandidateSet);
     }
+      
+    // Extension: We also add these operators for vector types.
+    for (BuiltinCandidateTypeSet::iterator Vec = CandidateTypes.vector_begin(),
+                                        VecEnd = CandidateTypes.vector_end(); 
+         Vec != VecEnd; ++Vec) {
+      QualType VecTy = *Vec;
+      AddBuiltinCandidate(VecTy, &VecTy, Args, 1, CandidateSet);
+    }
     break;
 
   case OO_Tilde:
@@ -3994,6 +4709,14 @@
       QualType IntTy = ArithmeticTypes[Int];
       AddBuiltinCandidate(IntTy, &IntTy, Args, 1, CandidateSet);
     }
+      
+    // Extension: We also add this operator for vector types.
+    for (BuiltinCandidateTypeSet::iterator Vec = CandidateTypes.vector_begin(),
+                                        VecEnd = CandidateTypes.vector_end(); 
+         Vec != VecEnd; ++Vec) {
+      QualType VecTy = *Vec;
+      AddBuiltinCandidate(VecTy, &VecTy, Args, 1, CandidateSet);
+    }      
     break;
 
   case OO_New:
@@ -4150,6 +4873,30 @@
         AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet);
       }
     }
+
+    // Extension: Add the binary operators ==, !=, <, <=, >=, >, *, /, and the
+    // conditional operator for vector types.
+    for (BuiltinCandidateTypeSet::iterator Vec1 = CandidateTypes.vector_begin(),
+         Vec1End = CandidateTypes.vector_end(); 
+         Vec1 != Vec1End; ++Vec1)
+      for (BuiltinCandidateTypeSet::iterator 
+           Vec2 = CandidateTypes.vector_begin(),
+           Vec2End = CandidateTypes.vector_end(); 
+           Vec2 != Vec2End; ++Vec2) {
+        QualType LandR[2] = { *Vec1, *Vec2 };
+        QualType Result;
+        if (isComparison)
+          Result = Context.BoolTy;
+        else {
+          if ((*Vec1)->isExtVectorType() || !(*Vec2)->isExtVectorType())
+            Result = *Vec1;
+          else
+            Result = *Vec2;
+        }
+        
+        AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet);
+      }
+      
     break;
 
   case OO_Percent:
@@ -4205,7 +4952,8 @@
          MemPtr != MemPtrEnd; ++MemPtr)
       AddBuiltinAssignmentOperatorCandidates(*this, *MemPtr, Args, 2,
                                              CandidateSet);
-      // Fall through.
+      
+    // Fall through.
 
   case OO_PlusEqual:
   case OO_MinusEqual:
@@ -4280,6 +5028,30 @@
         }
       }
     }
+      
+    // Extension: Add the binary operators =, +=, -=, *=, /= for vector types.
+    for (BuiltinCandidateTypeSet::iterator Vec1 = CandidateTypes.vector_begin(),
+                                        Vec1End = CandidateTypes.vector_end(); 
+         Vec1 != Vec1End; ++Vec1)
+      for (BuiltinCandidateTypeSet::iterator 
+                Vec2 = CandidateTypes.vector_begin(),
+             Vec2End = CandidateTypes.vector_end(); 
+           Vec2 != Vec2End; ++Vec2) {
+        QualType ParamTypes[2];
+        ParamTypes[1] = *Vec2;
+        // Add this built-in operator as a candidate (VQ is empty).
+        ParamTypes[0] = Context.getLValueReferenceType(*Vec1);
+        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(*Vec1);
+          ParamTypes[0] = Context.getLValueReferenceType(ParamTypes[0]);
+          AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+                              /*IsAssigmentOperator=*/Op == OO_Equal);
+        }
+      }
     break;
 
   case OO_PercentEqual:
@@ -4365,7 +5137,7 @@
     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 PointeeType = (*Ptr)->getPointeeType();
       QualType ResultTy = Context.getLValueReferenceType(PointeeType);
 
       // T& operator[](T*, ptrdiff_t)
@@ -4375,7 +5147,7 @@
       ParamTypes[0] = ParamTypes[1];
       ParamTypes[1] = *Ptr;
       AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet);
-    }
+    }      
     break;
 
   case OO_ArrowStar:
@@ -4393,18 +5165,16 @@
         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;
-        }
+        C1 = QualType(Q1.strip(C1Ty->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();
@@ -4513,9 +5283,10 @@
 /// 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) {
+isBetterOverloadCandidate(Sema &S,
+                          const OverloadCandidate& Cand1,
+                          const OverloadCandidate& Cand2,
+                          SourceLocation Loc) {
   // Define viable functions to be better candidates than non-viable
   // functions.
   if (!Cand2.Viable)
@@ -4541,7 +5312,8 @@
   assert(Cand2.Conversions.size() == NumArgs && "Overload candidate mismatch");
   bool HasBetterConversion = false;
   for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) {
-    switch (CompareImplicitConversionSequences(Cand1.Conversions[ArgIdx],
+    switch (CompareImplicitConversionSequences(S,
+                                               Cand1.Conversions[ArgIdx],
                                                Cand2.Conversions[ArgIdx])) {
     case ImplicitConversionSequence::Better:
       // Cand1 has a better conversion sequence.
@@ -4565,7 +5337,7 @@
 
   //     - F1 is a non-template function and F2 is a function template
   //       specialization, or, if not that,
-  if (Cand1.Function && !Cand1.Function->getPrimaryTemplate() &&
+  if ((!Cand1.Function || !Cand1.Function->getPrimaryTemplate()) &&
       Cand2.Function && Cand2.Function->getPrimaryTemplate())
     return true;
 
@@ -4576,9 +5348,9 @@
   if (Cand1.Function && Cand1.Function->getPrimaryTemplate() &&
       Cand2.Function && Cand2.Function->getPrimaryTemplate())
     if (FunctionTemplateDecl *BetterTemplate
-          = getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
-                                       Cand2.Function->getPrimaryTemplate(),
-                                       Loc,
+          = S.getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
+                                         Cand2.Function->getPrimaryTemplate(),
+                                         Loc,
                        isa<CXXConversionDecl>(Cand1.Function)? TPOC_Conversion 
                                                              : TPOC_Call))
       return BetterTemplate == Cand1.Function->getPrimaryTemplate();
@@ -4592,7 +5364,8 @@
   if (Cand1.Function && Cand2.Function &&
       isa<CXXConversionDecl>(Cand1.Function) &&
       isa<CXXConversionDecl>(Cand2.Function)) {
-    switch (CompareStandardConversionSequences(Cand1.FinalConversion,
+    switch (CompareStandardConversionSequences(S,
+                                               Cand1.FinalConversion,
                                                Cand2.FinalConversion)) {
     case ImplicitConversionSequence::Better:
       // Cand1 has a better conversion sequence.
@@ -4623,32 +5396,28 @@
 /// function, Best points to the candidate function found.
 ///
 /// \returns The result of overload resolution.
-OverloadingResult Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
-                                           SourceLocation Loc,
-                                        OverloadCandidateSet::iterator& Best) {
+OverloadingResult
+OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
+                                         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 = end();
+  for (iterator Cand = begin(); Cand != end(); ++Cand) {
+    if (Cand->Viable)
+      if (Best == end() || isBetterOverloadCandidate(S, *Cand, *Best, Loc))
         Best = Cand;
-    }
   }
 
   // If we didn't find any viable functions, abort.
-  if (Best == CandidateSet.end())
+  if (Best == 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) {
+  for (iterator Cand = begin(); Cand != end(); ++Cand) {
     if (Cand->Viable &&
         Cand != Best &&
-        !isBetterOverloadCandidate(*Best, *Cand, Loc)) {
-      Best = CandidateSet.end();
+        !isBetterOverloadCandidate(S, *Best, *Cand, Loc)) {
+      Best = end();
       return OR_Ambiguous;
     }
   }
@@ -4666,7 +5435,7 @@
   //   (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);
+    S.MarkDeclarationReferenced(Loc, Best->Function);
   return OR_Success;
 }
 
@@ -4730,14 +5499,15 @@
 /// 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();
+void ImplicitConversionSequence::DiagnoseAmbiguousConversion(
+                                 Sema &S,
+                                 SourceLocation CaretLoc,
+                                 const PartialDiagnostic &PDiag) const {
+  S.Diag(CaretLoc, PDiag)
+    << Ambiguous.getFromType() << Ambiguous.getToType();
   for (AmbiguousConversionSequence::const_iterator
-         I = ICS.Ambiguous.begin(), E = ICS.Ambiguous.end(); I != E; ++I) {
-    NoteOverloadCandidate(*I);
+         I = Ambiguous.begin(), E = Ambiguous.end(); I != E; ++I) {
+    S.NoteOverloadCandidate(*I);
   }
 }
 
@@ -4846,6 +5616,46 @@
     return;
   }
 
+  // Diagnose base -> derived pointer conversions.
+  unsigned BaseToDerivedConversion = 0;
+  if (const PointerType *FromPtrTy = FromTy->getAs<PointerType>()) {
+    if (const PointerType *ToPtrTy = ToTy->getAs<PointerType>()) {
+      if (ToPtrTy->getPointeeType().isAtLeastAsQualifiedAs(
+                                               FromPtrTy->getPointeeType()) &&
+          !FromPtrTy->getPointeeType()->isIncompleteType() &&
+          !ToPtrTy->getPointeeType()->isIncompleteType() &&
+          S.IsDerivedFrom(ToPtrTy->getPointeeType(), 
+                          FromPtrTy->getPointeeType()))
+        BaseToDerivedConversion = 1;
+    }
+  } else if (const ObjCObjectPointerType *FromPtrTy
+                                    = FromTy->getAs<ObjCObjectPointerType>()) {
+    if (const ObjCObjectPointerType *ToPtrTy
+                                        = ToTy->getAs<ObjCObjectPointerType>())
+      if (const ObjCInterfaceDecl *FromIface = FromPtrTy->getInterfaceDecl())
+        if (const ObjCInterfaceDecl *ToIface = ToPtrTy->getInterfaceDecl())
+          if (ToPtrTy->getPointeeType().isAtLeastAsQualifiedAs(
+                                                FromPtrTy->getPointeeType()) &&
+              FromIface->isSuperClassOf(ToIface))
+            BaseToDerivedConversion = 2;
+  } else if (const ReferenceType *ToRefTy = ToTy->getAs<ReferenceType>()) {
+      if (ToRefTy->getPointeeType().isAtLeastAsQualifiedAs(FromTy) &&
+          !FromTy->isIncompleteType() &&
+          !ToRefTy->getPointeeType()->isIncompleteType() &&
+          S.IsDerivedFrom(ToRefTy->getPointeeType(), FromTy))
+        BaseToDerivedConversion = 3;
+    }
+    
+  if (BaseToDerivedConversion) {
+    S.Diag(Fn->getLocation(), 
+           diag::note_ovl_candidate_bad_base_to_derived_conv)
+      << (unsigned) FnKind << FnDesc
+      << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
+      << (BaseToDerivedConversion - 1)
+      << FromTy << ToTy << 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
@@ -4863,16 +5673,21 @@
   unsigned MinParams = Fn->getMinRequiredArguments();
   
   // at least / at most / exactly
+  // FIXME: variadic templates "at most" should account for parameter packs
   unsigned mode, modeCount;
   if (NumFormalArgs < MinParams) {
-    assert(Cand->FailureKind == ovl_fail_too_few_arguments);
+    assert((Cand->FailureKind == ovl_fail_too_few_arguments) ||
+           (Cand->FailureKind == ovl_fail_bad_deduction &&
+            Cand->DeductionFailure.Result == Sema::TDK_TooFewArguments));
     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);
+    assert((Cand->FailureKind == ovl_fail_too_many_arguments) ||
+           (Cand->FailureKind == ovl_fail_bad_deduction &&
+            Cand->DeductionFailure.Result == Sema::TDK_TooManyArguments));
     if (MinParams != FnTy->getNumArgs())
       mode = 1; // "at most"
     else
@@ -4884,7 +5699,8 @@
   OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, Description);
 
   S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity)
-    << (unsigned) FnKind << Description << mode << modeCount << NumFormalArgs;
+    << (unsigned) FnKind << (Fn->getDescribedFunctionTemplate() != 0) << mode 
+    << modeCount << NumFormalArgs;
 }
 
 /// Diagnose a failed template-argument deduction.
@@ -4892,34 +5708,109 @@
                           Expr **Args, unsigned NumArgs) {
   FunctionDecl *Fn = Cand->Function; // pattern
 
-  TemplateParameter Param = TemplateParameter::getFromOpaqueValue(
-                                   Cand->DeductionFailure.TemplateParameter);
-
+  TemplateParameter Param = Cand->DeductionFailure.getTemplateParameter();
+  NamedDecl *ParamD;
+  (ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) ||
+  (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()) ||
+  (ParamD = Param.dyn_cast<TemplateTemplateParmDecl*>());
   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_Underqualified: {
+    assert(ParamD && "no parameter found for bad qualifiers deduction result");
+    TemplateTypeParmDecl *TParam = cast<TemplateTypeParmDecl>(ParamD);
+
+    QualType Param = Cand->DeductionFailure.getFirstArg()->getAsType();
+
+    // Param will have been canonicalized, but it should just be a
+    // qualified version of ParamD, so move the qualifiers to that.
+    QualifierCollector Qs(S.Context);
+    Qs.strip(Param);
+    QualType NonCanonParam = Qs.apply(TParam->getTypeForDecl());
+    assert(S.Context.hasSameType(Param, NonCanonParam));
+
+    // Arg has also been canonicalized, but there's nothing we can do
+    // about that.  It also doesn't matter as much, because it won't
+    // have any template parameters in it (because deduction isn't
+    // done on dependent types).
+    QualType Arg = Cand->DeductionFailure.getSecondArg()->getAsType();
+
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_underqualified)
+      << ParamD->getDeclName() << Arg << NonCanonParam;
+    return;
+  }
+
+  case Sema::TDK_Inconsistent: {
+    assert(ParamD && "no parameter found for inconsistent deduction result");    
+    int which = 0;
+    if (isa<TemplateTypeParmDecl>(ParamD))
+      which = 0;
+    else if (isa<NonTypeTemplateParmDecl>(ParamD))
+      which = 1;
+    else {
+      which = 2;
+    }
+    
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_inconsistent_deduction)
+      << which << ParamD->getDeclName() 
+      << *Cand->DeductionFailure.getFirstArg()
+      << *Cand->DeductionFailure.getSecondArg();
+    return;
+  }
+
+  case Sema::TDK_InvalidExplicitArguments:
+    assert(ParamD && "no parameter found for invalid explicit arguments");    
+    if (ParamD->getDeclName())
+      S.Diag(Fn->getLocation(), 
+             diag::note_ovl_candidate_explicit_arg_mismatch_named)
+        << ParamD->getDeclName();
+    else {
+      int index = 0;
+      if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ParamD))
+        index = TTP->getIndex();
+      else if (NonTypeTemplateParmDecl *NTTP
+                                  = dyn_cast<NonTypeTemplateParmDecl>(ParamD))
+        index = NTTP->getIndex();
+      else
+        index = cast<TemplateTemplateParmDecl>(ParamD)->getIndex();
+      S.Diag(Fn->getLocation(), 
+             diag::note_ovl_candidate_explicit_arg_mismatch_unnamed)
+        << (index + 1);
+    }
+    return;
+      
   case Sema::TDK_TooManyArguments:
   case Sema::TDK_TooFewArguments:
-  case Sema::TDK_InvalidExplicitArguments:
+    DiagnoseArityMismatch(S, Cand, NumArgs);
+    return;
+
+  case Sema::TDK_InstantiationDepth:
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_instantiation_depth);
+    return;
+
+  case Sema::TDK_SubstitutionFailure: {
+    std::string ArgString;
+    if (TemplateArgumentList *Args
+                            = Cand->DeductionFailure.getTemplateArgumentList())
+      ArgString = S.getTemplateArgumentBindingsText(
+                    Fn->getDescribedFunctionTemplate()->getTemplateParameters(),
+                                                    *Args);
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_substitution_failure)
+      << ArgString;
+    return;
+  }
+      
+  // TODO: diagnose these individually, then kill off
+  // note_ovl_candidate_bad_deduction, which is uselessly vague.
+  case Sema::TDK_NonDeducedMismatch:
   case Sema::TDK_FailedOverloadResolution:
     S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_deduction);
     return;
@@ -5046,7 +5937,7 @@
     if (ICS.isBad()) break; // all meaningless after first invalid
     if (!ICS.isAmbiguous()) continue;
 
-    S.DiagnoseAmbiguousConversion(ICS, OpLoc,
+    ICS.DiagnoseAmbiguousConversion(S, OpLoc,
                               S.PDiag(diag::note_ambiguous_type_conversion));
   }
 }
@@ -5075,8 +5966,8 @@
       // 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;
+      if (isBetterOverloadCandidate(S, *L, *R, SourceLocation())) return true;
+      if (isBetterOverloadCandidate(S, *R, *L, SourceLocation())) return false;
     } else if (R->Viable)
       return false;
 
@@ -5105,8 +5996,9 @@
         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])) {
+          switch (CompareImplicitConversionSequences(S,
+                                                     L->Conversions[I],
+                                                     R->Conversions[I])) {
           case ImplicitConversionSequence::Better:
             leftBetter++;
             break;
@@ -5214,44 +6106,53 @@
 /// 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) {
+void OverloadCandidateSet::NoteCandidates(Sema &S,
+                                          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 (OCD == OCD_AllCandidates) Cands.reserve(size());
+  for (iterator Cand = begin(), LastCand = 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);
+      CompleteNonViableCandidate(S, Cand, Args, NumArgs);
+      if (Cand->Function || Cand->IsSurrogate)
+        Cands.push_back(Cand);
+      // Otherwise, this a non-viable builtin candidate.  We do not, in general,
+      // want to list every possible builtin candidate.
     }
   }
 
   std::sort(Cands.begin(), Cands.end(),
-            CompareOverloadCandidatesForDisplay(*this));
+            CompareOverloadCandidatesForDisplay(S));
   
   bool ReportedAmbiguousConversions = false;
 
   llvm::SmallVectorImpl<OverloadCandidate*>::iterator I, E;
+  const Diagnostic::OverloadsShown ShowOverloads = S.Diags.getShowOverloads();
+  unsigned CandsShown = 0;
   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);
+    // Set an arbitrary limit on the number of candidate functions we'll spam
+    // the user with.  FIXME: This limit should depend on details of the
+    // candidate list.
+    if (CandsShown >= 4 && ShowOverloads == Diagnostic::Ovl_Best) {
+      break;
+    }
+    ++CandsShown;
 
-    // This a builtin candidate.  We do not, in general, want to list
-    // every possible builtin candidate.
-    else if (Cand->Viable) {
+    if (Cand->Function)
+      NoteFunctionCandidate(S, Cand, Args, NumArgs);
+    else if (Cand->IsSurrogate)
+      NoteSurrogateCandidate(S, Cand);
+    else {
+      assert(Cand->Viable &&
+             "Non-viable built-in candidates are not added to Cands.");
       // Generally we only see ambiguities including viable builtin
       // operators if overload resolution got screwed up by an
       // ambiguous user-defined conversion.
@@ -5259,14 +6160,17 @@
       // FIXME: It's quite possible for different conversions to see
       // different ambiguities, though.
       if (!ReportedAmbiguousConversions) {
-        NoteAmbiguousUserConversions(*this, OpLoc, Cand);
+        NoteAmbiguousUserConversions(S, OpLoc, Cand);
         ReportedAmbiguousConversions = true;
       }
 
       // If this is a viable builtin, print it.
-      NoteBuiltinOperatorCandidate(*this, Opc, OpLoc, Cand);
+      NoteBuiltinOperatorCandidate(S, Opc, OpLoc, Cand);
     }
   }
+
+  if (I != E)
+    S.Diag(OpLoc, diag::note_ovl_too_many_candidates) << int(E - I);
 }
 
 static bool CheckUnresolvedAccess(Sema &S, OverloadExpr *E, DeclAccessPair D) {
@@ -5313,12 +6217,13 @@
   // 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;
-  }
+  // However, remember whether the expression has member-pointer form:
+  // C++ [expr.unary.op]p4:
+  //     A pointer to member is only formed when an explicit & is used
+  //     and its operand is a qualified-id not enclosed in
+  //     parentheses.
+  OverloadExpr::FindResult Ovl = OverloadExpr::find(From);
+  OverloadExpr *OvlExpr = Ovl.Expression;
   
   // We expect a pointer or reference to function, or a function pointer.
   FunctionType = Context.getCanonicalType(FunctionType).getUnqualifiedType();
@@ -5330,6 +6235,25 @@
     return 0;
   }
 
+  // If the overload expression doesn't have the form of a pointer to
+  // member, don't try to convert it to a pointer-to-member type.
+  if (IsMember && !Ovl.HasFormOfMemberPointer) {
+    if (!Complain) return 0;
+
+    // TODO: Should we condition this on whether any functions might
+    // have matched, or is it more appropriate to do that in callers?
+    // TODO: a fixit wouldn't hurt.
+    Diag(OvlExpr->getNameLoc(), diag::err_addr_ovl_no_qualifier)
+      << ToType << OvlExpr->getSourceRange();
+    return 0;
+  }
+
+  TemplateArgumentListInfo ETABuffer, *ExplicitTemplateArgs = 0;
+  if (OvlExpr->hasExplicitTemplateArgs()) {
+    OvlExpr->getExplicitTemplateArgs().copyInto(ETABuffer);
+    ExplicitTemplateArgs = &ETABuffer;
+  }
+
   assert(From->getType() == Context.OverloadTy);
 
   // Look through all of the overloaded functions, searching for one
@@ -5462,8 +6386,10 @@
     assert(Result != MatchesCopy.end() && "no most-specialized template");
     MarkDeclarationReferenced(From->getLocStart(), *Result);
     FoundResult = Matches[Result - MatchesCopy.begin()].first;
-    if (Complain)
+    if (Complain) {
       CheckUnresolvedAccess(*this, OvlExpr, FoundResult);
+      DiagnoseUseOfDecl(FoundResult, OvlExpr->getNameLoc());
+    }
     return cast<FunctionDecl>(*Result);
   }
 
@@ -5483,8 +6409,10 @@
   if (Matches.size() == 1) {
     MarkDeclarationReferenced(From->getLocStart(), Matches[0].second);
     FoundResult = Matches[0].first;
-    if (Complain)
+    if (Complain) {
       CheckUnresolvedAccess(*this, OvlExpr, Matches[0].first);
+      DiagnoseUseOfDecl(Matches[0].first, OvlExpr->getNameLoc());
+    }
     return cast<FunctionDecl>(Matches[0].second);
   }
 
@@ -5515,7 +6443,7 @@
   if (From->getType() != Context.OverloadTy)
     return 0;
 
-  OverloadExpr *OvlExpr = OverloadExpr::find(From).getPointer();
+  OverloadExpr *OvlExpr = OverloadExpr::find(From).Expression;
   
   // If we didn't actually find any template-ids, we're done.
   if (!OvlExpr->hasExplicitTemplateArgs())
@@ -5535,7 +6463,8 @@
     //   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);
+    FunctionTemplateDecl *FunctionTemplate
+      = cast<FunctionTemplateDecl>((*I)->getUnderlyingDecl());
     
     // C++ [over.over]p2:
     //   If the name is a function template, template argument deduction is
@@ -5652,18 +6581,10 @@
                                          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
+static ExprResult
 BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
                       UnresolvedLookupExpr *ULE,
                       SourceLocation LParenLoc,
@@ -5686,14 +6607,14 @@
 
   LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
                  Sema::LookupOrdinaryName);
-  if (SemaRef.DiagnoseEmptyLookup(S, SS, R))
-    return Destroy(SemaRef, Fn, Args, NumArgs);
+  if (SemaRef.DiagnoseEmptyLookup(S, SS, R, Sema::CTC_Expression))
+    return ExprError();
 
   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();
+  ExprResult NewFn = ExprError();
   if ((*R.begin())->isCXXClassMember())
     NewFn = SemaRef.BuildPossibleImplicitMemberExpr(SS, R, ExplicitTemplateArgs);
   else if (ExplicitTemplateArgs)
@@ -5702,18 +6623,16 @@
     NewFn = SemaRef.BuildDeclarationNameExpr(SS, R, false);
 
   if (NewFn.isInvalid())
-    return Destroy(SemaRef, Fn, Args, NumArgs);
-
-  Fn->Destroy(SemaRef.Context);
+    return ExprError();
 
   // 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),
+  return SemaRef.ActOnCallExpr(/*Scope*/ 0, NewFn.take(), LParenLoc,
+                               MultiExprArg(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
@@ -5721,7 +6640,7 @@
 /// the function declaration produced by overload
 /// resolution. Otherwise, emits diagnostics, deletes all of the
 /// arguments and Fn, and returns NULL.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
                               SourceLocation LParenLoc,
                               Expr **Args, unsigned NumArgs,
@@ -5759,10 +6678,11 @@
                                  CommaLocs, RParenLoc);
 
   OverloadCandidateSet::iterator Best;
-  switch (BestViableFunction(CandidateSet, Fn->getLocStart(), Best)) {
+  switch (CandidateSet.BestViableFunction(*this, Fn->getLocStart(), Best)) {
   case OR_Success: {
     FunctionDecl *FDecl = Best->Function;
     CheckUnresolvedLookupAccess(ULE, Best->FoundDecl);
+    DiagnoseUseOfDecl(Best->FoundDecl, ULE->getNameLoc());
     Fn = FixOverloadedFunctionReference(Fn, Best->FoundDecl, FDecl);
     return BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs, RParenLoc);
   }
@@ -5771,13 +6691,13 @@
     Diag(Fn->getSourceRange().getBegin(),
          diag::err_ovl_no_viable_function_in_call)
       << ULE->getName() << Fn->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+    CandidateSet.NoteCandidates(*this, 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);
+    CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, NumArgs);
     break;
 
   case OR_Deleted:
@@ -5785,15 +6705,11 @@
       << Best->Function->isDeleted()
       << ULE->getName()
       << Fn->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+    CandidateSet.NoteCandidates(*this, 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);
+  // Overload resolution failed.
   return ExprError();
 }
 
@@ -5818,16 +6734,17 @@
 /// by CreateOverloadedUnaryOp().
 ///
 /// \param input The input argument.
-Sema::OwningExprResult
+ExprResult
 Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
                               const UnresolvedSetImpl &Fns,
-                              ExprArg input) {
+                              Expr *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);
+  // TODO: provide better source location info.
+  DeclarationNameInfo OpNameInfo(OpName, OpLoc);
 
   Expr *Args[2] = { Input, 0 };
   unsigned NumArgs = 1;
@@ -5835,22 +6752,26 @@
   // 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) {
+  if (Opc == UO_PostInc || Opc == UO_PostDec) {
     llvm::APSInt Zero(Context.getTypeSize(Context.IntTy), false);
-    Args[1] = new (Context) IntegerLiteral(Zero, Context.IntTy,
-                                           SourceLocation());
+    Args[1] = IntegerLiteral::Create(Context, Zero, Context.IntTy,
+                                     SourceLocation());
     NumArgs = 2;
   }
 
   if (Input->isTypeDependent()) {
+    if (Fns.empty())
+      return Owned(new (Context) UnaryOperator(Input,
+                                               Opc, 
+                                               Context.DependentTy,
+                                               OpLoc));
+    
     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();
+                                     0, SourceRange(), OpNameInfo,
+                                     /*ADL*/ true, IsOverloaded(Fns),
+                                     Fns.begin(), Fns.end());
     return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
                                                    &Args[0], NumArgs,
                                                    Context.DependentTy,
@@ -5877,7 +6798,7 @@
 
   // Perform overload resolution.
   OverloadCandidateSet::iterator Best;
-  switch (BestViableFunction(CandidateSet, OpLoc, Best)) {
+  switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) {
   case OR_Success: {
     // We found a built-in operator or an overloaded operator.
     FunctionDecl *FnDecl = Best->Function;
@@ -5895,37 +6816,36 @@
           return ExprError();
       } else {
         // Convert the arguments.
-        OwningExprResult InputInit
+        ExprResult InputInit
           = PerformCopyInitialization(InitializedEntity::InitializeParameter(
                                                       FnDecl->getParamDecl(0)),
                                       SourceLocation(), 
-                                      move(input));
+                                      Input);
         if (InputInit.isInvalid())
           return ExprError();
-        
-        input = move(InputInit);
-        Input = (Expr *)input.get();
+        Input = InputInit.take();
       }
 
+      DiagnoseUseOfDecl(Best->FoundDecl, OpLoc);
+
       // Determine the result type
-      QualType ResultTy = FnDecl->getResultType().getNonReferenceType();
+      QualType ResultTy = FnDecl->getCallResultType();
 
       // 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,
+      CallExpr *TheCall =
         new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
-                                          Args, NumArgs, ResultTy, OpLoc));
-      
-      if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall.get(), 
+                                          Args, NumArgs, ResultTy, OpLoc);
+
+      if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall, 
                               FnDecl))
         return ExprError();
 
-      return MaybeBindToTemporary(TheCall.release());
+      return MaybeBindToTemporary(TheCall);
     } else {
       // We matched a built-in operator. Convert the arguments, then
       // break out so that we will build the appropriate built-in
@@ -5947,8 +6867,9 @@
       Diag(OpLoc,  diag::err_ovl_ambiguous_oper)
           << UnaryOperator::getOpcodeStr(Opc)
           << Input->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs,
-                              UnaryOperator::getOpcodeStr(Opc), OpLoc);
+      CandidateSet.NoteCandidates(*this, OCD_ViableCandidates,
+                                  Args, NumArgs,
+                                  UnaryOperator::getOpcodeStr(Opc), OpLoc);
       return ExprError();
 
     case OR_Deleted:
@@ -5956,15 +6877,14 @@
         << Best->Function->isDeleted()
         << UnaryOperator::getOpcodeStr(Opc)
         << Input->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+      CandidateSet.NoteCandidates(*this, 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));
+  return CreateBuiltinUnaryOp(OpLoc, Opc, Input);
 }
 
 /// \brief Create a binary operation that may resolve to an overloaded
@@ -5984,7 +6904,7 @@
 ///
 /// \param LHS Left-hand argument.
 /// \param RHS Right-hand argument.
-Sema::OwningExprResult
+ExprResult
 Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
                             unsigned OpcIn,
                             const UnresolvedSetImpl &Fns,
@@ -6002,7 +6922,7 @@
     if (Fns.empty()) {
       // If there are no functions to store, just build a dependent 
       // BinaryOperator or CompoundAssignment.
-      if (Opc <= BinaryOperator::Assign || Opc > BinaryOperator::OrAssign)
+      if (Opc <= BO_Assign || Opc > BO_OrAssign)
         return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc,
                                                   Context.DependentTy, OpLoc));
       
@@ -6015,12 +6935,13 @@
 
     // FIXME: save results of ADL from here?
     CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
+    // TODO: provide better source location info in DNLoc component.
+    DeclarationNameInfo OpNameInfo(OpName, OpLoc);
     UnresolvedLookupExpr *Fn
       = UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass,
-                                     0, SourceRange(), OpName, OpLoc,
-                                     /*ADL*/ true, IsOverloaded(Fns));
-
-    Fn->addDecls(Fns.begin(), Fns.end());
+                                     0, SourceRange(), OpNameInfo,
+                                     /*ADL*/ true, IsOverloaded(Fns),
+                                     Fns.begin(), Fns.end());
     return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
                                                    Args, 2,
                                                    Context.DependentTy,
@@ -6029,7 +6950,7 @@
 
   // If this is the .* operator, which is not overloadable, just
   // create a built-in binary operator.
-  if (Opc == BinaryOperator::PtrMemD)
+  if (Opc == BO_PtrMemD)
     return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
 
   // If this is the assignment operator, we only perform overload resolution
@@ -6038,7 +6959,7 @@
   // 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())
+  if (Opc == BO_Assign && !Args[0]->getType()->isOverloadableType())
     return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
 
   // Build an empty overload set.
@@ -6061,7 +6982,7 @@
 
   // Perform overload resolution.
   OverloadCandidateSet::iterator Best;
-  switch (BestViableFunction(CandidateSet, OpLoc, Best)) {
+  switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) {
     case OR_Success: {
       // We found a built-in operator or an overloaded operator.
       FunctionDecl *FnDecl = Best->Function;
@@ -6075,7 +6996,7 @@
           // Best->Access is only meaningful for class members.
           CheckMemberOperatorAccess(OpLoc, Args[0], Args[1], Best->FoundDecl);
 
-          OwningExprResult Arg1
+          ExprResult Arg1
             = PerformCopyInitialization(
                                         InitializedEntity::InitializeParameter(
                                                         FnDecl->getParamDecl(0)),
@@ -6091,7 +7012,7 @@
           Args[1] = RHS = Arg1.takeAs<Expr>();
         } else {
           // Convert the arguments.
-          OwningExprResult Arg0
+          ExprResult Arg0
             = PerformCopyInitialization(
                                         InitializedEntity::InitializeParameter(
                                                         FnDecl->getParamDecl(0)),
@@ -6100,7 +7021,7 @@
           if (Arg0.isInvalid())
             return ExprError();
 
-          OwningExprResult Arg1
+          ExprResult Arg1
             = PerformCopyInitialization(
                                         InitializedEntity::InitializeParameter(
                                                         FnDecl->getParamDecl(1)),
@@ -6112,26 +7033,27 @@
           Args[1] = RHS = Arg1.takeAs<Expr>();
         }
 
+        DiagnoseUseOfDecl(Best->FoundDecl, OpLoc);
+
         // Determine the result type
         QualType ResultTy
-          = FnDecl->getType()->getAs<FunctionType>()->getResultType();
-        ResultTy = ResultTy.getNonReferenceType();
+          = FnDecl->getType()->getAs<FunctionType>()
+                                                ->getCallResultType(Context);
 
         // 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));
+        CXXOperatorCallExpr *TheCall =
+          new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
+                                            Args, 2, ResultTy, OpLoc);
         
-        if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall.get(), 
+        if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall, 
                                 FnDecl))
           return ExprError();
 
-        return MaybeBindToTemporary(TheCall.release());
+        return MaybeBindToTemporary(TheCall);
       } else {
         // We matched a built-in operator. Convert the arguments, then
         // break out so that we will build the appropriate built-in
@@ -6151,15 +7073,15 @@
       //   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)
+      if (Opc == BO_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();
+      ExprResult Result = ExprError();
       if (Args[0]->getType()->isRecordType() && 
-          Opc >= BinaryOperator::Assign && Opc <= BinaryOperator::OrAssign) {
+          Opc >= BO_Assign && Opc <= BO_OrAssign) {
         Diag(OpLoc,  diag::err_ovl_no_viable_oper)
              << BinaryOperator::getOpcodeStr(Opc)
              << Args[0]->getSourceRange() << Args[1]->getSourceRange();
@@ -6171,8 +7093,8 @@
       assert(Result.isInvalid() && 
              "C++ binary operator overloading is missing candidates!");
       if (Result.isInvalid())
-        PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2,
-                                BinaryOperator::getOpcodeStr(Opc), OpLoc);
+        CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, 2,
+                                    BinaryOperator::getOpcodeStr(Opc), OpLoc);
       return move(Result);
     }
 
@@ -6180,8 +7102,8 @@
       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);
+      CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, 2,
+                                  BinaryOperator::getOpcodeStr(Opc), OpLoc);
       return ExprError();
 
     case OR_Deleted:
@@ -6189,7 +7111,7 @@
         << Best->Function->isDeleted()
         << BinaryOperator::getOpcodeStr(Opc)
         << Args[0]->getSourceRange() << Args[1]->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2);
+      CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, 2);
       return ExprError();
   }
 
@@ -6197,12 +7119,11 @@
   return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
 }
 
-Action::OwningExprResult
+ExprResult
 Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
                                          SourceLocation RLoc,
-                                         ExprArg Base, ExprArg Idx) {
-  Expr *Args[2] = { static_cast<Expr*>(Base.get()),
-                    static_cast<Expr*>(Idx.get()) };
+                                         Expr *Base, Expr *Idx) {
+  Expr *Args[2] = { Base, Idx };
   DeclarationName OpName =
       Context.DeclarationNames.getCXXOperatorName(OO_Subscript);
 
@@ -6211,14 +7132,17 @@
   if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
 
     CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
+    // CHECKME: no 'operator' keyword?
+    DeclarationNameInfo OpNameInfo(OpName, LLoc);
+    OpNameInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc));
     UnresolvedLookupExpr *Fn
       = UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass,
-                                     0, SourceRange(), OpName, LLoc,
-                                     /*ADL*/ true, /*Overloaded*/ false);
+                                     0, SourceRange(), OpNameInfo,
+                                     /*ADL*/ true, /*Overloaded*/ false,
+                                     UnresolvedSetIterator(),
+                                     UnresolvedSetIterator());
     // Can't add any actual overloads yet
 
-    Base.release();
-    Idx.release();
     return Owned(new (Context) CXXOperatorCallExpr(Context, OO_Subscript, Fn,
                                                    Args, 2,
                                                    Context.DependentTy,
@@ -6238,7 +7162,7 @@
 
   // Perform overload resolution.
   OverloadCandidateSet::iterator Best;
-  switch (BestViableFunction(CandidateSet, LLoc, Best)) {
+  switch (CandidateSet.BestViableFunction(*this, LLoc, Best)) {
     case OR_Success: {
       // We found a built-in operator or an overloaded operator.
       FunctionDecl *FnDecl = Best->Function;
@@ -6248,6 +7172,7 @@
         // operator.
 
         CheckMemberOperatorAccess(LLoc, Args[0], Args[1], Best->FoundDecl);
+        DiagnoseUseOfDecl(Best->FoundDecl, LLoc);
 
         // Convert the arguments.
         CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
@@ -6256,7 +7181,7 @@
           return ExprError();
 
         // Convert the arguments.
-        OwningExprResult InputInit
+        ExprResult InputInit
           = PerformCopyInitialization(InitializedEntity::InitializeParameter(
                                                       FnDecl->getParamDecl(0)),
                                       SourceLocation(), 
@@ -6268,26 +7193,24 @@
 
         // Determine the result type
         QualType ResultTy
-          = FnDecl->getType()->getAs<FunctionType>()->getResultType();
-        ResultTy = ResultTy.getNonReferenceType();
+          = FnDecl->getType()->getAs<FunctionType>()
+                                                  ->getCallResultType(Context);
 
         // 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));
+        CXXOperatorCallExpr *TheCall =
+          new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
+                                            FnExpr, Args, 2,
+                                            ResultTy, RLoc);
 
-        if (CheckCallReturnType(FnDecl->getResultType(), LLoc, TheCall.get(),
+        if (CheckCallReturnType(FnDecl->getResultType(), LLoc, TheCall,
                                 FnDecl))
           return ExprError();
 
-        return MaybeBindToTemporary(TheCall.release());
+        return MaybeBindToTemporary(TheCall);
       } else {
         // We matched a built-in operator. Convert the arguments, then
         // break out so that we will build the appropriate built-in
@@ -6311,32 +7234,29 @@
         Diag(LLoc, diag::err_ovl_no_viable_subscript)
           << Args[0]->getType()
           << Args[0]->getSourceRange() << Args[1]->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2,
-                              "[]", LLoc);
+      CandidateSet.NoteCandidates(*this, 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);
+      CandidateSet.NoteCandidates(*this, 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);
+      CandidateSet.NoteCandidates(*this, 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);
+  return CreateBuiltinArraySubscriptExpr(Args[0], LLoc, Args[1], RLoc);
 }
 
 /// BuildCallToMemberFunction - Build a call to a member
@@ -6346,7 +7266,7 @@
 /// parameter). The caller needs to validate that the member
 /// expression refers to a member function or an overloaded member
 /// function.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
                                 SourceLocation LParenLoc, Expr **Args,
                                 unsigned NumArgs, SourceLocation *CommaLocs,
@@ -6409,25 +7329,27 @@
     DeclarationName DeclName = UnresExpr->getMemberName();
 
     OverloadCandidateSet::iterator Best;
-    switch (BestViableFunction(CandidateSet, UnresExpr->getLocStart(), Best)) {
+    switch (CandidateSet.BestViableFunction(*this, UnresExpr->getLocStart(),
+                               Best)) {
     case OR_Success:
       Method = cast<CXXMethodDecl>(Best->Function);
       FoundDecl = Best->FoundDecl;
       CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
+      DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc());
       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);
+      CandidateSet.NoteCandidates(*this, 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);
+      CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
       // FIXME: Leaking incoming expressions!
       return ExprError();
 
@@ -6435,7 +7357,7 @@
       Diag(UnresExpr->getMemberLoc(), diag::err_ovl_deleted_member_call)
         << Best->Function->isDeleted()
         << DeclName << MemExprE->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+      CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
       // FIXME: Leaking incoming expressions!
       return ExprError();
     }
@@ -6453,15 +7375,14 @@
   }
 
   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));
+  CXXMemberCallExpr *TheCall = 
+    new (Context) CXXMemberCallExpr(Context, MemExprE, Args, NumArgs,
+                                    Method->getCallResultType(),
+                                    RParenLoc);
 
   // Check for a valid return type.
   if (CheckCallReturnType(Method->getResultType(), MemExpr->getMemberLoc(), 
-                          TheCall.get(), Method))
+                          TheCall, Method))
     return ExprError();
   
   // Convert the object argument (for a non-static member function call).
@@ -6475,22 +7396,22 @@
   MemExpr->setBase(ObjectArg);
 
   // Convert the rest of the arguments
-  const FunctionProtoType *Proto = cast<FunctionProtoType>(Method->getType());
-  if (ConvertArgumentsForCall(&*TheCall, MemExpr, Method, Proto, Args, NumArgs,
+  const FunctionProtoType *Proto = Method->getType()->getAs<FunctionProtoType>();
+  if (ConvertArgumentsForCall(TheCall, MemExpr, Method, Proto, Args, NumArgs,
                               RParenLoc))
     return ExprError();
 
-  if (CheckFunctionCall(Method, TheCall.get()))
+  if (CheckFunctionCall(Method, TheCall))
     return ExprError();
 
-  return MaybeBindToTemporary(TheCall.release());
+  return MaybeBindToTemporary(TheCall);
 }
 
 /// 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
+ExprResult
 Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
                                    SourceLocation LParenLoc,
                                    Expr **Args, unsigned NumArgs,
@@ -6572,7 +7493,8 @@
 
   // Perform overload resolution.
   OverloadCandidateSet::iterator Best;
-  switch (BestViableFunction(CandidateSet, Object->getLocStart(), Best)) {
+  switch (CandidateSet.BestViableFunction(*this, Object->getLocStart(),
+                             Best)) {
   case OR_Success:
     // Overload resolution succeeded; we'll build the appropriate call
     // below.
@@ -6587,14 +7509,14 @@
       Diag(Object->getSourceRange().getBegin(),
            diag::err_ovl_no_viable_object_call)
         << Object->getType() << Object->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+    CandidateSet.NoteCandidates(*this, 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);
+    CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, NumArgs);
     break;
 
   case OR_Deleted:
@@ -6602,18 +7524,12 @@
          diag::err_ovl_deleted_object_call)
       << Best->Function->isDeleted()
       << Object->getType() << Object->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+    CandidateSet.NoteCandidates(*this, 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);
+  if (Best == CandidateSet.end())
     return true;
-  }
 
   if (Best->Function == 0) {
     // Since there is no function declaration, this is one of the
@@ -6623,6 +7539,7 @@
                          Best->Conversions[0].UserDefined.ConversionFunction);
 
     CheckMemberOperatorAccess(LParenLoc, Object, 0, Best->FoundDecl);
+    DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc);
 
     // We selected one of the surrogate functions that converts the
     // object parameter to a function pointer. Perform the conversion
@@ -6633,12 +7550,12 @@
     CXXMemberCallExpr *CE = BuildCXXMemberCallExpr(Object, Best->FoundDecl,
                                                    Conv);
       
-    return ActOnCallExpr(S, ExprArg(*this, CE), LParenLoc,
-                         MultiExprArg(*this, (ExprTy**)Args, NumArgs),
-                         CommaLocs, RParenLoc).result();
+    return ActOnCallExpr(S, CE, LParenLoc, MultiExprArg(Args, NumArgs),
+                         CommaLocs, RParenLoc);
   }
 
   CheckMemberOperatorAccess(LParenLoc, Object, 0, Best->FoundDecl);
+  DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc);
 
   // We found an overloaded operator(). Build a CXXOperatorCallExpr
   // that calls this method, using Object for the implicit object
@@ -6669,14 +7586,14 @@
 
   // 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));
+  QualType ResultTy = Method->getCallResultType();
+  CXXOperatorCallExpr *TheCall =
+    new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn,
+                                      MethodArgs, NumArgs + 1,
+                                      ResultTy, RParenLoc);
   delete [] MethodArgs;
 
-  if (CheckCallReturnType(Method->getResultType(), LParenLoc, TheCall.get(), 
+  if (CheckCallReturnType(Method->getResultType(), LParenLoc, TheCall, 
                           Method))
     return true;
   
@@ -6703,15 +7620,15 @@
 
       // Pass the argument.
 
-      OwningExprResult InputInit
+      ExprResult InputInit
         = PerformCopyInitialization(InitializedEntity::InitializeParameter(
                                                     Method->getParamDecl(i)),
-                                    SourceLocation(), Owned(Arg));
+                                    SourceLocation(), Arg);
       
       IsError |= InputInit.isInvalid();
       Arg = InputInit.takeAs<Expr>();
     } else {
-      OwningExprResult DefArg
+      ExprResult DefArg
         = BuildCXXDefaultArgExpr(LParenLoc, Method, Method->getParamDecl(i));
       if (DefArg.isInvalid()) {
         IsError = true;
@@ -6729,25 +7646,24 @@
     // Promote the arguments (C99 6.5.2.2p7).
     for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
       Expr *Arg = Args[i];
-      IsError |= DefaultVariadicArgumentPromotion(Arg, VariadicMethod);
+      IsError |= DefaultVariadicArgumentPromotion(Arg, VariadicMethod, 0);
       TheCall->setArg(i + 1, Arg);
     }
   }
 
   if (IsError) return true;
 
-  if (CheckFunctionCall(Method, TheCall.get()))
+  if (CheckFunctionCall(Method, TheCall))
     return true;
 
-  return MaybeBindToTemporary(TheCall.release()).result();
+  return MaybeBindToTemporary(TheCall);
 }
 
 /// 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());
+ExprResult
+Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) {
   assert(Base->getType()->isRecordType() && "left-hand side must have class type");
 
   SourceLocation Loc = Base->getExprLoc();
@@ -6779,7 +7695,7 @@
 
   // Perform overload resolution.
   OverloadCandidateSet::iterator Best;
-  switch (BestViableFunction(CandidateSet, OpLoc, Best)) {
+  switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) {
   case OR_Success:
     // Overload resolution succeeded; we'll build the call below.
     break;
@@ -6791,24 +7707,25 @@
     else
       Diag(OpLoc, diag::err_ovl_no_viable_oper)
         << "operator->" << Base->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, &Base, 1);
+    CandidateSet.NoteCandidates(*this, OCD_AllCandidates, &Base, 1);
     return ExprError();
 
   case OR_Ambiguous:
     Diag(OpLoc,  diag::err_ovl_ambiguous_oper)
       << "->" << Base->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, &Base, 1);
+    CandidateSet.NoteCandidates(*this, 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);
+    CandidateSet.NoteCandidates(*this, OCD_AllCandidates, &Base, 1);
     return ExprError();
   }
 
   CheckMemberOperatorAccess(OpLoc, Base, 0, Best->FoundDecl);
+  DiagnoseUseOfDecl(Best->FoundDecl, OpLoc);
 
   // Convert the object parameter.
   CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
@@ -6816,23 +7733,20 @@
                                           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));
+  QualType ResultTy = Method->getCallResultType();
+  CXXOperatorCallExpr *TheCall =
+    new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr, 
+                                      &Base, 1, ResultTy, OpLoc);
 
-  if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall.get(), 
+  if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall, 
                           Method))
           return ExprError();
-  return move(TheCall);
+  return Owned(TheCall);
 }
 
 /// FixOverloadedFunctionReference - E is an expression that refers to
@@ -6857,17 +7771,18 @@
     assert(Context.hasSameType(ICE->getSubExpr()->getType(), 
                                SubExpr->getType()) &&
            "Implicit cast type cannot be determined from overload");
+    assert(ICE->path_empty() && "fixing up hierarchy conversion?");
     if (SubExpr == ICE->getSubExpr())
       return ICE->Retain();
     
-    return new (Context) ImplicitCastExpr(ICE->getType(), 
-                                          ICE->getCastKind(),
-                                          SubExpr, CXXBaseSpecifierArray(),
-                                          ICE->isLvalueCast());
+    return ImplicitCastExpr::Create(Context, ICE->getType(), 
+                                    ICE->getCastKind(),
+                                    SubExpr, 0,
+                                    ICE->getValueKind());
   } 
   
   if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) {
-    assert(UnOp->getOpcode() == UnaryOperator::AddrOf &&
+    assert(UnOp->getOpcode() == UO_AddrOf &&
            "Can only take the address of an overloaded function");
     if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
       if (Method->isStatic()) {
@@ -6895,7 +7810,7 @@
         QualType MemPtrType
           = Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr());
 
-        return new (Context) UnaryOperator(SubExpr, UnaryOperator::AddrOf,
+        return new (Context) UnaryOperator(SubExpr, UO_AddrOf,
                                            MemPtrType, UnOp->getOperatorLoc());
       }
     }
@@ -6904,7 +7819,7 @@
     if (SubExpr == UnOp->getSubExpr())
       return UnOp->Retain();
     
-    return new (Context) UnaryOperator(SubExpr, UnaryOperator::AddrOf,
+    return new (Context) UnaryOperator(SubExpr, UO_AddrOf,
                                      Context.getPointerType(SubExpr->getType()),
                                        UnOp->getOperatorLoc());
   } 
@@ -6963,7 +7878,7 @@
                               MemExpr->getQualifierRange(),
                               Fn, 
                               Found,
-                              MemExpr->getMemberLoc(),
+                              MemExpr->getMemberNameInfo(),
                               TemplateArgs,
                               Fn->getType());
   }
@@ -6972,9 +7887,9 @@
   return E->Retain();
 }
 
-Sema::OwningExprResult Sema::FixOverloadedFunctionReference(OwningExprResult E, 
-                                                          DeclAccessPair Found,
-                                                            FunctionDecl *Fn) {
+ExprResult Sema::FixOverloadedFunctionReference(ExprResult E, 
+                                                DeclAccessPair Found,
+                                                FunctionDecl *Fn) {
   return Owned(FixOverloadedFunctionReference((Expr *)E.get(), Found, Fn));
 }
 
diff --git a/lib/Sema/SemaOverload.h b/lib/Sema/SemaOverload.h
deleted file mode 100644
index 5e61111..0000000
--- a/lib/Sema/SemaOverload.h
+++ /dev/null
@@ -1,584 +0,0 @@
-//===--- 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
index 9d6132d..aa1aa02 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -11,8 +11,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/Initialization.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
@@ -26,19 +28,11 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 using namespace clang;
+using namespace sema;
 
-Sema::OwningStmtResult Sema::ActOnExprStmt(FullExprArg expr) {
-  Expr *E = expr->takeAs<Expr>();
+StmtResult Sema::ActOnExprStmt(FullExprArg expr) {
+  Expr *E = expr.get();
   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.
@@ -48,11 +42,11 @@
 }
 
 
-Sema::OwningStmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc) {
+StmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc) {
   return Owned(new (Context) NullStmt(SemiLoc));
 }
 
-Sema::OwningStmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg,
+StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg,
                                            SourceLocation StartLoc,
                                            SourceLocation EndLoc) {
   DeclGroupRef DG = dg.getAsVal<DeclGroupRef>();
@@ -92,12 +86,6 @@
   
   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())
@@ -147,10 +135,10 @@
     }
   }
 
-  Diag(Loc, DiagID) << R1 << R2;
+  DiagRuntimeBehavior(Loc, PDiag(DiagID) << R1 << R2);
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
                         MultiStmtArg elts, bool isStmtExpr) {
   unsigned NumElts = elts.size();
@@ -185,70 +173,60 @@
   return Owned(new (Context) CompoundStmt(Context, Elts, NumElts, L, R));
 }
 
-Action::OwningStmtResult
-Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprArg lhsval,
-                    SourceLocation DotDotDotLoc, ExprArg rhsval,
+StmtResult
+Sema::ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
+                    SourceLocation DotDotDotLoc, Expr *RHSVal,
                     SourceLocation ColonLoc) {
-  assert((lhsval.get() != 0) && "missing expression in case statement");
+  assert((LHSVal != 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()) {
+  if (getCurFunction()->SwitchStack.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);
+  getCurFunction()->SwitchStack.back()->addSwitchCase(CS);
   return Owned(CS);
 }
 
 /// ActOnCaseStmtBody - This installs a statement as the body of a case.
-void Sema::ActOnCaseStmtBody(StmtTy *caseStmt, StmtArg subStmt) {
+void Sema::ActOnCaseStmtBody(Stmt *caseStmt, Stmt *SubStmt) {
   CaseStmt *CS = static_cast<CaseStmt*>(caseStmt);
-  Stmt *SubStmt = subStmt.takeAs<Stmt>();
   CS->setSubStmt(SubStmt);
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
-                       StmtArg subStmt, Scope *CurScope) {
-  Stmt *SubStmt = subStmt.takeAs<Stmt>();
-
-  if (getSwitchStack().empty()) {
+                       Stmt *SubStmt, Scope *CurScope) {
+  if (getCurFunction()->SwitchStack.empty()) {
     Diag(DefaultLoc, diag::err_default_not_in_switch);
     return Owned(SubStmt);
   }
 
   DefaultStmt *DS = new (Context) DefaultStmt(DefaultLoc, ColonLoc, SubStmt);
-  getSwitchStack().back()->addSwitchCase(DS);
+  getCurFunction()->SwitchStack.back()->addSwitchCase(DS);
   return Owned(DS);
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
-                     SourceLocation ColonLoc, StmtArg subStmt) {
-  Stmt *SubStmt = subStmt.takeAs<Stmt>();
+                     SourceLocation ColonLoc, Stmt *SubStmt) {
   // Look up the record for this label identifier.
-  LabelStmt *&LabelDecl = getLabelMap()[II];
+  LabelStmt *&LabelDecl = getCurFunction()->LabelMap[II];
 
   // If not forward referenced or defined already, just create a new LabelStmt.
   if (LabelDecl == 0)
@@ -271,16 +249,16 @@
   return Owned(LabelDecl);
 }
 
-Action::OwningStmtResult
-Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, DeclPtrTy CondVar,
-                  StmtArg ThenVal, SourceLocation ElseLoc,
-                  StmtArg ElseVal) {
-  OwningExprResult CondResult(CondVal.release());
+StmtResult
+Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
+                  Stmt *thenStmt, SourceLocation ElseLoc,
+                  Stmt *elseStmt) {
+  ExprResult CondResult(CondVal.release());
 
   VarDecl *ConditionVar = 0;
-  if (CondVar.get()) {
-    ConditionVar = CondVar.getAs<VarDecl>();
-    CondResult = CheckConditionVariable(ConditionVar);
+  if (CondVar) {
+    ConditionVar = cast<VarDecl>(CondVar);
+    CondResult = CheckConditionVariable(ConditionVar, IfLoc, true);
     if (CondResult.isInvalid())
       return StmtError();
   }
@@ -288,48 +266,23 @@
   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 (!elseStmt) {
     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, 
+  return Owned(new (Context) IfStmt(Context, 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.
@@ -422,158 +375,79 @@
 /// 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) {
+  if (const CastExpr *ImplicitCast = dyn_cast<ImplicitCastExpr>(expr)) {
     const Expr *ExprBeforePromotion = ImplicitCast->getSubExpr();
     QualType TypeBeforePromotion = ExprBeforePromotion->getType();
-    if (TypeBeforePromotion->isIntegralType()) {
+    if (TypeBeforePromotion->isIntegralOrEnumerationType()) {
       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;
+StmtResult
+Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond, 
+                             Decl *CondVar) {
+  ExprResult CondResult;
 
-  QualType CondType = CondExpr->getType();
+  VarDecl *ConditionVar = 0;
+  if (CondVar) {
+    ConditionVar = cast<VarDecl>(CondVar);
+    CondResult = CheckConditionVariable(ConditionVar, SourceLocation(), false);
+    if (CondResult.isInvalid())
+      return StmtError();
+    
+    Cond = CondResult.release();
+  }
+  
+  if (!Cond)
+    return StmtError();
+  
+  CondResult
+    = ConvertToIntegralOrEnumerationType(SwitchLoc, Cond, 
+                          PDiag(diag::err_typecheck_statement_requires_integer),
+                                   PDiag(diag::err_switch_incomplete_class_type)
+                                     << Cond->getSourceRange(),
+                                   PDiag(diag::err_switch_explicit_conversion),
+                                         PDiag(diag::note_switch_conversion),
+                                   PDiag(diag::err_switch_multiple_conversions),
+                                         PDiag(diag::note_switch_conversion),
+                                         PDiag(0));
+  if (CondResult.isInvalid()) return StmtError();
+  Cond = CondResult.take();
+  
+  if (!CondVar) {
+    CondResult = MaybeCreateCXXExprWithTemporaries(Cond);
+    if (CondResult.isInvalid())
+      return StmtError();
+    Cond = CondResult.take();
+  }
 
-  // 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;
+  getCurFunction()->setHasBranchIntoScope();
+    
+  SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, Cond);
+  getCurFunction()->SwitchStack.push_back(SS);
+  return Owned(SS);
 }
 
-/// 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() &&
+StmtResult
+Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
+                            Stmt *BodyStmt) {
+  SwitchStmt *SS = cast<SwitchStmt>(Switch);
+  assert(SS == getCurFunction()->SwitchStack.back() &&
          "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();
+  getCurFunction()->SwitchStack.pop_back();
 
-  if (SS->getCond() == 0) {
-    SS->Destroy(Context);
+  if (SS->getCond() == 0)
     return StmtError();
-  }
     
   Expr *CondExpr = SS->getCond();
+  Expr *CondExprBeforePromotion = CondExpr;
   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();
@@ -587,11 +461,11 @@
   // 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();
+    // We have already converted the expression to an integral or enumeration
+    // type, when we started the switch statement. If we don't have an 
+    // appropriate type now, just return an error.
+    if (!CondType->isIntegralOrEnumerationType())
       return StmtError();
-    }
 
     if (CondExpr->isKnownToHaveBooleanValue()) {
       // switch(bool_expr) {...} is often a programmer error, e.g.
@@ -662,7 +536,7 @@
 
       // If the LHS is not the same type as the condition, insert an implicit
       // cast.
-      ImpCastExprToType(Lo, CondType, CastExpr::CK_IntegralCast);
+      ImpCastExprToType(Lo, CondType, CK_IntegralCast);
       CS->setLHS(Lo);
 
       // If this is a case range, remember it in CaseRanges, otherwise CaseVals.
@@ -679,16 +553,38 @@
   }
 
   if (!HasDependentValue) {
+    // If we don't have a default statement, check whether the
+    // condition is constant.
+    llvm::APSInt ConstantCondValue;
+    bool HasConstantCond = false;
+    bool ShouldCheckConstantCond = false;
+    if (!HasDependentValue && !TheDefaultStmt) {
+      Expr::EvalResult Result;
+      HasConstantCond = CondExprBeforePromotion->Evaluate(Result, Context);
+      if (HasConstantCond) {
+        assert(Result.Val.isInt() && "switch condition evaluated to non-int");
+        ConstantCondValue = Result.Val.getInt();
+        ShouldCheckConstantCond = true;
+
+        assert(ConstantCondValue.getBitWidth() == CondWidth &&
+               ConstantCondValue.isSigned() == CondIsSigned);
+      }
+    }
+
     // 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) {
+      for (unsigned i = 0, e = CaseVals.size(); i != e; ++i) {
+        if (ShouldCheckConstantCond &&
+            CaseVals[i].first == ConstantCondValue)
+          ShouldCheckConstantCond = false;
+
+        if (i != 0 && 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::err_duplicate_case) << CaseVals[i].first.toString(10);
+          Diag(CaseVals[i-1].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.
@@ -707,6 +603,7 @@
       // 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) {
+        llvm::APSInt &LoVal = CaseRanges[i].first;
         CaseStmt *CR = CaseRanges[i].second;
         Expr *Hi = CR->getRHS();
         llvm::APSInt HiVal = Hi->EvaluateAsInt(Context);
@@ -718,11 +615,11 @@
 
         // If the LHS is not the same type as the condition, insert an implicit
         // cast.
-        ImpCastExprToType(Hi, CondType, CastExpr::CK_IntegralCast);
+        ImpCastExprToType(Hi, CondType, CK_IntegralCast);
         CR->setRHS(Hi);
 
         // If the low value is bigger than the high value, the case is empty.
-        if (CaseRanges[i].first > HiVal) {
+        if (LoVal > HiVal) {
           Diag(CR->getLHS()->getLocStart(), diag::warn_case_empty_range)
             << SourceRange(CR->getLHS()->getLocStart(),
                            CR->getRHS()->getLocEnd());
@@ -730,6 +627,12 @@
           --i, --e;
           continue;
         }
+
+        if (ShouldCheckConstantCond &&
+            LoVal <= ConstantCondValue &&
+            ConstantCondValue <= HiVal)
+          ShouldCheckConstantCond = false;
+
         HiVals.push_back(HiVal);
       }
 
@@ -783,49 +686,71 @@
       }
     }
 
-    // Check to see if switch is over an Enum and handles all of its 
-    // values  
+    // Complain if we have a constant condition and we didn't find a match.
+    if (!CaseListIsErroneous && ShouldCheckConstantCond) {
+      // TODO: it would be nice if we printed enums as enums, chars as
+      // chars, etc.
+      Diag(CondExpr->getExprLoc(), diag::warn_missing_case_for_condition)
+        << ConstantCondValue.toString(10)
+        << CondExpr->getSourceRange();
+    }
+
+    // Check to see if switch is over an Enum and handles all of its
+    // values.  We don't need to do this if there's a default
+    // statement or if we have a constant condition.
+    //
+    // TODO: we might want to check whether case values are out of the
+    // enum even if we don't want to check whether all cases are handled.
     const EnumType* ET = CondTypeBeforePromotion->getAs<EnumType>();
     // If switch has default case, then ignore it.
-    if (!CaseListIsErroneous && !TheDefaultStmt && ET) {
+    if (!CaseListIsErroneous && !TheDefaultStmt && !HasConstantCond && 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++) {
+      // 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);
+        else if (Val.getBitWidth() > CondWidth)
+          Val.trunc(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);
+      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++) {
+      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();
+            Diag(CI->second->getLHS()->getExprLoc(), diag::warn_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++) {
+      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();
+          Diag(RI->second->getLHS()->getExprLoc(), diag::warn_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();
+          Diag(RI->second->getRHS()->getExprLoc(), diag::warn_not_in_enum)
+            << ED->getDeclName();
       }
       //Check which enum vals aren't in switch
       CaseValsTy::const_iterator CI = CaseVals.begin();
@@ -848,7 +773,8 @@
         }
 
         if (RI == CaseRanges.end() || EI->first < RI->first)
-          Diag(CondExpr->getExprLoc(), diag::warn_missing_cases) << EI->second->getDeclName();
+          Diag(CondExpr->getExprLoc(), diag::warn_missing_cases)
+            << EI->second->getDeclName();
       }
     }
   }
@@ -858,66 +784,55 @@
   if (CaseListIsErroneous)
     return StmtError();
 
-  Switch.release();
   return Owned(SS);
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond, 
-                     DeclPtrTy CondVar, StmtArg Body) {
-  OwningExprResult CondResult(Cond.release());
+                     Decl *CondVar, Stmt *Body) {
+  ExprResult CondResult(Cond.release());
   
   VarDecl *ConditionVar = 0;
-  if (CondVar.get()) {
-    ConditionVar = CondVar.getAs<VarDecl>();
-    CondResult = CheckConditionVariable(ConditionVar);
+  if (CondVar) {
+    ConditionVar = cast<VarDecl>(CondVar);
+    CondResult = CheckConditionVariable(ConditionVar, WhileLoc, true);
     if (CondResult.isInvalid())
       return StmtError();
   }
-  Expr *ConditionExpr = CondResult.takeAs<Expr>();
+  Expr *ConditionExpr = CondResult.take();
   if (!ConditionExpr)
     return StmtError();
   
-  if (CheckBooleanCondition(ConditionExpr, WhileLoc)) {
-    CondResult = ConditionExpr;
-    return StmtError();
-  }
+  DiagnoseUnusedExprResult(Body);
 
-  Stmt *bodyStmt = Body.takeAs<Stmt>();
-  DiagnoseUnusedExprResult(bodyStmt);
-
-  CondResult.release();
-  return Owned(new (Context) WhileStmt(ConditionVar, ConditionExpr, bodyStmt, 
-                                       WhileLoc));
+  return Owned(new (Context) WhileStmt(Context, ConditionVar, ConditionExpr,
+                                       Body, WhileLoc));
 }
 
-Action::OwningStmtResult
-Sema::ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
+StmtResult
+Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
                   SourceLocation WhileLoc, SourceLocation CondLParen,
-                  ExprArg Cond, SourceLocation CondRParen) {
-  Expr *condExpr = Cond.takeAs<Expr>();
-  assert(condExpr && "ActOnDoStmt(): missing expression");
+                  Expr *Cond, SourceLocation CondRParen) {
+  assert(Cond && "ActOnDoStmt(): missing expression");
 
-  if (CheckBooleanCondition(condExpr, DoLoc)) {
-    Cond = condExpr;
+  if (CheckBooleanCondition(Cond, DoLoc))
     return StmtError();
-  }
 
-  Stmt *bodyStmt = Body.takeAs<Stmt>();
-  DiagnoseUnusedExprResult(bodyStmt);
+  ExprResult CondResult = MaybeCreateCXXExprWithTemporaries(Cond);
+  if (CondResult.isInvalid())
+    return StmtError();
+  Cond = CondResult.take();
+  
+  DiagnoseUnusedExprResult(Body);
 
-  Cond.release();
-  return Owned(new (Context) DoStmt(bodyStmt, condExpr, DoLoc,
-                                    WhileLoc, CondRParen));
+  return Owned(new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen));
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
-                   StmtArg first, FullExprArg second, DeclPtrTy secondVar,
+                   Stmt *First, FullExprArg second, Decl *secondVar,
                    FullExprArg third,
-                   SourceLocation RParenLoc, StmtArg body) {
-  Stmt *First  = static_cast<Stmt*>(first.get());
-
+                   SourceLocation RParenLoc, Stmt *Body) {
   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
@@ -935,42 +850,32 @@
     }
   }
 
-  OwningExprResult SecondResult(second.release());
+  ExprResult SecondResult(second.release());
   VarDecl *ConditionVar = 0;
-  if (secondVar.get()) {
-    ConditionVar = secondVar.getAs<VarDecl>();
-    SecondResult = CheckConditionVariable(ConditionVar);
+  if (secondVar) {
+    ConditionVar = cast<VarDecl>(secondVar);
+    SecondResult = CheckConditionVariable(ConditionVar, ForLoc, true);
     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));
+  return Owned(new (Context) ForStmt(Context, First, 
+                                     SecondResult.take(), ConditionVar, 
+                                     Third, Body, ForLoc, LParenLoc, 
+                                     RParenLoc));
 }
 
-Action::OwningStmtResult
+StmtResult
 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());
+                                 Stmt *First, Expr *Second,
+                                 SourceLocation RParenLoc, Stmt *Body) {
   if (First) {
     QualType FirstType;
     if (DeclStmt *DS = dyn_cast<DeclStmt>(First)) {
@@ -1009,19 +914,39 @@
     if (!SecondType->isObjCObjectPointerType())
       Diag(ForLoc, diag::err_collection_expr_type)
         << SecondType << Second->getSourceRange();
+    else if (const ObjCObjectPointerType *OPT =
+             SecondType->getAsObjCInterfacePointerType()) {
+      llvm::SmallVector<IdentifierInfo *, 4> KeyIdents;
+      IdentifierInfo* selIdent = 
+        &Context.Idents.get("countByEnumeratingWithState");
+      KeyIdents.push_back(selIdent);
+      selIdent = &Context.Idents.get("objects");
+      KeyIdents.push_back(selIdent);
+      selIdent = &Context.Idents.get("count");
+      KeyIdents.push_back(selIdent);
+      Selector CSelector = Context.Selectors.getSelector(3, &KeyIdents[0]);
+      if (ObjCInterfaceDecl *IDecl = OPT->getInterfaceDecl()) {
+        if (!IDecl->isForwardDecl() && 
+            !IDecl->lookupInstanceMethod(CSelector)) {
+          // Must further look into private implementation methods.
+          if (!LookupPrivateInstanceMethod(CSelector, IDecl))
+            Diag(ForLoc, diag::warn_collection_expr_type)
+              << SecondType << CSelector << Second->getSourceRange();
+        }
+      }
+    }
   }
-  first.release();
-  second.release();
-  body.release();
   return Owned(new (Context) ObjCForCollectionStmt(First, Second, Body,
                                                    ForLoc, RParenLoc));
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
                     IdentifierInfo *LabelII) {
   // Look up the record for this label identifier.
-  LabelStmt *&LabelDecl = getLabelMap()[LabelII];
+  LabelStmt *&LabelDecl = getCurFunction()->LabelMap[LabelII];
+
+  getCurFunction()->setHasBranchIntoScope();
 
   // If we haven't seen this label yet, create a forward reference.
   if (LabelDecl == 0)
@@ -1030,11 +955,10 @@
   return Owned(new (Context) GotoStmt(LabelDecl, GotoLoc, LabelLoc));
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
-                            ExprArg DestExp) {
+                            Expr *E) {
   // Convert operand to void*
-  Expr* E = DestExp.takeAs<Expr>();
   if (!E->isTypeDependent()) {
     QualType ETy = E->getType();
     QualType DestTy = Context.getPointerType(Context.VoidTy.withConst());
@@ -1043,10 +967,13 @@
     if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, ETy, E, AA_Passing))
       return StmtError();
   }
+
+  getCurFunction()->setHasIndirectGoto();
+
   return Owned(new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E));
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {
   Scope *S = CurScope->getContinueParent();
   if (!S) {
@@ -1057,7 +984,7 @@
   return Owned(new (Context) ContinueStmt(ContinueLoc));
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
   Scope *S = CurScope->getBreakParent();
   if (!S) {
@@ -1068,9 +995,48 @@
   return Owned(new (Context) BreakStmt(BreakLoc));
 }
 
+/// \brief Determine whether a return statement is a candidate for the named
+/// return value optimization (C++0x 12.8p34, bullet 1).
+///
+/// \param Ctx The context in which the return expression and type occur.
+///
+/// \param RetType The return type of the function or block.
+///
+/// \param RetExpr The expression being returned from the function or block.
+///
+/// \returns The NRVO candidate variable, if the return statement may use the
+/// NRVO, or NULL if there is no such candidate.
+static const VarDecl *getNRVOCandidate(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 0;
+  // ... the same cv-unqualified type as the function return type ...
+  if (!Ctx.hasSameUnqualifiedType(RetType, ExprType))
+    return 0;
+  // ... the expression is the name of a non-volatile automatic object ...
+  // We ignore parentheses here.
+  // FIXME: Is this compliant? (Everyone else does it)
+  const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(RetExpr->IgnoreParens());
+  if (!DR)
+    return 0;
+  const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
+  if (!VD)
+    return 0;
+  
+  if (VD->getKind() == Decl::Var && VD->hasLocalStorage() && 
+      !VD->getType()->isReferenceType() && !VD->hasAttr<BlocksAttr>() &&
+      !VD->getType().isVolatileQualified())
+    return VD;
+  
+  return 0;
+}
+
 /// ActOnBlockReturnStmt - Utility routine to figure out block's return type.
 ///
-Action::OwningStmtResult
+StmtResult
 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.
@@ -1102,73 +1068,61 @@
   // 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.
+  ReturnStmt *Result = 0;
   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)
+    Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, 0);
+  } else if (!RetValExp) {
     return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr));
+  } else {
+    const VarDecl *NRVOCandidate = 0;
+    
+    if (!FnRetType->isDependentType() && !RetValExp->isTypeDependent()) {
+      // we have a non-void block with an expression, continue checking
 
-  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.
 
-    // 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.
+      NRVOCandidate = getNRVOCandidate(Context, FnRetType, RetValExp);
+      ExprResult Res = PerformCopyInitialization(
+                               InitializedEntity::InitializeResult(ReturnLoc, 
+                                                                   FnRetType,
+                                                            NRVOCandidate != 0),
+                               SourceLocation(),
+                               Owned(RetValExp));
+      if (Res.isInvalid()) {
+        // FIXME: Cleanup temporaries here, anyway?
+        return StmtError();
+      }
+      
+      if (RetValExp)
+        RetValExp = MaybeCreateCXXExprWithTemporaries(RetValExp);
 
-    // 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);
     }
     
-    RetValExp = Res.takeAs<Expr>();
-    if (RetValExp) 
-      CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
+    Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, NRVOCandidate);
   }
 
-  return Owned(new (Context) ReturnStmt(ReturnLoc, RetValExp));
+  // If we need to check for the named return value optimization, save the 
+  // return statement in our scope for later processing.
+  if (getLangOptions().CPlusPlus && FnRetType->isRecordType() &&
+      !CurContext->isDependentContext())
+    FunctionScopes.back()->Returns.push_back(Result);
+  
+  return Owned(Result);
 }
 
-/// 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>();
+StmtResult
+Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
   if (getCurBlock())
     return ActOnBlockReturnStmt(ReturnLoc, RetValExp);
 
@@ -1184,6 +1138,7 @@
   else // If we don't have a function/method context, bail.
     return StmtError();
 
+  ReturnStmt *Result = 0;
   if (FnRetType->isVoidType()) {
     if (RetValExp && !RetValExp->isTypeDependent()) {
       // C99 6.8.6.4p1 (ext_ since GCC warns)
@@ -1202,10 +1157,9 @@
 
       RetValExp = MaybeCreateCXXExprWithTemporaries(RetValExp);
     }
-    return Owned(new (Context) ReturnStmt(ReturnLoc, RetValExp));
-  }
-
-  if (!RetValExp && !FnRetType->isDependentType()) {
+    
+    Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, 0);
+  } else 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;
@@ -1214,54 +1168,47 @@
       Diag(ReturnLoc, DiagID) << FD->getIdentifier() << 0/*fn*/;
     else
       Diag(ReturnLoc, DiagID) << getCurMethodDecl()->getDeclName() << 1/*meth*/;
-    return Owned(new (Context) ReturnStmt(ReturnLoc, (Expr*)0));
-  }
+    Result = new (Context) ReturnStmt(ReturnLoc);
+  } else {
+    const VarDecl *NRVOCandidate = 0;
+    if (!FnRetType->isDependentType() && !RetValExp->isTypeDependent()) {
+      // we have a non-void function with an expression, continue checking
 
-  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.
 
-    // 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.
+      NRVOCandidate = getNRVOCandidate(Context, FnRetType, RetValExp);
+      ExprResult Res = PerformCopyInitialization(
+                               InitializedEntity::InitializeResult(ReturnLoc, 
+                                                                   FnRetType,
+                                                            NRVOCandidate != 0),
+                               SourceLocation(),
+                               Owned(RetValExp));
+      if (Res.isInvalid()) {
+        // FIXME: Cleanup temporaries here, anyway?
+        return StmtError();
+      }
 
-    // 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);
     }
-
-    RetValExp = Res.takeAs<Expr>();
-    if (RetValExp) 
-      CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
+    
+    if (RetValExp)
+      RetValExp = MaybeCreateCXXExprWithTemporaries(RetValExp);
+    Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, NRVOCandidate);
   }
-
-  if (RetValExp)
-    RetValExp = MaybeCreateCXXExprWithTemporaries(RetValExp);
-  return Owned(new (Context) ReturnStmt(ReturnLoc, RetValExp));
+  
+  // If we need to check for the named return value optimization, save the 
+  // return statement in our scope for later processing.
+  if (getLangOptions().CPlusPlus && FnRetType->isRecordType() &&
+      !CurContext->isDependentContext())
+    FunctionScopes.back()->Returns.push_back(Result);
+  
+  return Owned(Result);
 }
 
 /// CheckAsmLValue - GNU C has an extremely ugly extension whereby they silently
@@ -1298,7 +1245,7 @@
 }
 
 
-Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
+StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
                                           bool IsSimple,
                                           bool IsVolatile,
                                           unsigned NumOutputs,
@@ -1306,15 +1253,15 @@
                                           IdentifierInfo **Names,
                                           MultiExprArg constraints,
                                           MultiExprArg exprs,
-                                          ExprArg asmString,
+                                          Expr *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());
+  Expr **Exprs = exprs.get();
+  StringLiteral *AsmString = cast<StringLiteral>(asmString);
   StringLiteral **Clobbers = reinterpret_cast<StringLiteral**>(clobbers.get());
 
   llvm::SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos;
@@ -1410,10 +1357,6 @@
                   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, 
@@ -1454,14 +1397,14 @@
     
     if (InTy->isIntegerType() || InTy->isPointerType())
       InputDomain = AD_Int;
-    else if (InTy->isFloatingType())
+    else if (InTy->isRealFloatingType())
       InputDomain = AD_FP;
     else
       InputDomain = AD_Other;
 
     if (OutTy->isIntegerType() || OutTy->isPointerType())
       OutputDomain = AD_Int;
-    else if (OutTy->isFloatingType())
+    else if (OutTy->isRealFloatingType())
       OutputDomain = AD_FP;
     else
       OutputDomain = AD_Other;
@@ -1523,38 +1466,35 @@
   return Owned(NS);
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnObjCAtCatchStmt(SourceLocation AtLoc,
-                           SourceLocation RParen, DeclPtrTy Parm,
-                           StmtArg Body) {
-  VarDecl *Var = cast_or_null<VarDecl>(Parm.getAs<Decl>());
+                           SourceLocation RParen, Decl *Parm,
+                           Stmt *Body) {
+  VarDecl *Var = cast_or_null<VarDecl>(Parm);
   if (Var && Var->isInvalidDecl())
     return StmtError();
   
-  return Owned(new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, 
-                                             Body.takeAs<Stmt>()));
+  return Owned(new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body));
 }
 
-Action::OwningStmtResult
-Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, StmtArg Body) {
-  return Owned(new (Context) ObjCAtFinallyStmt(AtLoc,
-                                           static_cast<Stmt*>(Body.release())));
+StmtResult
+Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) {
+  return Owned(new (Context) ObjCAtFinallyStmt(AtLoc, Body));
 }
 
-Action::OwningStmtResult
-Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, StmtArg Try, 
-                         MultiStmtArg CatchStmts, StmtArg Finally) {
-  FunctionNeedsScopeChecking() = true;
+StmtResult
+Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, 
+                         MultiStmtArg CatchStmts, Stmt *Finally) {
+  getCurFunction()->setHasBranchProtectedScope();
   unsigned NumCatchStmts = CatchStmts.size();
-  return Owned(ObjCAtTryStmt::Create(Context, AtLoc, Try.takeAs<Stmt>(),
-                                     (Stmt **)CatchStmts.release(),
+  return Owned(ObjCAtTryStmt::Create(Context, AtLoc, Try,
+                                     CatchStmts.release(),
                                      NumCatchStmts,
-                                     Finally.takeAs<Stmt>()));
+                                     Finally));
 }
 
-Sema::OwningStmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc,
-                                                  ExprArg ThrowE) {
-  Expr *Throw = static_cast<Expr *>(ThrowE.get());
+StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc,
+                                                  Expr *Throw) {
   if (Throw) {
     QualType ThrowType = Throw->getType();
     // Make sure the expression type is an ObjC pointer or "void *".
@@ -1567,13 +1507,13 @@
     }
   }
   
-  return Owned(new (Context) ObjCAtThrowStmt(AtLoc, ThrowE.takeAs<Expr>()));
+  return Owned(new (Context) ObjCAtThrowStmt(AtLoc, Throw));
 }
 
-Action::OwningStmtResult
-Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, ExprArg Throw, 
+StmtResult
+Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, 
                            Scope *CurScope) {
-  if (!Throw.get()) {
+  if (!Throw) {
     // @throw without an expression designates a rethrow (which much occur
     // in the context of an @catch clause).
     Scope *AtCatchParent = CurScope;
@@ -1583,16 +1523,15 @@
       return StmtError(Diag(AtLoc, diag::error_rethrow_used_outside_catch));
   } 
   
-  return BuildObjCAtThrowStmt(AtLoc, move(Throw));
+  return BuildObjCAtThrowStmt(AtLoc, Throw);
 }
 
-Action::OwningStmtResult
-Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr,
-                                  StmtArg SynchBody) {
-  FunctionNeedsScopeChecking() = true;
+StmtResult
+Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SyncExpr,
+                                  Stmt *SyncBody) {
+  getCurFunction()->setHasBranchProtectedScope();
 
   // 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>();
@@ -1601,22 +1540,22 @@
                        << SyncExpr->getType() << SyncExpr->getSourceRange());
   }
 
-  return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc,
-                                                    SynchExpr.takeAs<Stmt>(),
-                                                    SynchBody.takeAs<Stmt>()));
+  return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody));
 }
 
 /// 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) {
+StmtResult
+Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl,
+                         Stmt *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>()));
+                                          cast_or_null<VarDecl>(ExDecl),
+                                          HandlerBlock));
 }
 
+namespace {
+
 class TypeWithHandler {
   QualType t;
   CXXCatchStmt *stmt;
@@ -1646,15 +1585,17 @@
   }
 };
 
+}
+
 /// 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,
+StmtResult
+Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *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());
+  Stmt **Handlers = RawHandlers.get();
 
   llvm::SmallVector<TypeWithHandler, 8> TypesWithHandlers;
 
@@ -1694,15 +1635,14 @@
     }
   }
 
+  getCurFunction()->setHasBranchProtectedScope();
+
   // 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()),
+  return Owned(CXXTryStmt::Create(Context, TryLoc, TryBlock,
                                   Handlers, NumHandlers));
 }
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 731836b..09656bc 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -9,30 +9,34 @@
 //  This file implements semantic analysis for C++ templates.
 //===----------------------------------------------------------------------===/
 
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/Template.h"
+#include "clang/Sema/TemplateDeduction.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/Sema/DeclSpec.h"
+#include "clang/Sema/ParsedTemplate.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "llvm/ADT/StringExtras.h"
 using namespace clang;
+using namespace sema;
 
 /// \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;
+static NamedDecl *isAcceptableTemplateName(ASTContext &Context,
+                                           NamedDecl *Orig) {
+  NamedDecl *D = Orig->getUnderlyingDecl();
 
   if (isa<TemplateDecl>(D))
-    return D;
+    return Orig;
 
   if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
     // C++ [temp.local]p1:
@@ -68,7 +72,7 @@
   LookupResult::Filter filter = R.makeFilter();
   while (filter.hasNext()) {
     NamedDecl *Orig = filter.next();
-    NamedDecl *Repl = isAcceptableTemplateName(C, Orig->getUnderlyingDecl());
+    NamedDecl *Repl = isAcceptableTemplateName(C, Orig);
     if (!Repl)
       filter.erase();
     else if (Repl != Orig) {
@@ -88,8 +92,13 @@
           filter.erase();
           continue;
         }
-          
-      filter.replace(Repl);
+
+      // FIXME: we promote access to public here as a workaround to
+      // the fact that LookupResult doesn't let us remember that we
+      // found this template through a particular injected class name,
+      // which means we end up doing nasty things to the invariants.
+      // Pretending that access is public is *much* safer.
+      filter.replace(Repl, AS_public);
     }
   }
   filter.done();
@@ -97,13 +106,16 @@
 
 TemplateNameKind Sema::isTemplateName(Scope *S,
                                       CXXScopeSpec &SS,
+                                      bool hasTemplateKeyword,
                                       UnqualifiedId &Name,
-                                      TypeTy *ObjectTypePtr,
+                                      ParsedType ObjectTypePtr,
                                       bool EnteringContext,
-                                      TemplateTy &TemplateResult) {
+                                      TemplateTy &TemplateResult,
+                                      bool &MemberOfUnknownSpecialization) {
   assert(getLangOptions().CPlusPlus && "No template names in C!");
 
   DeclarationName TName;
+  MemberOfUnknownSpecialization = false;
   
   switch (Name.getKind()) {
   case UnqualifiedId::IK_Identifier:
@@ -123,14 +135,16 @@
     return TNK_Non_template;
   }
 
-  QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+  QualType ObjectType = ObjectTypePtr.get();
 
   LookupResult R(*this, TName, Name.getSourceRange().getBegin(), 
                  LookupOrdinaryName);
-  R.suppressDiagnostics();
-  LookupTemplateName(R, S, SS, ObjectType, EnteringContext);
-  if (R.empty() || R.isAmbiguous())
+  LookupTemplateName(R, S, SS, ObjectType, EnteringContext,
+                     MemberOfUnknownSpecialization);
+  if (R.empty() || R.isAmbiguous()) {
+    R.suppressDiagnostics();
     return TNK_Non_template;
+  }
 
   TemplateName Template;
   TemplateNameKind TemplateKind;
@@ -141,20 +155,27 @@
     // template name in other ways.
     Template = Context.getOverloadedTemplateName(R.begin(), R.end());
     TemplateKind = TNK_Function_template;
+
+    // We'll do this lookup again later.
+    R.suppressDiagnostics();
   } 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);
+      Template = Context.getQualifiedTemplateName(Qualifier,
+                                                  hasTemplateKeyword, TD);
     } else {
       Template = TemplateName(TD);
     }
 
-    if (isa<FunctionTemplateDecl>(TD))
+    if (isa<FunctionTemplateDecl>(TD)) {
       TemplateKind = TNK_Function_template;
-    else {
+
+      // We'll do this lookup again later.
+      R.suppressDiagnostics();
+    } else {
       assert(isa<ClassTemplateDecl>(TD) || isa<TemplateTemplateParmDecl>(TD));
       TemplateKind = TNK_Type_template;
     }
@@ -172,6 +193,7 @@
                                        TemplateNameKind &SuggestedKind) {
   // We can't recover unless there's a dependent scope specifier preceding the
   // template name.
+  // FIXME: Typo correction?
   if (!SS || !SS->isSet() || !isDependentScopeSpecifier(*SS) ||
       computeDeclContext(*SS))
     return false;
@@ -191,8 +213,10 @@
 void Sema::LookupTemplateName(LookupResult &Found,
                               Scope *S, CXXScopeSpec &SS,
                               QualType ObjectType,
-                              bool EnteringContext) {
+                              bool EnteringContext,
+                              bool &MemberOfUnknownSpecialization) {
   // Determine where to perform name lookup
+  MemberOfUnknownSpecialization = false;
   DeclContext *LookupCtx = 0;
   bool isDependent = false;
   if (!ObjectType.isNull()) {
@@ -210,7 +234,7 @@
     isDependent = isDependentScopeSpecifier(SS);
     
     // The declaration context must be complete.
-    if (LookupCtx && RequireCompleteDeclContext(SS))
+    if (LookupCtx && RequireCompleteDeclContext(SS, LookupCtx))
       return;
   }
 
@@ -232,15 +256,13 @@
       //   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) {
+  } else if (isDependent && (!S || ObjectType.isNull())) {
     // We cannot look into a dependent object type or nested nme
     // specifier.
+    MemberOfUnknownSpecialization = true;
     return;
   } else {
     // Perform unqualified name lookup in the current scope.
@@ -251,9 +273,9 @@
     // 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)) {
+                                                false, CTC_CXXCasts)) {
       FilterAcceptableTemplateNames(Context, Found);
-      if (!Found.empty() && isa<TemplateDecl>(*Found.begin())) {
+      if (!Found.empty()) {
         if (LookupCtx)
           Diag(Found.getNameLoc(), diag::err_no_member_template_suggest)
             << Name << LookupCtx << Found.getLookupName() << SS.getRange()
@@ -267,16 +289,19 @@
         if (TemplateDecl *Template = Found.getAsSingle<TemplateDecl>())
           Diag(Template->getLocation(), diag::note_previous_decl)
             << Template->getDeclName();
-      } else
-        Found.clear();
+      }
     } else {
       Found.clear();
+      Found.setLookupName(Name);
     }
   }
 
   FilterAcceptableTemplateNames(Context, Found);
-  if (Found.empty())
+  if (Found.empty()) {
+    if (isDependent)
+      MemberOfUnknownSpecialization = true;
     return;
+  }
 
   if (S && !ObjectType.isNull() && !ObjectTypeSearchedInScope) {
     // C++ [basic.lookup.classref]p1:
@@ -296,7 +321,7 @@
       //   - 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 {
+    } else if (!Found.isSuppressingDiagnostics()) {
       //   - 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.
@@ -304,8 +329,9 @@
           Found.getFoundDecl()->getCanonicalDecl()
             != FoundOuter.getFoundDecl()->getCanonicalDecl()) {
         Diag(Found.getNameLoc(), 
-             diag::err_nested_name_member_ref_lookup_ambiguous)
-          << Found.getLookupName();
+             diag::ext_nested_name_member_ref_lookup_ambiguous)
+          << Found.getLookupName()
+          << ObjectType;
         Diag(Found.getRepresentativeDecl()->getLocation(),
              diag::note_ambig_member_ref_object_type)
           << ObjectType;
@@ -322,19 +348,20 @@
 /// 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
+ExprResult
 Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
-                                 DeclarationName Name,
-                                 SourceLocation NameLoc,
+                                 const DeclarationNameInfo &NameInfo,
                                  bool isAddressOfOperand,
                            const TemplateArgumentListInfo *TemplateArgs) {
   NestedNameSpecifier *Qualifier
     = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
+
+  DeclContext *DC = getFunctionLevelDeclContext();
     
   if (!isAddressOfOperand &&
-      isa<CXXMethodDecl>(CurContext) &&
-      cast<CXXMethodDecl>(CurContext)->isInstance()) {
-    QualType ThisType = cast<CXXMethodDecl>(CurContext)->getThisType(Context);
+      isa<CXXMethodDecl>(DC) &&
+      cast<CXXMethodDecl>(DC)->isInstance()) {
+    QualType ThisType = cast<CXXMethodDecl>(DC)->getThisType(Context);
     
     // Since the 'this' expression is synthesized, we don't need to
     // perform the double-lookup check.
@@ -346,22 +373,21 @@
                                                      /*Op*/ SourceLocation(),
                                                      Qualifier, SS.getRange(),
                                                      FirstQualifierInScope,
-                                                     Name, NameLoc,
+                                                     NameInfo,
                                                      TemplateArgs));
   }
 
-  return BuildDependentDeclRefExpr(SS, Name, NameLoc, TemplateArgs);
+  return BuildDependentDeclRefExpr(SS, NameInfo, TemplateArgs);
 }
 
-Sema::OwningExprResult
+ExprResult
 Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
-                                DeclarationName Name,
-                                SourceLocation NameLoc,
+                                const DeclarationNameInfo &NameInfo,
                                 const TemplateArgumentListInfo *TemplateArgs) {
   return Owned(DependentScopeDeclRefExpr::Create(Context,
                static_cast<NestedNameSpecifier*>(SS.getScopeRep()),
                                                  SS.getRange(),
-                                                 Name, NameLoc,
+                                                 NameInfo,
                                                  TemplateArgs));
 }
 
@@ -388,9 +414,9 @@
 /// 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());
+TemplateDecl *Sema::AdjustDeclIfTemplate(Decl *&D) {
+  if (TemplateDecl *Temp = dyn_cast_or_null<TemplateDecl>(D)) {
+    D = Temp->getTemplatedDecl();
     return Temp;
   }
   return 0;
@@ -414,8 +440,7 @@
   }
     
   case ParsedTemplateArgument::Template: {
-    TemplateName Template
-      = TemplateName::getFromVoidPointer(Arg.getAsTemplate().get());
+    TemplateName Template = Arg.getAsTemplate().get();
     return TemplateArgumentLoc(TemplateArgument(Template),
                                Arg.getScopeSpec().getRange(),
                                Arg.getLocation());
@@ -444,12 +469,14 @@
 /// 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) {
+Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+                               SourceLocation EllipsisLoc,
+                               SourceLocation KeyLoc,
+                               IdentifierInfo *ParamName,
+                               SourceLocation ParamNameLoc,
+                               unsigned Depth, unsigned Position,
+                               SourceLocation EqualLoc,
+                               ParsedType DefaultArg) {
   assert(S->isTemplateParamScope() &&
          "Template type parameter not in template parameter scope!");
   bool Invalid = false;
@@ -476,46 +503,35 @@
 
   if (ParamName) {
     // Add the template parameter into the current scope.
-    S->AddDecl(DeclPtrTy::make(Param));
+    S->AddDecl(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;
+  // Handle the default argument, if provided.
+  if (DefaultArg) {
+    TypeSourceInfo *DefaultTInfo;
+    GetTypeFromParser(DefaultArg, &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 (Ellipsis) {
+      Diag(EqualLoc, diag::err_template_param_pack_default_arg);
+      return Param;
+    }
+    
+    // Check the template argument itself.
+    if (CheckTemplateArgument(Param, DefaultTInfo)) {
+      Param->setInvalidDecl();
+      return Param;
+    }
+    
+    Param->setDefaultArgument(DefaultTInfo, false);
   }
-
-  // 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);
+  
+  return Param;
 }
 
 /// \brief Check that the type of a non-type template parameter is
@@ -525,17 +541,23 @@
 /// otherwise, produces a diagnostic and returns a NULL type.
 QualType
 Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) {
+  // We don't allow variably-modified types as the type of non-type template
+  // parameters.
+  if (T->isVariablyModifiedType()) {
+    Diag(Loc, diag::err_variably_modified_nontype_template_param)
+      << T;
+    return QualType();
+  }
+
   // 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() ||
+  if (T->isIntegralOrEnumerationType() ||
       //   -- pointer to object or pointer to function,
-      (T->isPointerType() &&
-       (T->getAs<PointerType>()->getPointeeType()->isObjectType() ||
-        T->getAs<PointerType>()->getPointeeType()->isFunctionType())) ||
+      T->isPointerType() ||
       //   -- reference to object or reference to function,
       T->isReferenceType() ||
       //   -- pointer to member.
@@ -555,22 +577,20 @@
   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);
+Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
+                                          unsigned Depth,
+                                          unsigned Position,
+                                          SourceLocation EqualLoc,
+                                          Expr *Default) {
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
+  QualType T = TInfo->getType();
 
   assert(S->isTemplateParamScope() &&
          "Non-type template parameter not in template parameter scope!");
@@ -601,47 +621,36 @@
 
   if (D.getIdentifier()) {
     // Add the template parameter into the current scope.
-    S->AddDecl(DeclPtrTy::make(Param));
+    S->AddDecl(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;
+  
+  // Check the well-formedness of the default template argument, if provided.
+  if (Default) {  
+    TemplateArgument Converted;
+    if (CheckTemplateArgument(Param, Param->getType(), Default, Converted)) {
+      Param->setInvalidDecl();
+      return Param;
+    }
+  
+    Param->setDefaultArgument(Default, false);
   }
-
-  TemplateParm->setDefaultArgument(DefaultE.takeAs<Expr>());
+  
+  return Param;
 }
 
-
 /// 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) {
+Decl *Sema::ActOnTemplateTemplateParameter(Scope* S,
+                                           SourceLocation TmpLoc,
+                                           TemplateParamsTy *Params,
+                                           IdentifierInfo *Name,
+                                           SourceLocation NameLoc,
+                                           unsigned Depth,
+                                           unsigned Position,
+                                           SourceLocation EqualLoc,
+                                       const ParsedTemplateArgument &Default) {
   assert(S->isTemplateParamScope() &&
          "Template template parameter not in template parameter scope!");
 
@@ -651,53 +660,33 @@
                                      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 the template template parameter has a name, then link the identifier 
+  // into the scope and lookup mechanisms.
   if (Name) {
-    S->AddDecl(DeclPtrTy::make(Param));
+    S->AddDecl(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;
+  if (!Default.isInvalid()) {
+    // 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 Param;
+    }
+    
+    Param->setDefaultArgument(DefaultArg, false);
   }
   
-  TemplateParm->setDefaultArgument(DefaultArg);
+  return Param;
 }
 
 /// ActOnTemplateParameterList - Builds a TemplateParameterList that
@@ -707,7 +696,7 @@
                                  SourceLocation ExportLoc,
                                  SourceLocation TemplateLoc,
                                  SourceLocation LAngleLoc,
-                                 DeclPtrTy *Params, unsigned NumParams,
+                                 Decl **Params, unsigned NumParams,
                                  SourceLocation RAngleLoc) {
   if (ExportLoc.isValid())
     Diag(ExportLoc, diag::warn_template_export_unsupported);
@@ -723,7 +712,7 @@
                         SS.getRange());
 }
 
-Sema::DeclResult
+DeclResult
 Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
                          SourceLocation KWLoc, CXXScopeSpec &SS,
                          IdentifierInfo *Name, SourceLocation NameLoc,
@@ -739,8 +728,8 @@
   if (CheckTemplateDeclScope(S, TemplateParams))
     return true;
 
-  TagDecl::TagKind Kind = TagDecl::getTagKindForTypeSpec(TagSpec);
-  assert(Kind != TagDecl::TK_enum && "can't build template of enumerated type");
+  TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
+  assert(Kind != TTK_Enum && "can't build template of enumerated type");
 
   // There is no such thing as an unnamed class template.
   if (!Name) {
@@ -753,15 +742,15 @@
   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;
     }
 
+    if (RequireCompleteDeclContext(SS, SemanticContext))
+      return true;
+
     LookupQualifiedName(Previous, SemanticContext);
   } else {
     SemanticContext = CurContext;
@@ -908,7 +897,7 @@
   NewClass->setDescribedClassTemplate(NewTemplate);
 
   // Build the type for the class template declaration now.
-  QualType T = NewTemplate->getInjectedClassNameSpecialization(Context);
+  QualType T = NewTemplate->getInjectedClassNameSpecialization();
   T = Context.getInjectedClassNameType(NewClass, T);
   assert(T->isDependentType() && "Class template type is not dependent?");
   (void)T;
@@ -965,7 +954,7 @@
     NewTemplate->setInvalidDecl();
     NewClass->setInvalidDecl();
   }
-  return DeclPtrTy::make(NewTemplate);
+  return NewTemplate;
 }
 
 /// \brief Diagnose the presence of a default template argument on a
@@ -1088,7 +1077,7 @@
           DiagnoseDefaultTemplateArgument(*this, TPC, 
                                           NewTypeParm->getLocation(), 
                NewTypeParm->getDefaultArgumentInfo()->getTypeLoc()
-                                                       .getFullSourceRange()))
+                                                       .getSourceRange()))
         NewTypeParm->removeDefaultArgument();
 
       // Merge default arguments for template type parameters.
@@ -1126,8 +1115,7 @@
           DiagnoseDefaultTemplateArgument(*this, TPC, 
                                           NewNonTypeParm->getLocation(), 
                     NewNonTypeParm->getDefaultArgument()->getSourceRange())) {
-        NewNonTypeParm->getDefaultArgument()->Destroy(Context);
-        NewNonTypeParm->setDefaultArgument(0);
+        NewNonTypeParm->removeDefaultArgument();
       }
 
       // Merge default arguments for non-type template parameters
@@ -1148,7 +1136,8 @@
         // expression that points to a previous template template
         // parameter.
         NewNonTypeParm->setDefaultArgument(
-                                        OldNonTypeParm->getDefaultArgument());
+                                         OldNonTypeParm->getDefaultArgument(),
+                                         /*Inherited=*/ true);
         PreviousDefaultArgLoc = OldNonTypeParm->getDefaultArgumentLoc();
       } else if (NewNonTypeParm->hasDefaultArgument()) {
         SawDefaultArgument = true;
@@ -1163,7 +1152,7 @@
           DiagnoseDefaultTemplateArgument(*this, TPC, 
                                           NewTemplateParm->getLocation(), 
                      NewTemplateParm->getDefaultArgument().getSourceRange()))
-        NewTemplateParm->setDefaultArgument(TemplateArgumentLoc());
+        NewTemplateParm->removeDefaultArgument();
 
       // Merge default arguments for template template parameters
       TemplateTemplateParmDecl *OldTemplateParm
@@ -1182,7 +1171,8 @@
         // FIXME: We need to create a new kind of "default argument" expression
         // that points to a previous template template parameter.
         NewTemplateParm->setDefaultArgument(
-                                        OldTemplateParm->getDefaultArgument());
+                                          OldTemplateParm->getDefaultArgument(),
+                                          /*Inherited=*/ true);
         PreviousDefaultArgLoc
           = OldTemplateParm->getDefaultArgument().getLocation();
       } else if (NewTemplateParm->hasDefaultArgument()) {
@@ -1255,7 +1245,8 @@
                                           TemplateParameterList **ParamLists,
                                               unsigned NumParamLists,
                                               bool IsFriend,
-                                              bool &IsExplicitSpecialization) {
+                                              bool &IsExplicitSpecialization,
+                                              bool &Invalid) {
   IsExplicitSpecialization = false;
   
   // Find the template-ids that occur within the nested-name-specifier. These
@@ -1333,6 +1324,7 @@
              diag::err_template_spec_needs_template_parameters)
           << TemplateId
           << SS.getRange();
+        Invalid = true;
       } else {
         Diag(SS.getRange().getBegin(), diag::err_template_spec_needs_header)
           << SS.getRange()
@@ -1395,7 +1387,13 @@
           << ExplicitSpecializationsInSpecifier.back();
         ExplicitSpecializationsInSpecifier.pop_back();
       }
-        
+
+      // We have a template parameter list with no corresponding scope, which 
+      // means that the resulting template declaration can't be instantiated
+      // properly (we'll end up with dependent nodes when we shouldn't).
+      if (!isExplicitSpecHeader)
+        Invalid = true;
+      
       ++Idx;
     }
   }
@@ -1428,7 +1426,6 @@
          "Converted template argument list is too short!");
 
   QualType CanonType;
-  bool IsCurrentInstantiation = false;
 
   if (Name.isDependent() ||
       TemplateSpecializationType::anyDependentTemplateArguments(
@@ -1485,7 +1482,6 @@
         // class name type of the record we just found.
         assert(ICNT.isCanonical());
         CanonType = ICNT;
-        IsCurrentInstantiation = true;
         break;
       }
     }
@@ -1493,24 +1489,21 @@
                = 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);
+      = ClassTemplate->findSpecialization(Converted.getFlatArguments(),
+                                          Converted.flatSize(), 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);
+                            ClassTemplate->getTemplatedDecl()->getTagKind(),
+                                                ClassTemplate->getDeclContext(),
+                                                ClassTemplate->getLocation(),
+                                                ClassTemplate,
+                                                Converted, 0);
+      ClassTemplate->AddSpecialization(Decl, InsertPos);
       Decl->setLexicalDeclContext(CurContext);
     }
 
@@ -1522,11 +1515,10 @@
   // 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);
+  return Context.getTemplateSpecializationType(Name, TemplateArgs, CanonType);
 }
 
-Action::TypeResult
+TypeResult
 Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
                           SourceLocation LAngleLoc,
                           ASTTemplateArgsPtr TemplateArgsIn,
@@ -1552,22 +1544,22 @@
   for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
     TL.setArgLocInfo(i, TemplateArgs[i].getLocInfo());
 
-  return CreateLocInfoType(Result, DI).getAsOpaquePtr();
+  return CreateParsedType(Result, DI);
 }
 
-Sema::TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult,
-                                              TagUseKind TUK,
-                                              DeclSpec::TST TagSpec,
-                                              SourceLocation TagLoc) {
+TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult,
+                                        TagUseKind TUK,
+                                        TypeSpecifierType TagSpec,
+                                        SourceLocation TagLoc) {
   if (TypeResult.isInvalid())
-    return Sema::TypeResult();
+    return ::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);
+  TagTypeKind TagKind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
 
   if (const RecordType *RT = Type->getAs<RecordType>()) {
     RecordDecl *D = RT->getDecl();
@@ -1583,12 +1575,14 @@
     }
   }
 
-  QualType ElabType = Context.getElaboratedType(Type, TagKind);
+  ElaboratedTypeKeyword Keyword
+    = TypeWithKeyword::getKeywordForTagTypeKind(TagKind);
+  QualType ElabType = Context.getElaboratedType(Keyword, /*NNS=*/0, Type);
 
-  return ElabType.getAsOpaquePtr();
+  return ParsedType::make(ElabType);
 }
 
-Sema::OwningExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
+ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
                                                  LookupResult &R,
                                                  bool RequiresADL,
                                  const TemplateArgumentListInfo &TemplateArgs) {
@@ -1617,40 +1611,42 @@
   UnresolvedLookupExpr *ULE
     = UnresolvedLookupExpr::Create(Context, Dependent, R.getNamingClass(),
                                    Qualifier, QualifierRange,
-                                   R.getLookupName(), R.getNameLoc(),
-                                   RequiresADL, TemplateArgs);
-  ULE->addDecls(R.begin(), R.end());
+                                   R.getLookupNameInfo(),
+                                   RequiresADL, TemplateArgs, 
+                                   R.begin(), R.end());
 
   return Owned(ULE);
 }
 
 // We actually only call this from template instantiation.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
-                                   DeclarationName Name,
-                                   SourceLocation NameLoc,
+                                   const DeclarationNameInfo &NameInfo,
                              const TemplateArgumentListInfo &TemplateArgs) {
   DeclContext *DC;
   if (!(DC = computeDeclContext(SS, false)) ||
       DC->isDependentContext() ||
-      RequireCompleteDeclContext(SS))
-    return BuildDependentDeclRefExpr(SS, Name, NameLoc, &TemplateArgs);
+      RequireCompleteDeclContext(SS, DC))
+    return BuildDependentDeclRefExpr(SS, NameInfo, &TemplateArgs);
 
-  LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
-  LookupTemplateName(R, (Scope*) 0, SS, QualType(), /*Entering*/ false);
+  bool MemberOfUnknownSpecialization;
+  LookupResult R(*this, NameInfo, LookupOrdinaryName);
+  LookupTemplateName(R, (Scope*) 0, SS, QualType(), /*Entering*/ false,
+                     MemberOfUnknownSpecialization);
 
   if (R.isAmbiguous())
     return ExprError();
   
   if (R.empty()) {
-    Diag(NameLoc, diag::err_template_kw_refers_to_non_template)
-      << Name << SS.getRange();
+    Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_non_template)
+      << NameInfo.getName() << 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(NameInfo.getLoc(), diag::err_template_kw_refers_to_class_template)
+      << (NestedNameSpecifier*) SS.getScopeRep()
+      << NameInfo.getName() << SS.getRange();
     Diag(Temp->getLocation(), diag::note_referenced_class_template);
     return ExprError();
   }
@@ -1665,17 +1661,23 @@
 /// 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) {
+TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S, 
+                                                  SourceLocation TemplateKWLoc,
+                                                  CXXScopeSpec &SS,
+                                                  UnqualifiedId &Name,
+                                                  ParsedType ObjectType,
+                                                  bool EnteringContext,
+                                                  TemplateTy &Result) {
+  if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent() &&
+      !getLangOptions().CPlusPlus0x)
+    Diag(TemplateKWLoc, diag::ext_template_outside_of_template)
+      << FixItHint::CreateRemoval(TemplateKWLoc);    
+  
   DeclContext *LookupCtx = 0;
   if (SS.isSet())
     LookupCtx = computeDeclContext(SS, EnteringContext);
   if (!LookupCtx && ObjectType)
-    LookupCtx = computeDeclContext(QualType::getFromOpaquePtr(ObjectType));
+    LookupCtx = computeDeclContext(ObjectType.get());
   if (LookupCtx) {
     // C++0x [temp.names]p5:
     //   If a name prefixed by the keyword template is not the name of
@@ -1692,23 +1694,25 @@
     // 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);
+    // rules, even in C++03 mode with a warning, retroactively applying the DR.
+    bool MemberOfUnknownSpecialization;
+    TemplateNameKind TNK = isTemplateName(0, SS, TemplateKWLoc.isValid(), Name,
+                                          ObjectType, EnteringContext, Result,
+                                          MemberOfUnknownSpecialization);
     if (TNK == TNK_Non_template && LookupCtx->isDependentContext() &&
         isa<CXXRecordDecl>(LookupCtx) &&
         cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases()) {
-      // This is a dependent template.
+      // This is a dependent template. Handle it below.
     } else if (TNK == TNK_Non_template) {
       Diag(Name.getSourceRange().getBegin(), 
            diag::err_template_kw_refers_to_non_template)
-        << GetNameFromUnqualifiedId(Name)
-        << Name.getSourceRange();
-      return TemplateTy();
+        << GetNameFromUnqualifiedId(Name).getName()
+        << Name.getSourceRange()
+        << TemplateKWLoc;
+      return TNK_Non_template;
     } else {
       // We found something; return it.
-      return Template;
+      return TNK;
     }
   }
 
@@ -1717,12 +1721,14 @@
   
   switch (Name.getKind()) {
   case UnqualifiedId::IK_Identifier:
-    return TemplateTy::make(Context.getDependentTemplateName(Qualifier, 
-                                                             Name.Identifier));
+    Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier, 
+                                                              Name.Identifier));
+    return TNK_Dependent_template_name;
     
   case UnqualifiedId::IK_OperatorFunctionId:
-    return TemplateTy::make(Context.getDependentTemplateName(Qualifier,
+    Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier,
                                              Name.OperatorFunctionId.Operator));
+    return TNK_Dependent_template_name;
 
   case UnqualifiedId::IK_LiteralOperatorId:
     assert(false && "We don't support these; Parse shouldn't have allowed propagation");
@@ -1733,9 +1739,10 @@
   
   Diag(Name.getSourceRange().getBegin(), 
        diag::err_template_kw_refers_to_non_template)
-    << GetNameFromUnqualifiedId(Name)
-    << Name.getSourceRange();
-  return TemplateTy();
+    << GetNameFromUnqualifiedId(Name).getName()
+    << Name.getSourceRange()
+    << TemplateKWLoc;
+  return TNK_Non_template;
 }
 
 bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
@@ -1857,7 +1864,7 @@
 /// parameters that precede \p Param in the template parameter list.
 ///
 /// \returns the substituted template argument, or NULL if an error occurred.
-static Sema::OwningExprResult
+static ExprResult
 SubstDefaultTemplateArgument(Sema &SemaRef,
                              TemplateDecl *Template,
                              SourceLocation TemplateLoc,
@@ -1953,7 +1960,7 @@
     if (!NonTypeParm->hasDefaultArgument())
       return TemplateArgumentLoc();
 
-    OwningExprResult Arg = SubstDefaultTemplateArgument(*this, Template,
+    ExprResult Arg = SubstDefaultTemplateArgument(*this, Template,
                                                         TemplateLoc,
                                                         RAngleLoc,
                                                         NonTypeParm,
@@ -2053,12 +2060,15 @@
         // 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.          
+        // template name into an expression.
+
+        DeclarationNameInfo NameInfo(DTN->getIdentifier(),
+                                     Arg.getTemplateNameLoc());
+
         Expr *E = DependentScopeDeclRefExpr::Create(Context,
                                                     DTN->getQualifier(),
                                                Arg.getTemplateQualifierRange(),
-                                                    DTN->getIdentifier(),
-                                                    Arg.getTemplateNameLoc());
+                                                    NameInfo);
         
         TemplateArgument Result;
         if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
@@ -2273,7 +2283,7 @@
         break;
       }
 
-      Sema::OwningExprResult E = SubstDefaultTemplateArgument(*this, Template,
+      ExprResult E = SubstDefaultTemplateArgument(*this, Template,
                                                               TemplateLoc, 
                                                               RAngleLoc, 
                                                               NTTP, 
@@ -2336,24 +2346,27 @@
   //   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.
+  // FIXME: Perform the unnamed type check.
+  SourceRange SR = ArgInfo->getTypeLoc().getSourceRange();
   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();
+    SourceRange SR = ArgInfo->getTypeLoc().getSourceRange();
     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 (Arg->isVariablyModifiedType()) {
+    Diag(SR.getBegin(), diag::err_variably_modified_template_arg)
+      << Arg;
+    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;
   }
 
@@ -2404,7 +2417,7 @@
   bool AddressTaken = false;
   SourceLocation AddrOpLoc;
   if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
-    if (UnOp->getOpcode() == UnaryOperator::AddrOf) {
+    if (UnOp->getOpcode() == UO_AddrOf) {
       DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr());
       AddressTaken = true;
       AddrOpLoc = UnOp->getOperatorLoc();
@@ -2651,7 +2664,7 @@
 
   // A pointer-to-member constant written &Class::member.
   if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
-    if (UnOp->getOpcode() == UnaryOperator::AddrOf) {
+    if (UnOp->getOpcode() == UO_AddrOf) {
       DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr());
       if (DRE && !DRE->getQualifier())
         DRE = 0;
@@ -2739,7 +2752,7 @@
   //        conversions (4.7) are applied.
   QualType ParamType = InstantiatedParamType;
   QualType ArgType = Arg->getType();
-  if (ParamType->isIntegralType() || ParamType->isEnumeralType()) {
+  if (ParamType->isIntegralOrEnumerationType()) {
     // C++ [temp.arg.nontype]p1:
     //   A template-argument for a non-type, non-template
     //   template-parameter shall be one of:
@@ -2749,7 +2762,7 @@
     //     -- the name of a non-type template-parameter; or
     SourceLocation NonConstantLoc;
     llvm::APSInt Value;
-    if (!ArgType->isIntegralType() && !ArgType->isEnumeralType()) {
+    if (!ArgType->isIntegralOrEnumerationType()) {
       Diag(Arg->getSourceRange().getBegin(),
            diag::err_template_arg_not_integral_or_enumeral)
         << ArgType << Arg->getSourceRange();
@@ -2786,7 +2799,7 @@
     } else if (IsIntegralPromotion(Arg, ArgType, ParamType) ||
                !ParamType->isEnumeralType()) {
       // This is an integral promotion or conversion.
-      ImpCastExprToType(Arg, ParamType, CastExpr::CK_IntegralCast);
+      ImpCastExprToType(Arg, ParamType, CK_IntegralCast);
     } else {
       // We can't perform this conversion.
       Diag(Arg->getSourceRange().getBegin(),
@@ -2907,8 +2920,7 @@
                                                             Arg, Converted);
 
     if (IsQualificationConversion(ArgType, ParamType.getNonReferenceType())) {
-      ImpCastExprToType(Arg, ParamType, CastExpr::CK_NoOp,
-                        Arg->isLvalue(Context) == Expr::LV_Valid);
+      ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg));
     } else if (!Context.hasSameUnqualifiedType(ArgType,
                                            ParamType.getNonReferenceType())) {
       // We can't perform this conversion.
@@ -2927,7 +2939,7 @@
     //      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() &&
+    assert(ParamType->getPointeeType()->isIncompleteOrObjectType() &&
            "Only object pointers allowed here");
 
     return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param, 
@@ -2942,7 +2954,7 @@
     //      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() &&
+    assert(ParamRefType->getPointeeType()->isIncompleteOrObjectType() &&
            "Only object references allowed here");
 
     if (Arg->getType() == Context.OverloadTy) {
@@ -2971,8 +2983,7 @@
   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);
+    ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg));
   } else {
     // We can't perform this conversion.
     Diag(Arg->getSourceRange().getBegin(),
@@ -3031,7 +3042,7 @@
 /// declaration and the type of its corresponding non-type template
 /// parameter, produce an expression that properly refers to that
 /// declaration.
-Sema::OwningExprResult 
+ExprResult 
 Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
                                               QualType ParamType,
                                               SourceLocation Loc) {
@@ -3050,20 +3061,32 @@
       QualType ClassType
         = Context.getTypeDeclType(cast<RecordDecl>(VD->getDeclContext()));
       NestedNameSpecifier *Qualifier
-        = NestedNameSpecifier::Create(Context, 0, false, ClassType.getTypePtr());
+        = NestedNameSpecifier::Create(Context, 0, false,
+                                      ClassType.getTypePtr());
       CXXScopeSpec SS;
       SS.setScopeRep(Qualifier);
-      OwningExprResult RefExpr = BuildDeclRefExpr(VD, 
+      ExprResult RefExpr = BuildDeclRefExpr(VD, 
                                            VD->getType().getNonReferenceType(), 
                                                   Loc,
                                                   &SS);
       if (RefExpr.isInvalid())
         return ExprError();
       
-      RefExpr = CreateBuiltinUnaryOp(Loc, UnaryOperator::AddrOf, move(RefExpr));
+      RefExpr = CreateBuiltinUnaryOp(Loc, UO_AddrOf, RefExpr.get());
+      
+      // We might need to perform a trailing qualification conversion, since
+      // the element type on the parameter could be more qualified than the
+      // element type in the expression we constructed.
+      if (IsQualificationConversion(((Expr*) RefExpr.get())->getType(),
+                                    ParamType.getUnqualifiedType())) {
+        Expr *RefE = RefExpr.takeAs<Expr>();
+        ImpCastExprToType(RefE, ParamType.getUnqualifiedType(), CK_NoOp);
+        RefExpr = Owned(RefE);
+      }
+      
       assert(!RefExpr.isInvalid() &&
              Context.hasSameType(((Expr*) RefExpr.get())->getType(),
-                                 ParamType));
+                                 ParamType.getUnqualifiedType()));
       return move(RefExpr);
     }
   }
@@ -3072,7 +3095,7 @@
   if (ParamType->isPointerType()) {
     // When the non-type template parameter is a pointer, take the
     // address of the declaration.
-    OwningExprResult RefExpr = BuildDeclRefExpr(VD, T, Loc);
+    ExprResult RefExpr = BuildDeclRefExpr(VD, T, Loc);
     if (RefExpr.isInvalid())
       return ExprError();
 
@@ -3089,7 +3112,7 @@
     }
     
     // Take the address of everything else
-    return CreateBuiltinUnaryOp(Loc, UnaryOperator::AddrOf, move(RefExpr));
+    return CreateBuiltinUnaryOp(Loc, UO_AddrOf, RefExpr.get());
   }
 
   // If the non-type template parameter has reference type, qualify the
@@ -3108,7 +3131,7 @@
 /// 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 
+ExprResult 
 Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
                                                   SourceLocation Loc) {
   assert(Arg.getKind() == TemplateArgument::Integral &&
@@ -3126,7 +3149,7 @@
                                             T,
                                             Loc));
 
-  return Owned(new (Context) IntegerLiteral(*Arg.getAsIntegral(), T, Loc));
+  return Owned(IntegerLiteral::Create(Context, *Arg.getAsIntegral(), T, Loc));
 }
 
 
@@ -3196,9 +3219,32 @@
       return false;
     }
 
-    if (isa<TemplateTypeParmDecl>(*OldParm)) {
-      // Okay; all template type parameters are equivalent (since we
-      // know we're at the same index).
+    if (TemplateTypeParmDecl *OldTTP
+                                  = dyn_cast<TemplateTypeParmDecl>(*OldParm)) {
+      // Template type parameters are equivalent if either both are template
+      // type parameter packs or neither are (since we know we're at the same 
+      // index).
+      TemplateTypeParmDecl *NewTTP = cast<TemplateTypeParmDecl>(*NewParm);
+      if (OldTTP->isParameterPack() != NewTTP->isParameterPack()) {
+        // FIXME: Implement the rules in C++0x [temp.arg.template]p5 that
+        // allow one to match a template parameter pack in the template
+        // parameter list of a template template parameter to one or more
+        // template parameters in the template parameter list of the 
+        // corresponding template template argument.        
+        if (Complain) {
+          unsigned NextDiag = diag::err_template_parameter_pack_non_pack;
+          if (TemplateArgLoc.isValid()) {
+            Diag(TemplateArgLoc,
+                 diag::err_template_arg_template_params_mismatch);
+            NextDiag = diag::note_template_parameter_pack_non_pack;
+          }
+          Diag(NewTTP->getLocation(), NextDiag)
+            << 0 << NewTTP->isParameterPack();
+          Diag(OldTTP->getLocation(), diag::note_template_parameter_pack_here)
+            << 0 << OldTTP->isParameterPack();
+        }
+        return false;
+      }
     } else if (NonTypeTemplateParmDecl *OldNTTP
                  = dyn_cast<NonTypeTemplateParmDecl>(*OldParm)) {
       // The types of non-type template parameters must agree.
@@ -3560,7 +3606,7 @@
   return 0;
 }
 
-Sema::DeclResult
+DeclResult
 Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
                                        TagUseKind TUK,
                                        SourceLocation KWLoc,
@@ -3593,12 +3639,21 @@
   // template.
   // FIXME: We probably shouldn't complain about these headers for
   // friend declarations.
+  bool Invalid = false;
   TemplateParameterList *TemplateParams
     = MatchTemplateParametersToScopeSpecifier(TemplateNameLoc, SS,
                         (TemplateParameterList**)TemplateParameterLists.get(),
                                               TemplateParameterLists.size(),
                                               TUK == TUK_Friend,
-                                              isExplicitSpecialization);
+                                              isExplicitSpecialization,
+                                              Invalid);
+  if (Invalid)
+    return true;
+    
+  unsigned NumMatchedTemplateParamLists = TemplateParameterLists.size();
+  if (TemplateParams)
+    --NumMatchedTemplateParamLists;
+
   if (TemplateParams && TemplateParams->size() > 0) {
     isPartialSpecialization = true;
 
@@ -3619,8 +3674,7 @@
           Diag(NTTP->getDefaultArgumentLoc(),
                diag::err_default_arg_in_partial_spec)
             << DefArg->getSourceRange();
-          NTTP->setDefaultArgument(0);
-          DefArg->Destroy(Context);
+          NTTP->removeDefaultArgument();
         }
       } else {
         TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(Param);
@@ -3628,7 +3682,7 @@
           Diag(TTP->getDefaultArgument().getLocation(),
                diag::err_default_arg_in_partial_spec)
             << TTP->getDefaultArgument().getSourceRange();
-          TTP->setDefaultArgument(TemplateArgumentLoc());
+          TTP->removeDefaultArgument();
         }
       }
     }
@@ -3649,13 +3703,8 @@
 
   // 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;
-  }
+  TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
+  assert(Kind != TTK_Enum && "Invalid enum tag in class template spec!");
   if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(),
                                     Kind, KWLoc,
                                     *ClassTemplate->getIdentifier())) {
@@ -3688,7 +3737,6 @@
 
   // Find the class template (partial) specialization declaration that
   // corresponds to these arguments.
-  llvm::FoldingSetNodeID ID;
   if (isPartialSpecialization) {
     bool MirrorsPrimaryTemplate;
     if (CheckClassTemplatePartialSpecializationArgs(
@@ -3721,30 +3769,22 @@
       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)
+    // FIXME: Template parameter list matters, too
     PrevDecl
-      = ClassTemplate->getPartialSpecializations().FindNodeOrInsertPos(ID,
-                                                                    InsertPos);
+      = ClassTemplate->findPartialSpecialization(Converted.getFlatArguments(),
+                                                 Converted.flatSize(),
+                                                 InsertPos);
   else
     PrevDecl
-      = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+      = ClassTemplate->findSpecialization(Converted.getFlatArguments(),
+                                          Converted.flatSize(), InsertPos);
 
   ClassTemplateSpecializationDecl *Specialization = 0;
 
@@ -3781,8 +3821,10 @@
     // Create a new class template partial specialization declaration node.
     ClassTemplatePartialSpecializationDecl *PrevPartial
       = cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl);
+    unsigned SequenceNumber = PrevPartial? PrevPartial->getSequenceNumber()
+                            : ClassTemplate->getNextPartialSpecSequenceNumber();
     ClassTemplatePartialSpecializationDecl *Partial
-      = ClassTemplatePartialSpecializationDecl::Create(Context,
+      = ClassTemplatePartialSpecializationDecl::Create(Context, Kind,
                                              ClassTemplate->getDeclContext(),
                                                        TemplateNameLoc,
                                                        TemplateParams,
@@ -3790,15 +3832,17 @@
                                                        Converted,
                                                        TemplateArgs,
                                                        CanonType,
-                                                       PrevPartial);
+                                                       PrevPartial,
+                                                       SequenceNumber);
     SetNestedNameSpecifier(Partial, SS);
-
-    if (PrevPartial) {
-      ClassTemplate->getPartialSpecializations().RemoveNode(PrevPartial);
-      ClassTemplate->getPartialSpecializations().GetOrInsertNode(Partial);
-    } else {
-      ClassTemplate->getPartialSpecializations().InsertNode(Partial, InsertPos);
+    if (NumMatchedTemplateParamLists > 0 && SS.isSet()) {
+      Partial->setTemplateParameterListsInfo(Context,
+                                             NumMatchedTemplateParamLists,
+                    (TemplateParameterList**) TemplateParameterLists.release());
     }
+
+    if (!PrevPartial)
+      ClassTemplate->AddPartialSpecialization(Partial, InsertPos);
     Specialization = Partial;
 
     // If we are providing an explicit specialization of a member class 
@@ -3834,7 +3878,7 @@
           else
             Diag(Param->getLocation(),
                  diag::note_partial_spec_unused_parameter)
-              << std::string("<anonymous>");
+              << "<anonymous>";
         }
       }
     }
@@ -3842,22 +3886,22 @@
     // Create a new class template specialization declaration node for
     // this explicit specialization or friend declaration.
     Specialization
-      = ClassTemplateSpecializationDecl::Create(Context,
+      = ClassTemplateSpecializationDecl::Create(Context, Kind,
                                              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);
+    if (NumMatchedTemplateParamLists > 0 && SS.isSet()) {
+      Specialization->setTemplateParameterListsInfo(Context,
+                                                  NumMatchedTemplateParamLists,
+                    (TemplateParameterList**) TemplateParameterLists.release());
     }
 
+    if (!PrevDecl)
+      ClassTemplate->AddSpecialization(Specialization, InsertPos);
+
     CanonType = Context.getTypeDeclType(Specialization);
   }
 
@@ -3916,8 +3960,11 @@
   TypeSourceInfo *WrittenTy
     = Context.getTemplateSpecializationTypeInfo(Name, TemplateNameLoc,
                                                 TemplateArgs, CanonType);
-  if (TUK != TUK_Friend)
+  if (TUK != TUK_Friend) {
     Specialization->setTypeAsWritten(WrittenTy);
+    if (TemplateParams)
+      Specialization->setTemplateKeywordLoc(TemplateParams->getTemplateLoc());
+  }
   TemplateArgsIn.release();
 
   // C++ [temp.expl.spec]p9:
@@ -3947,20 +3994,18 @@
     // context. However, specializations are not found by name lookup.
     CurContext->addDecl(Specialization);
   }
-  return DeclPtrTy::make(Specialization);
+  return Specialization;
 }
 
-Sema::DeclPtrTy
-Sema::ActOnTemplateDeclarator(Scope *S,
+Decl *Sema::ActOnTemplateDeclarator(Scope *S,
                               MultiTemplateParamsArg TemplateParameterLists,
-                              Declarator &D) {
+                                    Declarator &D) {
   return HandleDeclarator(S, D, move(TemplateParameterLists), false);
 }
 
-Sema::DeclPtrTy
-Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
+Decl *Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
                                MultiTemplateParamsArg TemplateParameterLists,
-                                      Declarator &D) {
+                                            Declarator &D) {
   assert(getCurFunctionDecl() == 0 && "Function parsing confused");
   assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
          "Not a function declarator!");
@@ -3972,22 +4017,22 @@
 
   Scope *ParentScope = FnBodyScope->getParent();
 
-  DeclPtrTy DP = HandleDeclarator(ParentScope, D,
-                                  move(TemplateParameterLists),
-                                  /*IsFunctionDefinition=*/true);
+  Decl *DP = HandleDeclarator(ParentScope, D,
+                              move(TemplateParameterLists),
+                              /*IsFunctionDefinition=*/true);
   if (FunctionTemplateDecl *FunctionTemplate
-        = dyn_cast_or_null<FunctionTemplateDecl>(DP.getAs<Decl>()))
+        = dyn_cast_or_null<FunctionTemplateDecl>(DP))
     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();
+                                   FunctionTemplate->getTemplatedDecl());
+  if (FunctionDecl *Function = dyn_cast_or_null<FunctionDecl>(DP))
+    return ActOnStartOfFunctionDef(FnBodyScope, Function);
+  return 0;
 }
 
 /// \brief Strips various properties off an implicit instantiation
 /// that has just been explicitly specialized.
 static void StripImplicitInstantiation(NamedDecl *D) {
-  D->invalidateAttrs();
+  D->dropAttrs();
 
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     FD->setInlineSpecified(false);
@@ -4011,7 +4056,7 @@
 /// \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 
+/// \param HasNoEffect 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
@@ -4022,8 +4067,8 @@
                                              NamedDecl *PrevDecl,
                                              TemplateSpecializationKind PrevTSK,
                                         SourceLocation PrevPointOfInstantiation,
-                                             bool &SuppressNew) {
-  SuppressNew = false;
+                                             bool &HasNoEffect) {
+  HasNoEffect = false;
   
   switch (NewTSK) {
   case TSK_Undeclared:
@@ -4080,7 +4125,7 @@
     switch (PrevTSK) {
     case TSK_ExplicitInstantiationDeclaration:
       // This explicit instantiation declaration is redundant (that's okay).
-      SuppressNew = true;
+      HasNoEffect = true;
       return false;
         
     case TSK_Undeclared:
@@ -4095,7 +4140,7 @@
       //   of a template appears after a declaration of an explicit 
       //   specialization for that template, the explicit instantiation has no
       //   effect.
-      SuppressNew = true;
+      HasNoEffect = true;
       return false;
         
     case TSK_ExplicitInstantiationDefinition:
@@ -4109,7 +4154,7 @@
            diag::note_explicit_instantiation_definition_here);
       assert(PrevPointOfInstantiation.isValid() &&
              "Explicit instantiation without point of instantiation?");
-      SuppressNew = true;
+      HasNoEffect = true;
       return false;
     }
     break;
@@ -4138,7 +4183,7 @@
         Diag(PrevDecl->getLocation(),
              diag::note_previous_template_specialization);
       }
-      SuppressNew = true;
+      HasNoEffect = true;
       return false;
         
     case TSK_ExplicitInstantiationDeclaration:
@@ -4155,7 +4200,7 @@
         << PrevDecl;
       Diag(PrevPointOfInstantiation, 
            diag::note_previous_explicit_instantiation);
-      SuppressNew = true;
+      HasNoEffect = true;
       return false;        
     }
     break;
@@ -4202,10 +4247,10 @@
   return false;
 }
 
-/// \brief Perform semantic analysis for the given function template 
+/// \brief Perform semantic analysis for the given function template
 /// specialization.
 ///
-/// This routine performs all of the semantic analysis required for an 
+/// 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.
@@ -4213,24 +4258,14 @@
 /// \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 ExplicitTemplateArgs the explicitly-provided template arguments,
+/// if any. Note that this may be valid info even when 0 arguments are
+/// explicitly provided as in, e.g., \c void sort<>(char*, char*);
+/// as it anyway contains info on the angle brackets locations.
 ///
-/// \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 
+/// \param PrevDecl the set of declarations that may be specialized by
+/// this function specialization.
+bool
 Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
                         const TemplateArgumentListInfo *ExplicitTemplateArgs,
                                           LookupResult &Previous) {
@@ -4314,30 +4349,36 @@
     = Specialization->getTemplateSpecializationInfo();
   assert(SpecInfo && "Function template specialization info missing?");
 
-  bool SuppressNew = false;
+  bool HasNoEffect = false;
   if (!isFriend &&
       CheckSpecializationInstantiationRedecl(FD->getLocation(),
                                              TSK_ExplicitSpecialization,
                                              Specialization,
                                    SpecInfo->getTemplateSpecializationKind(),
                                          SpecInfo->getPointOfInstantiation(),
-                                             SuppressNew))
+                                             HasNoEffect))
     return true;
   
   // Mark the prior declaration as an explicit specialization, so that later
   // clients know that this is an explicit specialization.
-  if (!isFriend)
+  if (!isFriend) {
     SpecInfo->setTemplateSpecializationKind(TSK_ExplicitSpecialization);
+    MarkUnusedFileScopedDecl(Specialization);
+  }
   
   // Turn the given function declaration into a function template
   // specialization, with the template arguments from the previous
   // specialization.
+  // Take copies of (semantic and syntactic) template argument lists.
+  const TemplateArgumentList* TemplArgs = new (Context)
+    TemplateArgumentList(Specialization->getTemplateSpecializationArgs());
+  const TemplateArgumentListInfo* TemplArgsAsWritten = ExplicitTemplateArgs
+    ? new (Context) TemplateArgumentListInfo(*ExplicitTemplateArgs) : 0;
   FD->setFunctionTemplateSpecialization(Specialization->getPrimaryTemplate(),
-                         new (Context) TemplateArgumentList(
-                             *Specialization->getTemplateSpecializationArgs()), 
-                                        /*InsertPos=*/0, 
-                                    SpecInfo->getTemplateSpecializationKind());
-  
+                                        TemplArgs, /*InsertPos=*/0,
+                                    SpecInfo->getTemplateSpecializationKind(),
+                                        TemplArgsAsWritten);
+
   // The "previous declaration" for this function template specialization is
   // the prior function template specialization.
   Previous.clear();
@@ -4444,13 +4485,13 @@
   //   use occurs; no diagnostic is required.
   assert(MSInfo && "Member specialization info missing?");
 
-  bool SuppressNew = false;
+  bool HasNoEffect = false;
   if (CheckSpecializationInstantiationRedecl(Member->getLocation(),
                                              TSK_ExplicitSpecialization,
                                              Instantiation,
                                      MSInfo->getTemplateSpecializationKind(),
                                            MSInfo->getPointOfInstantiation(),
-                                             SuppressNew))
+                                             HasNoEffect))
     return true;
   
   // Check the scope of this explicit specialization.
@@ -4476,6 +4517,7 @@
     cast<FunctionDecl>(Member)->setInstantiationOfMemberFunction(
                                         cast<CXXMethodDecl>(InstantiatedFrom),
                                                   TSK_ExplicitSpecialization);
+    MarkUnusedFileScopedDecl(InstantiationFunction);
   } else if (isa<VarDecl>(Member)) {
     VarDecl *InstantiationVar = cast<VarDecl>(Instantiation);
     if (InstantiationVar->getTemplateSpecializationKind() ==
@@ -4488,6 +4530,7 @@
     Context.setInstantiatedFromStaticDataMember(cast<VarDecl>(Member),
                                                 cast<VarDecl>(InstantiatedFrom),
                                                 TSK_ExplicitSpecialization);
+    MarkUnusedFileScopedDecl(InstantiationVar);
   } else {
     assert(isa<CXXRecordDecl>(Member) && "Only member classes remain");
     CXXRecordDecl *InstantiationClass = cast<CXXRecordDecl>(Instantiation);
@@ -4511,13 +4554,21 @@
 }
 
 /// \brief Check the scope of an explicit instantiation.
-static void CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
+///
+/// \returns true if a serious error occurs, false otherwise.
+static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
                                             SourceLocation InstLoc,
                                             bool WasQualifiedName) {
   DeclContext *ExpectedContext
     = D->getDeclContext()->getEnclosingNamespaceContext()->getLookupContext();
   DeclContext *CurContext = S.CurContext->getLookupContext();
   
+  if (CurContext->isRecord()) {
+    S.Diag(InstLoc, diag::err_explicit_instantiation_in_class)
+      << D;
+    return true;
+  }
+  
   // C++0x [temp.explicit]p2:
   //   An explicit instantiation shall appear in an enclosing namespace of its 
   //   template.
@@ -4526,13 +4577,19 @@
   if (S.getLangOptions().CPlusPlus0x && 
       !CurContext->Encloses(ExpectedContext)) {
     if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ExpectedContext))
-      S.Diag(InstLoc, diag::err_explicit_instantiation_out_of_scope)
+      S.Diag(InstLoc, 
+             S.getLangOptions().CPlusPlus0x? 
+                 diag::err_explicit_instantiation_out_of_scope
+               : diag::warn_explicit_instantiation_out_of_scope_0x)
         << D << NS;
     else
-      S.Diag(InstLoc, diag::err_explicit_instantiation_must_be_global)
+      S.Diag(InstLoc, 
+             S.getLangOptions().CPlusPlus0x?
+                 diag::err_explicit_instantiation_must_be_global
+               : diag::warn_explicit_instantiation_out_of_scope_0x)
         << D;
     S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
-    return;
+    return false;
   }
   
   // C++0x [temp.explicit]p2:
@@ -4541,14 +4598,18 @@
   //   its template is declared or, if that namespace is inline (7.3.1), any
   //   namespace from its enclosing namespace set.
   if (WasQualifiedName)
-    return;
+    return false;
   
   if (CurContext->Equals(ExpectedContext))
-    return;
+    return false;
   
-  S.Diag(InstLoc, diag::err_explicit_instantiation_unqualified_wrong_namespace)
+  S.Diag(InstLoc, 
+         S.getLangOptions().CPlusPlus0x?
+             diag::err_explicit_instantiation_unqualified_wrong_namespace
+           : diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x)
     << D << ExpectedContext;
   S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
+  return false;
 }
 
 /// \brief Determine whether the given scope specifier has a template-id in it.
@@ -4573,8 +4634,7 @@
 }
 
 // Explicit instantiation of a class template specialization
-// FIXME: Implement extern template semantics
-Sema::DeclResult
+DeclResult
 Sema::ActOnExplicitInstantiation(Scope *S,
                                  SourceLocation ExternLoc,
                                  SourceLocation TemplateLoc,
@@ -4594,13 +4654,9 @@
 
   // 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;
-  }
+  TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
+  assert(Kind != TTK_Enum &&
+         "Invalid enum tag in class template explicit instantiation!");
   if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(),
                                     Kind, KWLoc,
                                     *ClassTemplate->getIdentifier())) {
@@ -4639,71 +4695,66 @@
 
   // 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);
+    = ClassTemplate->findSpecialization(Converted.getFlatArguments(),
+                                        Converted.flatSize(), InsertPos);
+
+  TemplateSpecializationKind PrevDecl_TSK
+    = PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared;
 
   // 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());
+  if (CheckExplicitInstantiationScope(*this, ClassTemplate, TemplateNameLoc,
+                                      SS.isSet()))
+    return true;
   
   ClassTemplateSpecializationDecl *Specialization = 0;
 
   bool ReusedDecl = false;
+  bool HasNoEffect = false;
   if (PrevDecl) {
-    bool SuppressNew = false;
     if (CheckSpecializationInstantiationRedecl(TemplateNameLoc, TSK,
-                                               PrevDecl, 
-                                              PrevDecl->getSpecializationKind(), 
+                                               PrevDecl, PrevDecl_TSK,
                                             PrevDecl->getPointOfInstantiation(),
-                                               SuppressNew))
-      return DeclPtrTy::make(PrevDecl);
+                                               HasNoEffect))
+      return PrevDecl;
 
-    if (SuppressNew)
-      return DeclPtrTy::make(PrevDecl);
-    
-    if (PrevDecl->getSpecializationKind() == TSK_ImplicitInstantiation ||
-        PrevDecl->getSpecializationKind() == TSK_Undeclared) {
+    // Even though HasNoEffect == true means that this explicit instantiation
+    // has no effect on semantics, we go on to put its syntax in the AST.
+
+    if (PrevDecl_TSK == TSK_ImplicitInstantiation ||
+        PrevDecl_TSK == 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.
+      // declaration node as our own, updating the source location
+      // for the template name to reflect our new declaration.
+      // (Other source locations will be updated later.)
       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,
+      = ClassTemplateSpecializationDecl::Create(Context, Kind,
                                              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);
+    if (!HasNoEffect && !PrevDecl) {
+      // Insert the new specialization.
+      ClassTemplate->AddSpecialization(Specialization, InsertPos);
+    }
   }
 
   // Build the fully-sugared type for this explicit instantiation as
@@ -4720,12 +4771,21 @@
   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);
+  // Set source locations for keywords.
+  Specialization->setExternLoc(ExternLoc);
+  Specialization->setTemplateKeywordLoc(TemplateLoc);
+
+  // 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);
+
+  // Syntax is now OK, so return if it has no other effect on semantics.
+  if (HasNoEffect) {
+    // Set the template specialization kind.
+    Specialization->setTemplateSpecializationKind(TSK);
+    return Specialization;
   }
 
   // C++ [temp.explicit]p3:
@@ -4740,7 +4800,11 @@
                                               Specialization->getDefinition());
   if (!Def)
     InstantiateClassTemplateSpecialization(TemplateNameLoc, Specialization, TSK);
-  
+  else if (TSK == TSK_ExplicitInstantiationDefinition) {
+    MarkVTableUsed(TemplateNameLoc, Specialization, true);
+    Specialization->setPointOfInstantiation(Def->getPointOfInstantiation());
+  }
+
   // Instantiate the members of this class template specialization.
   Def = cast_or_null<ClassTemplateSpecializationDecl>(
                                        Specialization->getDefinition());
@@ -4756,11 +4820,13 @@
     InstantiateClassTemplateSpecializationMembers(TemplateNameLoc, Def, TSK);
   }
 
-  return DeclPtrTy::make(Specialization);
+  // Set the template specialization kind.
+  Specialization->setTemplateSpecializationKind(TSK);
+  return Specialization;
 }
 
 // Explicit instantiation of a member class of a class template.
-Sema::DeclResult
+DeclResult
 Sema::ActOnExplicitInstantiation(Scope *S,
                                  SourceLocation ExternLoc,
                                  SourceLocation TemplateLoc,
@@ -4773,16 +4839,16 @@
 
   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);
+  Decl *TagD = ActOnTag(S, TagSpec, Sema::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>());
+  TagDecl *Tag = cast<TagDecl>(TagD);
   if (Tag->isEnum()) {
     Diag(TemplateLoc, diag::err_explicit_instantiation_enum)
       << Context.getTypeDeclType(Tag);
@@ -4808,7 +4874,7 @@
   //
   // C++98 has the same restriction, just worded differently.
   if (!ScopeSpecifierHasTemplateId(SS))
-    Diag(TemplateLoc, diag::err_explicit_instantiation_without_qualified_id)
+    Diag(TemplateLoc, diag::ext_explicit_instantiation_without_qualified_id)
       << Record << SS.getRange();
            
   // C++0x [temp.explicit]p2:
@@ -4833,15 +4899,15 @@
     PrevDecl = Record;
   if (PrevDecl) {
     MemberSpecializationInfo *MSInfo = PrevDecl->getMemberSpecializationInfo();
-    bool SuppressNew = false;
+    bool HasNoEffect = false;
     assert(MSInfo && "No member specialization information?");
     if (CheckSpecializationInstantiationRedecl(TemplateLoc, TSK, 
                                                PrevDecl,
                                         MSInfo->getTemplateSpecializationKind(),
                                              MSInfo->getPointOfInstantiation(), 
-                                               SuppressNew))
+                                               HasNoEffect))
       return true;
-    if (SuppressNew)
+    if (HasNoEffect)
       return TagD;
   }
   
@@ -4875,6 +4941,9 @@
   InstantiateClassMembers(NameLoc, RecordDef,
                           getTemplateInstantiationArgs(Record), TSK);
 
+  if (TSK == TSK_ExplicitInstantiationDefinition)
+    MarkVTableUsed(NameLoc, RecordDef, true);
+
   // 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
@@ -4882,12 +4951,14 @@
   return TagD;
 }
 
-Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
-                                                  SourceLocation ExternLoc,
-                                                  SourceLocation TemplateLoc,
-                                                  Declarator &D) {
+DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
+                                            SourceLocation ExternLoc,
+                                            SourceLocation TemplateLoc,
+                                            Declarator &D) {
   // Explicit instantiations always require a name.
-  DeclarationName Name = GetNameForDeclarator(D);
+  // TODO: check if/when DNInfo should replace Name.
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
   if (!Name) {
     if (!D.isInvalidType())
       Diag(D.getDeclSpec().getSourceRange().getBegin(),
@@ -4905,7 +4976,8 @@
     S = S->getParent();
 
   // Determine the type of the declaration.
-  QualType R = GetTypeForDeclarator(D, S, 0);
+  TypeSourceInfo *T = GetTypeForDeclarator(D, S);
+  QualType R = T->getType();
   if (R.isNull())
     return true;
   
@@ -4936,7 +5008,7 @@
     = ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
                            : TSK_ExplicitInstantiationDeclaration;
     
-  LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName);
+  LookupResult Previous(*this, NameInfo, LookupOrdinaryName);
   LookupParsedName(Previous, S, &D.getCXXScopeSpec());
 
   if (!R->isFunctionType()) {
@@ -4977,7 +5049,7 @@
     // C++98 has the same restriction, just worded differently.
     if (!ScopeSpecifierHasTemplateId(D.getCXXScopeSpec()))
       Diag(D.getIdentifierLoc(), 
-           diag::err_explicit_instantiation_without_qualified_id)
+           diag::ext_explicit_instantiation_without_qualified_id)
         << Prev << D.getCXXScopeSpec().getRange();
     
     // Check the scope of this explicit instantiation.
@@ -4986,23 +5058,22 @@
     // Verify that it is okay to explicitly instantiate here.
     MemberSpecializationInfo *MSInfo = Prev->getMemberSpecializationInfo();
     assert(MSInfo && "Missing static data member specialization info?");
-    bool SuppressNew = false;
+    bool HasNoEffect = false;
     if (CheckSpecializationInstantiationRedecl(D.getIdentifierLoc(), TSK, Prev,
                                         MSInfo->getTemplateSpecializationKind(),
                                               MSInfo->getPointOfInstantiation(), 
-                                               SuppressNew))
+                                               HasNoEffect))
       return true;
-    if (SuppressNew)
-      return DeclPtrTy();
+    if (HasNoEffect)
+      return (Decl*) 0;
     
     // Instantiate static data member.
     Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
     if (TSK == TSK_ExplicitInstantiationDefinition)
-      InstantiateStaticDataMemberDefinition(D.getIdentifierLoc(), Prev, false,
-                                            /*DefinitionRequired=*/true);
+      InstantiateStaticDataMemberDefinition(D.getIdentifierLoc(), Prev);
     
     // FIXME: Create an ExplicitInstantiation node?
-    return DeclPtrTy();
+    return (Decl*) 0;
   }
   
   // If the declarator is a template-id, translate the parser's template 
@@ -5089,25 +5160,24 @@
     PrevDecl = Specialization;
 
   if (PrevDecl) {
-    bool SuppressNew = false;
+    bool HasNoEffect = false;
     if (CheckSpecializationInstantiationRedecl(D.getIdentifierLoc(), TSK,
                                                PrevDecl, 
                                      PrevDecl->getTemplateSpecializationKind(), 
                                           PrevDecl->getPointOfInstantiation(),
-                                               SuppressNew))
+                                               HasNoEffect))
       return true;
     
     // FIXME: We may still want to build some representation of this
     // explicit specialization.
-    if (SuppressNew)
-      return DeclPtrTy();
+    if (HasNoEffect)
+      return (Decl*) 0;
   }
 
   Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
   
   if (TSK == TSK_ExplicitInstantiationDefinition)
-    InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization, 
-                                  false, /*DefinitionRequired=*/true);
+    InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization);
  
   // C++0x [temp.explicit]p2:
   //   If the explicit instantiation is for a member function, a member class 
@@ -5121,7 +5191,7 @@
       D.getCXXScopeSpec().isSet() && 
       !ScopeSpecifierHasTemplateId(D.getCXXScopeSpec()))
     Diag(D.getIdentifierLoc(), 
-         diag::err_explicit_instantiation_without_qualified_id)
+         diag::ext_explicit_instantiation_without_qualified_id)
     << Specialization << D.getCXXScopeSpec().getRange();
   
   CheckExplicitInstantiationScope(*this,
@@ -5131,10 +5201,10 @@
                                   D.getCXXScopeSpec().isSet());
   
   // FIXME: Create some kind of ExplicitInstantiationDecl here.
-  return DeclPtrTy();
+  return (Decl*) 0;
 }
 
-Sema::TypeResult
+TypeResult
 Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
                         const CXXScopeSpec &SS, IdentifierInfo *Name,
                         SourceLocation TagLoc, SourceLocation NameLoc) {
@@ -5146,61 +5216,119 @@
   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!");
+  TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
 
   if (TUK == TUK_Declaration || TUK == TUK_Definition) {
     Diag(NameLoc, diag::err_dependent_tag_decl)
-      << (TUK == TUK_Definition) << TagDecl::getTagKindForTypeSpec(TagSpec)
-      << SS.getRange();
+      << (TUK == TUK_Definition) << Kind << SS.getRange();
     return true;
   }
-  
-  return Context.getDependentNameType(Keyword, NNS, Name).getAsOpaquePtr();
+
+  ElaboratedTypeKeyword Kwd = TypeWithKeyword::getKeywordForTagTypeKind(Kind);
+  return ParsedType::make(Context.getDependentNameType(Kwd, NNS, Name));
 }
 
-Sema::TypeResult
-Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
-                        const IdentifierInfo &II, SourceLocation IdLoc) {
+TypeResult
+Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, 
+                        const CXXScopeSpec &SS, const IdentifierInfo &II, 
+                        SourceLocation IdLoc) {
   NestedNameSpecifier *NNS
     = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
   if (!NNS)
     return true;
 
+  if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() &&
+      !getLangOptions().CPlusPlus0x)
+    Diag(TypenameLoc, diag::ext_typename_outside_of_template)
+      << FixItHint::CreateRemoval(TypenameLoc);    
+  
   QualType T = CheckTypenameType(ETK_Typename, NNS, II,
-                                 SourceRange(TypenameLoc, IdLoc));
+                                 TypenameLoc, SS.getRange(), IdLoc);
   if (T.isNull())
     return true;
-  return T.getAsOpaquePtr();
+
+  TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T);
+  if (isa<DependentNameType>(T)) {
+    DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc());
+    TL.setKeywordLoc(TypenameLoc);
+    TL.setQualifierRange(SS.getRange());
+    TL.setNameLoc(IdLoc);
+  } else {
+    ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc());
+    TL.setKeywordLoc(TypenameLoc);
+    TL.setQualifierRange(SS.getRange());
+    cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(IdLoc);
+  }
+  
+  return CreateParsedType(T, TSI);
 }
 
-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");
+TypeResult
+Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, 
+                        const CXXScopeSpec &SS, SourceLocation TemplateLoc, 
+                        ParsedType Ty) {
+  if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() &&
+      !getLangOptions().CPlusPlus0x)
+    Diag(TypenameLoc, diag::ext_typename_outside_of_template)
+      << FixItHint::CreateRemoval(TypenameLoc);    
+  
+  TypeSourceInfo *InnerTSI = 0;
+  QualType T = GetTypeFromParser(Ty, &InnerTSI);
+
+  assert(isa<TemplateSpecializationType>(T) && 
+         "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
+    // keyword was superfluous. Just build an ElaboratedType to keep
     // track of the nested-name-specifier.
 
-    // FIXME: Note that the QualifiedNameType had the "typename" keyword!
-    return Context.getQualifiedNameType(NNS, T).getAsOpaquePtr();
+    // Push the inner type, preserving its source locations if possible.
+    TypeLocBuilder Builder;
+    if (InnerTSI)
+      Builder.pushFullCopy(InnerTSI->getTypeLoc());
+    else
+      Builder.push<TemplateSpecializationTypeLoc>(T).initialize(TemplateLoc);
+
+    /* Note: NNS already embedded in template specialization type T. */
+    T = Context.getElaboratedType(ETK_Typename, /*NNS=*/0, T);
+    ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T);
+    TL.setKeywordLoc(TypenameLoc);
+    TL.setQualifierRange(SS.getRange());
+
+    TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T);
+    return CreateParsedType(T, TSI);
   }
 
-  return Context.getDependentNameType(ETK_Typename, NNS, TemplateId)
-                                                            .getAsOpaquePtr();
+  // TODO: it's really silly that we make a template specialization
+  // type earlier only to drop it again here.
+  TemplateSpecializationType *TST = cast<TemplateSpecializationType>(T);
+  DependentTemplateName *DTN =
+    TST->getTemplateName().getAsDependentTemplateName();
+  assert(DTN && "dependent template has non-dependent name?");
+  assert(DTN->getQualifier()
+         == static_cast<NestedNameSpecifier*>(SS.getScopeRep()));
+  T = Context.getDependentTemplateSpecializationType(ETK_Typename,
+                                                     DTN->getQualifier(),
+                                                     DTN->getIdentifier(),
+                                                     TST->getNumArgs(),
+                                                     TST->getArgs());
+  TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T);
+  DependentTemplateSpecializationTypeLoc TL =
+    cast<DependentTemplateSpecializationTypeLoc>(TSI->getTypeLoc());
+  if (InnerTSI) {
+    TemplateSpecializationTypeLoc TSTL =
+      cast<TemplateSpecializationTypeLoc>(InnerTSI->getTypeLoc());
+    TL.setLAngleLoc(TSTL.getLAngleLoc());
+    TL.setRAngleLoc(TSTL.getRAngleLoc());
+    for (unsigned I = 0, E = TST->getNumArgs(); I != E; ++I)
+      TL.setArgLocInfo(I, TSTL.getArgLocInfo(I));
+  } else {
+    TL.initializeLocal(SourceLocation());
+  }
+  TL.setKeywordLoc(TypenameLoc);
+  TL.setQualifierRange(SS.getRange());
+  return CreateParsedType(T, TSI);
 }
 
 /// \brief Build the type that describes a C++ typename specifier,
@@ -5208,40 +5336,31 @@
 QualType
 Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
                         NestedNameSpecifier *NNS, const IdentifierInfo &II,
-                        SourceRange Range) {
-  CXXRecordDecl *CurrentInstantiation = 0;
-  if (NNS->isDependent()) {
-    CurrentInstantiation = getCurrentInstantiationOf(NNS);
+                        SourceLocation KeywordLoc, SourceRange NNSRange,
+                        SourceLocation IILoc) {
+  CXXScopeSpec SS;
+  SS.setScopeRep(NNS);
+  SS.setRange(NNSRange);
 
-    // 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 = computeDeclContext(SS);
+  if (!Ctx) {
+    // If the nested-name-specifier is dependent and couldn't be
+    // resolved to a type, build a typename type.
+    assert(NNS->isDependent());
+    return Context.getDependentNameType(Keyword, NNS, &II);
   }
 
-  DeclContext *Ctx = 0;
+  // If the nested-name-specifier refers to the current instantiation,
+  // 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 with only a warning. In any case we continue.
 
-  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?");
+  if (RequireCompleteDeclContext(SS, Ctx))
+    return QualType();
 
   DeclarationName Name(&II);
-  LookupResult Result(*this, Name, Range.getEnd(), LookupOrdinaryName);
+  LookupResult Result(*this, Name, IILoc, LookupOrdinaryName);
   LookupQualifiedName(Result, Ctx);
   unsigned DiagID = 0;
   Decl *Referenced = 0;
@@ -5255,11 +5374,11 @@
     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));
+    if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) {      
+      // We found a type. Build an ElaboratedType, since the
+      // typename-specifier was just sugar.
+      return Context.getElaboratedType(ETK_Typename, NNS,
+                                       Context.getTypeDeclType(Type));
     }
 
     DiagID = diag::err_typename_nested_not_type;
@@ -5281,7 +5400,9 @@
 
   // 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;
+  SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : NNSRange.getBegin(),
+                        IILoc);
+  Diag(IILoc, DiagID) << FullRange << Name << Ctx;
   if (Referenced)
     Diag(Referenced->getLocation(), diag::note_typename_refers_here)
       << Name;
@@ -5296,6 +5417,8 @@
     DeclarationName Entity;
 
   public:
+    typedef TreeTransform<CurrentInstantiationRebuilder> inherited;
+      
     CurrentInstantiationRebuilder(Sema &SemaRef,
                                   SourceLocation Loc,
                                   DeclarationName Entity)
@@ -5324,75 +5447,9 @@
       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
@@ -5416,27 +5473,37 @@
 /// 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
+/// in X<T> and returning an ElaboratedType 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())
+TypeSourceInfo *Sema::RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
+                                                        SourceLocation Loc,
+                                                        DeclarationName Name) {
+  if (!T || !T->getType()->isDependentType())
     return T;
 
   CurrentInstantiationRebuilder Rebuilder(*this, Loc, Name);
   return Rebuilder.TransformType(T);
 }
 
-void Sema::RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS) {
-  if (SS.isInvalid()) return;
+ExprResult Sema::RebuildExprInCurrentInstantiation(Expr *E) {
+  CurrentInstantiationRebuilder Rebuilder(*this, E->getExprLoc(),
+                                          DeclarationName());
+  return Rebuilder.TransformExpr(E);
+}
+
+bool Sema::RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS) {
+  if (SS.isInvalid()) return true;
 
   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);
+  if (!Rebuilt) return true;
+
+  SS.setScopeRep(Rebuilt);
+  return false;
 }
 
 /// \brief Produces a formatted string that describes the binding of
@@ -5518,8 +5585,15 @@
       }
         
       case TemplateArgument::Expression: {
-        assert(false && "No expressions in deduced template arguments!");
-        Result += "<expression>";
+        // FIXME: This is non-optimal, since we're regurgitating the
+        // expression we were given.
+        std::string Str; 
+        {
+          llvm::raw_string_ostream OS(Str);
+          Args[I].getAsExpr()->printPretty(OS, Context, 0,
+                                           Context.PrintingPolicy);
+        }
+        Result += Str;
         break;
       }
         
diff --git a/lib/Sema/SemaTemplate.h b/lib/Sema/SemaTemplate.h
deleted file mode 100644
index ca59e27..0000000
--- a/lib/Sema/SemaTemplate.h
+++ /dev/null
@@ -1,138 +0,0 @@
-//===------- 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
index 7154d62..4691181 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -10,16 +10,21 @@
 //
 //===----------------------------------------------------------------------===/
 
-#include "Sema.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Template.h"
+#include "clang/Sema/TemplateDeduction.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.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 {
+  using namespace sema;
+
   /// \brief Various flags that control template argument deduction.
   ///
   /// These flags can be bitwise-OR'd together.
@@ -74,7 +79,7 @@
                         TemplateParameterList *TemplateParams,
                         const TemplateArgument &Param,
                         const TemplateArgument &Arg,
-                        Sema::TemplateDeductionInfo &Info,
+                        TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced);
 
 /// \brief If the given expression is of a form that permits the deduction
@@ -97,7 +102,7 @@
                               NonTypeTemplateParmDecl *NTTP,
                               llvm::APSInt Value, QualType ValueType,
                               bool DeducedFromArrayBound,
-                              Sema::TemplateDeductionInfo &Info,
+                              TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   assert(NTTP->getDepth() == 0 &&
          "Cannot deduce non-type template argument with depth > 0");
@@ -138,7 +143,7 @@
 DeduceNonTypeTemplateArgument(Sema &S,
                               NonTypeTemplateParmDecl *NTTP,
                               Expr *Value,
-                              Sema::TemplateDeductionInfo &Info,
+                              TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   assert(NTTP->getDepth() == 0 &&
          "Cannot deduce non-type template argument with depth > 0");
@@ -180,7 +185,7 @@
 DeduceNonTypeTemplateArgument(Sema &S,
                               NonTypeTemplateParmDecl *NTTP,
                               Decl *D,
-                              Sema::TemplateDeductionInfo &Info,
+                              TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   assert(NTTP->getDepth() == 0 &&
          "Cannot deduce non-type template argument with depth > 0");
@@ -214,7 +219,7 @@
                         TemplateParameterList *TemplateParams,
                         TemplateName Param,
                         TemplateName Arg,
-                        Sema::TemplateDeductionInfo &Info,
+                        TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   TemplateDecl *ParamDecl = Param.getAsTemplateDecl();
   if (!ParamDecl) {
@@ -278,7 +283,7 @@
                         TemplateParameterList *TemplateParams,
                         const TemplateSpecializationType *Param,
                         QualType Arg,
-                        Sema::TemplateDeductionInfo &Info,
+                        TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   assert(Arg.isCanonical() && "Argument type must be canonical");
 
@@ -370,7 +375,7 @@
 DeduceTemplateArguments(Sema &S,
                         TemplateParameterList *TemplateParams,
                         QualType ParamIn, QualType ArgIn,
-                        Sema::TemplateDeductionInfo &Info,
+                        TemplateDeductionInfo &Info,
                      llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
                         unsigned TDF) {
   // We only want to look at the canonical types, since typedefs and
@@ -428,9 +433,9 @@
     // type.
     if (Param.isMoreQualifiedThan(Arg) && !(TDF & TDF_IgnoreQualifiers)) {
       Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
-      Info.FirstArg = Deduced[Index];
+      Info.FirstArg = TemplateArgument(Param);
       Info.SecondArg = TemplateArgument(Arg);
-      return Sema::TDK_InconsistentQuals;
+      return Sema::TDK_Underqualified;
     }
 
     assert(TemplateTypeParm->getDepth() == 0 && "Can't deduce with depth > 0");
@@ -482,14 +487,20 @@
 
     //     T *
     case Type::Pointer: {
-      const PointerType *PointerArg = Arg->getAs<PointerType>();
-      if (!PointerArg)
+      QualType PointeeType;
+      if (const PointerType *PointerArg = Arg->getAs<PointerType>()) {
+        PointeeType = PointerArg->getPointeeType();
+      } else if (const ObjCObjectPointerType *PointerArg
+                   = Arg->getAs<ObjCObjectPointerType>()) {
+        PointeeType = PointerArg->getPointeeType();
+      } else {
         return Sema::TDK_NonDeducedMismatch;
+      }
 
       unsigned SubTDF = TDF & (TDF_IgnoreQualifiers | TDF_DerivedClass);
       return DeduceTemplateArguments(S, TemplateParams,
                                    cast<PointerType>(Param)->getPointeeType(),
-                                     PointerArg->getPointeeType(),
+                                     PointeeType,
                                      Info, Deduced, SubTDF);
     }
 
@@ -524,10 +535,11 @@
       if (!IncompleteArrayArg)
         return Sema::TDK_NonDeducedMismatch;
 
+      unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
       return DeduceTemplateArguments(S, TemplateParams,
                      S.Context.getAsIncompleteArrayType(Param)->getElementType(),
                                      IncompleteArrayArg->getElementType(),
-                                     Info, Deduced, 0);
+                                     Info, Deduced, SubTDF);
     }
 
     //     T [integer-constant]
@@ -542,10 +554,11 @@
       if (ConstantArrayArg->getSize() != ConstantArrayParm->getSize())
         return Sema::TDK_NonDeducedMismatch;
 
+      unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
       return DeduceTemplateArguments(S, TemplateParams,
                                      ConstantArrayParm->getElementType(),
                                      ConstantArrayArg->getElementType(),
-                                     Info, Deduced, 0);
+                                     Info, Deduced, SubTDF);
     }
 
     //     type [i]
@@ -554,6 +567,8 @@
       if (!ArrayArg)
         return Sema::TDK_NonDeducedMismatch;
 
+      unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
+
       // Check the element type of the arrays
       const DependentSizedArrayType *DependentArrayParm
         = S.Context.getAsDependentSizedArrayType(Param);
@@ -561,7 +576,7 @@
             = DeduceTemplateArguments(S, TemplateParams,
                                       DependentArrayParm->getElementType(),
                                       ArrayArg->getElementType(),
-                                      Info, Deduced, 0))
+                                      Info, Deduced, SubTDF))
         return Result;
 
       // Determine the array bound is something we can deduce.
@@ -791,7 +806,7 @@
                         TemplateParameterList *TemplateParams,
                         const TemplateArgument &Param,
                         const TemplateArgument &Arg,
-                        Sema::TemplateDeductionInfo &Info,
+                        TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   switch (Param.getKind()) {
   case TemplateArgument::Null:
@@ -841,7 +856,6 @@
       return Sema::TDK_NonDeducedMismatch;
     }
 
-    assert(false && "Type/value mismatch");
     Info.FirstArg = Param;
     Info.SecondArg = Arg;
     return Sema::TDK_NonDeducedMismatch;
@@ -862,7 +876,6 @@
         return DeduceNonTypeTemplateArgument(S, NTTP, Arg.getAsDecl(),
                                              Info, Deduced);
       
-      assert(false && "Type/value mismatch");
       Info.FirstArg = Param;
       Info.SecondArg = Arg;
       return Sema::TDK_NonDeducedMismatch;
@@ -884,7 +897,7 @@
                         TemplateParameterList *TemplateParams,
                         const TemplateArgumentList &ParamList,
                         const TemplateArgumentList &ArgList,
-                        Sema::TemplateDeductionInfo &Info,
+                        TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   assert(ParamList.size() == ArgList.size());
   for (unsigned I = 0, N = ParamList.size(); I != N; ++I) {
@@ -961,6 +974,113 @@
   return TemplateParameter(cast<TemplateTemplateParmDecl>(D));
 }
 
+/// Complete template argument deduction for a class template partial
+/// specialization.
+static Sema::TemplateDeductionResult
+FinishTemplateArgumentDeduction(Sema &S, 
+                                ClassTemplatePartialSpecializationDecl *Partial,
+                                const TemplateArgumentList &TemplateArgs,
+                      llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+                                TemplateDeductionInfo &Info) {
+  // Trap errors.
+  Sema::SFINAETrap Trap(S);
+  
+  Sema::ContextRAII SavedContext(S, Partial);
+
+  // 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 Sema::TDK_Incomplete;
+    }
+    
+    Builder.Append(Deduced[I]);
+  }
+  
+  // Form the template argument list from the deduced template arguments.
+  TemplateArgumentList *DeducedArgumentList
+    = new (S.Context) TemplateArgumentList(S.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?).
+  LocalInstantiationScope InstScope(S);
+  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 (S.Subst(PartialTemplateArgs[I], InstArg,
+                MultiLevelTemplateArgumentList(*DeducedArgumentList))) {
+      Info.Param = makeTemplateParameter(Param);
+      Info.FirstArg = PartialTemplateArgs[I].getArgument();
+      return Sema::TDK_SubstitutionFailure;
+    }
+    InstArgs.addArgument(InstArg);
+  }
+
+  TemplateArgumentListBuilder ConvertedInstArgs(
+                                  ClassTemplate->getTemplateParameters(), N);
+
+  if (S.CheckTemplateArgumentList(ClassTemplate, Partial->getLocation(),
+                                InstArgs, false, ConvertedInstArgs))
+    return Sema::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 (S.CheckTemplateArgument(NTTP, NTTP->getType(), InstExpr, InstArg)) {
+          Info.Param = makeTemplateParameter(Param);
+          Info.FirstArg = Partial->getTemplateArgs()[I];
+          return Sema::TDK_SubstitutionFailure;
+        }
+      }
+    }
+
+    if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg)) {
+      Info.Param = makeTemplateParameter(Param);
+      Info.FirstArg = TemplateArgs[I];
+      Info.SecondArg = InstArg;
+      return Sema::TDK_NonDeducedMismatch;
+    }
+  }
+
+  if (Trap.hasErrorOccurred())
+    return Sema::TDK_SubstitutionFailure;
+
+  return Sema::TDK_Success;
+}
+
 /// \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].
@@ -988,99 +1108,11 @@
   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;
+    return Sema::TDK_SubstitutionFailure;
+ 
+  return ::FinishTemplateArgumentDeduction(*this, Partial, TemplateArgs, 
+                                           Deduced, Info);
 }
 
 /// \brief Determine whether the given type T is a simple-template-id type.
@@ -1163,12 +1195,19 @@
   if (Inst)
     return TDK_InstantiationDepth;
 
+  ContextRAII SavedContext(*this, FunctionTemplate->getTemplatedDecl());
+
   if (CheckTemplateArgumentList(FunctionTemplate,
                                 SourceLocation(),
                                 ExplicitTemplateArgs,
                                 true,
-                                Builder) || Trap.hasErrorOccurred())
+                                Builder) || Trap.hasErrorOccurred()) {
+    unsigned Index = Builder.structuredSize();
+    if (Index >= TemplateParams->size())
+      Index = TemplateParams->size() - 1;
+    Info.Param = makeTemplateParameter(TemplateParams->getParam(Index));
     return TDK_InvalidExplicitArguments;
+  }
 
   // Form the template argument list from the explicitly-specified
   // template arguments.
@@ -1213,7 +1252,8 @@
                                       Proto->isVariadic(),
                                       Proto->getTypeQuals(),
                                       Function->getLocation(),
-                                      Function->getDeclName());
+                                      Function->getDeclName(),
+                                      Proto->getExtInfo());
     if (FunctionType->isNull() || Trap.hasErrorOccurred())
       return TDK_SubstitutionFailure;
   }
@@ -1311,6 +1351,8 @@
   if (Inst)
     return TDK_InstantiationDepth;
 
+  ContextRAII SavedContext(*this, FunctionTemplate->getTemplatedDecl());
+
   // C++ [temp.deduct.type]p2:
   //   [...] or if any template argument remains neither deduced nor
   //   explicitly specified, template argument deduction fails.
@@ -1349,6 +1391,8 @@
                                  NTTP->getDeclName());
             if (NTTPType.isNull()) {
               Info.Param = makeTemplateParameter(Param);
+              Info.reset(new (Context) TemplateArgumentList(Context, Builder, 
+                                                            /*TakeArgs=*/true));
               return TDK_SubstitutionFailure;
             }
           }
@@ -1374,6 +1418,8 @@
                                   : CTAK_Deduced)) {
         Info.Param = makeTemplateParameter(
                          const_cast<NamedDecl *>(TemplateParams->getParam(I)));
+        Info.reset(new (Context) TemplateArgumentList(Context, Builder, 
+                                                      /*TakeArgs=*/true));
         return TDK_SubstitutionFailure;
       }
 
@@ -1404,6 +1450,8 @@
                               CTAK_Deduced)) {
       Info.Param = makeTemplateParameter(
                          const_cast<NamedDecl *>(TemplateParams->getParam(I)));
+      Info.reset(new (Context) TemplateArgumentList(Context, Builder, 
+                                                    /*TakeArgs=*/true));
       return TDK_SubstitutionFailure;
     }
 
@@ -1417,9 +1465,11 @@
 
   // Substitute the deduced template arguments into the function template
   // declaration to produce the function template specialization.
+  DeclContext *Owner = FunctionTemplate->getDeclContext();
+  if (FunctionTemplate->getFriendObjectKind())
+    Owner = FunctionTemplate->getLexicalDeclContext();
   Specialization = cast_or_null<FunctionDecl>(
-                      SubstDecl(FunctionTemplate->getTemplatedDecl(),
-                                FunctionTemplate->getDeclContext(),
+                      SubstDecl(FunctionTemplate->getTemplatedDecl(), Owner,
                          MultiLevelTemplateArgumentList(*DeducedArgumentList)));
   if (!Specialization)
     return TDK_SubstitutionFailure;
@@ -1429,7 +1479,8 @@
   
   // If the template argument list is owned by the function template
   // specialization, release it.
-  if (Specialization->getTemplateSpecializationArgs() == DeducedArgumentList)
+  if (Specialization->getTemplateSpecializationArgs() == DeducedArgumentList &&
+      !Trap.hasErrorOccurred())
     Info.take();
 
   // There may have been an error that did not prevent us from constructing a
@@ -1443,14 +1494,22 @@
   return TDK_Success;
 }
 
+/// Gets the type of a function for template-argument-deducton
+/// purposes when it's considered as part of an overload set.
 static QualType GetTypeOfFunction(ASTContext &Context,
-                                  bool isAddressOfOperand,
+                                  const OverloadExpr::FindResult &R,
                                   FunctionDecl *Fn) {
-  if (!isAddressOfOperand) return Fn->getType();
   if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn))
-    if (Method->isInstance())
+    if (Method->isInstance()) {
+      // An instance method that's referenced in a form that doesn't
+      // look like a member pointer is just invalid.
+      if (!R.HasFormOfMemberPointer) return QualType();
+
       return Context.getMemberPointerType(Fn->getType(),
                Context.getTypeDeclType(Method->getParent()).getTypePtr());
+    }
+
+  if (!R.IsAddressOfOperand) return Fn->getType();
   return Context.getPointerType(Fn->getType());
 }
 
@@ -1461,10 +1520,10 @@
 static QualType
 ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
                             Expr *Arg, QualType ParamType) {
-  llvm::PointerIntPair<OverloadExpr*,1> R = OverloadExpr::find(Arg);
+  
+  OverloadExpr::FindResult R = OverloadExpr::find(Arg);
 
-  bool isAddressOfOperand = bool(R.getInt());
-  OverloadExpr *Ovl = R.getPointer();
+  OverloadExpr *Ovl = R.Expression;
 
   // If there were explicit template arguments, we can only find
   // something via C++ [temp.arg.explicit]p3, i.e. if the arguments
@@ -1473,7 +1532,7 @@
     // But we can still look for an explicit specialization.
     if (FunctionDecl *ExplicitSpec
           = S.ResolveSingleFunctionTemplateSpecialization(Ovl))
-      return GetTypeOfFunction(S.Context, isAddressOfOperand, ExplicitSpec);
+      return GetTypeOfFunction(S.Context, R, ExplicitSpec);
     return QualType();
   }
 
@@ -1498,7 +1557,8 @@
       return QualType();
 
     FunctionDecl *Fn = cast<FunctionDecl>(D);
-    QualType ArgType = GetTypeOfFunction(S.Context, isAddressOfOperand, Fn);
+    QualType ArgType = GetTypeOfFunction(S.Context, R, Fn);
+    if (ArgType.isNull()) continue;
 
     //   - If the argument is an overload set (not containing function
     //     templates), trial argument deduction is attempted using each
@@ -1514,7 +1574,7 @@
     // So we do not reject deductions which were made elsewhere.
     llvm::SmallVector<DeducedTemplateArgument, 8> 
       Deduced(TemplateParams->size());
-    Sema::TemplateDeductionInfo Info(S.Context, Ovl->getNameLoc());
+    TemplateDeductionInfo Info(S.Context, Ovl->getNameLoc());
     unsigned TDF = 0;
 
     Sema::TemplateDeductionResult Result
@@ -1581,7 +1641,7 @@
 
   // The types of the parameters from which we will perform template argument
   // deduction.
-  Sema::LocalInstantiationScope InstScope(*this);
+  LocalInstantiationScope InstScope(*this);
   TemplateParameterList *TemplateParams
     = FunctionTemplate->getTemplateParameters();
   llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
@@ -1677,7 +1737,8 @@
     //     - 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())
+    if (ArgType->isPointerType() || ArgType->isMemberPointerType() ||
+        ArgType->isObjCObjectPointerType())
       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,
@@ -1740,7 +1801,7 @@
   QualType FunctionType = Function->getType();
 
   // Substitute any explicit template arguments.
-  Sema::LocalInstantiationScope InstScope(*this);
+  LocalInstantiationScope InstScope(*this);
   llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
   unsigned NumExplicitlySpecified = 0;
   llvm::SmallVector<QualType, 4> ParamTypes;
@@ -1872,7 +1933,7 @@
   // modulo the various allowed differences.
 
   // Finish template argument deduction.
-  Sema::LocalInstantiationScope InstScope(*this);
+  LocalInstantiationScope InstScope(*this);
   FunctionDecl *Spec = 0;
   TemplateDeductionResult Result
     = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, 0, Spec, 
@@ -1936,7 +1997,7 @@
 DeduceTemplateArgumentsDuringPartialOrdering(Sema &S,
                                         TemplateParameterList *TemplateParams,
                                              QualType ParamIn, QualType ArgIn,
-                                             Sema::TemplateDeductionInfo &Info,
+                                             TemplateDeductionInfo &Info,
                       llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
    llvm::SmallVectorImpl<DeductionQualifierComparison> *QualifierComparisons) {
   CanQualType Param = S.Context.getCanonicalType(ParamIn);
@@ -2018,7 +2079,7 @@
   // 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);
+  TemplateDeductionInfo Info(S.Context, Loc);
   switch (TPOC) {
   case TPOC_Call: {
     //   - In the context of a function call, the function parameter types are
@@ -2333,14 +2394,17 @@
   //       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
+  // 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 deducible from the class
+  // template partial specialization's template arguments, for
+  // example.
   llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
-  Sema::TemplateDeductionInfo Info(Context, Loc);
+  TemplateDeductionInfo Info(Context, Loc);
 
   QualType PT1 = PS1->getInjectedSpecializationType();
   QualType PT2 = PS2->getInjectedSpecializationType();
@@ -2354,7 +2418,11 @@
                                                                Info,
                                                                Deduced,
                                                                0);
-
+  if (Better1)
+    Better1 = !::FinishTemplateArgumentDeduction(*this, PS2, 
+                                                 PS1->getTemplateArgs(), 
+                                                 Deduced, Info);
+  
   // Determine whether PS2 is at least as specialized as PS1
   Deduced.clear();
   Deduced.resize(PS1->getTemplateParameters()->size());
@@ -2365,6 +2433,10 @@
                                                                Info,
                                                                Deduced,
                                                                0);
+  if (Better2)
+    Better2 = !::FinishTemplateArgumentDeduction(*this, PS1, 
+                                                 PS2->getTemplateArgs(), 
+                                                 Deduced, Info);
   
   if (Better1 == Better2)
     return 0;
@@ -2570,6 +2642,18 @@
                                  OnlyDeduced, Depth, Used);
     break;
 
+  case Type::DependentTemplateSpecialization: {
+    const DependentTemplateSpecializationType *Spec
+      = cast<DependentTemplateSpecializationType>(T);
+    if (!OnlyDeduced)
+      MarkUsedTemplateParameters(SemaRef, Spec->getQualifier(),
+                                 OnlyDeduced, Depth, Used);
+    for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
+      MarkUsedTemplateParameters(SemaRef, Spec->getArg(I), OnlyDeduced, Depth,
+                                 Used);
+    break;
+  }
+
   case Type::TypeOf:
     if (!OnlyDeduced)
       MarkUsedTemplateParameters(SemaRef,
@@ -2598,6 +2682,7 @@
   case Type::Record:
   case Type::Enum:
   case Type::ObjCInterface:
+  case Type::ObjCObject:
   case Type::ObjCObjectPointer:
   case Type::UnresolvedUsing:
 #define TYPE(Class, Base)
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 6fdf243..4d4c181 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -10,17 +10,20 @@
 //
 //===----------------------------------------------------------------------===/
 
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
 #include "TreeTransform.h"
-#include "Lookup.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Template.h"
+#include "clang/Sema/TemplateDeduction.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;
+using namespace sema;
 
 //===----------------------------------------------------------------------===/
 // Template Instantiation Support
@@ -38,10 +41,16 @@
 /// arguments relative to the primary template, even when we're
 /// dealing with a specialization. This is only relevant for function
 /// template specializations.
+///
+/// \param Pattern If non-NULL, indicates the pattern from which we will be
+/// instantiating the definition of the given declaration, \p D. This is
+/// used to determine the proper set of template instantiation arguments for
+/// friend function template specializations.
 MultiLevelTemplateArgumentList
 Sema::getTemplateInstantiationArgs(NamedDecl *D, 
                                    const TemplateArgumentList *Innermost,
-                                   bool RelativeToPrimary) {
+                                   bool RelativeToPrimary,
+                                   const FunctionDecl *Pattern) {
   // Accumulate the set of template argument lists in this structure.
   MultiLevelTemplateArgumentList Result;
 
@@ -57,7 +66,8 @@
     if (ClassTemplateSpecializationDecl *Spec
           = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
       // We're done when we hit an explicit specialization.
-      if (Spec->getSpecializationKind() == TSK_ExplicitSpecialization)
+      if (Spec->getSpecializationKind() == TSK_ExplicitSpecialization &&
+          !isa<ClassTemplatePartialSpecializationDecl>(Spec))
         break;
 
       Result.addOuterTemplateArguments(&Spec->getTemplateInstantiationArgs());
@@ -89,13 +99,24 @@
       
       // 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.
+      // instead of its semantic parent, unless of course the pattern we're
+      // instantiating actually comes from the file's context!
       if (Function->getFriendObjectKind() &&
-          Function->getDeclContext()->isFileContext()) {
+          Function->getDeclContext()->isFileContext() &&
+          (!Pattern || !Pattern->getLexicalDeclContext()->isFileContext())) {
         Ctx = Function->getLexicalDeclContext();
         RelativeToPrimary = false;
         continue;
       }
+    } else if (CXXRecordDecl *Rec = dyn_cast<CXXRecordDecl>(Ctx)) {
+      if (ClassTemplateDecl *ClassTemplate = Rec->getDescribedClassTemplate()) {
+        QualType T = ClassTemplate->getInjectedClassNameSpecialization();
+        const TemplateSpecializationType *TST
+          = cast<TemplateSpecializationType>(Context.getCanonicalType(T));
+        Result.addOuterTemplateArguments(TST->getArgs(), TST->getNumArgs());
+        if (ClassTemplate->isMemberSpecialization())
+          break;
+      }
     }
 
     Ctx = Ctx->getParent();
@@ -532,8 +553,7 @@
 // Template Instantiation for Types
 //===----------------------------------------------------------------------===/
 namespace {
-  class TemplateInstantiator
-    : public TreeTransform<TemplateInstantiator> {
+  class TemplateInstantiator : public TreeTransform<TemplateInstantiator> {
     const MultiLevelTemplateArgumentList &TemplateArgs;
     SourceLocation Loc;
     DeclarationName Entity;
@@ -553,9 +573,7 @@
     ///
     /// 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();
-    }
+    bool AlreadyTransformed(QualType T);
 
     /// \brief Returns the location of the entity being instantiated, if known.
     SourceLocation getBaseLocation() { return Loc; }
@@ -596,21 +614,18 @@
       
     /// \brief Check for tag mismatches when instantiating an
     /// elaborated type.
-    QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag);
+    QualType RebuildElaboratedType(ElaboratedTypeKeyword Keyword,
+                                   NestedNameSpecifier *NNS, QualType T);
 
-    Sema::OwningExprResult TransformPredefinedExpr(PredefinedExpr *E);
-    Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E);
-    Sema::OwningExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
-    Sema::OwningExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
+    ExprResult TransformPredefinedExpr(PredefinedExpr *E);
+    ExprResult TransformDeclRefExpr(DeclRefExpr *E);
+    ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
+    ExprResult 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);
-
+    QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
+                                        FunctionProtoTypeLoc TL,
+                                        QualType ObjectType);
     ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm);
 
     /// \brief Transforms a template type parameter type by performing
@@ -618,9 +633,28 @@
     QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
                                            TemplateTypeParmTypeLoc TL,
                                            QualType ObjectType);
+
+    ExprResult TransformCallExpr(CallExpr *CE) {
+      getSema().CallsUndergoingInstantiation.push_back(CE);
+      ExprResult Result =
+          TreeTransform<TemplateInstantiator>::TransformCallExpr(CE);
+      getSema().CallsUndergoingInstantiation.pop_back();
+      return move(Result);
+    }
   };
 }
 
+bool TemplateInstantiator::AlreadyTransformed(QualType T) {
+  if (T.isNull())
+    return true;
+  
+  if (T->isDependentType() || T->isVariablyModifiedType())
+    return false;
+  
+  getSema().MarkDeclarationsReferencedInType(Loc, T);
+  return true;
+}
+
 Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {
   if (!D)
     return 0;
@@ -707,8 +741,9 @@
 }
 
 QualType
-TemplateInstantiator::RebuildElaboratedType(QualType T,
-                                            ElaboratedType::TagKind Tag) {
+TemplateInstantiator::RebuildElaboratedType(ElaboratedTypeKeyword Keyword,
+                                            NestedNameSpecifier *NNS,
+                                            QualType T) {
   if (const TagType *TT = T->getAs<TagType>()) {
     TagDecl* TD = TT->getDecl();
 
@@ -720,19 +755,23 @@
 
     // 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);
+    if (Keyword != ETK_None && Keyword != ETK_Typename) {
+      TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
+      if (!SemaRef.isAcceptableTagRedeclaration(TD, Kind, 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);
+  return TreeTransform<TemplateInstantiator>::RebuildElaboratedType(Keyword,
+                                                                    NNS, T);
 }
 
-Sema::OwningExprResult 
+ExprResult 
 TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
   if (!E->isTypeDependent())
     return SemaRef.Owned(E->Retain());
@@ -754,7 +793,7 @@
   return getSema().Owned(PE);
 }
 
-Sema::OwningExprResult
+ExprResult
 TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
                                                NonTypeTemplateParmDecl *NTTP) {
   // If the corresponding template argument is NULL or non-existent, it's
@@ -782,7 +821,7 @@
                             getSema().FindInstantiatedDecl(E->getLocation(),
                                                            VD, TemplateArgs));
     if (!VD)
-      return SemaRef.ExprError();
+      return ExprError();
 
     // Derive the type we want the substituted decl to have.  This had
     // better be non-dependent, or these checks will have serious problems.
@@ -801,7 +840,7 @@
 }
                                                    
 
-Sema::OwningExprResult
+ExprResult
 TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
   NamedDecl *D = E->getDecl();
   if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
@@ -815,7 +854,7 @@
   return TreeTransform<TemplateInstantiator>::TransformDeclRefExpr(E);
 }
 
-Sema::OwningExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
+ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
     CXXDefaultArgExpr *E) {
   assert(!cast<FunctionDecl>(E->getParam()->getDeclContext())->
              getDescribedFunctionTemplate() &&
@@ -825,23 +864,12 @@
                                         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;
+QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
+                                                        FunctionProtoTypeLoc TL,
+                                                          QualType ObjectType) {
+  // We need a local instantiation scope for this function prototype.
+  LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
+  return inherited::TransformFunctionProtoType(TLB, TL, ObjectType);
 }
 
 ParmVarDecl *
@@ -935,7 +963,8 @@
          "Cannot perform an instantiation without some context on the "
          "instantiation stack");
   
-  if (!T->getType()->isDependentType())
+  if (!T->getType()->isDependentType() && 
+      !T->getType()->isVariablyModifiedType())
     return T;
 
   TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
@@ -950,8 +979,9 @@
          "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())
+  // If T is not a dependent type or a variably-modified type, there
+  // is nothing to do.
+  if (!T->isDependentType() && !T->isVariablyModifiedType())
     return T;
 
   TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity);
@@ -959,7 +989,7 @@
 }
 
 static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) {
-  if (T->getType()->isDependentType())
+  if (T->getType()->isDependentType() || T->getType()->isVariablyModifiedType())
     return true;
 
   TypeLoc TL = T->getTypeLoc();
@@ -1040,6 +1070,10 @@
   NewParm->setHasInheritedDefaultArg(OldParm->hasInheritedDefaultArg());
 
   CurrentInstantiationScope->InstantiatedLocal(OldParm, NewParm);
+  // FIXME: OldParm may come from a FunctionProtoType, in which case CurContext
+  // can be anything, is this right ?
+  NewParm->setDeclContext(CurContext);
+  
   return NewParm;  
 }
 
@@ -1070,11 +1104,11 @@
       continue;
     }
 
-    QualType BaseType = SubstType(Base->getType(),
-                                  TemplateArgs,
-                                  Base->getSourceRange().getBegin(),
-                                  DeclarationName());
-    if (BaseType.isNull()) {
+    TypeSourceInfo *BaseTypeLoc = SubstType(Base->getTypeSourceInfo(),
+                                            TemplateArgs,
+                                            Base->getSourceRange().getBegin(),
+                                            DeclarationName());
+    if (!BaseTypeLoc) {
       Invalid = true;
       continue;
     }
@@ -1084,9 +1118,7 @@
                                Base->getSourceRange(),
                                Base->isVirtual(),
                                Base->getAccessSpecifierAsWritten(),
-                               BaseType,
-                               /*FIXME: Not totally accurate */
-                               Base->getSourceRange().getBegin()))
+                               BaseTypeLoc))
       InstantiatedBases.push_back(InstantiatedBase);
     else
       Invalid = true;
@@ -1167,30 +1199,36 @@
 
   // Enter the scope of this instantiation. We don't use
   // PushDeclContext because we don't have a scope.
-  DeclContext *PreviousContext = CurContext;
-  CurContext = Instantiation;
+  ContextRAII SavedContext(*this, Instantiation);
+  EnterExpressionEvaluationContext EvalContext(*this, 
+                                               Sema::PotentiallyEvaluated);
 
   // 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);
+  LocalInstantiationScope Scope(*this, MergeWithParentScope);
+
+  // Pull attributes from the pattern onto the instantiation.
+  InstantiateAttrs(TemplateArgs, Pattern, Instantiation);
 
   // Start the definition of this instantiation.
   Instantiation->startDefinition();
+  
+  Instantiation->setTagKind(Pattern->getTagKind());
 
   // Do substitution on the base class specifiers.
   if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs))
     Invalid = true;
 
-  llvm::SmallVector<DeclPtrTy, 4> Fields;
+  llvm::SmallVector<Decl*, 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));
+        Fields.push_back(Field);
       else if (NewMember->isInvalidDecl())
         Invalid = true;
     } else {
@@ -1201,35 +1239,25 @@
   }
 
   // Finish checking fields.
-  ActOnFields(0, Instantiation->getLocation(), DeclPtrTy::make(Instantiation),
+  ActOnFields(0, Instantiation->getLocation(), Instantiation,
               Fields.data(), Fields.size(), SourceLocation(), SourceLocation(),
               0);
-  CheckCompletedCXXClass(/*Scope=*/0, Instantiation);
+  CheckCompletedCXXClass(Instantiation);
   if (Instantiation->isInvalidDecl())
     Invalid = true;
   
   // Exit the scope of this instantiation.
-  CurContext = PreviousContext;
+  SavedContext.pop();
 
-  // 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)
+  if (!Invalid) {
     Consumer.HandleTagDeclDefinition(Instantiation);
 
+    // Always emit the vtable for an explicit instantiation definition
+    // of a polymorphic class template specialization.
+    if (TSK == TSK_ExplicitInstantiationDefinition)
+      MarkVTableUsed(PointOfInstantiation, Instantiation, true);
+  }
+
   return Invalid;
 }
 
@@ -1253,6 +1281,12 @@
       // declaration (C++0x [temp.explicit]p10); go ahead and perform the
       // explicit instantiation.
       ClassTemplateSpec->setSpecializationKind(TSK);
+      
+      // If this is an explicit instantiation definition, mark the
+      // vtable as used.
+      if (TSK == TSK_ExplicitInstantiationDefinition)
+        MarkVTableUsed(PointOfInstantiation, ClassTemplateSpec, true);
+
       return false;
     }
     
@@ -1279,21 +1313,20 @@
   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) {
+  llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
+  Template->getPartialSpecializations(PartialSpecs);
+  for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
+    ClassTemplatePartialSpecializationDecl *Partial = PartialSpecs[I];
     TemplateDeductionInfo Info(Context, PointOfInstantiation);
     if (TemplateDeductionResult Result
-          = DeduceTemplateArguments(&*Partial,
+          = 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()));
+      Matched.push_back(std::make_pair(Partial, Info.take()));
     }
   }
 
@@ -1388,12 +1421,6 @@
                                  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;
 }
 
@@ -1427,7 +1454,7 @@
             SuppressNew)
           continue;
         
-        if (Function->getBody())
+        if (Function->hasBody())
           continue;
 
         if (TSK == TSK_ExplicitInstantiationDefinition) {
@@ -1437,7 +1464,7 @@
           //   specialization and is only an explicit instantiation definition 
           //   of members whose definition is visible at the point of 
           //   instantiation.
-          if (!Pattern->getBody())
+          if (!Pattern->hasBody())
             continue;
         
           Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);
@@ -1555,7 +1582,7 @@
                           TSK);
 }
 
-Sema::OwningStmtResult
+StmtResult
 Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {
   if (!S)
     return Owned(S);
@@ -1566,7 +1593,7 @@
   return Instantiator.TransformStmt(S);
 }
 
-Sema::OwningExprResult
+ExprResult
 Sema::SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {
   if (!E)
     return Owned(E);
@@ -1587,6 +1614,15 @@
   return Instantiator.TransformNestedNameSpecifier(NNS, Range);
 }
 
+/// \brief Do template substitution on declaration name info.
+DeclarationNameInfo
+Sema::SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+                         const MultiLevelTemplateArgumentList &TemplateArgs) {
+  TemplateInstantiator Instantiator(*this, TemplateArgs, NameInfo.getLoc(),
+                                    NameInfo.getName());
+  return Instantiator.TransformDeclarationNameInfo(NameInfo);
+}
+
 TemplateName
 Sema::SubstTemplateName(TemplateName Name, SourceLocation Loc,
                         const MultiLevelTemplateArgumentList &TemplateArgs) {
@@ -1602,3 +1638,28 @@
 
   return Instantiator.TransformTemplateArgument(Input, Output);
 }
+
+Decl *LocalInstantiationScope::getInstantiationOf(const Decl *D) {
+  for (LocalInstantiationScope *Current = this; Current; 
+       Current = Current->Outer) {
+    // Check if we found something within this scope.
+    llvm::DenseMap<const Decl *, Decl *>::iterator Found
+      = Current->LocalDecls.find(D);
+    if (Found != Current->LocalDecls.end())
+      return Found->second;
+   
+    // If we aren't combined with our outer scope, we're done. 
+    if (!Current->CombineWithOuterScope)
+      break;
+  }
+  
+  assert(D->isInvalidDecl() && 
+         "declaration was not instantiated in this scope!");
+  return 0;
+}
+
+void LocalInstantiationScope::InstantiatedLocal(const Decl *D, Decl *Inst) {
+  Decl *&Stored = LocalDecls[D];
+  assert((!Stored || Stored == Inst)&& "Already instantiated this local");
+  Stored = Inst;
+}
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 4575d47..e40075a 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -9,8 +9,10 @@
 //  This file implements C++ template instantiation for declarations.
 //
 //===----------------------------------------------------------------------===/
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/PrettyDeclStackTrace.h"
+#include "clang/Sema/Template.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclTemplate.h"
@@ -19,7 +21,6 @@
 #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;
@@ -31,23 +32,20 @@
     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.
+    // clang/AST/DeclNodes.inc.
     Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D);
     Decl *VisitNamespaceDecl(NamespaceDecl *D);
     Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
     Decl *VisitTypedefDecl(TypedefDecl *D);
     Decl *VisitVarDecl(VarDecl *D);
+    Decl *VisitAccessSpecDecl(AccessSpecDecl *D);
     Decl *VisitFieldDecl(FieldDecl *D);
     Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
     Decl *VisitEnumDecl(EnumDecl *D);
@@ -86,10 +84,6 @@
       return 0;
     }
 
-    const LangOptions &getLangOptions() {
-      return SemaRef.getLangOptions();
-    }
-
     // Helper functions for instantiating methods.
     TypeSourceInfo *SubstFunctionType(FunctionDecl *D,
                              llvm::SmallVectorImpl<ParmVarDecl *> &Params);
@@ -142,14 +136,39 @@
   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 this still too simple?
+void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
+                            Decl *Tmpl, Decl *New) {
+  for (AttrVec::const_iterator i = Tmpl->attr_begin(), e = Tmpl->attr_end();
+       i != e; ++i) {
+    const Attr *TmplAttr = *i;
+    // FIXME: This should be generalized to more than just the AlignedAttr.
+    if (const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr)) {
+      if (Aligned->isAlignmentDependent()) {
+        // The alignment expression is not potentially evaluated.
+        EnterExpressionEvaluationContext Unevaluated(*this,
+                                                     Sema::Unevaluated);
+
+        if (Aligned->isAlignmentExpr()) {
+          ExprResult Result = SubstExpr(Aligned->getAlignmentExpr(),
+                                              TemplateArgs);
+          if (!Result.isInvalid())
+            AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>());
+        }
+        else {
+          TypeSourceInfo *Result = SubstType(Aligned->getAlignmentType(),
+                                              TemplateArgs,
+                                              Aligned->getLocation(), 
+                                              DeclarationName());
+          if (Result)
+            AddAlignedAttr(Aligned->getLocation(), New, Result);
+        }
+        continue;
+      }
+    }
+
     // FIXME: Is cloning correct for all attributes?
-    Attr *NewAttr = TmplAttr->clone(SemaRef.Context);
-    
+    Attr *NewAttr = TmplAttr->clone(Context);
     New->addAttr(NewAttr);
   }
 }
@@ -184,13 +203,16 @@
 Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
   bool Invalid = false;
   TypeSourceInfo *DI = D->getTypeSourceInfo();
-  if (DI->getType()->isDependentType()) {
+  if (DI->getType()->isDependentType() ||
+      DI->getType()->isVariablyModifiedType()) {
     DI = SemaRef.SubstType(DI, TemplateArgs,
                            D->getLocation(), D->getDeclName());
     if (!DI) {
       Invalid = true;
       DI = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.Context.IntTy);
     }
+  } else {
+    SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType());
   }
 
   // Create the new typedef
@@ -215,6 +237,7 @@
     Typedef->setPreviousDeclaration(cast<TypedefDecl>(InstPrev));
   }
 
+  SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef);
 
   Typedef->setAccess(D->getAccess());
   Owner->addDecl(Typedef);
@@ -229,14 +252,14 @@
                                                Expr **Args, unsigned NumArgs,
                            const MultiLevelTemplateArgumentList &TemplateArgs,
                          llvm::SmallVectorImpl<SourceLocation> &FakeCommaLocs,
-                           ASTOwningVector<&ActionBase::DeleteExpr> &InitArgs) {
+                           ASTOwningVector<Expr*> &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);
+    ExprResult Arg = SemaRef.SubstExpr(Args[I], TemplateArgs);
     if (Arg.isInvalid())
       return true;
   
@@ -268,7 +291,7 @@
                             const MultiLevelTemplateArgumentList &TemplateArgs,
                                    SourceLocation &LParenLoc,
                                llvm::SmallVector<SourceLocation, 4> &CommaLocs,
-                             ASTOwningVector<&ActionBase::DeleteExpr> &NewArgs,
+                             ASTOwningVector<Expr*> &NewArgs,
                                    SourceLocation &RParenLoc) {
   NewArgs.clear();
   LParenLoc = SourceLocation();
@@ -311,7 +334,7 @@
     }
   }
  
-  Sema::OwningExprResult Result = S.SubstExpr(Init, TemplateArgs);
+  ExprResult Result = S.SubstExpr(Init, TemplateArgs);
   if (Result.isInvalid())
     return true;
 
@@ -320,6 +343,13 @@
 }
 
 Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
+  // If this is the variable for an anonymous struct or union,
+  // instantiate the anonymous struct/union type first.
+  if (const RecordType *RecordTy = D->getType()->getAs<RecordType>())
+    if (RecordTy->getDecl()->isAnonymousStructOrUnion())
+      if (!VisitCXXRecordDecl(cast<CXXRecordDecl>(RecordTy->getDecl())))
+        return 0;
+
   // Do substitution on the type of the declaration
   TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(),
                                          TemplateArgs,
@@ -336,7 +366,6 @@
                                  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))
@@ -349,7 +378,10 @@
     Var->setLexicalDeclContext(D->getLexicalDeclContext());
 
   Var->setAccess(D->getAccess());
-
+  
+  if (!D->isStaticDataMember())
+    Var->setUsed(D->isUsed(false));
+  
   // FIXME: In theory, we could have a previous declaration for variables that
   // are not static data members.
   bool Redeclaration = false;
@@ -361,12 +393,16 @@
   SemaRef.CheckVariableDeclaration(Var, Previous, Redeclaration);
 
   if (D->isOutOfLine()) {
-    D->getLexicalDeclContext()->addDecl(Var);
+    if (!D->isStaticDataMember())
+      D->getLexicalDeclContext()->addDecl(Var);
     Owner->makeDeclVisibleInContext(Var);
   } else {
     Owner->addDecl(Var);
+    if (Owner->isFunctionOrMethod())
+      SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Var);
   }
-
+  SemaRef.InstantiateAttrs(TemplateArgs, D, Var);
+  
   // Link instantiations of static data members back to the template from
   // which they were instantiated.
   if (Var->isStaticDataMember())
@@ -384,25 +420,23 @@
     // Instantiate the initializer.
     SourceLocation LParenLoc, RParenLoc;
     llvm::SmallVector<SourceLocation, 4> CommaLocs;
-    ASTOwningVector<&ActionBase::DeleteExpr> InitArgs(SemaRef);
+    ASTOwningVector<Expr*> 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),
+        SemaRef.AddCXXDirectInitializerToDecl(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);        
+        Expr *Init = InitArgs.take()[0];
+        SemaRef.AddInitializerToDecl(Var, Init, false);
       } else {
         assert(InitArgs.size() == 0);
-        SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);    
+        SemaRef.ActOnUninitializedDecl(Var, false);    
       }
     } else {
       // FIXME: Not too happy about invalidating the declaration
@@ -412,15 +446,28 @@
     
     SemaRef.PopExpressionEvaluationContext();
   } else if (!Var->isStaticDataMember() || Var->isOutOfLine())
-    SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);
+    SemaRef.ActOnUninitializedDecl(Var, false);
+
+  // Diagnose unused local variables.
+  if (!Var->isInvalidDecl() && Owner->isFunctionOrMethod() && !Var->isUsed())
+    SemaRef.DiagnoseUnusedDecl(Var);
 
   return Var;
 }
 
+Decl *TemplateDeclInstantiator::VisitAccessSpecDecl(AccessSpecDecl *D) {
+  AccessSpecDecl* AD
+    = AccessSpecDecl::Create(SemaRef.Context, D->getAccess(), Owner,
+                             D->getAccessSpecifierLoc(), D->getColonLoc());
+  Owner->addHiddenDecl(AD);
+  return AD;
+}
+
 Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
   bool Invalid = false;
   TypeSourceInfo *DI = D->getTypeSourceInfo();
-  if (DI->getType()->isDependentType())  {
+  if (DI->getType()->isDependentType() ||
+      DI->getType()->isVariablyModifiedType())  {
     DI = SemaRef.SubstType(DI, TemplateArgs,
                            D->getLocation(), D->getDeclName());
     if (!DI) {
@@ -437,6 +484,8 @@
         << DI->getType();
       Invalid = true;
     }
+  } else {
+    SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType());
   }
 
   Expr *BitWidth = D->getBitWidth();
@@ -444,9 +493,9 @@
     BitWidth = 0;
   else if (BitWidth) {
     // The bit-width expression is not potentially evaluated.
-    EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
-    OwningExprResult InstantiatedBitWidth
+    ExprResult InstantiatedBitWidth
       = SemaRef.SubstExpr(BitWidth, TemplateArgs);
     if (InstantiatedBitWidth.isInvalid()) {
       Invalid = true;
@@ -469,7 +518,7 @@
     return 0;
   }
 
-  InstantiateAttrs(D, Field);
+  SemaRef.InstantiateAttrs(TemplateArgs, D, Field);
   
   if (Invalid)
     Field->setInvalidDecl();
@@ -477,6 +526,11 @@
   if (!Field->getDeclName()) {
     // Keep track of where this decl came from.
     SemaRef.Context.setInstantiatedFromUnnamedFieldDecl(Field, D);
+  } 
+  if (CXXRecordDecl *Parent= dyn_cast<CXXRecordDecl>(Field->getDeclContext())) {
+    if (Parent->isAnonymousStructOrUnion() &&
+        Parent->getLookupContext()->isFunctionOrMethod())
+      SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Field);
   }
 
   Field->setImplicit(D->isImplicit());
@@ -527,20 +581,18 @@
   Expr *AssertExpr = D->getAssertExpr();
 
   // The expression in a static assertion is not potentially evaluated.
-  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
-  OwningExprResult InstantiatedAssertExpr
+  ExprResult InstantiatedAssertExpr
     = SemaRef.SubstExpr(AssertExpr, TemplateArgs);
   if (InstantiatedAssertExpr.isInvalid())
     return 0;
 
-  OwningExprResult Message(SemaRef, D->getMessage());
+  ExprResult Message(D->getMessage());
   D->getMessage()->Retain();
-  Decl *StaticAssert
-    = SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
-                                           move(InstantiatedAssertExpr),
-                                           move(Message)).getAs<Decl>();
-  return StaticAssert;
+  return SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
+                                              InstantiatedAssertExpr.get(),
+                                              Message.get());
 }
 
 Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
@@ -557,18 +609,18 @@
   if (D->getDeclContext()->isFunctionOrMethod())
     SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum);
     
-  llvm::SmallVector<Sema::DeclPtrTy, 4> Enumerators;
+  llvm::SmallVector<Decl*, 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);
+    ExprResult Value = SemaRef.Owned((Expr *)0);
     if (Expr *UninstValue = EC->getInitExpr()) {
       // The enumerator's value expression is not potentially evaluated.
       EnterExpressionEvaluationContext Unevaluated(SemaRef,
-                                                   Action::Unevaluated);
+                                                   Sema::Unevaluated);
 
       Value = SemaRef.SubstExpr(UninstValue, TemplateArgs);
     }
@@ -583,7 +635,7 @@
     EnumConstantDecl *EnumConst
       = SemaRef.CheckEnumConstant(Enum, LastEnumConst,
                                   EC->getLocation(), EC->getIdentifier(),
-                                  move(Value));
+                                  Value.get());
 
     if (isInvalid) {
       if (EnumConst)
@@ -594,7 +646,7 @@
     if (EnumConst) {
       EnumConst->setAccess(Enum->getAccess());
       Enum->addDecl(EnumConst);
-      Enumerators.push_back(Sema::DeclPtrTy::make(EnumConst));
+      Enumerators.push_back(EnumConst);
       LastEnumConst = EnumConst;
       
       if (D->getDeclContext()->isFunctionOrMethod()) {
@@ -608,8 +660,8 @@
   // 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(),
+                        Enum,
+                        Enumerators.data(), Enumerators.size(),
                         0, 0);
 
   return Enum;
@@ -620,27 +672,12 @@
   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);
+  LocalInstantiationScope Scope(SemaRef);
   TemplateParameterList *TempParams = D->getTemplateParameters();
   TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
   if (!InstParams)
@@ -781,7 +818,7 @@
   
   // Trigger creation of the type for the instantiation.
   SemaRef.Context.getInjectedClassNameType(RecordInst,
-                  Inst->getInjectedClassNameSpecialization(SemaRef.Context));
+                                    Inst->getInjectedClassNameSpecialization());
 
   // Finish handling of friends.
   if (isFriend) {
@@ -791,19 +828,10 @@
   
   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.
+  llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
+  D->getPartialSpecializations(PartialSpecs);
   for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I)
     InstantiateClassTemplatePartialSpecialization(Inst, PartialSpecs[I]);
   
@@ -827,16 +855,7 @@
   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;
+  return InstClassTemplate->findPartialSpecInstantiatedFromMember(D);
 }
 
 Decl *
@@ -845,8 +864,8 @@
   // 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);
-  
+  LocalInstantiationScope Scope(SemaRef);
+
   TemplateParameterList *TempParams = D->getTemplateParameters();
   TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
   if (!InstParams)
@@ -924,7 +943,12 @@
   if (Decl::FriendObjectKind FOK = D->getFriendObjectKind())
     Record->setObjectOfFriendDecl(FOK == Decl::FOK_Declared);
 
-  Record->setAnonymousStructOrUnion(D->isAnonymousStructOrUnion());
+  // Make sure that anonymous structs and unions are recorded.
+  if (D->isAnonymousStructOrUnion()) {
+    Record->setAnonymousStructOrUnion(true);
+    if (Record->getDeclContext()->getLookupContext()->isFunctionOrMethod())
+      SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record);
+  }
 
   Owner->addDecl(Record);
   return Record;
@@ -942,19 +966,16 @@
   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);
+    std::pair<const TemplateArgument *, unsigned> Innermost 
+      = TemplateArgs.getInnermost();
 
-    FunctionTemplateSpecializationInfo *Info
-      = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID,
-                                                                   InsertPos);
+    FunctionDecl *SpecFunc
+      = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
+                                             InsertPos);
 
     // If we already have a function template specialization, return it.
-    if (Info)
-      return Info->Function;
+    if (SpecFunc)
+      return SpecFunc;
   }
 
   bool isFriend;
@@ -964,9 +985,10 @@
     isFriend = (D->getFriendObjectKind() != Decl::FOK_None);
 
   bool MergeWithParentScope = (TemplateParams != 0) ||
+    Owner->isFunctionOrMethod() ||
     !(isa<Decl>(Owner) && 
       cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
-  Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
+  LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
 
   llvm::SmallVector<ParmVarDecl *, 4> Params;
   TypeSourceInfo *TInfo = D->getTypeSourceInfo();
@@ -1021,6 +1043,7 @@
     Params[P]->setOwningFunction(Function);
   Function->setParams(Params.data(), Params.size());
 
+  SourceLocation InstantiateAtPOI;
   if (TemplateParams) {
     // Our resulting instantiation is actually a function template, since we
     // are substituting only the outer template parameters. For example, given
@@ -1052,8 +1075,12 @@
     }
   } else if (FunctionTemplate) {
     // Record this function template specialization.
+    std::pair<const TemplateArgument *, unsigned> Innermost 
+      = TemplateArgs.getInnermost();
     Function->setFunctionTemplateSpecialization(FunctionTemplate,
-                                                &TemplateArgs.getInnermost(),
+                  new (SemaRef.Context) TemplateArgumentList(SemaRef.Context,
+                                                             Innermost.first,
+                                                             Innermost.second),
                                                 InsertPos);
   } else if (isFriend && D->isThisDeclarationADefinition()) {
     // TODO: should we remember this connection regardless of whether
@@ -1139,6 +1166,38 @@
 
     PrincipalDecl->setObjectOfFriendDecl(PrevDecl != 0);
     DC->makeDeclVisibleInContext(PrincipalDecl, /*Recoverable=*/ false);
+    
+    if (!SemaRef.getLangOptions().CPlusPlus0x &&
+        D->isThisDeclarationADefinition()) {
+      // Check for a function body.
+      const FunctionDecl *Definition = 0;
+      if (Function->hasBody(Definition) &&
+          Definition->getTemplateSpecializationKind() == TSK_Undeclared) {
+        SemaRef.Diag(Function->getLocation(), diag::err_redefinition) 
+          << Function->getDeclName();
+        SemaRef.Diag(Definition->getLocation(), diag::note_previous_definition);
+        Function->setInvalidDecl();        
+      } 
+      // Check for redefinitions due to other instantiations of this or
+      // a similar friend function.
+      else for (FunctionDecl::redecl_iterator R = Function->redecls_begin(),
+                                           REnd = Function->redecls_end();
+                R != REnd; ++R) {
+        if (*R != Function && 
+            ((*R)->getFriendObjectKind() != Decl::FOK_None)) {
+          if (const FunctionDecl *RPattern
+              = (*R)->getTemplateInstantiationPattern())
+            if (RPattern->hasBody(RPattern)) {
+              SemaRef.Diag(Function->getLocation(), diag::err_redefinition) 
+                << Function->getDeclName();
+              SemaRef.Diag((*R)->getLocation(), diag::note_previous_definition);
+              Function->setInvalidDecl();
+              break;
+            }
+        }
+      }
+    }
+      
   }
 
   if (Function->isOverloadedOperator() && !DC->isRecord() &&
@@ -1157,19 +1216,16 @@
     // 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);
+    std::pair<const TemplateArgument *, unsigned> Innermost 
+      = TemplateArgs.getInnermost();
 
-    FunctionTemplateSpecializationInfo *Info
-      = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID,
-                                                                   InsertPos);
+    FunctionDecl *SpecFunc
+      = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
+                                             InsertPos);
 
     // If we already have a function template specialization, return it.
-    if (Info)
-      return Info->Function;
+    if (SpecFunc)
+      return SpecFunc;
   }
 
   bool isFriend;
@@ -1181,7 +1237,7 @@
   bool MergeWithParentScope = (TemplateParams != 0) ||
     !(isa<Decl>(Owner) && 
       cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
-  Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
+  LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
 
   llvm::SmallVector<ParmVarDecl *, 4> Params;
   TypeSourceInfo *TInfo = D->getTypeSourceInfo();
@@ -1190,6 +1246,27 @@
     return 0;
   QualType T = TInfo->getType();
 
+  // \brief If the type of this function is not *directly* a function
+  // type, then we're instantiating the a function that was declared
+  // via a typedef, e.g.,
+  //
+  //   typedef int functype(int, int);
+  //   functype func;
+  //
+  // In this case, we'll just go instantiate the ParmVarDecls that we
+  // synthesized in the method declaration.
+  if (!isa<FunctionProtoType>(T)) {
+    assert(!Params.size() && "Instantiating type could not yield parameters");
+    for (unsigned I = 0, N = D->getNumParams(); I != N; ++I) {
+      ParmVarDecl *P = SemaRef.SubstParmVarDecl(D->getParamDecl(I), 
+                                                TemplateArgs);
+      if (!P)
+        return 0;
+
+      Params.push_back(P);
+    }
+  }
+
   NestedNameSpecifier *Qualifier = D->getQualifier();
   if (Qualifier) {
     Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier,
@@ -1217,39 +1294,27 @@
   CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
   CXXMethodDecl *Method = 0;
 
-  DeclarationName Name = D->getDeclName();
+  DeclarationNameInfo NameInfo
+    = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
   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,
+                                        NameInfo, 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(),
+                                       NameInfo, 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,
+                                       NameInfo, T, TInfo,
                                        Conversion->isInlineSpecified(),
                                        Conversion->isExplicit());
   } else {
-    Method = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(),
-                                   D->getDeclName(), T, TInfo,
+    Method = CXXMethodDecl::Create(SemaRef.Context, Record,
+                                   NameInfo, T, TInfo,
                                    D->isStatic(),
                                    D->getStorageClassAsWritten(),
                                    D->isInlineSpecified());
@@ -1284,8 +1349,12 @@
     Method->setDescribedFunctionTemplate(FunctionTemplate);
   } else if (FunctionTemplate) {
     // Record this function template specialization.
+    std::pair<const TemplateArgument *, unsigned> Innermost 
+      = TemplateArgs.getInnermost();
     Method->setFunctionTemplateSpecialization(FunctionTemplate,
-                                              &TemplateArgs.getInnermost(),
+                    new (SemaRef.Context) TemplateArgumentList(SemaRef.Context,
+                                                              Innermost.first,
+                                                              Innermost.second),
                                               InsertPos);
   } else if (!isFriend) {
     // Record that this is an instantiation of a member function.
@@ -1309,8 +1378,8 @@
   if (InitMethodInstantiation(Method, D))
     Method->setInvalidDecl();
 
-  LookupResult Previous(SemaRef, Name, SourceLocation(),
-                        Sema::LookupOrdinaryName, Sema::ForRedeclaration);
+  LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName,
+                        Sema::ForRedeclaration);
 
   if (!FunctionTemplate || TemplateParams || isFriend) {
     SemaRef.LookupQualifiedName(Previous, Record);
@@ -1346,7 +1415,7 @@
     else
       Owner->addDecl(DeclToAdd);
   }
-
+  
   return Method;
 }
 
@@ -1422,7 +1491,7 @@
   if (Invalid)
     Param->setInvalidDecl();
   
-  Param->setDefaultArgument(D->getDefaultArgument());
+  Param->setDefaultArgument(D->getDefaultArgument(), false);
   
   // Introduce this template parameter's instantiation into the instantiation 
   // scope.
@@ -1439,7 +1508,7 @@
   {
     // Perform the actual substitution of template parameters within a new,
     // local instantiation scope.
-    Sema::LocalInstantiationScope Scope(SemaRef);
+    LocalInstantiationScope Scope(SemaRef);
     InstParams = SubstTemplateParams(TempParams);
     if (!InstParams)
       return NULL;
@@ -1450,7 +1519,7 @@
     = TemplateTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
                                        D->getDepth() - 1, D->getPosition(),
                                        D->getIdentifier(), InstParams);
-  Param->setDefaultArgument(D->getDefaultArgument());
+  Param->setDefaultArgument(D->getDefaultArgument(), false);
   
   // Introduce this template parameter's instantiation into the instantiation 
   // scope.
@@ -1475,22 +1544,22 @@
 
 Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {
   // The nested name specifier is non-dependent, so no transformation
-  // is required.
+  // is required. The same holds for the name info.
+  DeclarationNameInfo NameInfo = D->getNameInfo();
 
   // 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);
+  LookupResult Prev(SemaRef, NameInfo, Sema::LookupUsingDeclName,
+                    Sema::ForRedeclaration);
 
   UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner,
-                                       D->getLocation(),
                                        D->getNestedNameRange(),
                                        D->getUsingLocation(),
                                        D->getTargetNestedNameDecl(),
-                                       D->getDeclName(),
+                                       NameInfo,
                                        D->isTypeName());
 
   CXXScopeSpec SS;
@@ -1566,10 +1635,12 @@
   SS.setRange(D->getTargetNestedNameRange());
   SS.setScopeRep(NNS);
 
+  // Since NameInfo refers to a typename, it cannot be a C++ special name.
+  // Hence, no tranformation is required for it.
+  DeclarationNameInfo NameInfo(D->getDeclName(), D->getLocation());
   NamedDecl *UD =
     SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
-                                  D->getUsingLoc(), SS, D->getLocation(),
-                                  D->getDeclName(), 0,
+                                  D->getUsingLoc(), SS, NameInfo, 0,
                                   /*instantiation*/ true,
                                   /*typename*/ true, D->getTypenameLoc());
   if (UD)
@@ -1591,10 +1662,12 @@
   SS.setRange(D->getTargetNestedNameRange());
   SS.setScopeRep(NNS);
 
+  DeclarationNameInfo NameInfo
+    = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
+
   NamedDecl *UD =
     SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
-                                  D->getUsingLoc(), SS, D->getLocation(),
-                                  D->getDeclName(), 0,
+                                  D->getUsingLoc(), SS, NameInfo, 0,
                                   /*instantiation*/ true,
                                   /*typename*/ false, SourceLocation());
   if (UD)
@@ -1635,13 +1708,8 @@
   }
 
   // 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);
+  if (Invalid)
     return NULL;
-  }
 
   TemplateParameterList *InstL
     = TemplateParameterList::Create(SemaRef.Context, L->getTemplateLoc(),
@@ -1667,7 +1735,7 @@
   // Create a local instantiation scope for this class template partial
   // specialization, which will contain the instantiations of the template
   // parameters.
-  Sema::LocalInstantiationScope Scope(SemaRef);
+  LocalInstantiationScope Scope(SemaRef);
   
   // Substitute into the template parameters of the class template partial
   // specialization.
@@ -1704,15 +1772,10 @@
 
   // 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);
+    = ClassTemplate->findPartialSpecialization(Converted.getFlatArguments(),
+                                                Converted.flatSize(), InsertPos);
   
   // Build the canonical type that describes the converted template
   // arguments of the class template partial specialization.
@@ -1761,14 +1824,17 @@
   
   // Create the class template partial specialization declaration.
   ClassTemplatePartialSpecializationDecl *InstPartialSpec
-    = ClassTemplatePartialSpecializationDecl::Create(SemaRef.Context, Owner, 
+    = ClassTemplatePartialSpecializationDecl::Create(SemaRef.Context, 
+                                                     PartialSpec->getTagKind(),
+                                                     Owner, 
                                                      PartialSpec->getLocation(), 
                                                      InstParams,
                                                      ClassTemplate, 
                                                      Converted,
                                                      InstTemplateArgs,
                                                      CanonType,
-                                                     0);
+                                                     0,
+                             ClassTemplate->getNextPartialSpecSequenceNumber());
   // Substitute the nested name specifier, if any.
   if (SubstQualifier(PartialSpec, InstPartialSpec))
     return 0;
@@ -1778,8 +1844,7 @@
   
   // Add this partial specialization to the set of class template partial
   // specializations.
-  ClassTemplate->getPartialSpecializations().InsertNode(InstPartialSpec,
-                                                        InsertPos);
+  ClassTemplate->AddPartialSpecialization(InstPartialSpec, InsertPos);
   return false;
 }
 
@@ -1798,22 +1863,33 @@
 
   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));
+    TypeLoc OldTL = OldTInfo->getTypeLoc();
+    if (FunctionProtoTypeLoc *OldProtoLoc
+                                  = dyn_cast<FunctionProtoTypeLoc>(&OldTL)) {
+      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) {
+        // FIXME: Variadic templates will break this.
+        Params.push_back(NewProtoLoc->getArg(i));
+        SemaRef.CurrentInstantiationScope->InstantiatedLocal(
+                                                        OldProtoLoc->getArg(i),
+                                                        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);
+    if (FunctionProtoTypeLoc *OldProtoLoc
+                                    = dyn_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;
@@ -1889,6 +1965,8 @@
                                                  Proto->getExtInfo()));
   }
 
+  SemaRef.InstantiateAttrs(TemplateArgs, Tmpl, New);
+
   return false;
 }
 
@@ -1934,15 +2012,13 @@
                                          FunctionDecl *Function,
                                          bool Recursive,
                                          bool DefinitionRequired) {
-  if (Function->isInvalidDecl())
+  if (Function->isInvalidDecl() || Function->hasBody())
     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;
@@ -1963,8 +2039,13 @@
       if (PatternDecl)
         Diag(PatternDecl->getLocation(), 
              diag::note_explicit_instantiation_here);
+      Function->setInvalidDecl();
+    } else if (Function->getTemplateSpecializationKind()
+                 == TSK_ExplicitInstantiationDefinition) {
+      PendingInstantiations.push_back(
+        std::make_pair(Function, PointOfInstantiation));
     }
-      
+
     return;
   }
 
@@ -1979,16 +2060,18 @@
 
   InstantiatingTemplate Inst(*this, PointOfInstantiation, Function);
   if (Inst)
-    return;
-
+    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;
+  std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
   if (Recursive)
-    PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+    PendingInstantiations.swap(SavedPendingInstantiations);
 
-  ActOnStartOfFunctionDef(0, DeclPtrTy::make(Function));
+  EnterExpressionEvaluationContext EvalContext(*this, 
+                                               Sema::PotentiallyEvaluated);
+  ActOnStartOfFunctionDef(0, Function);
 
   // Introduce a new scope where local variable instantiations will be
   // recorded, unless we're actually a member function within a local
@@ -2001,10 +2084,14 @@
   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));
+  // instantiation scope, and set the parameter names to those used
+  // in the template.
+  for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I) {
+    const ParmVarDecl *PatternParam = PatternDecl->getParamDecl(I);
+    ParmVarDecl *FunctionParam = Function->getParamDecl(I);
+    FunctionParam->setDeclName(PatternParam->getDeclName());
+    Scope.InstantiatedLocal(PatternParam, FunctionParam);
+  }
 
   // Enter the scope of this instantiation. We don't use
   // PushDeclContext because we don't have a scope.
@@ -2012,7 +2099,7 @@
   CurContext = Function;
 
   MultiLevelTemplateArgumentList TemplateArgs =
-    getTemplateInstantiationArgs(Function);
+    getTemplateInstantiationArgs(Function, 0, false, PatternDecl);
 
   // If this is a constructor, instantiate the member initializers.
   if (const CXXConstructorDecl *Ctor =
@@ -2022,12 +2109,12 @@
   }
 
   // Instantiate the function body.
-  OwningStmtResult Body = SubstStmt(Pattern, TemplateArgs);
+  StmtResult Body = SubstStmt(Pattern, TemplateArgs);
 
   if (Body.isInvalid())
     Function->setInvalidDecl();
   
-  ActOnFinishFunctionBody(DeclPtrTy::make(Function), move(Body),
+  ActOnFinishFunctionBody(Function, Body.get(),
                           /*IsInstantiation=*/true);
 
   PerformDependentDiagnostics(PatternDecl, TemplateArgs);
@@ -2039,16 +2126,16 @@
 
   // This class may have local implicit instantiations that need to be
   // instantiation within this scope.
-  PerformPendingImplicitInstantiations(/*LocalOnly=*/true);
+  PerformPendingInstantiations(/*LocalOnly=*/true);
   Scope.Exit();
 
   if (Recursive) {
     // Instantiate any pending implicit instantiations found during the
     // instantiation of this template.
-    PerformPendingImplicitInstantiations();
+    PerformPendingInstantiations();
 
     // Restore the set of pending implicit instantiations.
-    PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+    PendingInstantiations.swap(SavedPendingInstantiations);
   }
 }
 
@@ -2093,8 +2180,12 @@
            diag::err_explicit_instantiation_undefined_member)
         << 2 << Var->getDeclName() << Var->getDeclContext();
       Diag(Def->getLocation(), diag::note_explicit_instantiation_here);
-    }    
-    
+    } else if (Var->getTemplateSpecializationKind()
+                 == TSK_ExplicitInstantiationDefinition) {
+      PendingInstantiations.push_back(
+        std::make_pair(Var, PointOfInstantiation));
+    }
+
     return;
   }
 
@@ -2117,9 +2208,9 @@
   // 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;
+  std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
   if (Recursive)
-    PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+    PendingInstantiations.swap(SavedPendingInstantiations);
 
   // Enter the scope of this instantiation. We don't use
   // PushDeclContext because we don't have a scope.
@@ -2143,10 +2234,10 @@
   if (Recursive) {
     // Instantiate any pending implicit instantiations found during the
     // instantiation of this template.
-    PerformPendingImplicitInstantiations();
+    PerformPendingInstantiations();
 
     // Restore the set of pending implicit instantiations.
-    PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+    PendingInstantiations.swap(SavedPendingInstantiations);
   }
 }
 
@@ -2165,7 +2256,7 @@
     CXXBaseOrMemberInitializer *Init = *Inits;
 
     SourceLocation LParenLoc, RParenLoc;
-    ASTOwningVector<&ActionBase::DeleteExpr> NewArgs(*this);
+    ASTOwningVector<Expr*> NewArgs(*this);
     llvm::SmallVector<SourceLocation, 4> CommaLocs;
 
     // Instantiate the initializer.
@@ -2224,7 +2315,7 @@
   }
 
   // Assign all the initializers to the new constructor.
-  ActOnMemInitializers(DeclPtrTy::make(New),
+  ActOnMemInitializers(New,
                        /*FIXME: ColonLoc */
                        SourceLocation(),
                        NewInits.data(), NewInits.size(),
@@ -2471,7 +2562,7 @@
   DeclContext *ParentDC = D->getDeclContext();
   if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
       isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||
-      ParentDC->isFunctionOrMethod()) {
+      (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext())) {
     // D is a local of some kind. Look into the map of local
     // declarations to their instantiations.
     return cast<NamedDecl>(CurrentInstantiationScope->getInstantiationOf(D));
@@ -2490,7 +2581,7 @@
     ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate();
     
     if (ClassTemplate) {
-      T = ClassTemplate->getInjectedClassNameSpecialization(Context);
+      T = ClassTemplate->getInjectedClassNameSpecialization();
     } else if (ClassTemplatePartialSpecializationDecl *PartialSpec
                  = dyn_cast<ClassTemplatePartialSpecializationDecl>(Record)) {
       ClassTemplate = PartialSpec->getSpecializedTemplate();
@@ -2612,14 +2703,14 @@
 
 /// \brief Performs template instantiation for all implicit template
 /// instantiations we have seen until this point.
-void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
+void Sema::PerformPendingInstantiations(bool LocalOnly) {
   while (!PendingLocalImplicitInstantiations.empty() ||
-         (!LocalOnly && !PendingImplicitInstantiations.empty())) {
+         (!LocalOnly && !PendingInstantiations.empty())) {
     PendingImplicitInstantiation Inst;
 
     if (PendingLocalImplicitInstantiations.empty()) {
-      Inst = PendingImplicitInstantiations.front();
-      PendingImplicitInstantiations.pop_front();
+      Inst = PendingInstantiations.front();
+      PendingInstantiations.pop_front();
     } else {
       Inst = PendingLocalImplicitInstantiations.front();
       PendingLocalImplicitInstantiations.pop_front();
@@ -2627,13 +2718,12 @@
 
     // 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);
+      PrettyDeclStackTraceEntry CrashInfo(*this, Function, SourceLocation(),
+                                          "instantiating function definition");
+      bool DefinitionRequired = Function->getTemplateSpecializationKind() ==
+                                TSK_ExplicitInstantiationDefinition;
+      InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true,
+                                    DefinitionRequired);
       continue;
     }
 
@@ -2652,20 +2742,24 @@
     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.
+      continue;  // No longer need to instantiate this type.
+    case TSK_ExplicitInstantiationDefinition:
+      // We only need an instantiation if the pending instantiation *is* the
+      // explicit instantiation.
+      if (Var != Var->getMostRecentDeclaration()) continue;
     case TSK_ImplicitInstantiation:
       break;
     }
 
-    PrettyStackTraceActionsDecl CrashInfo(DeclPtrTy::make(Var),
-                                          Var->getLocation(), *this,
-                                          Context.getSourceManager(),
-                                          "instantiating static data member "
-                                          "definition");
+    PrettyDeclStackTraceEntry CrashInfo(*this, Var, Var->getLocation(),
+                                        "instantiating static data member "
+                                        "definition");
 
-    InstantiateStaticDataMemberDefinition(/*FIXME:*/Inst.second, Var, true);
+    bool DefinitionRequired = Var->getTemplateSpecializationKind() ==
+                              TSK_ExplicitInstantiationDefinition;
+    InstantiateStaticDataMemberDefinition(/*FIXME:*/Inst.second, Var, true,
+                                          DefinitionRequired);
   }
 }
 
@@ -2682,3 +2776,4 @@
     }
   }
 }
+
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 4f1bea1..8988de8 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -11,7 +11,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Template.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclObjC.h"
@@ -20,7 +21,8 @@
 #include "clang/AST/TypeLocVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Sema/DeclSpec.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/ErrorHandling.h"
 using namespace clang;
@@ -81,9 +83,12 @@
                                   DelayedAttributeSet &Attrs) {
   for (DelayedAttributeSet::iterator I = Attrs.begin(),
          E = Attrs.end(); I != E; ++I)
-    if (ProcessFnAttr(S, Type, *I->first))
+    if (ProcessFnAttr(S, Type, *I->first)) {
       S.Diag(I->first->getLoc(), diag::warn_function_attribute_wrong_type)
         << I->first->getName() << I->second;
+      // Avoid any further processing of this attribute.
+      I->first->setInvalid();
+    }
   Attrs.clear();
 }
 
@@ -92,6 +97,8 @@
          E = Attrs.end(); I != E; ++I) {
     S.Diag(I->first->getLoc(), diag::warn_function_attribute_wrong_type)
       << I->first->getName() << I->second;
+    // Avoid any further processing of this attribute.
+    I->first->setInvalid();
   }
   Attrs.clear();
 }
@@ -157,9 +164,10 @@
   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());
+      Result = Context.getObjCObjectType(Context.ObjCBuiltinIdTy,
+                                         (ObjCProtocolDecl**)PQ,
+                                         DS.getNumProtocolQualifiers());
+      Result = Context.getObjCObjectPointerType(Result);
       break;
     }
     
@@ -258,8 +266,7 @@
   case DeclSpec::TST_enum:
   case DeclSpec::TST_union:
   case DeclSpec::TST_struct: {
-    TypeDecl *D 
-      = dyn_cast_or_null<TypeDecl>(static_cast<Decl *>(DS.getTypeRep()));
+    TypeDecl *D = dyn_cast_or_null<TypeDecl>(DS.getRepAsDecl());
     if (!D) {
       // This can happen in C++ with ambiguous lookups.
       Result = Context.IntTy;
@@ -278,12 +285,11 @@
 
     // 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);
+      ElaboratedTypeKeyword Keyword
+        = ElaboratedType::getKeywordForTypeSpec(DS.getTypeSpecType());
+      Result = TheSema.getElaboratedType(Keyword, DS.getTypeSpecScope(),
+                                         Result);
     }
-
     if (D->isInvalidDecl())
       TheDeclarator.setInvalidType(true);
     break;
@@ -292,31 +298,33 @@
     assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
            DS.getTypeSpecSign() == 0 &&
            "Can't handle qualifiers on typedef names yet!");
-    Result = TheSema.GetTypeFromParser(DS.getTypeRep());
+    Result = TheSema.GetTypeFromParser(DS.getRepAsType());
+    if (Result.isNull())
+      TheDeclarator.setInvalidType(true);
+    else if (DeclSpec::ProtocolQualifierListTy PQ
+               = DS.getProtocolQualifiers()) {
+      if (const ObjCObjectType *ObjT = Result->getAs<ObjCObjectType>()) {
+        // Silently drop any existing protocol qualifiers.
+        // TODO: determine whether that's the right thing to do.
+        if (ObjT->getNumProtocols())
+          Result = ObjT->getBaseType();
 
-    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())
+        if (DS.getNumProtocolQualifiers())
+          Result = Context.getObjCObjectType(Result,
+                                             (ObjCProtocolDecl**) PQ,
+                                             DS.getNumProtocolQualifiers());
+      } else if (Result->isObjCIdType()) {
         // id<protocol-list>
-        Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy,
-                        (ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers());
-      else if (Result->isObjCClassType()) {
+        Result = Context.getObjCObjectType(Context.ObjCBuiltinIdTy,
+                                           (ObjCProtocolDecl**) PQ,
+                                           DS.getNumProtocolQualifiers());
+        Result = Context.getObjCObjectPointerType(Result);
+      } else if (Result->isObjCClassType()) {
         // Class<protocol-list>
-        Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinClassTy,
-                        (ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers());
+        Result = Context.getObjCObjectType(Context.ObjCBuiltinClassTy,
+                                           (ObjCProtocolDecl**) PQ,
+                                           DS.getNumProtocolQualifiers());
+        Result = Context.getObjCObjectPointerType(Result);
       } else {
         TheSema.Diag(DeclLoc, diag::err_invalid_protocol_qualifiers)
           << DS.getSourceRange();
@@ -329,13 +337,13 @@
   }
   case DeclSpec::TST_typeofType:
     // FIXME: Preserve type source info.
-    Result = TheSema.GetTypeFromParser(DS.getTypeRep());
+    Result = TheSema.GetTypeFromParser(DS.getRepAsType());
     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());
+    Expr *E = DS.getRepAsExpr();
     assert(E && "Didn't get an expression for typeof?");
     // TypeQuals handled by caller.
     Result = TheSema.BuildTypeofExprType(E);
@@ -346,7 +354,7 @@
     break;
   }
   case DeclSpec::TST_decltype: {
-    Expr *E = static_cast<Expr *>(DS.getTypeRep());
+    Expr *E = DS.getRepAsExpr();
     assert(E && "Didn't get an expression for decltype?");
     // TypeQuals handled by caller.
     Result = TheSema.BuildDecltypeType(E);
@@ -376,8 +384,12 @@
   } 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());
+    VectorType::AltiVecSpecific AltiVecSpec = VectorType::AltiVec;
+    if (DS.isTypeAltiVecPixel())
+      AltiVecSpec = VectorType::Pixel;
+    else if (DS.isTypeAltiVecBool())
+      AltiVecSpec = VectorType::Bool;
+    Result = Context.getVectorType(Result, 128/typeSize, AltiVecSpec);
   }
 
   assert(DS.getTypeSpecComplex() != DeclSpec::TSC_imaginary &&
@@ -465,12 +477,49 @@
   return "type name";
 }
 
+QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc,
+                                  Qualifiers Qs) {
+  // Enforce C99 6.7.3p2: "Types other than pointer types derived from
+  // object or incomplete types shall not be restrict-qualified."
+  if (Qs.hasRestrict()) {
+    unsigned DiagID = 0;
+    QualType ProblemTy;
+
+    const Type *Ty = T->getCanonicalTypeInternal().getTypePtr();
+    if (const ReferenceType *RTy = dyn_cast<ReferenceType>(Ty)) {
+      if (!RTy->getPointeeType()->isIncompleteOrObjectType()) {
+        DiagID = diag::err_typecheck_invalid_restrict_invalid_pointee;
+        ProblemTy = T->getAs<ReferenceType>()->getPointeeType();
+      }
+    } else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
+      if (!PTy->getPointeeType()->isIncompleteOrObjectType()) {
+        DiagID = diag::err_typecheck_invalid_restrict_invalid_pointee;
+        ProblemTy = T->getAs<PointerType>()->getPointeeType();
+      }
+    } else if (const MemberPointerType *PTy = dyn_cast<MemberPointerType>(Ty)) {
+      if (!PTy->getPointeeType()->isIncompleteOrObjectType()) {
+        DiagID = diag::err_typecheck_invalid_restrict_invalid_pointee;
+        ProblemTy = T->getAs<PointerType>()->getPointeeType();
+      }      
+    } else if (!Ty->isDependentType()) {
+      // FIXME: this deserves a proper diagnostic
+      DiagID = diag::err_typecheck_invalid_restrict_invalid_pointee;
+      ProblemTy = T;
+    }
+
+    if (DiagID) {
+      Diag(Loc, DiagID) << ProblemTy;
+      Qs.removeRestrict();
+    }
+  }
+
+  return Context.getQualifiedType(T, Qs);
+}
+
 /// \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.
@@ -480,7 +529,7 @@
 ///
 /// \returns A suitable pointer type, if there are no
 /// errors. Otherwise, returns a NULL type.
-QualType Sema::BuildPointerType(QualType T, unsigned Quals,
+QualType Sema::BuildPointerType(QualType T,
                                 SourceLocation Loc, DeclarationName Entity) {
   if (T->isReferenceType()) {
     // C++ 8.3.2p4: There shall be no ... pointers to references ...
@@ -489,28 +538,16 @@
     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");
+  assert(!T->isObjCObjectType() && "Should build ObjCObjectPointerType");
 
   // Build the pointer type.
-  return Context.getQualifiedType(Context.getPointerType(T), Qs);
+  return Context.getPointerType(T);
 }
 
 /// \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.
@@ -521,10 +558,8 @@
 /// \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,
+                                  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
@@ -555,31 +590,10 @@
     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);
+    return Context.getLValueReferenceType(T, SpelledAsLValue);
+  return Context.getRValueReferenceType(T);
 }
 
 /// \brief Build an array type.
@@ -590,9 +604,6 @@
 ///
 /// \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.
@@ -607,15 +618,31 @@
                               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) {
+    // C++ [dcl.array]p1:
+    //   T is called the array element type; this type shall not be a reference
+    //   type, the (possibly cv-qualified) type void, a function type or an 
+    //   abstract class type.
+    //
+    // Note: function types are handled in the common path with C.
+    if (T->isReferenceType()) {
+      Diag(Loc, diag::err_illegal_decl_array_of_references)
+      << getPrintableNameForEntity(Entity) << T;
+      return QualType();
+    }
+    
     if (T->isVoidType()) {
       Diag(Loc, diag::err_illegal_decl_array_incomplete_type) << T;
       return QualType();
     }
+    
+    if (RequireNonAbstractType(Brackets.getBegin(), T, 
+                               diag::err_array_of_abstract_type))
+      return QualType();
+    
   } else {
+    // 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]())
     if (RequireCompleteType(Loc, T,
                             diag::err_illegal_decl_array_incomplete_type))
       return QualType();
@@ -627,13 +654,6 @@
     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);
@@ -645,7 +665,7 @@
     // 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()) {
+  } else if (T->isObjCObjectType()) {
     Diag(Loc, diag::err_objc_array_of_interfaces) << T;
     return QualType();
   }
@@ -655,16 +675,15 @@
       !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);
+  llvm::APSInt ConstVal(Context.getTypeSize(Context.getSizeType()));
   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()) {
+  } else if (ArraySize->isTypeDependent() || ArraySize->isValueDependent()) {
     T = Context.getDependentSizedArrayType(T, ArraySize, ASM, Quals, Brackets);
   } else if (!ArraySize->isIntegerConstantExpr(ConstVal, Context) ||
              (!T->isDependentType() && !T->isIncompleteType() &&
@@ -688,16 +707,38 @@
            isSFINAEContext()? diag::err_typecheck_zero_array_size
                             : diag::ext_typecheck_zero_array_size)
         << ArraySize->getSourceRange();
+    } else if (!T->isDependentType() && !T->isVariablyModifiedType() && 
+               !T->isIncompleteType()) {
+      // Is the array too large?      
+      unsigned ActiveSizeBits
+        = ConstantArrayType::getNumAddressingBits(Context, T, ConstVal);
+      if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context))
+        Diag(ArraySize->getLocStart(), diag::err_array_too_large)
+          << ConstVal.toString(10)
+          << 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)
+    if (T->isVariableArrayType()) {
+      // Prohibit the use of non-POD types in VLAs.
+      if (!T->isDependentType() && 
+          !Context.getBaseElementType(T)->isPODType()) {
+        Diag(Loc, diag::err_vla_non_pod)
+          << Context.getBaseElementType(T);
+        return QualType();
+      } 
+      // Prohibit the use of VLAs during template argument deduction.
+      else if (isSFINAEContext()) {
+        Diag(Loc, diag::err_vla_in_sfinae);
+        return QualType();
+      }
+      // Just extwarn about VLAs.
+      else
+        Diag(Loc, 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);
@@ -709,11 +750,8 @@
 /// \brief Build an ext-vector type.
 ///
 /// Run the required checks for the extended vector type.
-QualType Sema::BuildExtVectorType(QualType T, ExprArg ArraySize,
+QualType Sema::BuildExtVectorType(QualType T, Expr *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() &&
@@ -722,11 +760,11 @@
     return QualType();
   }
 
-  if (!Arg->isTypeDependent() && !Arg->isValueDependent()) {
+  if (!ArraySize->isTypeDependent() && !ArraySize->isValueDependent()) {
     llvm::APSInt vecSize(32);
-    if (!Arg->isIntegerConstantExpr(vecSize, Context)) {
+    if (!ArraySize->isIntegerConstantExpr(vecSize, Context)) {
       Diag(AttrLoc, diag::err_attribute_argument_not_int)
-      << "ext_vector_type" << Arg->getSourceRange();
+        << "ext_vector_type" << ArraySize->getSourceRange();
       return QualType();
     }
 
@@ -736,7 +774,7 @@
 
     if (vectorSize == 0) {
       Diag(AttrLoc, diag::err_attribute_zero_size)
-      << Arg->getSourceRange();
+      << ArraySize->getSourceRange();
       return QualType();
     }
 
@@ -744,8 +782,7 @@
       return Context.getExtVectorType(T, vectorSize);
   }
 
-  return Context.getDependentSizedExtVectorType(T, ArraySize.takeAs<Expr>(),
-                                                AttrLoc);
+  return Context.getDependentSizedExtVectorType(T, ArraySize, AttrLoc);
 }
 
 /// \brief Build a function type.
@@ -781,13 +818,14 @@
                                  QualType *ParamTypes,
                                  unsigned NumParamTypes,
                                  bool Variadic, unsigned Quals,
-                                 SourceLocation Loc, DeclarationName Entity) {
+                                 SourceLocation Loc, DeclarationName Entity,
+                                 const FunctionType::ExtInfo &Info) {
   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]);
@@ -803,8 +841,7 @@
     return QualType();
 
   return Context.getFunctionType(T, ParamTypes, NumParamTypes, Variadic,
-                                 Quals, false, false, 0, 0,
-                                 FunctionType::ExtInfo());
+                                 Quals, false, false, 0, 0, Info);
 }
 
 /// \brief Build a member pointer type \c T Class::*.
@@ -818,10 +855,8 @@
 /// \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,
+                                      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)) {
@@ -835,7 +870,7 @@
     T = Context.getCanonicalType(T);
   }
 
-  // C++ 8.3.3p3: A pointer to member shall not pointer to ... a member
+  // C++ 8.3.3p3: A pointer to member shall not point to ... a member
   //   with reference type, or "cv void."
   if (T->isReferenceType()) {
     Diag(Loc, diag::err_illegal_decl_mempointer_to_reference)
@@ -849,24 +884,20 @@
     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);
+  // In the Microsoft ABI, the class is allowed to be an incomplete
+  // type. In such cases, the compiler makes a worst-case assumption.
+  // We make no such assumption right now, so emit an error if the
+  // class isn't a complete type.
+  if (Context.Target.getCXXABI() == CXXABI_Microsoft &&
+      RequireCompleteType(Loc, Class, diag::err_incomplete_type))
+    return QualType();
+
+  return Context.getMemberPointerType(T, Class.getTypePtr());
 }
 
 /// \brief Build a block pointer type.
@@ -884,7 +915,7 @@
 ///
 /// \returns A suitable block pointer type, if there are no
 /// errors. Otherwise, returns a NULL type.
-QualType Sema::BuildBlockPointerType(QualType T, unsigned CVR,
+QualType Sema::BuildBlockPointerType(QualType T, 
                                      SourceLocation Loc,
                                      DeclarationName Entity) {
   if (!T->isFunctionType()) {
@@ -892,12 +923,11 @@
     return QualType();
   }
 
-  Qualifiers Quals = Qualifiers::fromCVRMask(CVR);
-  return Context.getQualifiedType(Context.getBlockPointerType(T), Quals);
+  return Context.getBlockPointerType(T);
 }
 
-QualType Sema::GetTypeFromParser(TypeTy *Ty, TypeSourceInfo **TInfo) {
-  QualType QT = QualType::getFromOpaquePtr(Ty);
+QualType Sema::GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo) {
+  QualType QT = Ty.get();
   if (QT.isNull()) {
     if (TInfo) *TInfo = 0;
     return QualType();
@@ -919,9 +949,11 @@
 /// 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) {
+///
+/// The result of this call will never be null, but the associated
+/// type may be a null type if there's an unrecoverable error.
+TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
+                                           TagDecl **OwnedDecl) {
   // Determine the type of the declarator. Not all forms of declarator
   // have a type.
   QualType T;
@@ -937,7 +969,7 @@
     T = ConvertDeclSpecToType(*this, D, FnAttrsFromDeclSpec);
     
     if (!D.isInvalidType() && D.getDeclSpec().isTypeSpecOwned()) {
-      TagDecl* Owned = cast<TagDecl>((Decl *)D.getDeclSpec().getTypeRep());
+      TagDecl* Owned = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
       // 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() ||
@@ -952,22 +984,18 @@
     // 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);
+                          &ReturnTypeInfo);
     break;
   }
   
   if (T.isNull())
-    return T;
+    return Context.getNullTypeSourceInfo();
 
   if (T == Context.UndeducedAutoTy) {
     int Error = -1;
@@ -981,10 +1009,10 @@
       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;
+      case TTK_Enum: assert(0 && "unhandled tag kind"); break;
+      case TTK_Struct: Error = 1; /* Struct member */ break;
+      case TTK_Union:  Error = 2; /* Union member */ break;
+      case TTK_Class:  Error = 3; /* Class member */ break;
       }
       break;
     case Declarator::CXXCatchContext:
@@ -1031,8 +1059,9 @@
       if (!LangOpts.Blocks)
         Diag(DeclType.Loc, diag::err_blocks_disable);
 
-      T = BuildBlockPointerType(T, DeclType.Cls.TypeQuals, D.getIdentifierLoc(),
-                                Name);
+      T = BuildBlockPointerType(T, D.getIdentifierLoc(), Name);
+      if (DeclType.Cls.TypeQuals)
+        T = BuildQualifiedType(T, DeclType.Loc, DeclType.Cls.TypeQuals);
       break;
     case DeclaratorChunk::Pointer:
       // Verify that we're not building a pointer to pointer to function with
@@ -1042,21 +1071,17 @@
         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);
+      if (getLangOptions().ObjC1 && T->getAs<ObjCObjectType>()) {
+        T = Context.getObjCObjectPointerType(T);
+        if (DeclType.Ptr.TypeQuals)
+          T = BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals);
         break;
       }
-      T = BuildPointerType(T, DeclType.Ptr.TypeQuals, DeclType.Loc, Name);
+      T = BuildPointerType(T, DeclType.Loc, Name);
+      if (DeclType.Ptr.TypeQuals)
+        T = BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals);
       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)) {
@@ -1064,8 +1089,11 @@
         D.setInvalidType(true);
         // Build the type anyway.
       }
-      T = BuildReferenceType(T, DeclType.Ref.LValueRef, Quals,
-                             DeclType.Loc, Name);
+      T = BuildReferenceType(T, DeclType.Ref.LValueRef, DeclType.Loc, Name);
+
+      Qualifiers Quals;
+      if (DeclType.Ref.HasRestrict)
+        T = BuildQualifiedType(T, DeclType.Loc, Qualifiers::Restrict);
       break;
     }
     case DeclaratorChunk::Array: {
@@ -1115,10 +1143,52 @@
         D.setInvalidType(true);
       }
 
+      // cv-qualifiers on return types are pointless except when the type is a
+      // class type in C++.
+      if (T.getCVRQualifiers() && D.getDeclSpec().getTypeQualifiers() &&
+          (!getLangOptions().CPlusPlus ||
+           (!T->isDependentType() && !T->isRecordType()))) {
+        unsigned Quals = D.getDeclSpec().getTypeQualifiers();
+        std::string QualStr;
+        unsigned NumQuals = 0;
+        SourceLocation Loc;
+        if (Quals & Qualifiers::Const) {
+          Loc = D.getDeclSpec().getConstSpecLoc();
+          ++NumQuals;
+          QualStr = "const";
+        }
+        if (Quals & Qualifiers::Volatile) {
+          if (NumQuals == 0) {
+            Loc = D.getDeclSpec().getVolatileSpecLoc();
+            QualStr = "volatile";
+          } else
+            QualStr += " volatile";
+          ++NumQuals;
+        }
+        if (Quals & Qualifiers::Restrict) {
+          if (NumQuals == 0) {
+            Loc = D.getDeclSpec().getRestrictSpecLoc();
+            QualStr = "restrict";
+          } else
+            QualStr += " restrict";
+          ++NumQuals;
+        }
+        assert(NumQuals > 0 && "No known qualifiers?");
+            
+        SemaDiagnosticBuilder DB = Diag(Loc, diag::warn_qual_return_type);
+        DB << QualStr << NumQuals;
+        if (Quals & Qualifiers::Const)
+          DB << FixItHint::CreateRemoval(D.getDeclSpec().getConstSpecLoc());
+        if (Quals & Qualifiers::Volatile)
+          DB << FixItHint::CreateRemoval(D.getDeclSpec().getVolatileSpecLoc());
+        if (Quals & Qualifiers::Restrict)
+          DB << FixItHint::CreateRemoval(D.getDeclSpec().getRestrictSpecLoc());
+      }
+      
       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());
+        TagDecl *Tag = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
         if (Tag->isDefinition())
           Diag(Tag->getLocation(), diag::err_type_defined_in_result_type)
             << Context.getTypeDeclType(Tag);
@@ -1130,29 +1200,14 @@
           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.
+      if (!FTI.NumArgs && !FTI.isVariadic && !getLangOptions().CPlusPlus) {
+        // Simple void foo(), where the incoming T is the result type.
+        T = Context.getFunctionNoProtoType(T);
+      } else {
+        // We allow a zero-parameter variadic function in C if the
+        // function is marked with the "overloadable" attribute. Scan
+        // for this attribute now.
+        if (!FTI.NumArgs && FTI.isVariadic && !getLangOptions().CPlusPlus) {
           bool Overloadable = false;
           for (const AttributeList *Attrs = D.getAttributes();
                Attrs; Attrs = Attrs->getNext()) {
@@ -1164,25 +1219,23 @@
 
           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 {
+
+        if (FTI.NumArgs && 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);
+          break;
+        }
+
         // Otherwise, we have a function with an argument list that is
         // potentially variadic.
         llvm::SmallVector<QualType, 16> ArgTys;
+        ArgTys.reserve(FTI.NumArgs);
 
         for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
-          ParmVarDecl *Param =
-            cast<ParmVarDecl>(FTI.ArgInfo[i].Param.getAs<Decl>());
+          ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
           QualType ArgTy = Param->getType();
           assert(!ArgTy.isNull() && "Couldn't parse type?");
 
@@ -1254,27 +1307,20 @@
       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.
+      CXXScopeSpec &SS = DeclType.Mem.Scope();
       QualType ClsType;
-      if (DeclType.Mem.Scope().isInvalid()) {
+      if (SS.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()))) {
+      } else if (isDependentScopeSpecifier(SS) ||
+                 dyn_cast_or_null<CXXRecordDecl>(computeDeclContext(SS))) {
         NestedNameSpecifier *NNS
-          = (NestedNameSpecifier *)DeclType.Mem.Scope().getScopeRep();
+          = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
         NestedNameSpecifier *NNSPrefix = NNS->getPrefix();
         switch (NNS->getKind()) {
         case NestedNameSpecifier::Identifier:
-          ClsType = Context.getDependentNameType(ETK_None, NNSPrefix, 
+          ClsType = Context.getDependentNameType(ETK_None, NNSPrefix,
                                                  NNS->getAsIdentifier());
           break;
 
@@ -1282,12 +1328,16 @@
         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);
+          // Note: if NNS is dependent, then its prefix (if any) is already
+          // included in ClsType; this does not hold if the NNS is
+          // nondependent: in this case (if there is indeed a prefix)
+          // ClsType needs to be wrapped into an elaborated type.
+          if (NNSPrefix && !NNS->isDependent())
+            ClsType = Context.getElaboratedType(ETK_None, NNSPrefix, ClsType);
           break;
         }
       } else {
@@ -1299,11 +1349,12 @@
       }
 
       if (!ClsType.isNull())
-        T = BuildMemberPointerType(T, ClsType, DeclType.Mem.TypeQuals,
-                                   DeclType.Loc, D.getIdentifier());
+        T = BuildMemberPointerType(T, ClsType, DeclType.Loc, D.getIdentifier());
       if (T.isNull()) {
         T = Context.IntTy;
         D.setInvalidType(true);
+      } else if (DeclType.Mem.TypeQuals) {
+        T = BuildQualifiedType(T, DeclType.Loc, DeclType.Mem.TypeQuals);
       }
       break;
     }
@@ -1328,18 +1379,19 @@
     // 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.
+    bool FreeFunction = (D.getContext() != Declarator::MemberContext &&
+        (!D.getCXXScopeSpec().isSet() ||
+         !computeDeclContext(D.getCXXScopeSpec(), /*FIXME:*/true)->isRecord()));
     if (FnTy->getTypeQuals() != 0 &&
         D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
-        ((D.getContext() != Declarator::MemberContext &&
-          (!D.getCXXScopeSpec().isSet() ||
-           !computeDeclContext(D.getCXXScopeSpec(), /*FIXME:*/true)
-              ->isRecord())) ||
+        (FreeFunction ||
          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);
+             diag::err_invalid_qualified_typedef_function_type_use)
+          << FreeFunction;
 
       // Strip the cv-quals from the type.
       T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(),
@@ -1348,6 +1400,11 @@
     }
   }
 
+  // If there's a constexpr specifier, treat it as a top-level const.
+  if (D.getDeclSpec().isConstexprSpecified()) {
+    T.addConst();
+  }
+
   // Process any function attributes we might have delayed from the
   // declaration-specifiers.
   ProcessDelayedFnAttrs(*this, T, FnAttrsFromDeclSpec);
@@ -1362,14 +1419,11 @@
 
   DiagnoseDelayedFnAttrs(*this, FnAttrsFromPreviousChunk);
 
-  if (TInfo) {
-    if (D.isInvalidType())
-      *TInfo = 0;
-    else
-      *TInfo = GetTypeSourceInfoForDeclarator(D, T, ReturnTypeInfo);
-  }
-
-  return T;
+  if (T.isNull())
+    return Context.getNullTypeSourceInfo();
+  else if (D.isInvalidType())
+    return Context.getTrivialTypeSourceInfo(T);
+  return GetTypeSourceInfoForDeclarator(D, T, ReturnTypeInfo);
 }
 
 namespace {
@@ -1387,7 +1441,18 @@
     }
     void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
       TL.setNameLoc(DS.getTypeSpecTypeLoc());
+    }
+    void VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
+      // Handle the base type, which might not have been written explicitly.
+      if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) {
+        TL.setHasBaseTypeAsWritten(false);
+        TL.getBaseLoc().initialize(SourceLocation());
+      } else {
+        TL.setHasBaseTypeAsWritten(true);
+        Visit(TL.getBaseLoc());
+      }
 
+      // Protocol qualifiers.
       if (DS.getProtocolQualifiers()) {
         assert(TL.getNumProtocols() > 0);
         assert(TL.getNumProtocols() == DS.getNumProtocolQualifiers());
@@ -1402,38 +1467,12 @@
       }
     }
     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());
-      }
+      Visit(TL.getPointeeLoc());
     }
     void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
       TypeSourceInfo *TInfo = 0;
-      Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+      Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
 
       // If we got no declarator info from previous Sema routines,
       // just fill with the typespec loc.
@@ -1442,9 +1481,15 @@
         return;
       }
 
-      TemplateSpecializationTypeLoc OldTL =
-        cast<TemplateSpecializationTypeLoc>(TInfo->getTypeLoc());
-      TL.copy(OldTL);
+      TypeLoc OldTL = TInfo->getTypeLoc();
+      if (TInfo->getType()->getAs<ElaboratedType>()) {
+        ElaboratedTypeLoc ElabTL = cast<ElaboratedTypeLoc>(OldTL);
+        TemplateSpecializationTypeLoc NamedTL =
+          cast<TemplateSpecializationTypeLoc>(ElabTL.getNamedTypeLoc());
+        TL.copy(NamedTL);
+      }
+      else
+        TL.copy(cast<TemplateSpecializationTypeLoc>(OldTL));
     }
     void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
       assert(DS.getTypeSpecType() == DeclSpec::TST_typeofExpr);
@@ -1455,9 +1500,9 @@
       assert(DS.getTypeSpecType() == DeclSpec::TST_typeofType);
       TL.setTypeofLoc(DS.getTypeSpecTypeLoc());
       TL.setParensRange(DS.getTypeofParensRange());
-      assert(DS.getTypeRep());
+      assert(DS.getRepAsType());
       TypeSourceInfo *TInfo = 0;
-      Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+      Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
       TL.setUnderlyingTInfo(TInfo);
     }
     void VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
@@ -1475,6 +1520,66 @@
           TL.setBuiltinLoc(DS.getTypeSpecWidthLoc());
       }
     }
+    void VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
+      ElaboratedTypeKeyword Keyword
+        = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
+      if (Keyword == ETK_Typename) {
+        TypeSourceInfo *TInfo = 0;
+        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
+        if (TInfo) {
+          TL.copy(cast<ElaboratedTypeLoc>(TInfo->getTypeLoc()));
+          return;
+        }
+      }
+      TL.setKeywordLoc(Keyword != ETK_None
+                       ? DS.getTypeSpecTypeLoc()
+                       : SourceLocation());
+      const CXXScopeSpec& SS = DS.getTypeSpecScope();
+      TL.setQualifierRange(SS.isEmpty() ? SourceRange(): SS.getRange());
+      Visit(TL.getNextTypeLoc().getUnqualifiedLoc());
+    }
+    void VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
+      ElaboratedTypeKeyword Keyword
+        = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
+      if (Keyword == ETK_Typename) {
+        TypeSourceInfo *TInfo = 0;
+        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
+        if (TInfo) {
+          TL.copy(cast<DependentNameTypeLoc>(TInfo->getTypeLoc()));
+          return;
+        }
+      }
+      TL.setKeywordLoc(Keyword != ETK_None
+                       ? DS.getTypeSpecTypeLoc()
+                       : SourceLocation());
+      const CXXScopeSpec& SS = DS.getTypeSpecScope();
+      TL.setQualifierRange(SS.isEmpty() ? SourceRange() : SS.getRange());
+      // FIXME: load appropriate source location.
+      TL.setNameLoc(DS.getTypeSpecTypeLoc());
+    }
+    void VisitDependentTemplateSpecializationTypeLoc(
+                                 DependentTemplateSpecializationTypeLoc TL) {
+      ElaboratedTypeKeyword Keyword
+        = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
+      if (Keyword == ETK_Typename) {
+        TypeSourceInfo *TInfo = 0;
+        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
+        if (TInfo) {
+          TL.copy(cast<DependentTemplateSpecializationTypeLoc>(
+                    TInfo->getTypeLoc()));
+          return;
+        }
+      }
+      TL.initializeLocal(SourceLocation());
+      TL.setKeywordLoc(Keyword != ETK_None
+                       ? DS.getTypeSpecTypeLoc()
+                       : SourceLocation());
+      const CXXScopeSpec& SS = DS.getTypeSpecScope();
+      TL.setQualifierRange(SS.isEmpty() ? SourceRange() : SS.getRange());
+      // FIXME: load appropriate source location.
+      TL.setNameLoc(DS.getTypeSpecTypeLoc());
+    }
+
     void VisitTypeLoc(TypeLoc TL) {
       // FIXME: add other typespec types and change this to an assert.
       TL.initialize(DS.getTypeSpecTypeLoc());
@@ -1502,10 +1607,6 @@
     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);
@@ -1536,7 +1637,7 @@
 
       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>();
+        ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
         TL.setArg(tpi++, Param);
       }
       // FIXME: exception specs
@@ -1567,24 +1668,21 @@
     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) {
+  // If we have different source information for the return type, use
+  // that.  This really only applies to C++ conversion functions.
+  if (ReturnTypeInfo) {
     TypeLoc TL = ReturnTypeInfo->getTypeLoc();
     assert(TL.getFullDataSize() == CurrTL.getFullDataSize());
     memcpy(CurrTL.getOpaqueData(), TL.getOpaqueData(), TL.getFullDataSize());
+  } else {
+    TypeSpecLocFiller(D.getDeclSpec()).Visit(CurrTL);
   }
       
   return TInfo;
 }
 
 /// \brief Create a LocInfoType to hold the given QualType and TypeSourceInfo.
-QualType Sema::CreateLocInfoType(QualType T, TypeSourceInfo *TInfo) {
+ParsedType Sema::CreateParsedType(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.
@@ -1592,7 +1690,7 @@
   new (LocT) LocInfoType(T, TInfo);
   assert(LocT->getTypeClass() != T->getTypeClass() &&
          "LocInfoType's TypeClass conflicts with an existing Type class");
-  return QualType(LocT, 0);
+  return ParsedType::make(QualType(LocT, 0));
 }
 
 void LocInfoType::getAsStringInternal(std::string &Str,
@@ -1602,43 +1700,14 @@
          " 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) {
+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);
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S, &OwnedTag);
+  QualType T = TInfo->getType();
   if (D.isInvalidType())
     return true;
 
@@ -1655,10 +1724,7 @@
         << Context.getTypeDeclType(OwnedTag);
   }
 
-  if (TInfo)
-    T = CreateLocInfoType(T, TInfo);
-
-  return T.getAsOpaquePtr();
+  return CreateParsedType(T, TInfo);
 }
 
 
@@ -1678,19 +1744,23 @@
   // for two or more different address spaces."
   if (Type.getAddressSpace()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_address_multiple_qualifiers);
+    Attr.setInvalid();
     return;
   }
 
   // Check the attribute arguments.
   if (Attr.getNumArgs() != 1) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    Attr.setInvalid();
     return;
   }
   Expr *ASArgExpr = static_cast<Expr *>(Attr.getArg(0));
   llvm::APSInt addrSpace(32);
-  if (!ASArgExpr->isIntegerConstantExpr(addrSpace, S.Context)) {
+  if (ASArgExpr->isTypeDependent() || ASArgExpr->isValueDependent() ||
+      !ASArgExpr->isIntegerConstantExpr(addrSpace, S.Context)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_address_space_not_int)
       << ASArgExpr->getSourceRange();
+    Attr.setInvalid();
     return;
   }
 
@@ -1699,6 +1769,7 @@
     if (addrSpace.isNegative()) {
       S.Diag(Attr.getLoc(), diag::err_attribute_address_space_negative)
         << ASArgExpr->getSourceRange();
+      Attr.setInvalid();
       return;
     }
     addrSpace.setIsSigned(false);
@@ -1708,6 +1779,7 @@
   if (addrSpace > max) {
     S.Diag(Attr.getLoc(), diag::err_attribute_address_space_too_high)
       << Qualifiers::MaxAddressSpace << ASArgExpr->getSourceRange();
+    Attr.setInvalid();
     return;
   }
 
@@ -1721,6 +1793,7 @@
                                       const AttributeList &Attr, Sema &S) {
   if (Type.getObjCGCAttr() != Qualifiers::GCNone) {
     S.Diag(Attr.getLoc(), diag::err_attribute_multiple_objc_gc);
+    Attr.setInvalid();
     return;
   }
 
@@ -1728,11 +1801,13 @@
   if (!Attr.getParameterName()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
       << "objc_gc" << 1;
+    Attr.setInvalid();
     return;
   }
   Qualifiers::GC GCAttr;
   if (Attr.getNumArgs() != 0) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    Attr.setInvalid();
     return;
   }
   if (Attr.getParameterName()->isStr("weak"))
@@ -1742,12 +1817,21 @@
   else {
     S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
       << "objc_gc" << Attr.getParameterName();
+    Attr.setInvalid();
     return;
   }
 
   Type = S.Context.getObjCGCQualType(Type, GCAttr);
 }
 
+static QualType GetResultType(QualType T) {
+  if (const PointerType *PT = T->getAs<PointerType>())
+    T = PT->getPointeeType();
+  else if (const BlockPointerType *BT = T->getAs<BlockPointerType>())
+    T = BT->getPointeeType();
+  return T->getAs<FunctionType>()->getResultType();
+}
+
 /// 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) {
@@ -1755,6 +1839,7 @@
     // Complain immediately if the arg count is wrong.
     if (Attr.getNumArgs() != 0) {
       S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+      Attr.setInvalid();
       return false;
     }
 
@@ -1763,7 +1848,12 @@
         && !Type->isBlockPointerType()
         && !Type->isFunctionType())
       return true;
-
+    
+    if (!GetResultType(Type)->isVoidType()) {
+      S.Diag(Attr.getLoc(), diag::warn_noreturn_function_has_nonvoid_result)
+        << (Type->isBlockPointerType() ? /* blocks */ 1 : /* functions */ 0);
+    }
+    
     // Otherwise we can process right away.
     Type = S.Context.getNoReturnType(Type);
     return false;
@@ -1786,7 +1876,8 @@
     llvm::APSInt NumParams(32);
 
     // The warning is emitted elsewhere
-    if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context))
+    if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
+        !NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context))
       return false;
 
     Type = S.Context.getRegParmType(Type, NumParams.getZExtValue());
@@ -1796,6 +1887,7 @@
   // Otherwise, a calling convention.
   if (Attr.getNumArgs() != 0) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    Attr.setInvalid();
     return false;
   }
 
@@ -1813,18 +1905,23 @@
   case AttributeList::AT_cdecl: CC = CC_C; break;
   case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
   case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
+  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
   default: llvm_unreachable("unexpected attribute kind"); return false;
   }
 
   CallingConv CCOld = Fn->getCallConv();
   if (S.Context.getCanonicalCallConv(CC) ==
-      S.Context.getCanonicalCallConv(CCOld)) return false;
+      S.Context.getCanonicalCallConv(CCOld)) {
+    Attr.setInvalid();
+    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);
+    Attr.setInvalid();
     return false;
   }
 
@@ -1833,6 +1930,7 @@
     if (isa<FunctionNoProtoType>(Fn)) {
       S.Diag(Attr.getLoc(), diag::err_cconv_knr)
         << FunctionType::getNameForCallConv(CC);
+      Attr.setInvalid();
       return false;
     }
 
@@ -1840,6 +1938,7 @@
     if (FnP->isVariadic()) {
       S.Diag(Attr.getLoc(), diag::err_cconv_varargs)
         << FunctionType::getNameForCallConv(CC);
+      Attr.setInvalid();
       return false;
     }
   }
@@ -1855,23 +1954,27 @@
 /// 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) {
+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;
+    Attr.setInvalid();
     return;
   }
   Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
   llvm::APSInt vecSize(32);
-  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
+  if (sizeExpr->isTypeDependent() || sizeExpr->isValueDependent() ||
+      !sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
       << "vector_size" << sizeExpr->getSourceRange();
+    Attr.setInvalid();
     return;
   }
   // the base type must be integer or float, and can't already be a vector.
-  if (CurType->isVectorType() ||
-      (!CurType->isIntegerType() && !CurType->isRealFloatingType())) {
+  if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
+    Attr.setInvalid();
     return;
   }
   unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
@@ -1882,17 +1985,20 @@
   if (vectorSize % typeSize) {
     S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size)
       << sizeExpr->getSourceRange();
+    Attr.setInvalid();
     return;
   }
   if (vectorSize == 0) {
     S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
       << sizeExpr->getSourceRange();
+    Attr.setInvalid();
     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);
+  CurType = S.Context.getVectorType(CurType, vectorSize/typeSize,
+                                    VectorType::NotAltiVec);
 }
 
 void ProcessTypeAttributeList(Sema &S, QualType &Result,
@@ -1903,8 +2009,12 @@
   // 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.
+    // Skip attributes that were marked to be invalid.
+    if (AL->isInvalid())
+      continue;
+
+    // If this is an attribute we can handle, do so now,
+    // otherwise, add it to the FnAttrs list for rechaining.
     switch (AL->getKind()) {
     default: break;
 
@@ -1922,6 +2032,7 @@
     case AttributeList::AT_cdecl:
     case AttributeList::AT_fastcall:
     case AttributeList::AT_stdcall:
+    case AttributeList::AT_thiscall:
     case AttributeList::AT_regparm:
       // Don't process these on the DeclSpec.
       if (IsDeclSpec ||
@@ -2042,15 +2153,21 @@
                              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())
+/// \brief Retrieve a version of the type 'T' that is elaborated by Keyword
+/// and qualified by the nested-name-specifier contained in SS.
+QualType Sema::getElaboratedType(ElaboratedTypeKeyword Keyword,
+                                 const CXXScopeSpec &SS, QualType T) {
+  if (T.isNull())
     return T;
-
-  NestedNameSpecifier *NNS
-    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
-  return Context.getQualifiedNameType(NNS, T);
+  NestedNameSpecifier *NNS;
+  if (SS.isValid())
+    NNS = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  else {
+    if (Keyword == ETK_None)
+      return T;
+    NNS = 0;
+  }
+  return Context.getElaboratedType(Keyword, NNS, T);
 }
 
 QualType Sema::BuildTypeofExprType(Expr *E) {
diff --git a/lib/Sema/TargetAttributesSema.cpp b/lib/Sema/TargetAttributesSema.cpp
index 87e7b9d..1854e74 100644
--- a/lib/Sema/TargetAttributesSema.cpp
+++ b/lib/Sema/TargetAttributesSema.cpp
@@ -12,9 +12,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
 #include "TargetAttributesSema.h"
+#include "clang/Sema/SemaInternal.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/AST/DeclCXX.h"
 #include "llvm/ADT/Triple.h"
 
 using namespace clang;
@@ -51,8 +52,8 @@
       return;
     }
 
-    d->addAttr(::new (S.Context) MSP430InterruptAttr(Num));
-    d->addAttr(::new (S.Context) UsedAttr());
+    d->addAttr(::new (S.Context) MSP430InterruptAttr(Attr.getLoc(), S.Context, Num));
+    d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
   }
 
 namespace {
@@ -97,7 +98,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr());
+  D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -109,7 +110,7 @@
 
   // Attribute can be applied only to functions or variables.
   if (isa<VarDecl>(D)) {
-    D->addAttr(::new (S.Context) DLLImportAttr());
+    D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context));
     return;
   }
 
@@ -146,7 +147,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) DLLImportAttr());
+  D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -158,7 +159,7 @@
 
   // Attribute can be applied only to functions or variables.
   if (isa<VarDecl>(D)) {
-    D->addAttr(::new (S.Context) DLLExportAttr());
+    D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context));
     return;
   }
 
@@ -177,7 +178,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) DLLExportAttr());
+  D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context));
 }
 
 namespace {
diff --git a/lib/Sema/TargetAttributesSema.h b/lib/Sema/TargetAttributesSema.h
index 8794e40..410c900 100644
--- a/lib/Sema/TargetAttributesSema.h
+++ b/lib/Sema/TargetAttributesSema.h
@@ -13,7 +13,7 @@
 namespace clang {
   class Scope;
   class Decl;
-  class Attr;
+  class AttributeList;
   class Sema;
 
   class TargetAttributesSema {
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index f80747b..08cfd68 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -13,10 +13,12 @@
 #ifndef LLVM_CLANG_SEMA_TREETRANSFORM_H
 #define LLVM_CLANG_SEMA_TREETRANSFORM_H
 
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
 #include "clang/Sema/SemaDiagnostic.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
@@ -24,13 +26,14 @@
 #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/Sema/Ownership.h"
+#include "clang/Sema/Designator.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/Support/ErrorHandling.h"
 #include <algorithm>
 
 namespace clang {
+using namespace sema;
 
 /// \brief A semantic tree transformation that allows one to transform one
 /// abstract syntax tree into another.
@@ -89,14 +92,6 @@
   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) { }
 
@@ -108,6 +103,9 @@
     return static_cast<const Derived&>(*this);
   }
 
+  static inline ExprResult Owned(Expr *E) { return E; }
+  static inline StmtResult Owned(Stmt *S) { return S; }
+
   /// \brief Retrieves a reference to the semantic analysis object used for
   /// this tree transform.
   Sema &getSema() const { return SemaRef; }
@@ -220,7 +218,7 @@
   /// other mechanism.
   ///
   /// \returns the transformed statement.
-  OwningStmtResult TransformStmt(Stmt *S);
+  StmtResult TransformStmt(Stmt *S);
 
   /// \brief Transform the given expression.
   ///
@@ -230,7 +228,7 @@
   /// other mechanism.
   ///
   /// \returns the transformed expression.
-  OwningExprResult TransformExpr(Expr *E);
+  ExprResult TransformExpr(Expr *E);
 
   /// \brief Transform the given declaration, which is referenced from a type
   /// or expression.
@@ -276,9 +274,9 @@
   /// 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());
+  DeclarationNameInfo
+  TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+                               QualType ObjectType = QualType());
 
   /// \brief Transform the given template name.
   ///
@@ -337,15 +335,15 @@
   TransformTemplateSpecializationType(const TemplateSpecializationType *T,
                                       QualType ObjectType);
 
-  OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
-  OwningExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
+  StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
+  ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
 
 #define STMT(Node, Parent)                        \
-  OwningStmtResult Transform##Node(Node *S);
+  StmtResult Transform##Node(Node *S);
 #define EXPR(Node, Parent)                        \
-  OwningExprResult Transform##Node(Node *E);
-#define ABSTRACT_EXPR(Node, Parent)
-#include "clang/AST/StmtNodes.def"
+  ExprResult Transform##Node(Node *E);
+#define ABSTRACT_STMT(Stmt)
+#include "clang/AST/StmtNodes.inc"
 
   /// \brief Build a new pointer type given its pointee type.
   ///
@@ -421,7 +419,7 @@
   /// Subclasses may override this routine to provide different behavior.
   QualType RebuildVariableArrayType(QualType ElementType,
                                     ArrayType::ArraySizeModifier SizeMod,
-                                    ExprArg SizeExpr,
+                                    Expr *SizeExpr,
                                     unsigned IndexTypeQuals,
                                     SourceRange BracketsRange);
 
@@ -432,7 +430,7 @@
   /// Subclasses may override this routine to provide different behavior.
   QualType RebuildDependentSizedArrayType(QualType ElementType,
                                           ArrayType::ArraySizeModifier SizeMod,
-                                          ExprArg SizeExpr,
+                                          Expr *SizeExpr,
                                           unsigned IndexTypeQuals,
                                           SourceRange BracketsRange);
 
@@ -442,7 +440,7 @@
   /// 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);
+    VectorType::AltiVecSpecific AltiVecSpec);
 
   /// \brief Build a new extended vector type given the element type and
   /// number of elements.
@@ -458,7 +456,7 @@
   /// 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,
+                                              Expr *SizeExpr,
                                               SourceLocation AttributeLoc);
 
   /// \brief Build a new function type.
@@ -468,7 +466,8 @@
   QualType RebuildFunctionProtoType(QualType T,
                                     QualType *ParamTypes,
                                     unsigned NumParamTypes,
-                                    bool Variadic, unsigned Quals);
+                                    bool Variadic, unsigned Quals,
+                                    const FunctionType::ExtInfo &Info);
 
   /// \brief Build a new unprototyped function type.
   QualType RebuildFunctionNoProtoType(QualType ResultType);
@@ -492,16 +491,11 @@
     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);
+  QualType RebuildTypeOfExprType(Expr *Underlying);
 
   /// \brief Build a new typeof(type) type.
   ///
@@ -512,7 +506,7 @@
   ///
   /// By default, performs semantic analysis when building the decltype type.
   /// Subclasses may override this routine to provide different behavior.
-  QualType RebuildDecltypeType(ExprArg Underlying);
+  QualType RebuildDecltypeType(Expr *Underlying);
 
   /// \brief Build a new template specialization type.
   ///
@@ -525,73 +519,86 @@
 
   /// \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);
+  /// By default, builds a new ElaboratedType type from the keyword,
+  /// the nested-name-specifier and the named type.
+  /// Subclasses may override this routine to provide different behavior.
+  QualType RebuildElaboratedType(ElaboratedTypeKeyword Keyword,
+                                 NestedNameSpecifier *NNS, QualType Named) {
+    return SemaRef.Context.getElaboratedType(Keyword, 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));
-    }
+  /// 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 RebuildDependentTemplateSpecializationType(
+                                    ElaboratedTypeKeyword Keyword,
+                                    NestedNameSpecifier *NNS,
+                                    const IdentifierInfo *Name,
+                                    SourceLocation NameLoc,
+                                    const TemplateArgumentListInfo &Args) {
+    // Rebuild the template name.
+    // TODO: avoid TemplateName abstraction
+    TemplateName InstName =
+      getDerived().RebuildTemplateName(NNS, *Name, QualType());
     
-    // FIXME: Handle elaborated-type-specifiers separately.
-    return SemaRef.Context.getQualifiedNameType(NNS, T);
+    if (InstName.isNull())
+      return QualType();
+
+    // If it's still dependent, make a dependent specialization.
+    if (InstName.getAsDependentTemplateName())
+      return SemaRef.Context.getDependentTemplateSpecializationType(
+                                          Keyword, NNS, Name, Args);
+
+    // Otherwise, make an elaborated type wrapping a non-dependent
+    // specialization.
+    QualType T =
+      getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
+    if (T.isNull()) return QualType();
+
+    // NOTE: NNS is already recorded in template specialization type T.
+    return SemaRef.Context.getElaboratedType(Keyword, /*NNS=*/0, 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
+  /// (or elaborated type). Subclasses may override this routine to provide
   /// different behavior.
-  QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword, 
+  QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
                                     NestedNameSpecifier *NNS,
                                     const IdentifierInfo *Id,
-                                    SourceRange SR) {
+                                    SourceLocation KeywordLoc,
+                                    SourceRange NNSRange,
+                                    SourceLocation IdLoc) {
     CXXScopeSpec SS;
     SS.setScopeRep(NNS);
-    
+    SS.setRange(NNSRange);
+
     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
+    if (Keyword == ETK_None || Keyword == ETK_Typename)
+      return SemaRef.CheckTypenameType(Keyword, NNS, *Id,
+                                       KeywordLoc, NNSRange, IdLoc);
+
+    TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
+
+    // We had a dependent elaborated-type-specifier that has been transformed
     // into a non-dependent elaborated-type-specifier. Find the tag we're
     // referring to.
-    LookupResult Result(SemaRef, Id, SR.getEnd(), Sema::LookupTagName);
+    LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
     DeclContext *DC = SemaRef.computeDeclContext(SS, false);
     if (!DC)
       return QualType();
 
+    if (SemaRef.RequireCompleteDeclContext(SS, DC))
+      return QualType();
+
     TagDecl *Tag = 0;
     SemaRef.LookupQualifiedName(Result, DC);
     switch (Result.getResultKind()) {
@@ -615,22 +622,20 @@
 
     if (!Tag) {
       // FIXME: Would be nice to highlight just the source range.
-      SemaRef.Diag(SR.getEnd(), diag::err_not_tag_in_scope)
+      SemaRef.Diag(IdLoc, 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;
+
+    if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, IdLoc, *Id)) {
+      SemaRef.Diag(KeywordLoc, 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);
+    return SemaRef.Context.getElaboratedType(Keyword, NNS, T);
   }
 
   /// \brief Build a new nested-name-specifier given the prefix and an
@@ -702,11 +707,11 @@
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
+  StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
                                        MultiStmtArg Statements,
                                        SourceLocation RBraceLoc,
                                        bool IsStmtExpr) {
-    return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, move(Statements),
+    return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
                                        IsStmtExpr);
   }
 
@@ -714,12 +719,12 @@
   ///
   /// 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,
+  StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
+                                   Expr *LHS,
                                    SourceLocation EllipsisLoc,
-                                   ExprArg RHS,
+                                   Expr *RHS,
                                    SourceLocation ColonLoc) {
-    return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
+    return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
                                    ColonLoc);
   }
 
@@ -727,19 +732,19 @@
   ///
   /// 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);
+  StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
+    getSema().ActOnCaseStmtBody(S, Body);
+    return 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,
+  StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
                                       SourceLocation ColonLoc,
-                                      StmtArg SubStmt) {
-    return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
+                                      Stmt *SubStmt) {
+    return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
                                       /*CurScope=*/0);
   }
 
@@ -747,87 +752,85 @@
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
+  StmtResult RebuildLabelStmt(SourceLocation IdentLoc,
                                     IdentifierInfo *Id,
                                     SourceLocation ColonLoc,
-                                    StmtArg SubStmt) {
-    return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, move(SubStmt));
+                                    Stmt *SubStmt) {
+    return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, 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));
+  StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
+                                 VarDecl *CondVar, Stmt *Then, 
+                                 SourceLocation ElseLoc, Stmt *Else) {
+    return getSema().ActOnIfStmt(IfLoc, Cond, CondVar, Then, ElseLoc, 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));
+  StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
+                                          Expr *Cond, VarDecl *CondVar) {
+    return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond, 
+                                            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));
+  StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
+                                         Stmt *Switch, Stmt *Body) {
+    return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, 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,
+  StmtResult RebuildWhileStmt(SourceLocation WhileLoc,
                                     Sema::FullExprArg Cond,
                                     VarDecl *CondVar,
-                                    StmtArg Body) {
-    return getSema().ActOnWhileStmt(WhileLoc, Cond, DeclPtrTy::make(CondVar),
-                                    move(Body));
+                                    Stmt *Body) {
+    return getSema().ActOnWhileStmt(WhileLoc, Cond, CondVar, 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,
+  StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
                                  SourceLocation WhileLoc,
                                  SourceLocation LParenLoc,
-                                 ExprArg Cond,
+                                 Expr *Cond,
                                  SourceLocation RParenLoc) {
-    return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
-                                 move(Cond), RParenLoc);
+    return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
+                                 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,
+  StmtResult RebuildForStmt(SourceLocation ForLoc,
                                   SourceLocation LParenLoc,
-                                  StmtArg Init, Sema::FullExprArg Cond, 
+                                  Stmt *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));
+                                  SourceLocation RParenLoc, Stmt *Body) {
+    return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond, 
+                                  CondVar,
+                                  Inc, RParenLoc, 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,
+  StmtResult RebuildGotoStmt(SourceLocation GotoLoc,
                                    SourceLocation LabelLoc,
                                    LabelStmt *Label) {
     return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
@@ -837,27 +840,27 @@
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
+  StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
                                            SourceLocation StarLoc,
-                                           ExprArg Target) {
-    return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(Target));
+                                           Expr *Target) {
+    return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, 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) {
+  StmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
+                                     Expr *Result) {
 
-    return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
+    return getSema().ActOnReturnStmt(ReturnLoc, 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,
+  StmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
                                    SourceLocation StartLoc,
                                    SourceLocation EndLoc) {
     return getSema().Owned(
@@ -871,7 +874,7 @@
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildAsmStmt(SourceLocation AsmLoc,
+  StmtResult RebuildAsmStmt(SourceLocation AsmLoc,
                                   bool IsSimple,
                                   bool IsVolatile,
                                   unsigned NumOutputs,
@@ -879,13 +882,13 @@
                                   IdentifierInfo **Names,
                                   MultiExprArg Constraints,
                                   MultiExprArg Exprs,
-                                  ExprArg AsmString,
+                                  Expr *AsmString,
                                   MultiExprArg Clobbers,
                                   SourceLocation RParenLoc,
                                   bool MSAsm) {
     return getSema().ActOnAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs, 
                                   NumInputs, Names, move(Constraints),
-                                  move(Exprs), move(AsmString), move(Clobbers),
+                                  Exprs, AsmString, Clobbers,
                                   RParenLoc, MSAsm);
   }
 
@@ -893,12 +896,12 @@
   ///
   /// 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,
+  StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
+                                        Stmt *TryBody,
                                         MultiStmtArg CatchStmts,
-                                        StmtArg Finally) {
-    return getSema().ActOnObjCAtTryStmt(AtLoc, move(TryBody), move(CatchStmts),
-                                        move(Finally));
+                                        Stmt *Finally) {
+    return getSema().ActOnObjCAtTryStmt(AtLoc, TryBody, move(CatchStmts),
+                                        Finally);
   }
 
   /// \brief Rebuild an Objective-C exception declaration.
@@ -916,59 +919,58 @@
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
+  StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
                                           SourceLocation RParenLoc,
                                           VarDecl *Var,
-                                          StmtArg Body) {
+                                          Stmt *Body) {
     return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc,
-                                          Sema::DeclPtrTy::make(Var),
-                                          move(Body));
+                                          Var, 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));
+  StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
+                                            Stmt *Body) {
+    return getSema().ActOnObjCAtFinallyStmt(AtLoc, 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));
+  StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
+                                          Expr *Operand) {
+    return getSema().BuildObjCAtThrowStmt(AtLoc, 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));
+  StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
+                                                 Expr *Object,
+                                                 Stmt *Body) {
+    return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object,
+                                                 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) {
+  StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
+                                          SourceLocation LParenLoc,
+                                          Stmt *Element,
+                                          Expr *Collection,
+                                          SourceLocation RParenLoc,
+                                          Stmt *Body) {
     return getSema().ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
-                                                move(Element), 
-                                                move(Collection),
+                                                Element, 
+                                                Collection,
                                                 RParenLoc,
-                                                move(Body));
+                                                Body);
   }
   
   /// \brief Build a new C++ exception declaration.
@@ -988,31 +990,30 @@
   ///
   /// 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>()));
+  StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
+                                 VarDecl *ExceptionDecl,
+                                 Stmt *Handler) {
+    return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
+                                                      Handler));
   }
 
   /// \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));
+  StmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
+                               Stmt *TryBlock,
+                               MultiStmtArg Handlers) {
+    return getSema().ActOnCXXTryBlock(TryLoc, 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) {
+  ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
+                                        LookupResult &R,
+                                        bool RequiresADL) {
     return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
   }
 
@@ -1021,33 +1022,34 @@
   ///
   /// 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) {
+  ExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
+                                SourceRange QualifierRange,
+                                ValueDecl *VD,
+                                const DeclarationNameInfo &NameInfo,
+                                TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
     SS.setScopeRep(Qualifier);
     SS.setRange(QualifierRange);
 
     // FIXME: loses template args.
-    
-    return getSema().BuildDeclarationNameExpr(SS, Loc, VD);
+
+    return getSema().BuildDeclarationNameExpr(SS, NameInfo, 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,
+  ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
                                     SourceLocation RParen) {
-    return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
+    return getSema().ActOnParenExpr(LParen, RParen, 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,
+  ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
                                                   SourceLocation OperatorLoc,
                                                   bool isArrow,
                                                 NestedNameSpecifier *Qualifier,
@@ -1061,17 +1063,30 @@
   ///
   /// 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));
+  ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
+                                        UnaryOperatorKind Opc,
+                                        Expr *SubExpr) {
+    return getSema().BuildUnaryOp(/*Scope=*/0, OpLoc, Opc, SubExpr);
   }
 
+  /// \brief Build a new builtin offsetof expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
+                                       TypeSourceInfo *Type,
+                                       Sema::OffsetOfComponent *Components,
+                                       unsigned NumComponents,
+                                       SourceLocation RParenLoc) {
+    return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
+                                          NumComponents, RParenLoc);
+  }
+  
   /// \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,
+  ExprResult RebuildSizeOfAlignOf(TypeSourceInfo *TInfo,
                                         SourceLocation OpLoc,
                                         bool isSizeOf, SourceRange R) {
     return getSema().CreateSizeOfAlignOfExpr(TInfo, OpLoc, isSizeOf, R);
@@ -1082,15 +1097,13 @@
   ///
   /// 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,
+  ExprResult RebuildSizeOfAlignOf(Expr *SubExpr, SourceLocation OpLoc,
                                         bool isSizeOf, SourceRange R) {
-    OwningExprResult Result
-      = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
-                                          OpLoc, isSizeOf, R);
+    ExprResult Result
+      = getSema().CreateSizeOfAlignOfExpr(SubExpr, OpLoc, isSizeOf, R);
     if (Result.isInvalid())
-      return getSema().ExprError();
+      return ExprError();
 
-    SubExpr.release();
     return move(Result);
   }
 
@@ -1098,12 +1111,12 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
+  ExprResult RebuildArraySubscriptExpr(Expr *LHS,
                                              SourceLocation LBracketLoc,
-                                             ExprArg RHS,
+                                             Expr *RHS,
                                              SourceLocation RBracketLoc) {
-    return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
-                                             LBracketLoc, move(RHS),
+    return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, LHS,
+                                             LBracketLoc, RHS,
                                              RBracketLoc);
   }
 
@@ -1111,11 +1124,11 @@
   ///
   /// 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,
+  ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
                                    MultiExprArg Args,
                                    SourceLocation *CommaLocs,
                                    SourceLocation RParenLoc) {
-    return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
+    return getSema().ActOnCallExpr(/*Scope=*/0, Callee, LParenLoc,
                                    move(Args), CommaLocs, RParenLoc);
   }
 
@@ -1123,11 +1136,11 @@
   ///
   /// 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,
+  ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
                                      bool isArrow,
                                      NestedNameSpecifier *Qualifier,
                                      SourceRange QualifierRange,
-                                     SourceLocation MemberLoc,
+                                     const DeclarationNameInfo &MemberNameInfo,
                                      ValueDecl *Member,
                                      NamedDecl *FoundDecl,
                         const TemplateArgumentListInfo *ExplicitTemplateArgs,
@@ -1136,14 +1149,13 @@
       // 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,
+      if (getSema().PerformObjectMemberConversion(Base, Qualifier,
                                                   FoundDecl, Member))
-        return getSema().ExprError();
+        return ExprError();
 
       MemberExpr *ME =
-        new (getSema().Context) MemberExpr(BaseExpr, isArrow,
-                                           Member, MemberLoc,
+        new (getSema().Context) MemberExpr(Base, isArrow,
+                                           Member, MemberNameInfo,
                                            cast<FieldDecl>(Member)->getType());
       return getSema().Owned(ME);
     }
@@ -1154,17 +1166,16 @@
       SS.setScopeRep(Qualifier);
     }
 
-    QualType BaseType = ((Expr*) Base.get())->getType();
+    getSema().DefaultFunctionArrayConversion(Base);
+    QualType BaseType = Base->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);
+    LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
     R.addDecl(FoundDecl);
     R.resolveKind();
 
-    return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
-                                              OpLoc, isArrow,
+    return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
                                               SS, FirstQualifierInScope,
                                               R, ExplicitTemplateArgs);
   }
@@ -1173,66 +1184,64 @@
   ///
   /// 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>());
+  ExprResult RebuildBinaryOperator(SourceLocation OpLoc,
+                                         BinaryOperatorKind Opc,
+                                         Expr *LHS, Expr *RHS) {
+    return getSema().BuildBinOp(/*Scope=*/0, OpLoc, Opc, LHS, RHS);
   }
 
   /// \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,
+  ExprResult RebuildConditionalOperator(Expr *Cond,
                                               SourceLocation QuestionLoc,
-                                              ExprArg LHS,
+                                              Expr *LHS,
                                               SourceLocation ColonLoc,
-                                              ExprArg RHS) {
-    return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
-                                        move(LHS), move(RHS));
+                                              Expr *RHS) {
+    return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
+                                        LHS, 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,
+  ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
                                          TypeSourceInfo *TInfo,
                                          SourceLocation RParenLoc,
-                                         ExprArg SubExpr) {
+                                         Expr *SubExpr) {
     return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
-                                         move(SubExpr));
+                                         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,
+  ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
                                               TypeSourceInfo *TInfo,
                                               SourceLocation RParenLoc,
-                                              ExprArg Init) {
+                                              Expr *Init) {
     return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
-                                              move(Init));
+                                              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,
+  ExprResult RebuildExtVectorElementExpr(Expr *Base,
                                                SourceLocation OpLoc,
                                                SourceLocation AccessorLoc,
                                                IdentifierInfo &Accessor) {
 
     CXXScopeSpec SS;
-    QualType BaseType = ((Expr*) Base.get())->getType();
-    return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
+    DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
+    return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
                                               OpLoc, /*IsArrow*/ false,
                                               SS, /*FirstQualifierInScope*/ 0,
-                                              DeclarationName(&Accessor),
-                                              AccessorLoc,
+                                              NameInfo,
                                               /* TemplateArgs */ 0);
   }
 
@@ -1240,11 +1249,11 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
+  ExprResult RebuildInitList(SourceLocation LBraceLoc,
                                    MultiExprArg Inits,
                                    SourceLocation RBraceLoc,
                                    QualType ResultTy) {
-    OwningExprResult Result
+    ExprResult Result
       = SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
     if (Result.isInvalid() || ResultTy->isDependentType())
       return move(Result);
@@ -1260,16 +1269,16 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
+  ExprResult RebuildDesignatedInitExpr(Designation &Desig,
                                              MultiExprArg ArrayExprs,
                                              SourceLocation EqualOrColonLoc,
                                              bool GNUSyntax,
-                                             ExprArg Init) {
-    OwningExprResult Result
+                                             Expr *Init) {
+    ExprResult Result
       = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
-                                           move(Init));
+                                           Init);
     if (Result.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArrayExprs.release();
     return move(Result);
@@ -1280,7 +1289,7 @@
   /// 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) {
+  ExprResult RebuildImplicitValueInitExpr(QualType T) {
     return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
   }
 
@@ -1288,17 +1297,19 @@
   ///
   /// 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);
+  ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
+                                    Expr *SubExpr, TypeSourceInfo *TInfo,
+                                    SourceLocation RParenLoc) {
+    return getSema().BuildVAArgExpr(BuiltinLoc,
+                                    SubExpr, TInfo,
+                                    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,
+  ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
                                         MultiExprArg SubExprs,
                                         SourceLocation RParenLoc) {
     return getSema().ActOnParenOrParenListExpr(LParenLoc, RParenLoc, 
@@ -1310,7 +1321,7 @@
   /// 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,
+  ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
                                         SourceLocation LabelLoc,
                                         LabelStmt *Label) {
     return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
@@ -1320,22 +1331,22 @@
   ///
   /// 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,
+  ExprResult RebuildStmtExpr(SourceLocation LParenLoc,
+                                   Stmt *SubStmt,
                                    SourceLocation RParenLoc) {
-    return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
+    return getSema().ActOnStmtExpr(LParenLoc, 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,
+  ExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
+                                              TypeSourceInfo *TInfo1,
+                                              TypeSourceInfo *TInfo2,
                                               SourceLocation RParenLoc) {
-    return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
-                                              T1.getAsOpaquePtr(),
-                                              T2.getAsOpaquePtr(),
+    return getSema().BuildTypesCompatibleExpr(BuiltinLoc,
+                                              TInfo1, TInfo2,
                                               RParenLoc);
   }
 
@@ -1343,11 +1354,11 @@
   ///
   /// 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,
+  ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
+                                     Expr *Cond, Expr *LHS, Expr *RHS,
                                      SourceLocation RParenLoc) {
     return SemaRef.ActOnChooseExpr(BuiltinLoc,
-                                   move(Cond), move(LHS), move(RHS),
+                                   Cond, LHS, RHS,
                                    RParenLoc);
   }
 
@@ -1359,11 +1370,11 @@
   /// 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,
+  ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
                                               SourceLocation OpLoc,
-                                              ExprArg Callee,
-                                              ExprArg First,
-                                              ExprArg Second);
+                                              Expr *Callee,
+                                              Expr *First,
+                                              Expr *Second);
 
   /// \brief Build a new C++ "named" cast expression, such as static_cast or
   /// reinterpret_cast.
@@ -1371,57 +1382,57 @@
   /// 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,
+  ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
                                            Stmt::StmtClass Class,
                                            SourceLocation LAngleLoc,
                                            TypeSourceInfo *TInfo,
                                            SourceLocation RAngleLoc,
                                            SourceLocation LParenLoc,
-                                           ExprArg SubExpr,
+                                           Expr *SubExpr,
                                            SourceLocation RParenLoc) {
     switch (Class) {
     case Stmt::CXXStaticCastExprClass:
       return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
                                                    RAngleLoc, LParenLoc,
-                                                   move(SubExpr), RParenLoc);
+                                                   SubExpr, RParenLoc);
 
     case Stmt::CXXDynamicCastExprClass:
       return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
                                                     RAngleLoc, LParenLoc,
-                                                    move(SubExpr), RParenLoc);
+                                                    SubExpr, RParenLoc);
 
     case Stmt::CXXReinterpretCastExprClass:
       return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
                                                         RAngleLoc, LParenLoc,
-                                                        move(SubExpr),
+                                                        SubExpr,
                                                         RParenLoc);
 
     case Stmt::CXXConstCastExprClass:
       return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
                                                    RAngleLoc, LParenLoc,
-                                                   move(SubExpr), RParenLoc);
+                                                   SubExpr, RParenLoc);
 
     default:
       assert(false && "Invalid C++ named cast");
       break;
     }
 
-    return getSema().ExprError();
+    return 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,
+  ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
                                             SourceLocation LAngleLoc,
                                             TypeSourceInfo *TInfo,
                                             SourceLocation RAngleLoc,
                                             SourceLocation LParenLoc,
-                                            ExprArg SubExpr,
+                                            Expr *SubExpr,
                                             SourceLocation RParenLoc) {
     return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
-                                       TInfo, move(SubExpr),
+                                       TInfo, SubExpr,
                                        SourceRange(LAngleLoc, RAngleLoc),
                                        SourceRange(LParenLoc, RParenLoc));
   }
@@ -1430,15 +1441,15 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
+  ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
                                              SourceLocation LAngleLoc,
                                              TypeSourceInfo *TInfo,
                                              SourceLocation RAngleLoc,
                                              SourceLocation LParenLoc,
-                                             ExprArg SubExpr,
+                                             Expr *SubExpr,
                                              SourceLocation RParenLoc) {
     return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
-                                       TInfo, move(SubExpr),
+                                       TInfo, SubExpr,
                                        SourceRange(LAngleLoc, RAngleLoc),
                                        SourceRange(LParenLoc, RParenLoc));
   }
@@ -1447,15 +1458,15 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
+  ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
                                                  SourceLocation LAngleLoc,
                                                  TypeSourceInfo *TInfo,
                                                  SourceLocation RAngleLoc,
                                                  SourceLocation LParenLoc,
-                                                 ExprArg SubExpr,
+                                                 Expr *SubExpr,
                                                  SourceLocation RParenLoc) {
     return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
-                                       TInfo, move(SubExpr),
+                                       TInfo, SubExpr,
                                        SourceRange(LAngleLoc, RAngleLoc),
                                        SourceRange(LParenLoc, RParenLoc));
   }
@@ -1464,15 +1475,15 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
+  ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
                                            SourceLocation LAngleLoc,
                                            TypeSourceInfo *TInfo,
                                            SourceLocation RAngleLoc,
                                            SourceLocation LParenLoc,
-                                           ExprArg SubExpr,
+                                           Expr *SubExpr,
                                            SourceLocation RParenLoc) {
     return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
-                                       TInfo, move(SubExpr),
+                                       TInfo, SubExpr,
                                        SourceRange(LAngleLoc, RAngleLoc),
                                        SourceRange(LParenLoc, RParenLoc));
   }
@@ -1481,16 +1492,15 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
+  ExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
                                                 TypeSourceInfo *TInfo,
                                                 SourceLocation LParenLoc,
-                                                ExprArg SubExpr,
+                                                Expr *Sub,
                                                 SourceLocation RParenLoc) {
-    void *Sub = SubExpr.takeAs<Expr>();
     return getSema().ActOnCXXTypeConstructExpr(TypeRange,
-                                               TInfo->getType().getAsOpaquePtr(),
+                                             ParsedType::make(TInfo->getType()),
                                                LParenLoc,
-                                         Sema::MultiExprArg(getSema(), &Sub, 1),
+                                               MultiExprArg(&Sub, 1),
                                                /*CommaLocs=*/0,
                                                RParenLoc);
   }
@@ -1499,7 +1509,7 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
+  ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
                                         SourceLocation TypeidLoc,
                                         TypeSourceInfo *Operand,
                                         SourceLocation RParenLoc) {
@@ -1511,11 +1521,11 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
+  ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
                                         SourceLocation TypeidLoc,
-                                        ExprArg Operand,
+                                        Expr *Operand,
                                         SourceLocation RParenLoc) {
-    return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, move(Operand),
+    return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
                                     RParenLoc);
   }
 
@@ -1524,7 +1534,7 @@
   /// 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,
+  ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
                                       QualType ThisType,
                                       bool isImplicit) {
     return getSema().Owned(
@@ -1536,8 +1546,8 @@
   ///
   /// 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));
+  ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub) {
+    return getSema().ActOnCXXThrow(ThrowLoc, Sub);
   }
 
   /// \brief Build a new C++ default-argument expression.
@@ -1545,7 +1555,7 @@
   /// 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, 
+  ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, 
                                             ParmVarDecl *Param) {
     return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Loc,
                                                      Param));
@@ -1555,12 +1565,12 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
+  ExprResult RebuildCXXScalarValueInitExpr(SourceLocation TypeStartLoc,
                                                SourceLocation LParenLoc,
                                                QualType T,
                                                SourceLocation RParenLoc) {
     return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
-                                               T.getAsOpaquePtr(), LParenLoc,
+                                               ParsedType::make(T), LParenLoc,
                                                MultiExprArg(getSema(), 0, 0),
                                                0, RParenLoc);
   }
@@ -1569,16 +1579,16 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
+  ExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
                                      bool UseGlobal,
                                      SourceLocation PlacementLParen,
                                      MultiExprArg PlacementArgs,
                                      SourceLocation PlacementRParen,
-                                     bool ParenTypeId,
+                                     SourceRange TypeIdParens,
                                      QualType AllocType,
                                      SourceLocation TypeLoc,
                                      SourceRange TypeRange,
-                                     ExprArg ArraySize,
+                                     Expr *ArraySize,
                                      SourceLocation ConstructorLParen,
                                      MultiExprArg ConstructorArgs,
                                      SourceLocation ConstructorRParen) {
@@ -1586,11 +1596,11 @@
                                  PlacementLParen,
                                  move(PlacementArgs),
                                  PlacementRParen,
-                                 ParenTypeId,
+                                 TypeIdParens,
                                  AllocType,
                                  TypeLoc,
                                  TypeRange,
-                                 move(ArraySize),
+                                 ArraySize,
                                  ConstructorLParen,
                                  move(ConstructorArgs),
                                  ConstructorRParen);
@@ -1600,25 +1610,25 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
+  ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
                                         bool IsGlobalDelete,
                                         bool IsArrayForm,
-                                        ExprArg Operand) {
+                                        Expr *Operand) {
     return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
-                                    move(Operand));
+                                    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,
+  ExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
                                          SourceLocation StartLoc,
                                          SourceLocation LParenLoc,
                                          QualType T,
                                          SourceLocation RParenLoc) {
     return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
-                                         T.getAsOpaquePtr(), RParenLoc);
+                                         ParsedType::make(T), RParenLoc);
   }
 
   /// \brief Build a new (previously unresolved) declaration reference
@@ -1626,27 +1636,26 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildDependentScopeDeclRefExpr(NestedNameSpecifier *NNS,
+  ExprResult RebuildDependentScopeDeclRefExpr(NestedNameSpecifier *NNS,
                                                 SourceRange QualifierRange,
-                                                DeclarationName Name,
-                                                SourceLocation Location,
+                                       const DeclarationNameInfo &NameInfo,
                               const TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
     SS.setRange(QualifierRange);
     SS.setScopeRep(NNS);
 
     if (TemplateArgs)
-      return getSema().BuildQualifiedTemplateIdExpr(SS, Name, Location,
+      return getSema().BuildQualifiedTemplateIdExpr(SS, NameInfo,
                                                     *TemplateArgs);
 
-    return getSema().BuildQualifiedDeclarationNameExpr(SS, Name, Location);
+    return getSema().BuildQualifiedDeclarationNameExpr(SS, NameInfo);
   }
 
   /// \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,
+  ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
                                          LookupResult &R,
                                          bool RequiresADL,
                               const TemplateArgumentListInfo &TemplateArgs) {
@@ -1657,32 +1666,35 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXConstructExpr(QualType T,
+  ExprResult RebuildCXXConstructExpr(QualType T,
                                            SourceLocation Loc,
                                            CXXConstructorDecl *Constructor,
                                            bool IsElidable,
-                                           MultiExprArg Args) {
-    ASTOwningVector<&ActionBase::DeleteExpr> ConvertedArgs(SemaRef);
+                                           MultiExprArg Args,
+                                           bool RequiresZeroInit,
+                             CXXConstructExpr::ConstructionKind ConstructKind) {
+    ASTOwningVector<Expr*> ConvertedArgs(SemaRef);
     if (getSema().CompleteConstructorCall(Constructor, move(Args), Loc, 
                                           ConvertedArgs))
-      return getSema().ExprError();
+      return ExprError();
     
     return getSema().BuildCXXConstructExpr(Loc, T, Constructor, IsElidable,
-                                           move_arg(ConvertedArgs));
+                                           move_arg(ConvertedArgs),
+                                           RequiresZeroInit, ConstructKind);
   }
 
   /// \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,
+  ExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
                                                  QualType T,
                                                  SourceLocation LParenLoc,
                                                  MultiExprArg Args,
                                                  SourceLocation *Commas,
                                                  SourceLocation RParenLoc) {
     return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
-                                               T.getAsOpaquePtr(),
+                                               ParsedType::make(T),
                                                LParenLoc,
                                                move(Args),
                                                Commas,
@@ -1693,7 +1705,7 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
+  ExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
                                                      QualType T,
                                                      SourceLocation LParenLoc,
                                                      MultiExprArg Args,
@@ -1701,7 +1713,7 @@
                                                      SourceLocation RParenLoc) {
     return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
                                                            /*FIXME*/LParenLoc),
-                                               T.getAsOpaquePtr(),
+                                               ParsedType::make(T),
                                                LParenLoc,
                                                move(Args),
                                                Commas,
@@ -1712,31 +1724,31 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXDependentScopeMemberExpr(ExprArg BaseE,
+  ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
                                                   QualType BaseType,
                                                   bool IsArrow,
                                                   SourceLocation OperatorLoc,
                                               NestedNameSpecifier *Qualifier,
                                                   SourceRange QualifierRange,
                                             NamedDecl *FirstQualifierInScope,
-                                                  DeclarationName Name,
-                                                  SourceLocation MemberLoc,
+                                   const DeclarationNameInfo &MemberNameInfo,
                               const TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
     SS.setRange(QualifierRange);
     SS.setScopeRep(Qualifier);
 
-    return SemaRef.BuildMemberReferenceExpr(move(BaseE), BaseType,
+    return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
                                             OperatorLoc, IsArrow,
                                             SS, FirstQualifierInScope,
-                                            Name, MemberLoc, TemplateArgs);
+                                            MemberNameInfo,
+                                            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,
+  ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE,
                                                QualType BaseType,
                                                SourceLocation OperatorLoc,
                                                bool IsArrow,
@@ -1749,7 +1761,7 @@
     SS.setRange(QualifierRange);
     SS.setScopeRep(Qualifier);
 
-    return SemaRef.BuildMemberReferenceExpr(move(BaseE), BaseType,
+    return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
                                             OperatorLoc, IsArrow,
                                             SS, FirstQualifierInScope,
                                             R, TemplateArgs);
@@ -1759,7 +1771,7 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
+  ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
                                          TypeSourceInfo *EncodeTypeInfo,
                                          SourceLocation RParenLoc) {
     return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,
@@ -1767,7 +1779,7 @@
   }
 
   /// \brief Build a new Objective-C class message.
-  OwningExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
+  ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
                                           Selector Sel,
                                           ObjCMethodDecl *Method,
                                           SourceLocation LBracLoc, 
@@ -1781,15 +1793,14 @@
   }
 
   /// \brief Build a new Objective-C instance message.
-  OwningExprResult RebuildObjCMessageExpr(ExprArg Receiver,
+  ExprResult RebuildObjCMessageExpr(Expr *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,
+    return SemaRef.BuildInstanceMessage(Receiver,
+                                        Receiver->getType(),
                                         /*SuperLoc=*/SourceLocation(),
                                         Sel, Method, LBracLoc, RBracLoc,
                                         move(Args));
@@ -1799,25 +1810,25 @@
   ///
   /// 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,
+  ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
                                           SourceLocation IvarLoc,
                                           bool IsArrow, bool IsFreeIvar) {
     // FIXME: We lose track of the IsFreeIvar bit.
     CXXScopeSpec SS;
-    Expr *Base = BaseArg.takeAs<Expr>();
+    Expr *Base = BaseArg;
     LookupResult R(getSema(), Ivar->getDeclName(), IvarLoc,
                    Sema::LookupMemberName);
-    OwningExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
+    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
                                                          /*FIME:*/IvarLoc,
-                                                         SS, DeclPtrTy());
+                                                         SS, 0,
+                                                         false);
     if (Result.isInvalid())
-      return getSema().ExprError();
+      return ExprError();
     
     if (Result.get())
       return move(Result);
     
-    return getSema().BuildMemberReferenceExpr(getSema().Owned(Base), 
-                                              Base->getType(),
+    return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
                                               /*FIXME:*/IvarLoc, IsArrow, SS, 
                                               /*FirstQualifierInScope=*/0,
                                               R, 
@@ -1828,25 +1839,24 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildObjCPropertyRefExpr(ExprArg BaseArg, 
+  ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg, 
                                               ObjCPropertyDecl *Property,
                                               SourceLocation PropertyLoc) {
     CXXScopeSpec SS;
-    Expr *Base = BaseArg.takeAs<Expr>();
+    Expr *Base = BaseArg;
     LookupResult R(getSema(), Property->getDeclName(), PropertyLoc,
                    Sema::LookupMemberName);
     bool IsArrow = false;
-    OwningExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
+    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
                                                          /*FIME:*/PropertyLoc,
-                                                         SS, DeclPtrTy());
+                                                         SS, 0, false);
     if (Result.isInvalid())
-      return getSema().ExprError();
+      return ExprError();
     
     if (Result.get())
       return move(Result);
     
-    return getSema().BuildMemberReferenceExpr(getSema().Owned(Base), 
-                                              Base->getType(),
+    return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
                                               /*FIXME:*/PropertyLoc, IsArrow, 
                                               SS, 
                                               /*FirstQualifierInScope=*/0,
@@ -1859,42 +1869,41 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.  
-  OwningExprResult RebuildObjCImplicitSetterGetterRefExpr(
+  ExprResult RebuildObjCImplicitSetterGetterRefExpr(
                                                         ObjCMethodDecl *Getter,
                                                           QualType T,
                                                         ObjCMethodDecl *Setter,
                                                         SourceLocation NameLoc,
-                                                          ExprArg Base) {
+                                                          Expr *Base) {
     // Since these expressions can only be value-dependent, we do not need to
     // perform semantic analysis again.
-    return getSema().Owned(
+    return Owned(
              new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T,
                                                                      Setter,
                                                                      NameLoc,
-                                                          Base.takeAs<Expr>()));
+                                                                     Base));
   }
 
   /// \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,
+  ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
                                       bool IsArrow) {
     CXXScopeSpec SS;
-    Expr *Base = BaseArg.takeAs<Expr>();
+    Expr *Base = BaseArg;
     LookupResult R(getSema(), &getSema().Context.Idents.get("isa"), IsaLoc,
                    Sema::LookupMemberName);
-    OwningExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
+    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
                                                          /*FIME:*/IsaLoc,
-                                                         SS, DeclPtrTy());
+                                                         SS, 0, false);
     if (Result.isInvalid())
-      return getSema().ExprError();
+      return ExprError();
     
     if (Result.get())
       return move(Result);
     
-    return getSema().BuildMemberReferenceExpr(getSema().Owned(Base), 
-                                              Base->getType(),
+    return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
                                               /*FIXME:*/IsaLoc, IsArrow, SS, 
                                               /*FirstQualifierInScope=*/0,
                                               R, 
@@ -1905,7 +1914,7 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
+  ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
                                             MultiExprArg SubExprs,
                                             SourceLocation RParenLoc) {
     // Find the declaration for __builtin_shufflevector
@@ -1927,14 +1936,14 @@
     Expr **Subs = (Expr **)SubExprs.release();
     CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
                                                        Subs, NumSubExprs,
-                                                       Builtin->getResultType(),
+                                                   Builtin->getCallResultType(),
                                                        RParenLoc);
-    OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
+    ExprResult OwnedCall(SemaRef.Owned(TheCall));
 
     // Type-check the __builtin_shufflevector expression.
-    OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
+    ExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
     if (Result.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     OwnedCall.release();
     return move(Result);
@@ -1942,7 +1951,7 @@
 };
 
 template<typename Derived>
-Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
+StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
   if (!S)
     return SemaRef.Owned(S);
 
@@ -1953,19 +1962,19 @@
 #define STMT(Node, Parent)                                              \
   case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
 #define EXPR(Node, Parent)
-#include "clang/AST/StmtNodes.def"
+#include "clang/AST/StmtNodes.inc"
 
   // Transform expressions by calling TransformExpr.
 #define STMT(Node, Parent)
-#define ABSTRACT_EXPR(Node, Parent)
+#define ABSTRACT_STMT(Stmt)
 #define EXPR(Node, Parent) case Stmt::Node##Class:
-#include "clang/AST/StmtNodes.def"
+#include "clang/AST/StmtNodes.inc"
     {
-      Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
+      ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
       if (E.isInvalid())
-        return getSema().StmtError();
+        return StmtError();
 
-      return getSema().ActOnExprStmt(getSema().MakeFullExpr(E));
+      return getSema().ActOnExprStmt(getSema().MakeFullExpr(E.take()));
     }
   }
 
@@ -1974,17 +1983,17 @@
 
 
 template<typename Derived>
-Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
+ExprResult 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 ABSTRACT_STMT(Stmt)
 #define EXPR(Node, Parent)                                              \
     case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
-#include "clang/AST/StmtNodes.def"
+#include "clang/AST/StmtNodes.inc"
   }
 
   return SemaRef.Owned(E->Retain());
@@ -2069,12 +2078,13 @@
 }
 
 template<typename Derived>
-DeclarationName
-TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
-                                                 SourceLocation Loc,
-                                                 QualType ObjectType) {
+DeclarationNameInfo
+TreeTransform<Derived>
+::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+                               QualType ObjectType) {
+  DeclarationName Name = NameInfo.getName();
   if (!Name)
-    return Name;
+    return DeclarationNameInfo();
 
   switch (Name.getNameKind()) {
   case DeclarationName::Identifier:
@@ -2084,24 +2094,41 @@
   case DeclarationName::CXXOperatorName:
   case DeclarationName::CXXLiteralOperatorName:
   case DeclarationName::CXXUsingDirective:
-    return Name;
+    return NameInfo;
 
   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();
+    TypeSourceInfo *NewTInfo;
+    CanQualType NewCanTy;
+    if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
+       NewTInfo = getDerived().TransformType(OldTInfo, ObjectType);
+       if (!NewTInfo)
+         return DeclarationNameInfo();
+       NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
+    }
+    else {
+      NewTInfo = 0;
+      TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
+      QualType NewT = getDerived().TransformType(Name.getCXXNameType(),
+                                                 ObjectType);
+      if (NewT.isNull())
+        return DeclarationNameInfo();
+      NewCanTy = SemaRef.Context.getCanonicalType(NewT);
+    }
 
-    return SemaRef.Context.DeclarationNames.getCXXSpecialName(
-                                                           Name.getNameKind(),
-                                          SemaRef.Context.getCanonicalType(T));
+    DeclarationName NewName
+      = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
+                                                           NewCanTy);
+    DeclarationNameInfo NewNameInfo(NameInfo);
+    NewNameInfo.setName(NewName);
+    NewNameInfo.setNamedTypeInfo(NewTInfo);
+    return NewNameInfo;
   }
   }
 
-  return DeclarationName();
+  assert(0 && "Unknown name kind.");
+  return DeclarationNameInfo();
 }
 
 template<typename Derived>
@@ -2243,14 +2270,9 @@
     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();
-      }
+                                                   Sema::Unevaluated);
+      ExprResult E = getDerived().TransformExpr(SourceExpr);
+      SourceExpr = (E.isInvalid() ? 0 : E.take());
     }
 
     Output = TemplateArgumentLoc(TemplateArgument(D), SourceExpr);
@@ -2273,18 +2295,15 @@
   case TemplateArgument::Expression: {
     // Template argument expressions are not potentially evaluated.
     EnterExpressionEvaluationContext Unevaluated(getSema(),
-                                                 Action::Unevaluated);
+                                                 Sema::Unevaluated);
 
     Expr *InputExpr = Input.getSourceExpression();
     if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
 
-    Sema::OwningExprResult E
+    ExprResult E
       = getDerived().TransformExpr(InputExpr);
     if (E.isInvalid()) return true;
-
-    Expr *ETaken = E.takeAs<Expr>();
-    ETaken->Retain();
-    Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
+    Output = TemplateArgumentLoc(TemplateArgument(E.take()), E.take());
     return false;
   }
 
@@ -2399,11 +2418,11 @@
   if (Result->isFunctionType() || Result->isReferenceType())
     return Result;
 
-  Result = SemaRef.Context.getQualifiedType(Result, Quals);
-
-  TLB.push<QualifiedTypeLoc>(Result);
-
-  // No location information to preserve.
+  if (!Quals.empty()) {
+    Result = SemaRef.BuildQualifiedType(Result, T.getBeginLoc(), Quals);
+    TLB.push<QualifiedTypeLoc>(Result);
+    // No location information to preserve.
+  }
 
   return Result;
 }
@@ -2444,23 +2463,15 @@
     return QualType();
 
   QualType Result = TL.getType();
-  if (PointeeType->isObjCInterfaceType()) {
+  if (PointeeType->getAs<ObjCObjectType>()) {
     // 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());
+    Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);
     
-    ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);   
-    NewT.setStarLoc(TL.getSigilLoc());       
-    NewT.setHasProtocolsAsWritten(false);
-    NewT.setLAngleLoc(SourceLocation());
-    NewT.setRAngleLoc(SourceLocation());
-    NewT.setHasBaseTypeAsWritten(true);
+    ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
+    NewT.setStarLoc(TL.getStarLoc());
     return Result;
   }
                                                             
@@ -2614,7 +2625,7 @@
 
   Expr *Size = TL.getSizeExpr();
   if (Size) {
-    EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
     Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
   }
   NewTL.setSizeExpr(Size);
@@ -2662,14 +2673,14 @@
     return QualType();
 
   // Array bounds are not potentially evaluated contexts
-  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
-  Sema::OwningExprResult SizeResult
+  ExprResult SizeResult
     = getDerived().TransformExpr(T->getSizeExpr());
   if (SizeResult.isInvalid())
     return QualType();
 
-  Expr *Size = static_cast<Expr*>(SizeResult.get());
+  Expr *Size = SizeResult.take();
 
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
@@ -2677,13 +2688,12 @@
       Size != T->getSizeExpr()) {
     Result = getDerived().RebuildVariableArrayType(ElementType,
                                                    T->getSizeModifier(),
-                                                   move(SizeResult),
+                                                   Size,
                                              T->getIndexTypeCVRQualifiers(),
                                                    TL.getBracketsRange());
     if (Result.isNull())
       return QualType();
   }
-  else SizeResult.take();
   
   VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
   NewTL.setLBracketLoc(TL.getLBracketLoc());
@@ -2704,9 +2714,9 @@
     return QualType();
 
   // Array bounds are not potentially evaluated contexts
-  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
-  Sema::OwningExprResult SizeResult
+  ExprResult SizeResult
     = getDerived().TransformExpr(T->getSizeExpr());
   if (SizeResult.isInvalid())
     return QualType();
@@ -2719,7 +2729,7 @@
       Size != T->getSizeExpr()) {
     Result = getDerived().RebuildDependentSizedArrayType(ElementType,
                                                          T->getSizeModifier(),
-                                                         move(SizeResult),
+                                                         Size,
                                                 T->getIndexTypeCVRQualifiers(),
                                                         TL.getBracketsRange());
     if (Result.isNull())
@@ -2750,9 +2760,9 @@
     return QualType();
 
   // Vector sizes are not potentially evaluated contexts
-  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
-  Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
+  ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
   if (Size.isInvalid())
     return QualType();
 
@@ -2761,12 +2771,11 @@
       ElementType != T->getElementType() ||
       Size.get() != T->getSizeExpr()) {
     Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
-                                                         move(Size),
+                                                             Size.take(),
                                                          T->getAttributeLoc());
     if (Result.isNull())
       return QualType();
   }
-  else Size.take();
 
   // Result might be dependent or not.
   if (isa<DependentSizedExtVectorType>(Result)) {
@@ -2794,7 +2803,7 @@
   if (getDerived().AlwaysRebuild() ||
       ElementType != T->getElementType()) {
     Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
-      T->isAltiVec(), T->isPixel());
+      T->getAltiVecSpecific());
     if (Result.isNull())
       return QualType();
   }
@@ -2894,17 +2903,19 @@
 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.
+  // Transform the parameters. We do this first for the benefit of template
+  // instantiations, so that the ParmVarDecls get/ placed into the template
+  // instantiation scope before we transform the function type.
   llvm::SmallVector<QualType, 4> ParamTypes;
   llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
   if (getDerived().TransformFunctionTypeParams(TL, ParamTypes, ParamDecls))
     return QualType();
-
+  
+  FunctionProtoType *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() ||
@@ -2913,7 +2924,8 @@
                                                    ParamTypes.data(),
                                                    ParamTypes.size(),
                                                    T->isVariadic(),
-                                                   T->getTypeQuals());
+                                                   T->getTypeQuals(),
+                                                   T->getExtInfo());
     if (Result.isNull())
       return QualType();
   }
@@ -3003,16 +3015,16 @@
                                                       TypeOfExprTypeLoc TL,
                                                        QualType ObjectType) {
   // typeof expressions are not potentially evaluated contexts
-  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
-  Sema::OwningExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
+  ExprResult 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));
+    Result = getDerived().RebuildTypeOfExprType(E.get());
     if (Result.isNull())
       return QualType();
   }
@@ -3058,16 +3070,16 @@
   DecltypeType *T = TL.getTypePtr();
 
   // decltype expressions are not potentially evaluated contexts
-  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
-  Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
+  ExprResult 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));
+    Result = getDerived().RebuildDecltypeType(E.get());
     if (Result.isNull())
       return QualType();
   }
@@ -3129,31 +3141,6 @@
   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,
@@ -3258,32 +3245,54 @@
 
 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();
+TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
+                                                ElaboratedTypeLoc TL,
+                                                QualType ObjectType) {
+  ElaboratedType *T = TL.getTypePtr();
 
-  QualType Named = getDerived().TransformType(T->getNamedType());
-  if (Named.isNull())
-    return QualType();
+  NestedNameSpecifier *NNS = 0;
+  // NOTE: the qualifier in an ElaboratedType is optional.
+  if (T->getQualifier() != 0) {
+    NNS = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
+                                                    TL.getQualifierRange(),
+                                                    ObjectType);
+    if (!NNS)
+      return QualType();
+  }
+
+  QualType NamedT;
+  // FIXME: this test is meant to workaround a problem (failing assertion)
+  // occurring if directly executing the code in the else branch.
+  if (isa<TemplateSpecializationTypeLoc>(TL.getNamedTypeLoc())) {
+    TemplateSpecializationTypeLoc OldNamedTL
+      = cast<TemplateSpecializationTypeLoc>(TL.getNamedTypeLoc());
+    const TemplateSpecializationType* OldTST
+      = OldNamedTL.getType()->template getAs<TemplateSpecializationType>();
+    NamedT = TransformTemplateSpecializationType(OldTST, ObjectType);
+    if (NamedT.isNull())
+      return QualType();
+    TemplateSpecializationTypeLoc NewNamedTL
+      = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
+    NewNamedTL.copy(OldNamedTL);
+  }
+  else {
+    NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
+    if (NamedT.isNull())
+      return QualType();
+  }
 
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
       NNS != T->getQualifier() ||
-      Named != T->getNamedType()) {
-    Result = getDerived().RebuildQualifiedNameType(NNS, Named);
+      NamedT != T->getNamedType()) {
+    Result = getDerived().RebuildElaboratedType(T->getKeyword(), NNS, NamedT);
     if (Result.isNull())
       return QualType();
   }
 
-  QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result);
-  NewTL.setNameLoc(TL.getNameLoc());
+  ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
+  NewTL.setKeywordLoc(TL.getKeywordLoc());
+  NewTL.setQualifierRange(TL.getQualifierRange());
 
   return Result;
 }
@@ -3294,40 +3303,91 @@
                                                        QualType ObjectType) {
   DependentNameType *T = TL.getTypePtr();
 
-  /* FIXME: preserve source information better than this */
-  SourceRange SR(TL.getNameLoc());
-
   NestedNameSpecifier *NNS
-    = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR,
+    = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
+                                                TL.getQualifierRange(),
                                                 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);
-  }
+  QualType Result
+    = getDerived().RebuildDependentNameType(T->getKeyword(), NNS,
+                                            T->getIdentifier(),
+                                            TL.getKeywordLoc(),
+                                            TL.getQualifierRange(),
+                                            TL.getNameLoc());
   if (Result.isNull())
     return QualType();
 
-  DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
-  NewTL.setNameLoc(TL.getNameLoc());
+  if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
+    QualType NamedT = ElabT->getNamedType();
+    TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
 
+    ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
+    NewTL.setKeywordLoc(TL.getKeywordLoc());
+    NewTL.setQualifierRange(TL.getQualifierRange());
+  } else {
+    DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
+    NewTL.setKeywordLoc(TL.getKeywordLoc());
+    NewTL.setQualifierRange(TL.getQualifierRange());
+    NewTL.setNameLoc(TL.getNameLoc());
+  }
+  return Result;
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::
+          TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
+                                 DependentTemplateSpecializationTypeLoc TL,
+                                                       QualType ObjectType) {
+  DependentTemplateSpecializationType *T = TL.getTypePtr();
+
+  NestedNameSpecifier *NNS
+    = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
+                                                TL.getQualifierRange(),
+                                                ObjectType);
+  if (!NNS)
+    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);
+  }
+
+  QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
+                                                     T->getKeyword(),
+                                                     NNS,
+                                                     T->getIdentifier(),
+                                                     TL.getNameLoc(),
+                                                     NewTemplateArgs);
+  if (Result.isNull())
+    return QualType();
+
+  if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
+    QualType NamedT = ElabT->getNamedType();
+
+    // Copy information relevant to the template specialization.
+    TemplateSpecializationTypeLoc NamedTL
+      = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
+    NamedTL.setLAngleLoc(TL.getLAngleLoc());
+    NamedTL.setRAngleLoc(TL.getRAngleLoc());
+    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
+      NamedTL.setArgLocInfo(I, TL.getArgLocInfo(I));
+
+    // Copy information relevant to the elaborated type.
+    ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
+    NewTL.setKeywordLoc(TL.getKeywordLoc());
+    NewTL.setQualifierRange(TL.getQualifierRange());
+  } else {
+    TypeLoc NewTL(Result, TL.getOpaqueData());
+    TLB.pushFullCopy(NewTL);
+  }
   return Result;
 }
 
@@ -3337,6 +3397,17 @@
                                                    ObjCInterfaceTypeLoc TL,
                                                    QualType ObjectType) {
   // ObjCInterfaceType is never dependent.
+  TLB.pushFullCopy(TL);
+  return TL.getType();
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
+                                                ObjCObjectTypeLoc TL,
+                                                QualType ObjectType) {
+  // ObjCObjectType is never dependent.
+  TLB.pushFullCopy(TL);
   return TL.getType();
 }
 
@@ -3346,6 +3417,7 @@
                                                ObjCObjectPointerTypeLoc TL,
                                                        QualType ObjectType) {
   // ObjCObjectPointerType is never dependent.
+  TLB.pushFullCopy(TL);
   return TL.getType();
 }
 
@@ -3353,33 +3425,45 @@
 // Statement transformation
 //===----------------------------------------------------------------------===//
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
   return SemaRef.Owned(S->Retain());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
   return getDerived().TransformCompoundStmt(S, false);
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
                                               bool IsStmtExpr) {
+  bool SubStmtInvalid = false;
   bool SubStmtChanged = false;
-  ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
+  ASTOwningVector<Stmt*> 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();
+    StmtResult Result = getDerived().TransformStmt(*B);
+    if (Result.isInvalid()) {
+      // Immediately fail if this was a DeclStmt, since it's very
+      // likely that this will cause problems for future statements.
+      if (isa<DeclStmt>(*B))
+        return StmtError();
+
+      // Otherwise, just keep processing substatements and fail later.
+      SubStmtInvalid = true;
+      continue;
+    }
 
     SubStmtChanged = SubStmtChanged || Result.get() != *B;
     Statements.push_back(Result.takeAs<Stmt>());
   }
 
+  if (SubStmtInvalid)
+    return StmtError();
+
   if (!getDerived().AlwaysRebuild() &&
       !SubStmtChanged)
     return SemaRef.Owned(S->Retain());
@@ -3391,75 +3475,75 @@
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
-  OwningExprResult LHS(SemaRef), RHS(SemaRef);
+  ExprResult LHS, RHS;
   {
     // The case value expressions are not potentially evaluated.
-    EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
     // Transform the left-hand case value.
     LHS = getDerived().TransformExpr(S->getLHS());
     if (LHS.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
 
     // Transform the right-hand case value (for the GNU case-range extension).
     RHS = getDerived().TransformExpr(S->getRHS());
     if (RHS.isInvalid())
-      return SemaRef.StmtError();
+      return 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),
+  StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
+                                                       LHS.get(),
                                                        S->getEllipsisLoc(),
-                                                       move(RHS),
+                                                       RHS.get(),
                                                        S->getColonLoc());
   if (Case.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Transform the statement following the case
-  OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+  StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
   if (SubStmt.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Attach the body to the case statement
-  return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
+  return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
   // Transform the statement following the default case
-  OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+  StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
   if (SubStmt.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Default statements are always rebuilt
   return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
-                                         move(SubStmt));
+                                         SubStmt.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
-  OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+  StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
   if (SubStmt.isInvalid())
-    return SemaRef.StmtError();
+    return 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));
+                                       SubStmt.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
   // Transform the condition
-  OwningExprResult Cond(SemaRef);
+  ExprResult Cond;
   VarDecl *ConditionVar = 0;
   if (S->getConditionVariable()) {
     ConditionVar 
@@ -3468,43 +3552,56 @@
                                       S->getConditionVariable()->getLocation(),
                                                     S->getConditionVariable()));
     if (!ConditionVar)
-      return SemaRef.StmtError();
+      return StmtError();
   } else {
     Cond = getDerived().TransformExpr(S->getCond());
   
     if (Cond.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
+    
+    // Convert the condition to a boolean value.
+    if (S->getCond()) {
+      ExprResult CondE = getSema().ActOnBooleanCondition(0, 
+                                                               S->getIfLoc(), 
+                                                               Cond.get());
+      if (CondE.isInvalid())
+        return StmtError();
+    
+      Cond = CondE.get();
+    }
   }
   
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
-
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
+    return StmtError();
+  
   // Transform the "then" branch.
-  OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
+  StmtResult Then = getDerived().TransformStmt(S->getThen());
   if (Then.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Transform the "else" branch.
-  OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
+  StmtResult Else = getDerived().TransformStmt(S->getElse());
   if (Else.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   if (!getDerived().AlwaysRebuild() &&
-      FullCond->get() == S->getCond() &&
+      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));
+                                    Then.get(),
+                                    S->getElseLoc(), Else.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
   // Transform the condition.
-  OwningExprResult Cond(SemaRef);
+  ExprResult Cond;
   VarDecl *ConditionVar = 0;
   if (S->getConditionVariable()) {
     ConditionVar 
@@ -3513,37 +3610,36 @@
                                       S->getConditionVariable()->getLocation(),
                                                     S->getConditionVariable()));
     if (!ConditionVar)
-      return SemaRef.StmtError();
+      return StmtError();
   } else {
     Cond = getDerived().TransformExpr(S->getCond());
     
     if (Cond.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
   }
 
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
-  
   // Rebuild the switch statement.
-  OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(FullCond,
-                                                                ConditionVar);
+  StmtResult Switch
+    = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Cond.get(),
+                                          ConditionVar);
   if (Switch.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Transform the body of the switch statement.
-  OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+  StmtResult Body = getDerived().TransformStmt(S->getBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Complete the switch statement.
-  return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
-                                            move(Body));
+  return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
+                                            Body.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
   // Transform the condition
-  OwningExprResult Cond(SemaRef);
+  ExprResult Cond;
   VarDecl *ConditionVar = 0;
   if (S->getConditionVariable()) {
     ConditionVar 
@@ -3552,64 +3648,76 @@
                                       S->getConditionVariable()->getLocation(),
                                                     S->getConditionVariable()));
     if (!ConditionVar)
-      return SemaRef.StmtError();
+      return StmtError();
   } else {
     Cond = getDerived().TransformExpr(S->getCond());
     
     if (Cond.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
+
+    if (S->getCond()) {
+      // Convert the condition to a boolean value.
+      ExprResult CondE = getSema().ActOnBooleanCondition(0, 
+                                                             S->getWhileLoc(), 
+                                                               Cond.get());
+      if (CondE.isInvalid())
+        return StmtError();
+      Cond = CondE;
+    }
   }
 
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
+    return StmtError();
 
   // Transform the body
-  OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+  StmtResult Body = getDerived().TransformStmt(S->getBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   if (!getDerived().AlwaysRebuild() &&
-      FullCond->get() == S->getCond() &&
+      FullCond.get() == S->getCond() &&
       ConditionVar == S->getConditionVariable() &&
       Body.get() == S->getBody())
-    return SemaRef.Owned(S->Retain());
+    return Owned(S);
 
-  return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, ConditionVar,
-                                       move(Body));
+  return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond,
+                                       ConditionVar, Body.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 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());
+  StmtResult Body = getDerived().TransformStmt(S->getBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
+  // Transform the condition
+  ExprResult Cond = getDerived().TransformExpr(S->getCond());
+  if (Cond.isInvalid())
+    return 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),
+  return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
+                                    /*FIXME:*/S->getWhileLoc(), Cond.get(),
                                     S->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
   // Transform the initialization statement
-  OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
+  StmtResult Init = getDerived().TransformStmt(S->getInit());
   if (Init.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Transform the condition
-  OwningExprResult Cond(SemaRef);
+  ExprResult Cond;
   VarDecl *ConditionVar = 0;
   if (S->getConditionVariable()) {
     ConditionVar 
@@ -3618,40 +3726,57 @@
                                       S->getConditionVariable()->getLocation(),
                                                     S->getConditionVariable()));
     if (!ConditionVar)
-      return SemaRef.StmtError();
+      return StmtError();
   } else {
     Cond = getDerived().TransformExpr(S->getCond());
     
     if (Cond.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
+
+    if (S->getCond()) {
+      // Convert the condition to a boolean value.
+      ExprResult CondE = getSema().ActOnBooleanCondition(0, 
+                                                               S->getForLoc(), 
+                                                               Cond.get());
+      if (CondE.isInvalid())
+        return StmtError();
+
+      Cond = CondE.get();
+    }
   }
 
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));  
+  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
+    return StmtError();
+
   // Transform the increment
-  OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
+  ExprResult Inc = getDerived().TransformExpr(S->getInc());
   if (Inc.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
+
+  Sema::FullExprArg FullInc(getSema().MakeFullExpr(Inc.get()));
+  if (S->getInc() && !FullInc.get())
+    return StmtError();
 
   // Transform the body
-  OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+  StmtResult Body = getDerived().TransformStmt(S->getBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   if (!getDerived().AlwaysRebuild() &&
       Init.get() == S->getInit() &&
-      Cond.get() == S->getCond() &&
+      FullCond.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));
+                                     Init.get(), FullCond, ConditionVar,
+                                     FullInc, S->getRParenLoc(), Body.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
   // Goto statements must always be rebuilt, to resolve the label.
   return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
@@ -3659,46 +3784,46 @@
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
-  OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
+  ExprResult Target = getDerived().TransformExpr(S->getTarget());
   if (Target.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   if (!getDerived().AlwaysRebuild() &&
       Target.get() == S->getTarget())
     return SemaRef.Owned(S->Retain());
 
   return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
-                                              move(Target));
+                                              Target.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
   return SemaRef.Owned(S->Retain());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
   return SemaRef.Owned(S->Retain());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
-  Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
+  ExprResult Result = getDerived().TransformExpr(S->getRetValue());
   if (Result.isInvalid())
-    return SemaRef.StmtError();
+    return 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));
+  return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
   bool DeclChanged = false;
   llvm::SmallVector<Decl *, 4> Decls;
@@ -3707,7 +3832,7 @@
     Decl *Transformed = getDerived().TransformDefinition((*D)->getLocation(),
                                                          *D);
     if (!Transformed)
-      return SemaRef.StmtError();
+      return StmtError();
 
     if (Transformed != *D)
       DeclChanged = true;
@@ -3723,22 +3848,22 @@
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
   assert(false && "SwitchCase is abstract and cannot be transformed");
   return SemaRef.Owned(S->Retain());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
   
-  ASTOwningVector<&ActionBase::DeleteExpr> Constraints(getSema());
-  ASTOwningVector<&ActionBase::DeleteExpr> Exprs(getSema());
+  ASTOwningVector<Expr*> Constraints(getSema());
+  ASTOwningVector<Expr*> Exprs(getSema());
   llvm::SmallVector<IdentifierInfo *, 4> Names;
 
-  OwningExprResult AsmString(SemaRef);
-  ASTOwningVector<&ActionBase::DeleteExpr> Clobbers(getSema());
+  ExprResult AsmString;
+  ASTOwningVector<Expr*> Clobbers(getSema());
 
   bool ExprsChanged = false;
   
@@ -3751,13 +3876,13 @@
     
     // Transform the output expr.
     Expr *OutputExpr = S->getOutputExpr(I);
-    OwningExprResult Result = getDerived().TransformExpr(OutputExpr);
+    ExprResult Result = getDerived().TransformExpr(OutputExpr);
     if (Result.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
     
     ExprsChanged |= Result.get() != OutputExpr;
     
-    Exprs.push_back(Result.takeAs<Expr>());
+    Exprs.push_back(Result.get());
   }
   
   // Go through the inputs.
@@ -3769,13 +3894,13 @@
     
     // Transform the input expr.
     Expr *InputExpr = S->getInputExpr(I);
-    OwningExprResult Result = getDerived().TransformExpr(InputExpr);
+    ExprResult Result = getDerived().TransformExpr(InputExpr);
     if (Result.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
     
     ExprsChanged |= Result.get() != InputExpr;
     
-    Exprs.push_back(Result.takeAs<Expr>());
+    Exprs.push_back(Result.get());
   }
   
   if (!getDerived().AlwaysRebuild() && !ExprsChanged)
@@ -3796,7 +3921,7 @@
                                      Names.data(),
                                      move_arg(Constraints),
                                      move_arg(Exprs),
-                                     move(AsmString),
+                                     AsmString.get(),
                                      move_arg(Clobbers),
                                      S->getRParenLoc(),
                                      S->isMSAsm());
@@ -3804,31 +3929,31 @@
 
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
   // Transform the body of the @try.
-  OwningStmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
+  StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
   if (TryBody.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   // Transform the @catch statements (if present).
   bool AnyCatchChanged = false;
-  ASTOwningVector<&ActionBase::DeleteStmt> CatchStmts(SemaRef);
+  ASTOwningVector<Stmt*> CatchStmts(SemaRef);
   for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
-    OwningStmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
+    StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
     if (Catch.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
     if (Catch.get() != S->getCatchStmt(I))
       AnyCatchChanged = true;
     CatchStmts.push_back(Catch.release());
   }
   
   // Transform the @finally statement (if present).
-  OwningStmtResult Finally(SemaRef);
+  StmtResult Finally;
   if (S->getFinallyStmt()) {
     Finally = getDerived().TransformStmt(S->getFinallyStmt());
     if (Finally.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
   }
 
   // If nothing changed, just retain this statement.
@@ -3839,12 +3964,12 @@
     return SemaRef.Owned(S->Retain());
   
   // Build a new statement.
-  return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), move(TryBody),
-                                           move_arg(CatchStmts), move(Finally));
+  return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
+                                           move_arg(CatchStmts), Finally.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
   // Transform the @catch parameter, if there is one.
   VarDecl *Var = 0;
@@ -3853,7 +3978,7 @@
     if (FromVar->getTypeSourceInfo()) {
       TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
       if (!TSInfo)
-        return SemaRef.StmtError();
+        return StmtError();
     }
     
     QualType T;
@@ -3862,30 +3987,30 @@
     else {
       T = getDerived().TransformType(FromVar->getType());
       if (T.isNull())
-        return SemaRef.StmtError();        
+        return StmtError();        
     }
     
     Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
     if (!Var)
-      return SemaRef.StmtError();
+      return StmtError();
   }
   
-  OwningStmtResult Body = getDerived().TransformStmt(S->getCatchBody());
+  StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(), 
                                              S->getRParenLoc(),
-                                             Var, move(Body));
+                                             Var, Body.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
   // Transform the body.
-  OwningStmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
+  StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   // If nothing changed, just retain this statement.
   if (!getDerived().AlwaysRebuild() &&
@@ -3894,39 +4019,39 @@
 
   // Build a new statement.
   return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
-                                               move(Body));
+                                               Body.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
-  OwningExprResult Operand(SemaRef);
+  ExprResult Operand;
   if (S->getThrowExpr()) {
     Operand = getDerived().TransformExpr(S->getThrowExpr());
     if (Operand.isInvalid())
-      return getSema().StmtError();
+      return StmtError();
   }
   
   if (!getDerived().AlwaysRebuild() &&
       Operand.get() == S->getThrowExpr())
     return getSema().Owned(S->Retain());
     
-  return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), move(Operand));
+  return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
                                                   ObjCAtSynchronizedStmt *S) {
   // Transform the object we are locking.
-  OwningExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
+  ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
   if (Object.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   // Transform the body.
-  OwningStmtResult Body = getDerived().TransformStmt(S->getSynchBody());
+  StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   // If nothing change, just retain the current statement.
   if (!getDerived().AlwaysRebuild() &&
@@ -3936,27 +4061,27 @@
 
   // Build a new statement.
   return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
-                                                    move(Object), move(Body));
+                                                    Object.get(), Body.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformObjCForCollectionStmt(
                                                   ObjCForCollectionStmt *S) {
   // Transform the element statement.
-  OwningStmtResult Element = getDerived().TransformStmt(S->getElement());
+  StmtResult Element = getDerived().TransformStmt(S->getElement());
   if (Element.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   // Transform the collection expression.
-  OwningExprResult Collection = getDerived().TransformExpr(S->getCollection());
+  ExprResult Collection = getDerived().TransformExpr(S->getCollection());
   if (Collection.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   // Transform the body.
-  OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+  StmtResult Body = getDerived().TransformStmt(S->getBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   // If nothing changed, just retain this statement.
   if (!getDerived().AlwaysRebuild() &&
@@ -3968,15 +4093,15 @@
   // Build a new statement.
   return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
                                                    /*FIXME:*/S->getForLoc(),
-                                                   move(Element),
-                                                   move(Collection),
+                                                   Element.get(),
+                                                   Collection.get(),
                                                    S->getRParenLoc(),
-                                                   move(Body));
+                                                   Body.get());
 }
 
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
   // Transform the exception declaration, if any.
   VarDecl *Var = 0;
@@ -3987,7 +4112,7 @@
 
     QualType T = getDerived().TransformType(ExceptionDecl->getType());
     if (T.isNull())
-      return SemaRef.StmtError();
+      return StmtError();
 
     Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
                                             T,
@@ -3996,20 +4121,14 @@
                                             ExceptionDecl->getLocation(),
                                             /*FIXME: Inaccurate*/
                                     SourceRange(ExceptionDecl->getLocation()));
-    if (!Var || Var->isInvalidDecl()) {
-      if (Var)
-        Var->Destroy(SemaRef.Context);
-      return SemaRef.StmtError();
-    }
+    if (!Var || Var->isInvalidDecl())
+      return StmtError();
   }
 
   // Transform the actual exception handler.
-  OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
-  if (Handler.isInvalid()) {
-    if (Var)
-      Var->Destroy(SemaRef.Context);
-    return SemaRef.StmtError();
-  }
+  StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
+  if (Handler.isInvalid())
+    return StmtError();
 
   if (!getDerived().AlwaysRebuild() &&
       !Var &&
@@ -4018,26 +4137,26 @@
 
   return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
                                           Var,
-                                          move(Handler));
+                                          Handler.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
   // Transform the try block itself.
-  OwningStmtResult TryBlock
+  StmtResult TryBlock
     = getDerived().TransformCompoundStmt(S->getTryBlock());
   if (TryBlock.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Transform the handlers.
   bool HandlerChanged = false;
-  ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
+  ASTOwningVector<Stmt*> Handlers(SemaRef);
   for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
-    OwningStmtResult Handler
+    StmtResult Handler
       = getDerived().TransformCXXCatchStmt(S->getHandler(I));
     if (Handler.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
 
     HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
     Handlers.push_back(Handler.takeAs<Stmt>());
@@ -4048,7 +4167,7 @@
       !HandlerChanged)
     return SemaRef.Owned(S->Retain());
 
-  return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
+  return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
                                         move_arg(Handlers));
 }
 
@@ -4056,32 +4175,40 @@
 // Expression transformation
 //===----------------------------------------------------------------------===//
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
   NestedNameSpecifier *Qualifier = 0;
   if (E->getQualifier()) {
     Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
                                                        E->getQualifierRange());
     if (!Qualifier)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
   ValueDecl *ND
     = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
                                                          E->getDecl()));
   if (!ND)
-    return SemaRef.ExprError();
+    return ExprError();
 
-  if (!getDerived().AlwaysRebuild() && 
+  DeclarationNameInfo NameInfo = E->getNameInfo();
+  if (NameInfo.getName()) {
+    NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
+    if (!NameInfo.getName())
+      return ExprError();
+  }
+
+  if (!getDerived().AlwaysRebuild() &&
       Qualifier == E->getQualifier() &&
       ND == E->getDecl() &&
-      !E->hasExplicitTemplateArgumentList()) {
+      NameInfo.getName() == E->getDecl()->getDeclName() &&
+      !E->hasExplicitTemplateArgs()) {
 
     // Mark it referenced in the new context regardless.
     // FIXME: this is a bit instantiation-specific.
@@ -4091,90 +4218,156 @@
   }
 
   TemplateArgumentListInfo TransArgs, *TemplateArgs = 0;
-  if (E->hasExplicitTemplateArgumentList()) {
+  if (E->hasExplicitTemplateArgs()) {
     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();
+        return ExprError();
       TransArgs.addArgument(Loc);
     }
   }
 
   return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
-                                         ND, E->getLocation(), TemplateArgs);
+                                         ND, NameInfo, TemplateArgs);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
-  OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+  ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
     return SemaRef.Owned(E->Retain());
 
-  return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
+  return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
                                        E->getRParen());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
-  OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+  ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
     return SemaRef.Owned(E->Retain());
 
   return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
                                            E->getOpcode(),
-                                           move(SubExpr));
+                                           SubExpr.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
+TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
+  // Transform the type.
+  TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
+  if (!Type)
+    return ExprError();
+  
+  // Transform all of the components into components similar to what the
+  // parser uses.
+  // FIXME: It would be slightly more efficient in the non-dependent case to 
+  // just map FieldDecls, rather than requiring the rebuilder to look for 
+  // the fields again. However, __builtin_offsetof is rare enough in 
+  // template code that we don't care.
+  bool ExprChanged = false;
+  typedef Sema::OffsetOfComponent Component;
+  typedef OffsetOfExpr::OffsetOfNode Node;
+  llvm::SmallVector<Component, 4> Components;
+  for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
+    const Node &ON = E->getComponent(I);
+    Component Comp;
+    Comp.isBrackets = true;
+    Comp.LocStart = ON.getRange().getBegin();
+    Comp.LocEnd = ON.getRange().getEnd();
+    switch (ON.getKind()) {
+    case Node::Array: {
+      Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
+      ExprResult Index = getDerived().TransformExpr(FromIndex);
+      if (Index.isInvalid())
+        return ExprError();
+      
+      ExprChanged = ExprChanged || Index.get() != FromIndex;
+      Comp.isBrackets = true;
+      Comp.U.E = Index.get();
+      break;
+    }
+        
+    case Node::Field:
+    case Node::Identifier:
+      Comp.isBrackets = false;
+      Comp.U.IdentInfo = ON.getFieldName();
+      if (!Comp.U.IdentInfo)
+        continue;
+        
+      break;
+        
+    case Node::Base:
+      // Will be recomputed during the rebuild.
+      continue;
+    }
+    
+    Components.push_back(Comp);
+  }
+  
+  // If nothing changed, retain the existing expression.
+  if (!getDerived().AlwaysRebuild() &&
+      Type == E->getTypeSourceInfo() &&
+      !ExprChanged)
+    return SemaRef.Owned(E->Retain());
+  
+  // Build a new offsetof expression.
+  return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
+                                          Components.data(), Components.size(),
+                                          E->getRParenLoc());
+}
+
+template<typename Derived>
+ExprResult
 TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
   if (E->isArgumentType()) {
     TypeSourceInfo *OldT = E->getArgumentTypeInfo();
 
     TypeSourceInfo *NewT = getDerived().TransformType(OldT);
     if (!NewT)
-      return SemaRef.ExprError();
+      return ExprError();
 
     if (!getDerived().AlwaysRebuild() && OldT == NewT)
       return SemaRef.Owned(E->Retain());
@@ -4184,36 +4377,36 @@
                                              E->getSourceRange());
   }
 
-  Sema::OwningExprResult SubExpr(SemaRef);
+  ExprResult SubExpr;
   {
     // C++0x [expr.sizeof]p1:
     //   The operand is either an expression, which is an unevaluated operand
     //   [...]
-    EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
     SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
     if (SubExpr.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
       return SemaRef.Owned(E->Retain());
   }
 
-  return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
+  return getDerived().RebuildSizeOfAlignOf(SubExpr.get(), E->getOperatorLoc(),
                                            E->isSizeOf(),
                                            E->getSourceRange());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
-  OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+  ExprResult LHS = getDerived().TransformExpr(E->getLHS());
   if (LHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+  ExprResult RHS = getDerived().TransformExpr(E->getRHS());
   if (RHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
 
   if (!getDerived().AlwaysRebuild() &&
@@ -4221,35 +4414,35 @@
       RHS.get() == E->getRHS())
     return SemaRef.Owned(E->Retain());
 
-  return getDerived().RebuildArraySubscriptExpr(move(LHS),
+  return getDerived().RebuildArraySubscriptExpr(LHS.get(),
                                            /*FIXME:*/E->getLHS()->getLocStart(),
-                                                move(RHS),
+                                                RHS.get(),
                                                 E->getRBracketLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
   // Transform the callee.
-  OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
+  ExprResult Callee = getDerived().TransformExpr(E->getCallee());
   if (Callee.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   // Transform arguments.
   bool ArgChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  ASTOwningVector<Expr*> Args(SemaRef);
   llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
-    OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
+    ExprResult Arg = getDerived().TransformExpr(E->getArg(I));
     if (Arg.isInvalid())
-      return SemaRef.ExprError();
+      return 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>());
+    Args.push_back(Arg.get());
   }
 
   if (!getDerived().AlwaysRebuild() &&
@@ -4260,18 +4453,18 @@
   // FIXME: Wrong source location information for the '('.
   SourceLocation FakeLParenLoc
     = ((Expr *)Callee.get())->getSourceRange().getBegin();
-  return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
+  return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
                                       move_arg(Args),
                                       FakeCommaLocs.data(),
                                       E->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
-  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   NestedNameSpecifier *Qualifier = 0;
   if (E->hasQualifier()) {
@@ -4279,14 +4472,14 @@
       = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
                                                   E->getQualifierRange());
     if (Qualifier == 0)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
   ValueDecl *Member
     = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
                                                          E->getMemberDecl()));
   if (!Member)
-    return SemaRef.ExprError();
+    return ExprError();
 
   NamedDecl *FoundDecl = E->getFoundDecl();
   if (FoundDecl == E->getMemberDecl()) {
@@ -4295,7 +4488,7 @@
     FoundDecl = cast_or_null<NamedDecl>(
                    getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
     if (!FoundDecl)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
   if (!getDerived().AlwaysRebuild() &&
@@ -4303,7 +4496,7 @@
       Qualifier == E->getQualifier() &&
       Member == E->getMemberDecl() &&
       FoundDecl == E->getFoundDecl() &&
-      !E->hasExplicitTemplateArgumentList()) {
+      !E->hasExplicitTemplateArgs()) {
     
     // Mark it referenced in the new context regardless.
     // FIXME: this is a bit instantiation-specific.
@@ -4312,13 +4505,13 @@
   }
 
   TemplateArgumentListInfo TransArgs;
-  if (E->hasExplicitTemplateArgumentList()) {
+  if (E->hasExplicitTemplateArgs()) {
     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();
+        return ExprError();
       TransArgs.addArgument(Loc);
     }
   }
@@ -4333,28 +4526,28 @@
   // nested-name-qualifier (and therefore could do the lookup).
   NamedDecl *FirstQualifierInScope = 0;
 
-  return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
+  return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
                                         E->isArrow(),
                                         Qualifier,
                                         E->getQualifierRange(),
-                                        E->getMemberLoc(),
+                                        E->getMemberNameInfo(),
                                         Member,
                                         FoundDecl,
-                                        (E->hasExplicitTemplateArgumentList()
+                                        (E->hasExplicitTemplateArgs()
                                            ? &TransArgs : 0),
                                         FirstQualifierInScope);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
-  OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+  ExprResult LHS = getDerived().TransformExpr(E->getLHS());
   if (LHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+  ExprResult RHS = getDerived().TransformExpr(E->getRHS());
   if (RHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       LHS.get() == E->getLHS() &&
@@ -4362,30 +4555,30 @@
     return SemaRef.Owned(E->Retain());
 
   return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
-                                            move(LHS), move(RHS));
+                                            LHS.get(), RHS.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCompoundAssignOperator(
                                                       CompoundAssignOperator *E) {
   return getDerived().TransformBinaryOperator(E);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
-  OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
+  ExprResult Cond = getDerived().TransformExpr(E->getCond());
   if (Cond.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+  ExprResult LHS = getDerived().TransformExpr(E->getLHS());
   if (LHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+  ExprResult RHS = getDerived().TransformExpr(E->getRHS());
   if (RHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       Cond.get() == E->getCond() &&
@@ -4393,15 +4586,15 @@
       RHS.get() == E->getRHS())
     return SemaRef.Owned(E->Retain());
 
-  return getDerived().RebuildConditionalOperator(move(Cond),
+  return getDerived().RebuildConditionalOperator(Cond.get(),
                                                  E->getQuestionLoc(),
-                                                 move(LHS),
+                                                 LHS.get(),
                                                  E->getColonLoc(),
-                                                 move(RHS));
+                                                 RHS.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
   // Implicit casts are eliminated during transformation, since they
   // will be recomputed by semantic analysis after transformation.
@@ -4409,7 +4602,7 @@
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
   TypeSourceInfo *OldT;
   TypeSourceInfo *NewT;
@@ -4422,13 +4615,13 @@
     OldT = E->getTypeInfoAsWritten();
     NewT = getDerived().TransformType(OldT);
     if (!NewT)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
-  OwningExprResult SubExpr
+  ExprResult SubExpr
     = getDerived().TransformExpr(E->getSubExprAsWritten());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       OldT == NewT &&
@@ -4438,20 +4631,20 @@
   return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
                                             NewT,
                                             E->getRParenLoc(),
-                                            move(SubExpr));
+                                            SubExpr.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
   TypeSourceInfo *OldT = E->getTypeSourceInfo();
   TypeSourceInfo *NewT = getDerived().TransformType(OldT);
   if (!NewT)
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
+  ExprResult Init = getDerived().TransformExpr(E->getInitializer());
   if (Init.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       OldT == NewT &&
@@ -4464,15 +4657,15 @@
 
   return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), NewT,
                                    /*FIXME:*/E->getInitializer()->getLocEnd(),
-                                                 move(Init));
+                                                 Init.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
-  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase())
@@ -4481,24 +4674,24 @@
   // FIXME: Bad source location
   SourceLocation FakeOperatorLoc
     = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
-  return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
+  return getDerived().RebuildExtVectorElementExpr(Base.get(), FakeOperatorLoc,
                                                   E->getAccessorLoc(),
                                                   E->getAccessor());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
   bool InitChanged = false;
 
-  ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
+  ASTOwningVector<Expr*, 4> Inits(SemaRef);
   for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
-    OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
+    ExprResult Init = getDerived().TransformExpr(E->getInit(I));
     if (Init.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     InitChanged = InitChanged || Init.get() != E->getInit(I);
-    Inits.push_back(Init.takeAs<Expr>());
+    Inits.push_back(Init.get());
   }
 
   if (!getDerived().AlwaysRebuild() && !InitChanged)
@@ -4509,17 +4702,17 @@
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
   Designation Desig;
 
   // transform the initializer value
-  OwningExprResult Init = getDerived().TransformExpr(E->getInit());
+  ExprResult Init = getDerived().TransformExpr(E->getInit());
   if (Init.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   // transform the designators.
-  ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
+  ASTOwningVector<Expr*, 4> ArrayExprs(SemaRef);
   bool ExprChanged = false;
   for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
                                              DEnd = E->designators_end();
@@ -4532,9 +4725,9 @@
     }
 
     if (D->isArrayDesignator()) {
-      OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
+      ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
       if (Index.isInvalid())
-        return SemaRef.ExprError();
+        return ExprError();
 
       Desig.AddDesignator(Designator::getArray(Index.get(),
                                                D->getLBracketLoc()));
@@ -4545,14 +4738,14 @@
     }
 
     assert(D->isArrayRangeDesignator() && "New kind of designator?");
-    OwningExprResult Start
+    ExprResult Start
       = getDerived().TransformExpr(E->getArrayRangeStart(*D));
     if (Start.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
-    OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
+    ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
     if (End.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     Desig.AddDesignator(Designator::getArrayRange(Start.get(),
                                                   End.get(),
@@ -4573,11 +4766,11 @@
 
   return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
                                                 E->getEqualOrColonLoc(),
-                                                E->usesGNUSyntax(), move(Init));
+                                                E->usesGNUSyntax(), Init.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformImplicitValueInitExpr(
                                                      ImplicitValueInitExpr *E) {
   TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
@@ -4586,7 +4779,7 @@
   // need to transform the type?
   QualType T = getDerived().TransformType(E->getType());
   if (T.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       T == E->getType())
@@ -4596,44 +4789,37 @@
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
-  // FIXME: Do we want the type as written?
-  QualType T;
+  TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
+  if (!TInfo)
+    return ExprError();
 
-  {
-    // 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());
+  ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
-      T == E->getType() &&
+      TInfo == E->getWrittenTypeInfo() &&
       SubExpr.get() == E->getSubExpr())
     return SemaRef.Owned(E->Retain());
 
-  return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
-                                       T, E->getRParenLoc());
+  return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
+                                       TInfo, E->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
   bool ArgumentChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
+  ASTOwningVector<Expr*, 4> Inits(SemaRef);
   for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
-    OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
+    ExprResult Init = getDerived().TransformExpr(E->getExpr(I));
     if (Init.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
-    Inits.push_back(Init.takeAs<Expr>());
+    Inits.push_back(Init.get());
   }
 
   return getDerived().RebuildParenListExpr(E->getLParenLoc(),
@@ -4647,69 +4833,67 @@
 /// rebuilds the expression, so that the label identifier can be resolved to
 /// the corresponding label statement by semantic analysis.
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
   return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
                                            E->getLabel());
 }
 
 template<typename Derived>
-Sema::OwningExprResult 
+ExprResult 
 TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
-  OwningStmtResult SubStmt
+  StmtResult SubStmt
     = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
   if (SubStmt.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       SubStmt.get() == E->getSubStmt())
     return SemaRef.Owned(E->Retain());
 
   return getDerived().RebuildStmtExpr(E->getLParenLoc(),
-                                      move(SubStmt),
+                                      SubStmt.get(),
                                       E->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
-  QualType T1, T2;
-  {
-    // FIXME: Source location isn't quite accurate.
-    TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
+  TypeSourceInfo *TInfo1;
+  TypeSourceInfo *TInfo2;
+  
+  TInfo1 = getDerived().TransformType(E->getArgTInfo1());
+  if (!TInfo1)
+    return ExprError();
 
-    T1 = getDerived().TransformType(E->getArgType1());
-    if (T1.isNull())
-      return SemaRef.ExprError();
-
-    T2 = getDerived().TransformType(E->getArgType2());
-    if (T2.isNull())
-      return SemaRef.ExprError();
-  }
+  TInfo2 = getDerived().TransformType(E->getArgTInfo2());
+  if (!TInfo2)
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
-      T1 == E->getArgType1() &&
-      T2 == E->getArgType2())
+      TInfo1 == E->getArgTInfo1() &&
+      TInfo2 == E->getArgTInfo2())
     return SemaRef.Owned(E->Retain());
 
   return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
-                                                 T1, T2, E->getRParenLoc());
+                                                 TInfo1, TInfo2,
+                                                 E->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
-  OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
+  ExprResult Cond = getDerived().TransformExpr(E->getCond());
   if (Cond.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+  ExprResult LHS = getDerived().TransformExpr(E->getLHS());
   if (LHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+  ExprResult RHS = getDerived().TransformExpr(E->getRHS());
   if (RHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       Cond.get() == E->getCond() &&
@@ -4718,18 +4902,18 @@
     return SemaRef.Owned(E->Retain());
 
   return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
-                                        move(Cond), move(LHS), move(RHS),
+                                        Cond.get(), LHS.get(), RHS.get(),
                                         E->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
   switch (E->getOperator()) {
   case OO_New:
@@ -4737,16 +4921,16 @@
   case OO_Array_New:
   case OO_Array_Delete:
     llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
-    return SemaRef.ExprError();
+    return 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));
+    ExprResult Object = getDerived().TransformExpr(E->getArg(0));
     if (Object.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     // FIXME: Poor location information
     SourceLocation FakeLParenLoc
@@ -4754,15 +4938,15 @@
                               static_cast<Expr *>(Object.get())->getLocEnd());
 
     // Transform the call arguments.
-    ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+    ASTOwningVector<Expr*> 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));
+      ExprResult Arg = getDerived().TransformExpr(E->getArg(I));
       if (Arg.isInvalid())
-        return SemaRef.ExprError();
+        return ExprError();
 
       // FIXME: Poor source location information.
       SourceLocation FakeCommaLoc
@@ -4772,7 +4956,7 @@
       Args.push_back(Arg.release());
     }
 
-    return getDerived().RebuildCallExpr(move(Object), FakeLParenLoc,
+    return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc,
                                         move_arg(Args),
                                         FakeCommaLocs.data(),
                                         E->getLocEnd());
@@ -4788,27 +4972,27 @@
 
   case OO_Conditional:
     llvm_unreachable("conditional operator is not actually overloadable");
-    return SemaRef.ExprError();
+    return ExprError();
 
   case OO_None:
   case NUM_OVERLOADED_OPERATORS:
     llvm_unreachable("not an overloaded operator?");
-    return SemaRef.ExprError();
+    return ExprError();
   }
 
-  OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
+  ExprResult Callee = getDerived().TransformExpr(E->getCallee());
   if (Callee.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
+  ExprResult First = getDerived().TransformExpr(E->getArg(0));
   if (First.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult Second(SemaRef);
+  ExprResult Second;
   if (E->getNumArgs() == 2) {
     Second = getDerived().TransformExpr(E->getArg(1));
     if (Second.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
   if (!getDerived().AlwaysRebuild() &&
@@ -4819,19 +5003,19 @@
 
   return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
                                                  E->getOperatorLoc(),
-                                                 move(Callee),
-                                                 move(First),
-                                                 move(Second));
+                                                 Callee.get(),
+                                                 First.get(),
+                                                 Second.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
   return getDerived().TransformCallExpr(E);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
   TypeSourceInfo *OldT;
   TypeSourceInfo *NewT;
@@ -4844,13 +5028,13 @@
     OldT = E->getTypeInfoAsWritten();
     NewT = getDerived().TransformType(OldT);
     if (!NewT)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
-  OwningExprResult SubExpr
+  ExprResult SubExpr
     = getDerived().TransformExpr(E->getSubExprAsWritten());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       OldT == NewT &&
@@ -4870,37 +5054,37 @@
                                               NewT,
                                               FakeRAngleLoc,
                                               FakeRAngleLoc,
-                                              move(SubExpr),
+                                              SubExpr.get(),
                                               FakeRParenLoc);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
   return getDerived().TransformCXXNamedCastExpr(E);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
   return getDerived().TransformCXXNamedCastExpr(E);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
                                                       CXXReinterpretCastExpr *E) {
   return getDerived().TransformCXXNamedCastExpr(E);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
   return getDerived().TransformCXXNamedCastExpr(E);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
                                                      CXXFunctionalCastExpr *E) {
   TypeSourceInfo *OldT;
@@ -4911,13 +5095,13 @@
     OldT = E->getTypeInfoAsWritten();
     NewT = getDerived().TransformType(OldT);
     if (!NewT)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
-  OwningExprResult SubExpr
+  ExprResult SubExpr
     = getDerived().TransformExpr(E->getSubExprAsWritten());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       OldT == NewT &&
@@ -4929,18 +5113,18 @@
                                   /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
                                                    NewT,
                                       /*FIXME:*/E->getSubExpr()->getLocStart(),
-                                                   move(SubExpr),
+                                                   SubExpr.get(),
                                                    E->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
   if (E->isTypeOperand()) {
     TypeSourceInfo *TInfo
       = getDerived().TransformType(E->getTypeOperandSourceInfo());
     if (!TInfo)
-      return SemaRef.ExprError();
+      return ExprError();
 
     if (!getDerived().AlwaysRebuild() &&
         TInfo == E->getTypeOperandSourceInfo())
@@ -4956,11 +5140,11 @@
   // after we perform semantic analysis, so the expression is potentially
   // potentially evaluated.
   EnterExpressionEvaluationContext Unevaluated(SemaRef,
-                                      Action::PotentiallyPotentiallyEvaluated);
+                                      Sema::PotentiallyPotentiallyEvaluated);
 
-  OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
+  ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       SubExpr.get() == E->getExprOperand())
@@ -4968,31 +5152,31 @@
 
   return getDerived().RebuildCXXTypeidExpr(E->getType(),
                                            E->getLocStart(),
-                                           move(SubExpr),
+                                           SubExpr.get(),
                                            E->getLocEnd());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
                                                      CXXNullPtrLiteralExpr *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
   TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
 
   QualType T = getDerived().TransformType(E->getType());
   if (T.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       T == E->getType())
@@ -5002,27 +5186,27 @@
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
-  OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+  ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       SubExpr.get() == E->getSubExpr())
     return SemaRef.Owned(E->Retain());
 
-  return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
+  return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
   ParmVarDecl *Param
     = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getLocStart(),
                                                            E->getParam()));
   if (!Param)
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       Param == E->getParam())
@@ -5032,56 +5216,59 @@
 }
 
 template<typename Derived>
-Sema::OwningExprResult
-TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+ExprResult
+TreeTransform<Derived>::TransformCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
   TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
 
   QualType T = getDerived().TransformType(E->getType());
   if (T.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       T == E->getType())
     return SemaRef.Owned(E->Retain());
 
-  return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
-                                                /*FIXME:*/E->getTypeBeginLoc(),
-                                                  T,
-                                                  E->getRParenLoc());
+  return getDerived().RebuildCXXScalarValueInitExpr(E->getTypeBeginLoc(),
+                                                 /*FIXME:*/E->getTypeBeginLoc(),
+                                                    T,
+                                                    E->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 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();
+    return ExprError();
 
   // Transform the size of the array we're allocating (if any).
-  OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
+  ExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
   if (ArraySize.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   // Transform the placement arguments (if any).
   bool ArgumentChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
+  ASTOwningVector<Expr*> PlacementArgs(SemaRef);
   for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
-    OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
+    ExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
     if (Arg.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
     PlacementArgs.push_back(Arg.take());
   }
 
   // transform the constructor arguments (if any).
-  ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
+  ASTOwningVector<Expr*> ConstructorArgs(SemaRef);
   for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
-    OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
+    if (getDerived().DropCallArgument(E->getConstructorArg(I)))
+      break;
+    
+    ExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
     if (Arg.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
     ConstructorArgs.push_back(Arg.take());
@@ -5094,7 +5281,7 @@
                                    getDerived().TransformDecl(E->getLocStart(),
                                                          E->getConstructor()));
     if (!Constructor)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
   FunctionDecl *OperatorNew = 0;
@@ -5103,7 +5290,7 @@
                                  getDerived().TransformDecl(E->getLocStart(),
                                                          E->getOperatorNew()));
     if (!OperatorNew)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
   FunctionDecl *OperatorDelete = 0;
@@ -5112,7 +5299,7 @@
                                    getDerived().TransformDecl(E->getLocStart(),
                                                        E->getOperatorDelete()));
     if (!OperatorDelete)
-      return SemaRef.ExprError();
+      return ExprError();
   }
   
   if (!getDerived().AlwaysRebuild() &&
@@ -5145,10 +5332,10 @@
     } else if (const ConstantArrayType *ConsArrayT
                                      = dyn_cast<ConstantArrayType>(ArrayT)) {
       ArraySize 
-        = SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
-                                                  ConsArrayT->getSize(), 
-                                                  SemaRef.Context.getSizeType(),
-                                                  /*FIXME:*/E->getLocStart()));
+        = SemaRef.Owned(IntegerLiteral::Create(SemaRef.Context,
+                                               ConsArrayT->getSize(), 
+                                               SemaRef.Context.getSizeType(),
+                                               /*FIXME:*/E->getLocStart()));
       AllocType = ConsArrayT->getElementType();
     } else if (const DependentSizedArrayType *DepArrayT
                               = dyn_cast<DependentSizedArrayType>(ArrayT)) {
@@ -5163,22 +5350,22 @@
                                         /*FIXME:*/E->getLocStart(),
                                         move_arg(PlacementArgs),
                                         /*FIXME:*/E->getLocStart(),
-                                        E->isParenTypeId(),
+                                        E->getTypeIdParens(),
                                         AllocType,
                                         /*FIXME:*/E->getLocStart(),
                                         /*FIXME:*/SourceRange(),
-                                        move(ArraySize),
+                                        ArraySize.get(),
                                         /*FIXME:*/E->getLocStart(),
                                         move_arg(ConstructorArgs),
                                         E->getLocEnd());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
-  OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
+  ExprResult Operand = getDerived().TransformExpr(E->getArgument());
   if (Operand.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   // Transform the delete operator, if known.
   FunctionDecl *OperatorDelete = 0;
@@ -5187,7 +5374,7 @@
                                    getDerived().TransformDecl(E->getLocStart(),
                                                        E->getOperatorDelete()));
     if (!OperatorDelete)
-      return SemaRef.ExprError();
+      return ExprError();
   }
   
   if (!getDerived().AlwaysRebuild() &&
@@ -5203,41 +5390,41 @@
   return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
                                            E->isGlobalDelete(),
                                            E->isArrayForm(),
-                                           move(Operand));
+                                           Operand.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
                                                      CXXPseudoDestructorExpr *E) {
-  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  Sema::TypeTy *ObjectTypePtr = 0;
+  ParsedType ObjectTypePtr;
   bool MayBePseudoDestructor = false;
-  Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base), 
+  Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(), 
                                               E->getOperatorLoc(),
                                         E->isArrow()? tok::arrow : tok::period,
                                               ObjectTypePtr,
                                               MayBePseudoDestructor);
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
                                               
-  QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+  QualType ObjectType = ObjectTypePtr.get();
   NestedNameSpecifier *Qualifier
     = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
                                                 E->getQualifierRange(),
                                                 ObjectType);
   if (E->getQualifier() && !Qualifier)
-    return SemaRef.ExprError();
+    return ExprError();
 
   PseudoDestructorTypeStorage Destroyed;
   if (E->getDestroyedTypeInfo()) {
     TypeSourceInfo *DestroyedTypeInfo
       = getDerived().TransformType(E->getDestroyedTypeInfo(), ObjectType);
     if (!DestroyedTypeInfo)
-      return SemaRef.ExprError();
+      return ExprError();
     Destroyed = DestroyedTypeInfo;
   } else if (ObjectType->isDependentType()) {
     // We aren't likely to be able to resolve the identifier down to a type
@@ -5252,14 +5439,14 @@
       SS.setRange(E->getQualifierRange());
     }
     
-    Sema::TypeTy *T = SemaRef.getDestructorName(E->getTildeLoc(),
+    ParsedType T = SemaRef.getDestructorName(E->getTildeLoc(),
                                               *E->getDestroyedTypeIdentifier(),
                                                 E->getDestroyedTypeLoc(),
                                                 /*Scope=*/0,
                                                 SS, ObjectTypePtr,
                                                 false);
     if (!T)
-      return SemaRef.ExprError();
+      return ExprError();
     
     Destroyed
       = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T),
@@ -5271,10 +5458,10 @@
     ScopeTypeInfo = getDerived().TransformType(E->getScopeTypeInfo(), 
                                                ObjectType);
     if (!ScopeTypeInfo)
-      return SemaRef.ExprError();
+      return ExprError();
   }
   
-  return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
+  return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
                                                      E->getOperatorLoc(),
                                                      E->isArrow(),
                                                      Qualifier,
@@ -5286,7 +5473,7 @@
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformUnresolvedLookupExpr(
                                                   UnresolvedLookupExpr *Old) {
   TemporaryBase Rebase(*this, Old->getNameLoc(), DeclarationName());
@@ -5306,7 +5493,7 @@
       if (isa<UsingShadowDecl>(*I))
         continue;
       else
-        return SemaRef.ExprError();
+        return ExprError();
     }
 
     // Expand using declarations.
@@ -5332,10 +5519,21 @@
     Qualifier = getDerived().TransformNestedNameSpecifier(Old->getQualifier(),
                                                     Old->getQualifierRange());
     if (!Qualifier)
-      return SemaRef.ExprError();
+      return ExprError();
     
     SS.setScopeRep(Qualifier);
     SS.setRange(Old->getQualifierRange());
+  } 
+  
+  if (Old->getNamingClass()) {
+    CXXRecordDecl *NamingClass
+      = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
+                                                            Old->getNameLoc(),
+                                                        Old->getNamingClass()));
+    if (!NamingClass)
+      return ExprError();
+    
+    R.setNamingClass(NamingClass);
   }
 
   // If we have no template arguments, it's a normal declaration name.
@@ -5348,7 +5546,7 @@
   for (unsigned I = 0, N = Old->getNumTemplateArgs(); I != N; ++I) {
     TemplateArgumentLoc Loc;
     if (getDerived().TransformTemplateArgument(Old->getTemplateArgs()[I], Loc))
-      return SemaRef.ExprError();
+      return ExprError();
     TransArgs.addArgument(Loc);
   }
 
@@ -5357,13 +5555,13 @@
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
   TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
 
   QualType T = getDerived().TransformType(E->getQueriedType());
   if (T.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       T == E->getQueriedType())
@@ -5381,29 +5579,31 @@
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
-                                                  DependentScopeDeclRefExpr *E) {
+                                               DependentScopeDeclRefExpr *E) {
   NestedNameSpecifier *NNS
     = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
                                                 E->getQualifierRange());
   if (!NNS)
-    return SemaRef.ExprError();
+    return ExprError();
 
-  DeclarationName Name
-    = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
-  if (!Name)
-    return SemaRef.ExprError();
+  DeclarationNameInfo NameInfo
+    = getDerived().TransformDeclarationNameInfo(E->getNameInfo());
+  if (!NameInfo.getName())
+    return ExprError();
 
   if (!E->hasExplicitTemplateArgs()) {
     if (!getDerived().AlwaysRebuild() &&
         NNS == E->getQualifier() &&
-        Name == E->getDeclName())
+        // Note: it is sufficient to compare the Name component of NameInfo:
+        // if name has not changed, DNLoc has not changed either.
+        NameInfo.getName() == E->getDeclName())
       return SemaRef.Owned(E->Retain());
 
     return getDerived().RebuildDependentScopeDeclRefExpr(NNS,
                                                          E->getQualifierRange(),
-                                                         Name, E->getLocation(),
+                                                         NameInfo,
                                                          /*TemplateArgs*/ 0);
   }
 
@@ -5411,18 +5611,18 @@
   for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
     TemplateArgumentLoc Loc;
     if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
-      return SemaRef.ExprError();
+      return ExprError();
     TransArgs.addArgument(Loc);
   }
 
   return getDerived().RebuildDependentScopeDeclRefExpr(NNS,
                                                        E->getQualifierRange(),
-                                                       Name, E->getLocation(),
+                                                       NameInfo,
                                                        &TransArgs);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
   // CXXConstructExprs are always implicit, so when we have a
   // 1-argument construction we just transform that argument.
@@ -5434,17 +5634,17 @@
 
   QualType T = getDerived().TransformType(E->getType());
   if (T.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   CXXConstructorDecl *Constructor
     = cast_or_null<CXXConstructorDecl>(
                                 getDerived().TransformDecl(E->getLocStart(),
                                                          E->getConstructor()));
   if (!Constructor)
-    return SemaRef.ExprError();
+    return ExprError();
 
   bool ArgumentChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  ASTOwningVector<Expr*> Args(SemaRef);
   for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
        ArgEnd = E->arg_end();
        Arg != ArgEnd; ++Arg) {
@@ -5453,12 +5653,12 @@
       break;
     }
 
-    OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
+    ExprResult TransArg = getDerived().TransformExpr(*Arg);
     if (TransArg.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
-    Args.push_back(TransArg.takeAs<Expr>());
+    Args.push_back(TransArg.get());
   }
 
   if (!getDerived().AlwaysRebuild() &&
@@ -5473,7 +5673,9 @@
 
   return getDerived().RebuildCXXConstructExpr(T, /*FIXME:*/E->getLocStart(),
                                               Constructor, E->isElidable(),
-                                              move_arg(Args));
+                                              move_arg(Args),
+                                              E->requiresZeroInitialization(),
+                                              E->getConstructionKind());
 }
 
 /// \brief Transform a C++ temporary-binding expression.
@@ -5481,7 +5683,7 @@
 /// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
 /// transform the subexpression and return that.
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
   return getDerived().TransformExpr(E->getSubExpr());
 }
@@ -5491,7 +5693,7 @@
 /// Since CXXBindReferenceExpr nodes are implicitly generated, we just
 /// transform the subexpression and return that.
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXBindReferenceExpr(CXXBindReferenceExpr *E) {
   return getDerived().TransformExpr(E->getSubExpr());
 }
@@ -5502,30 +5704,30 @@
 /// Since CXXExprWithTemporaries nodes are implicitly generated, we
 /// just transform the subexpression and return that.
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXExprWithTemporaries(
                                                     CXXExprWithTemporaries *E) {
   return getDerived().TransformExpr(E->getSubExpr());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
                                                       CXXTemporaryObjectExpr *E) {
   TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
   QualType T = getDerived().TransformType(E->getType());
   if (T.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   CXXConstructorDecl *Constructor
     = cast_or_null<CXXConstructorDecl>(
                                   getDerived().TransformDecl(E->getLocStart(), 
                                                          E->getConstructor()));
   if (!Constructor)
-    return SemaRef.ExprError();
+    return ExprError();
 
   bool ArgumentChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  ASTOwningVector<Expr*> Args(SemaRef);
   Args.reserve(E->getNumArgs());
   for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
                                          ArgEnd = E->arg_end();
@@ -5535,9 +5737,9 @@
       break;
     }
 
-    OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
+    ExprResult TransArg = getDerived().TransformExpr(*Arg);
     if (TransArg.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
     Args.push_back((Expr *)TransArg.release());
@@ -5568,28 +5770,28 @@
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
                                                   CXXUnresolvedConstructExpr *E) {
   TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
   QualType T = getDerived().TransformType(E->getTypeAsWritten());
   if (T.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   bool ArgumentChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  ASTOwningVector<Expr*> 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);
+    ExprResult TransArg = getDerived().TransformExpr(*Arg);
     if (TransArg.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
     FakeCommaLocs.push_back(
                         SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
-    Args.push_back(TransArg.takeAs<Expr>());
+    Args.push_back(TransArg.get());
   }
 
   if (!getDerived().AlwaysRebuild() &&
@@ -5607,11 +5809,11 @@
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
-                                                     CXXDependentScopeMemberExpr *E) {
+                                             CXXDependentScopeMemberExpr *E) {
   // Transform the base of the expression.
-  OwningExprResult Base(SemaRef, (Expr*) 0);
+  ExprResult Base((Expr*) 0);
   Expr *OldBase;
   QualType BaseType;
   QualType ObjectType;
@@ -5619,20 +5821,20 @@
     OldBase = E->getBase();
     Base = getDerived().TransformExpr(OldBase);
     if (Base.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     // Start the member reference and compute the object's type.
-    Sema::TypeTy *ObjectTy = 0;
+    ParsedType ObjectTy;
     bool MayBePseudoDestructor = false;
-    Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
+    Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(),
                                                 E->getOperatorLoc(),
                                       E->isArrow()? tok::arrow : tok::period,
                                                 ObjectTy,
                                                 MayBePseudoDestructor);
     if (Base.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
-    ObjectType = QualType::getFromOpaquePtr(ObjectTy);
+    ObjectType = ObjectTy.get();
     BaseType = ((Expr*) Base.get())->getType();
   } else {
     OldBase = 0;
@@ -5654,14 +5856,14 @@
                                                       ObjectType,
                                                       FirstQualifierInScope);
     if (!Qualifier)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
-  DeclarationName Name
-    = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
-                                            ObjectType);
-  if (!Name)
-    return SemaRef.ExprError();
+  DeclarationNameInfo NameInfo
+    = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo(),
+                                                ObjectType);
+  if (!NameInfo.getName())
+    return ExprError();
 
   if (!E->hasExplicitTemplateArgs()) {
     // This is a reference to a member without an explicitly-specified
@@ -5670,19 +5872,18 @@
         Base.get() == OldBase &&
         BaseType == E->getBaseType() &&
         Qualifier == E->getQualifier() &&
-        Name == E->getMember() &&
+        NameInfo.getName() == E->getMember() &&
         FirstQualifierInScope == E->getFirstQualifierFoundInScope())
       return SemaRef.Owned(E->Retain());
 
-    return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
+    return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
                                                        BaseType,
                                                        E->isArrow(),
                                                        E->getOperatorLoc(),
                                                        Qualifier,
                                                        E->getQualifierRange(),
                                                        FirstQualifierInScope,
-                                                       Name,
-                                                       E->getMemberLoc(),
+                                                       NameInfo,
                                                        /*TemplateArgs*/ 0);
   }
 
@@ -5690,32 +5891,31 @@
   for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
     TemplateArgumentLoc Loc;
     if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
-      return SemaRef.ExprError();
+      return ExprError();
     TransArgs.addArgument(Loc);
   }
 
-  return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
+  return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
                                                      BaseType,
                                                      E->isArrow(),
                                                      E->getOperatorLoc(),
                                                      Qualifier,
                                                      E->getQualifierRange(),
                                                      FirstQualifierInScope,
-                                                     Name,
-                                                     E->getMemberLoc(),
+                                                     NameInfo,
                                                      &TransArgs);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) {
   // Transform the base of the expression.
-  OwningExprResult Base(SemaRef, (Expr*) 0);
+  ExprResult Base((Expr*) 0);
   QualType BaseType;
   if (!Old->isImplicitAccess()) {
     Base = getDerived().TransformExpr(Old->getBase());
     if (Base.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
     BaseType = ((Expr*) Base.get())->getType();
   } else {
     BaseType = getDerived().TransformType(Old->getBaseType());
@@ -5727,10 +5927,10 @@
       = getDerived().TransformNestedNameSpecifier(Old->getQualifier(),
                                                   Old->getQualifierRange());
     if (Qualifier == 0)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
-  LookupResult R(SemaRef, Old->getMemberName(), Old->getMemberLoc(),
+  LookupResult R(SemaRef, Old->getMemberNameInfo(),
                  Sema::LookupOrdinaryName);
 
   // Transform all the decls.
@@ -5745,7 +5945,7 @@
       if (isa<UsingShadowDecl>(*I))
         continue;
       else
-        return SemaRef.ExprError();
+        return ExprError();
     }
 
     // Expand using declarations.
@@ -5762,6 +5962,18 @@
 
   R.resolveKind();
 
+  // Determine the naming class.
+  if (Old->getNamingClass()) {
+    CXXRecordDecl *NamingClass 
+      = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
+                                                          Old->getMemberLoc(),
+                                                        Old->getNamingClass()));
+    if (!NamingClass)
+      return ExprError();
+    
+    R.setNamingClass(NamingClass);
+  }
+  
   TemplateArgumentListInfo TransArgs;
   if (Old->hasExplicitTemplateArgs()) {
     TransArgs.setLAngleLoc(Old->getLAngleLoc());
@@ -5770,7 +5982,7 @@
       TemplateArgumentLoc Loc;
       if (getDerived().TransformTemplateArgument(Old->getTemplateArgs()[I],
                                                  Loc))
-        return SemaRef.ExprError();
+        return ExprError();
       TransArgs.addArgument(Loc);
     }
   }
@@ -5781,7 +5993,7 @@
   // nested-name-qualifier (and therefore could do the lookup).
   NamedDecl *FirstQualifierInScope = 0;
   
-  return getDerived().RebuildUnresolvedMemberExpr(move(Base),
+  return getDerived().RebuildUnresolvedMemberExpr(Base.get(),
                                                   BaseType,
                                                   Old->getOperatorLoc(),
                                                   Old->isArrow(),
@@ -5794,18 +6006,18 @@
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
   TypeSourceInfo *EncodedTypeInfo
     = getDerived().TransformType(E->getEncodedTypeSourceInfo());
   if (!EncodedTypeInfo)
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       EncodedTypeInfo == E->getEncodedTypeSourceInfo())
@@ -5817,18 +6029,18 @@
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
   // Transform arguments.
   bool ArgChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  ASTOwningVector<Expr*> Args(SemaRef);
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
-    OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
+    ExprResult Arg = getDerived().TransformExpr(E->getArg(I));
     if (Arg.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
     
     ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
-    Args.push_back(Arg.takeAs<Expr>());
+    Args.push_back(Arg.get());
   }
 
   if (E->getReceiverKind() == ObjCMessageExpr::Class) {
@@ -5836,7 +6048,7 @@
     TypeSourceInfo *ReceiverTypeInfo
       = getDerived().TransformType(E->getClassReceiverTypeInfo());
     if (!ReceiverTypeInfo)
-      return SemaRef.ExprError();
+      return ExprError();
     
     // If nothing changed, just retain the existing message send.
     if (!getDerived().AlwaysRebuild() &&
@@ -5855,10 +6067,10 @@
   // Instance message: transform the receiver
   assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
          "Only class and instance messages may be instantiated");
-  OwningExprResult Receiver
+  ExprResult Receiver
     = getDerived().TransformExpr(E->getInstanceReceiver());
   if (Receiver.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   // If nothing changed, just retain the existing message send.
   if (!getDerived().AlwaysRebuild() &&
@@ -5866,7 +6078,7 @@
     return SemaRef.Owned(E->Retain());
   
   // Build a new instance message send.
-  return getDerived().RebuildObjCMessageExpr(move(Receiver),
+  return getDerived().RebuildObjCMessageExpr(Receiver.get(),
                                              E->getSelector(),
                                              E->getMethodDecl(),
                                              E->getLeftLoc(),
@@ -5875,24 +6087,24 @@
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
   // Transform the base expression.
-  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   // We don't need to transform the ivar; it will never change.
   
@@ -5901,18 +6113,18 @@
       Base.get() == E->getBase())
     return SemaRef.Owned(E->Retain());
   
-  return getDerived().RebuildObjCIvarRefExpr(move(Base), E->getDecl(),
+  return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
                                              E->getLocation(),
                                              E->isArrow(), E->isFreeIvar());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
   // Transform the base expression.
-  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
   
   // We don't need to transform the property; it will never change.
   
@@ -5921,12 +6133,12 @@
       Base.get() == E->getBase())
     return SemaRef.Owned(E->Retain());
   
-  return getDerived().RebuildObjCPropertyRefExpr(move(Base), E->getProperty(),
+  return getDerived().RebuildObjCPropertyRefExpr(Base.get(), E->getProperty(),
                                                  E->getLocation());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
                                           ObjCImplicitSetterGetterRefExpr *E) {
   // If this implicit setter/getter refers to class methods, it cannot have any
@@ -5935,9 +6147,9 @@
     return SemaRef.Owned(E->Retain());
   
   // Transform the base expression.
-  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
   
   // We don't need to transform the getters/setters; they will never change.
   
@@ -5951,46 +6163,46 @@
                                                              E->getType(),
                                                           E->getSetterMethod(),
                                                              E->getLocation(),
-                                                             move(Base));
+                                                             Base.get());
                                                              
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
   // Can never occur in a dependent context.
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
   // Transform the base expression.
-  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return 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(),
+  return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
                                          E->isArrow());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
   bool ArgumentChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
+  ASTOwningVector<Expr*> SubExprs(SemaRef);
   for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
-    OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
+    ExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
     if (SubExpr.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
-    SubExprs.push_back(SubExpr.takeAs<Expr>());
+    SubExprs.push_back(SubExpr.get());
   }
 
   if (!getDerived().AlwaysRebuild() &&
@@ -6003,19 +6215,79 @@
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
-  // FIXME: Implement this!
-  assert(false && "Cannot transform block expressions yet");
-  return SemaRef.Owned(E->Retain());
+  SourceLocation CaretLoc(E->getExprLoc());
+  
+  SemaRef.ActOnBlockStart(CaretLoc, /*Scope=*/0);
+  BlockScopeInfo *CurBlock = SemaRef.getCurBlock();
+  CurBlock->TheDecl->setIsVariadic(E->getBlockDecl()->isVariadic());
+  llvm::SmallVector<ParmVarDecl*, 4> Params;
+  llvm::SmallVector<QualType, 4> ParamTypes;
+  
+  // Parameter substitution.
+  const BlockDecl *BD = E->getBlockDecl();
+  for (BlockDecl::param_const_iterator P = BD->param_begin(),
+       EN = BD->param_end(); P != EN; ++P) {
+    ParmVarDecl *OldParm = (*P);
+    ParmVarDecl *NewParm = getDerived().TransformFunctionTypeParam(OldParm);
+    QualType NewType = NewParm->getType();
+    Params.push_back(NewParm);
+    ParamTypes.push_back(NewParm->getType());
+  }
+  
+  const FunctionType *BExprFunctionType = E->getFunctionType();
+  QualType BExprResultType = BExprFunctionType->getResultType();
+  if (!BExprResultType.isNull()) {
+    if (!BExprResultType->isDependentType())
+      CurBlock->ReturnType = BExprResultType;
+    else if (BExprResultType != SemaRef.Context.DependentTy)
+      CurBlock->ReturnType = getDerived().TransformType(BExprResultType);
+  }
+    
+  // Transform the body
+  StmtResult Body = getDerived().TransformStmt(E->getBody());
+  if (Body.isInvalid())
+    return ExprError();
+  // Set the parameters on the block decl.
+  if (!Params.empty())
+    CurBlock->TheDecl->setParams(Params.data(), Params.size());
+    
+  QualType FunctionType = getDerived().RebuildFunctionProtoType(
+                                                        CurBlock->ReturnType,
+                                                        ParamTypes.data(),
+                                                        ParamTypes.size(),
+                                                        BD->isVariadic(),
+                                                        0,
+                                               BExprFunctionType->getExtInfo());
+  
+  CurBlock->FunctionType = FunctionType;
+  return SemaRef.ActOnBlockStmtExpr(CaretLoc, Body.get(), /*Scope=*/0);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
-  // FIXME: Implement this!
-  assert(false && "Cannot transform block-related expressions yet");
-  return SemaRef.Owned(E->Retain());
+  NestedNameSpecifier *Qualifier = 0;
+    
+  ValueDecl *ND
+  = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
+                                                       E->getDecl()));
+  if (!ND)
+    return ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      ND == E->getDecl()) {
+    // 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());
+  }
+  
+  DeclarationNameInfo NameInfo(E->getDecl()->getDeclName(), E->getLocation());
+  return getDerived().RebuildDeclRefExpr(Qualifier, SourceLocation(),
+                                         ND, NameInfo, 0);
 }
 
 //===----------------------------------------------------------------------===//
@@ -6025,14 +6297,14 @@
 template<typename Derived>
 QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
                                                     SourceLocation Star) {
-  return SemaRef.BuildPointerType(PointeeType, Qualifiers(), Star,
+  return SemaRef.BuildPointerType(PointeeType, Star,
                                   getDerived().getBaseEntity());
 }
 
 template<typename Derived>
 QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
                                                          SourceLocation Star) {
-  return SemaRef.BuildBlockPointerType(PointeeType, Qualifiers(), Star,
+  return SemaRef.BuildBlockPointerType(PointeeType, Star,
                                        getDerived().getBaseEntity());
 }
 
@@ -6041,7 +6313,7 @@
 TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
                                              bool WrittenAsLValue,
                                              SourceLocation Sigil) {
-  return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue, Qualifiers(),
+  return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue,
                                     Sigil, getDerived().getBaseEntity());
 }
 
@@ -6050,7 +6322,7 @@
 TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
                                                  QualType ClassType,
                                                  SourceLocation Sigil) {
-  return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Qualifiers(),
+  return SemaRef.BuildMemberPointerType(PointeeType, ClassType,
                                         Sigil, getDerived().getBaseEntity());
 }
 
@@ -6080,7 +6352,8 @@
       break;
     }
 
-  IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
+  IntegerLiteral ArraySize(SemaRef.Context, *Size, SizeType,
+                           /*FIXME*/BracketsRange.getBegin());
   return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
                                 IndexTypeQuals, BracketsRange,
                                 getDerived().getBaseEntity());
@@ -6111,11 +6384,11 @@
 QualType
 TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
                                           ArrayType::ArraySizeModifier SizeMod,
-                                                 ExprArg SizeExpr,
+                                                 Expr *SizeExpr,
                                                  unsigned IndexTypeQuals,
                                                  SourceRange BracketsRange) {
   return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
-                                       SizeExpr.takeAs<Expr>(),
+                                       SizeExpr,
                                        IndexTypeQuals, BracketsRange);
 }
 
@@ -6123,21 +6396,20 @@
 QualType
 TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
                                           ArrayType::ArraySizeModifier SizeMod,
-                                                       ExprArg SizeExpr,
+                                                       Expr *SizeExpr,
                                                        unsigned IndexTypeQuals,
                                                    SourceRange BracketsRange) {
   return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
-                                       SizeExpr.takeAs<Expr>(),
+                                       SizeExpr,
                                        IndexTypeQuals, BracketsRange);
 }
 
 template<typename Derived>
 QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
-                                       unsigned NumElements,
-                                       bool IsAltiVec, bool IsPixel) {
+                                     unsigned NumElements,
+                                     VectorType::AltiVecSpecific AltiVecSpec) {
   // FIXME: semantic checking!
-  return SemaRef.Context.getVectorType(ElementType, NumElements,
-                                       IsAltiVec, IsPixel);
+  return SemaRef.Context.getVectorType(ElementType, NumElements, AltiVecSpec);
 }
 
 template<typename Derived>
@@ -6147,18 +6419,17 @@
   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);
+    = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
+                             AttributeLoc);
+  return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
 }
 
 template<typename Derived>
 QualType
 TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
-                                                           ExprArg SizeExpr,
+                                                           Expr *SizeExpr,
                                                   SourceLocation AttributeLoc) {
-  return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
+  return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);
 }
 
 template<typename Derived>
@@ -6166,11 +6437,13 @@
                                                           QualType *ParamTypes,
                                                         unsigned NumParamTypes,
                                                           bool Variadic,
-                                                          unsigned Quals) {
+                                                          unsigned Quals,
+                                            const FunctionType::ExtInfo &Info) {
   return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
                                    Quals,
                                    getDerived().getBaseLocation(),
-                                   getDerived().getBaseEntity());
+                                   getDerived().getBaseEntity(),
+                                   Info);
 }
 
 template<typename Derived>
@@ -6204,8 +6477,8 @@
 }
 
 template<typename Derived>
-QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
-  return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
+QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E) {
+  return SemaRef.BuildTypeofExprType(E);
 }
 
 template<typename Derived>
@@ -6214,8 +6487,8 @@
 }
 
 template<typename Derived>
-QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
-  return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
+QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E) {
+  return SemaRef.BuildDecltypeType(E);
 }
 
 template<typename Derived>
@@ -6289,13 +6562,15 @@
   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>();
+  Sema::TemplateTy Template;
+  getSema().ActOnDependentTemplateName(/*Scope=*/0,
+                                       /*FIXME:*/getDerived().getBaseLocation(),
+                                       SS,
+                                       Name,
+                                       ParsedType::make(ObjectType),
+                                       /*EnteringContext=*/false,
+                                       Template);
+  return Template.template getAsVal<TemplateName>();
 }
 
 template<typename Derived>
@@ -6310,59 +6585,57 @@
   SourceLocation SymbolLocations[3]; // FIXME: Bogus location information.
   Name.setOperatorFunctionId(/*FIXME:*/getDerived().getBaseLocation(),
                              Operator, SymbolLocations);
-  return getSema().ActOnDependentTemplateName(
+  Sema::TemplateTy Template;
+  getSema().ActOnDependentTemplateName(/*Scope=*/0,
                                        /*FIXME:*/getDerived().getBaseLocation(),
-                                              SS,
-                                              Name,
-                                              ObjectType.getAsOpaquePtr(),
-                                              /*EnteringContext=*/false)
-           .template getAsVal<TemplateName>();
+                                       SS,
+                                       Name,
+                                       ParsedType::make(ObjectType),
+                                       /*EnteringContext=*/false,
+                                       Template);
+  return Template.template getAsVal<TemplateName>();
 }
   
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 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);
+                                                   Expr *OrigCallee,
+                                                   Expr *First,
+                                                   Expr *Second) {
+  Expr *Callee = OrigCallee->IgnoreParenCasts();
+  bool isPostIncDec = Second && (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);
+    if (!First->getType()->isOverloadableType() &&
+        !Second->getType()->isOverloadableType())
+      return getSema().CreateBuiltinArraySubscriptExpr(First,
+                                                       Callee->getLocStart(),
+                                                       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()) {
+    return SemaRef.BuildOverloadedArrowExpr(0, First, OpLoc);
+  } else if (Second == 0 || isPostIncDec) {
+    if (!First->getType()->isOverloadableType()) {
       // The argument is not of overloadable type, so try to create a
       // built-in unary operation.
-      UnaryOperator::Opcode Opc
+      UnaryOperatorKind Opc
         = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
 
-      return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
+      return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
     }
   } else {
-    if (!FirstExpr->getType()->isOverloadableType() &&
-        !SecondExpr->getType()->isOverloadableType()) {
+    if (!First->getType()->isOverloadableType() &&
+        !Second->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);
+      BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
+      ExprResult Result
+        = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
       if (Result.isInvalid())
-        return SemaRef.ExprError();
+        return ExprError();
 
-      First.release();
-      Second.release();
       return move(Result);
     }
   }
@@ -6371,49 +6644,46 @@
   // used during overload resolution.
   UnresolvedSet<16> Functions;
 
-  if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(CalleeExpr)) {
+  if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
     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());
+    Functions.addDecl(cast<DeclRefExpr>(Callee)->getDecl());
   }
 
   // Add any functions found via argument-dependent lookup.
-  Expr *Args[2] = { FirstExpr, SecondExpr };
-  unsigned NumArgs = 1 + (SecondExpr != 0);
+  Expr *Args[2] = { First, Second };
+  unsigned NumArgs = 1 + (Second != 0);
 
   // Create the overloaded operator invocation for unary operators.
   if (NumArgs == 1 || isPostIncDec) {
-    UnaryOperator::Opcode Opc
+    UnaryOperatorKind Opc
       = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
-    return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
+    return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First);
   }
 
   if (Op == OO_Subscript)
-    return SemaRef.CreateOverloadedArraySubscriptExpr(CalleeExpr->getLocStart(),
+    return SemaRef.CreateOverloadedArraySubscriptExpr(Callee->getLocStart(),
                                                       OpLoc,
-                                                      move(First),
-                                                      move(Second));
+                                                      First,
+                                                      Second);
 
   // Create the overloaded operator invocation for binary operators.
-  BinaryOperator::Opcode Opc =
-    BinaryOperator::getOverloadedOpcode(Op);
-  OwningExprResult Result
+  BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
+  ExprResult Result
     = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
   if (Result.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  First.release();
-  Second.release();
   return move(Result);
 }
 
 template<typename Derived>
-Sema::OwningExprResult 
-TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(ExprArg Base,
+ExprResult 
+TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
                                                      SourceLocation OperatorLoc,
                                                        bool isArrow,
                                                  NestedNameSpecifier *Qualifier,
@@ -6428,32 +6698,32 @@
     SS.setScopeRep(Qualifier);
   }
 
-  Expr *BaseE = (Expr *)Base.get();
-  QualType BaseType = BaseE->getType();
-  if (BaseE->isTypeDependent() || Destroyed.getIdentifier() ||
+  QualType BaseType = Base->getType();
+  if (Base->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,
+    return SemaRef.BuildPseudoDestructorExpr(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()));
-  
+  DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
+                 SemaRef.Context.getCanonicalType(DestroyedType->getType())));
+  DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
+  NameInfo.setNamedTypeInfo(DestroyedType);
+
   // FIXME: the ScopeType should be tacked onto SS.
-  
-  return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
+
+  return getSema().BuildMemberReferenceExpr(Base, BaseType,
                                             OperatorLoc, isArrow,
                                             SS, /*FIXME: FirstQualifier*/ 0,
-                                            Name, Destroyed.getLocation(),
+                                            NameInfo,
                                             /*TemplateArgs*/ 0);
 }
 
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp
new file mode 100644
index 0000000..77c1aff
--- /dev/null
+++ b/lib/Serialization/ASTCommon.cpp
@@ -0,0 +1,69 @@
+//===--- ASTCommon.cpp - Common stuff for ASTReader/ASTWriter----*- 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 common functions that both ASTReader and ASTWriter use.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ASTCommon.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "llvm/ADT/StringExtras.h"
+
+using namespace clang;
+
+serialization::TypeIdx
+serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
+  unsigned ID = 0;
+  switch (BT->getKind()) {
+  case BuiltinType::Void:       ID = PREDEF_TYPE_VOID_ID;       break;
+  case BuiltinType::Bool:       ID = PREDEF_TYPE_BOOL_ID;       break;
+  case BuiltinType::Char_U:     ID = PREDEF_TYPE_CHAR_U_ID;     break;
+  case BuiltinType::UChar:      ID = PREDEF_TYPE_UCHAR_ID;      break;
+  case BuiltinType::UShort:     ID = PREDEF_TYPE_USHORT_ID;     break;
+  case BuiltinType::UInt:       ID = PREDEF_TYPE_UINT_ID;       break;
+  case BuiltinType::ULong:      ID = PREDEF_TYPE_ULONG_ID;      break;
+  case BuiltinType::ULongLong:  ID = PREDEF_TYPE_ULONGLONG_ID;  break;
+  case BuiltinType::UInt128:    ID = PREDEF_TYPE_UINT128_ID;    break;
+  case BuiltinType::Char_S:     ID = PREDEF_TYPE_CHAR_S_ID;     break;
+  case BuiltinType::SChar:      ID = PREDEF_TYPE_SCHAR_ID;      break;
+  case BuiltinType::WChar:      ID = PREDEF_TYPE_WCHAR_ID;      break;
+  case BuiltinType::Short:      ID = PREDEF_TYPE_SHORT_ID;      break;
+  case BuiltinType::Int:        ID = PREDEF_TYPE_INT_ID;        break;
+  case BuiltinType::Long:       ID = PREDEF_TYPE_LONG_ID;       break;
+  case BuiltinType::LongLong:   ID = PREDEF_TYPE_LONGLONG_ID;   break;
+  case BuiltinType::Int128:     ID = PREDEF_TYPE_INT128_ID;     break;
+  case BuiltinType::Float:      ID = PREDEF_TYPE_FLOAT_ID;      break;
+  case BuiltinType::Double:     ID = PREDEF_TYPE_DOUBLE_ID;     break;
+  case BuiltinType::LongDouble: ID = PREDEF_TYPE_LONGDOUBLE_ID; break;
+  case BuiltinType::NullPtr:    ID = PREDEF_TYPE_NULLPTR_ID;    break;
+  case BuiltinType::Char16:     ID = PREDEF_TYPE_CHAR16_ID;     break;
+  case BuiltinType::Char32:     ID = PREDEF_TYPE_CHAR32_ID;     break;
+  case BuiltinType::Overload:   ID = PREDEF_TYPE_OVERLOAD_ID;   break;
+  case BuiltinType::Dependent:  ID = PREDEF_TYPE_DEPENDENT_ID;  break;
+  case BuiltinType::ObjCId:     ID = PREDEF_TYPE_OBJC_ID;       break;
+  case BuiltinType::ObjCClass:  ID = PREDEF_TYPE_OBJC_CLASS;    break;
+  case BuiltinType::ObjCSel:    ID = PREDEF_TYPE_OBJC_SEL;      break;
+  case BuiltinType::UndeducedAuto:
+    assert(0 && "Should not see undeduced auto here");
+    break;
+  }
+
+  return TypeIdx(ID);
+}
+
+unsigned serialization::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;
+}
diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h
new file mode 100644
index 0000000..a0e2ecd
--- /dev/null
+++ b/lib/Serialization/ASTCommon.h
@@ -0,0 +1,50 @@
+//===- ASTCommon.h - Common stuff for ASTReader/ASTWriter -*- 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 common functions that both ASTReader and ASTWriter use.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SERIALIZATION_LIB_AST_COMMON_H
+#define LLVM_CLANG_SERIALIZATION_LIB_AST_COMMON_H
+
+#include "clang/Serialization/ASTBitCodes.h"
+
+namespace clang {
+
+namespace serialization {
+
+TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
+
+template <typename IdxForTypeTy>
+TypeID MakeTypeID(QualType T, IdxForTypeTy IdxForType) {
+  if (T.isNull())
+    return PREDEF_TYPE_NULL_ID;
+
+  unsigned FastQuals = T.getLocalFastQualifiers();
+  T.removeFastQualifiers();
+
+  if (T.hasLocalNonFastQualifiers())
+    return IdxForType(T).asTypeID(FastQuals);
+
+  assert(!T.hasLocalQualifiers());
+
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr()))
+    return TypeIdxFromBuiltin(BT).asTypeID(FastQuals);
+
+  return IdxForType(T).asTypeID(FastQuals);
+}
+
+unsigned ComputeHash(Selector Sel);
+
+} // namespace serialization
+
+} // namespace clang
+
+#endif
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
new file mode 100644
index 0000000..f07215c
--- /dev/null
+++ b/lib/Serialization/ASTReader.cpp
@@ -0,0 +1,4147 @@
+//===--- ASTReader.cpp - AST File 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 ASTReader class, which reads AST files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Serialization/ASTReader.h"
+#include "clang/Serialization/ASTDeserializationListener.h"
+#include "ASTCommon.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/Utils.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/Scope.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.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;
+using namespace clang::serialization;
+
+//===----------------------------------------------------------------------===//
+// PCH validator implementation
+//===----------------------------------------------------------------------===//
+
+ASTReaderListener::~ASTReaderListener() {}
+
+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_BENIGN(getSignedOverflowBehavior());
+  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);
+  PARSE_LANGOPT_BENIGN(SpellChecking);
+#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;
+}
+
+struct EmptyStringRef {
+  bool operator ()(llvm::StringRef r) const { return r.empty(); }
+};
+struct EmptyBlock {
+  bool operator ()(const PCHPredefinesBlock &r) const { return r.Data.empty(); }
+};
+
+static bool EqualConcatenations(llvm::SmallVector<llvm::StringRef, 2> L,
+                                PCHPredefinesBlocks R) {
+  // First, sum up the lengths.
+  unsigned LL = 0, RL = 0;
+  for (unsigned I = 0, N = L.size(); I != N; ++I) {
+    LL += L[I].size();
+  }
+  for (unsigned I = 0, N = R.size(); I != N; ++I) {
+    RL += R[I].Data.size();
+  }
+  if (LL != RL)
+    return false;
+  if (LL == 0 && RL == 0)
+    return true;
+
+  // Kick out empty parts, they confuse the algorithm below.
+  L.erase(std::remove_if(L.begin(), L.end(), EmptyStringRef()), L.end());
+  R.erase(std::remove_if(R.begin(), R.end(), EmptyBlock()), R.end());
+
+  // Do it the hard way. At this point, both vectors must be non-empty.
+  llvm::StringRef LR = L[0], RR = R[0].Data;
+  unsigned LI = 0, RI = 0, LN = L.size(), RN = R.size();
+  (void) RN;
+  for (;;) {
+    // Compare the current pieces.
+    if (LR.size() == RR.size()) {
+      // If they're the same length, it's pretty easy.
+      if (LR != RR)
+        return false;
+      // Both pieces are done, advance.
+      ++LI;
+      ++RI;
+      // If either string is done, they're both done, since they're the same
+      // length.
+      if (LI == LN) {
+        assert(RI == RN && "Strings not the same length after all?");
+        return true;
+      }
+      LR = L[LI];
+      RR = R[RI].Data;
+    } else if (LR.size() < RR.size()) {
+      // Right piece is longer.
+      if (!RR.startswith(LR))
+        return false;
+      ++LI;
+      assert(LI != LN && "Strings not the same length after all?");
+      RR = RR.substr(LR.size());
+      LR = L[LI];
+    } else {
+      // Left piece is longer.
+      if (!LR.startswith(RR))
+        return false;
+      ++RI;
+      assert(RI != RN && "Strings not the same length after all?");
+      LR = LR.substr(RR.size());
+      RR = R[RI].Data;
+    }
+  }
+}
+
+static std::pair<FileID, llvm::StringRef::size_type>
+FindMacro(const PCHPredefinesBlocks &Buffers, llvm::StringRef MacroDef) {
+  std::pair<FileID, llvm::StringRef::size_type> Res;
+  for (unsigned I = 0, N = Buffers.size(); I != N; ++I) {
+    Res.second = Buffers[I].Data.find(MacroDef);
+    if (Res.second != llvm::StringRef::npos) {
+      Res.first = Buffers[I].BufferID;
+      break;
+    }
+  }
+  return Res;
+}
+
+bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
+                                        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 concatenation of all the PCH buffers is equal to the adjusted
+  // command line, we're done.
+  llvm::SmallVector<llvm::StringRef, 2> CommandLine;
+  CommandLine.push_back(Left);
+  CommandLine.push_back(Right);
+  if (EqualConcatenations(CommandLine, Buffers))
+    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;
+  for (unsigned I = 0, N = Buffers.size(); I != N; ++I)
+    Buffers[I].Data.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.
+      std::pair<FileID, llvm::StringRef::size_type> MacroLoc =
+          FindMacro(Buffers, Missing);
+      assert(MacroLoc.second!=llvm::StringRef::npos && "Unable to find macro!");
+      SourceLocation PCHMissingLoc =
+          SourceMgr.getLocForStartOfFile(MacroLoc.first)
+            .getFileLocWithOffset(MacroLoc.second);
+      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.
+    std::pair<FileID, llvm::StringRef::size_type> MacroLoc =
+        FindMacro(Buffers, Missing);
+    assert(MacroLoc.second!=llvm::StringRef::npos && "Unable to find macro!");
+    SourceLocation PCHMissingLoc =
+        SourceMgr.getLocForStartOfFile(MacroLoc.first)
+          .getFileLocWithOffset(MacroLoc.second);
+    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);
+}
+
+//===----------------------------------------------------------------------===//
+// AST reader implementation
+//===----------------------------------------------------------------------===//
+
+void
+ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
+  DeserializationListener = Listener;
+  if (DeserializationListener)
+    DeserializationListener->SetReader(this);
+}
+
+
+namespace {
+class ASTSelectorLookupTrait {
+  ASTReader &Reader;
+
+public:
+  struct data_type {
+    SelectorID ID;
+    ObjCMethodList Instance, Factory;
+  };
+
+  typedef Selector external_key_type;
+  typedef external_key_type internal_key_type;
+
+  explicit ASTSelectorLookupTrait(ASTReader &Reader) : Reader(Reader) { }
+
+  static bool EqualKey(const internal_key_type& a,
+                       const internal_key_type& b) {
+    return a == b;
+  }
+
+  static unsigned ComputeHash(Selector Sel) {
+    return serialization::ComputeHash(Sel);
+  }
+
+  // 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;
+
+    data_type Result;
+
+    Result.ID = ReadUnalignedLE32(d);
+    unsigned NumInstanceMethods = ReadUnalignedLE16(d);
+    unsigned NumFactoryMethods = ReadUnalignedLE16(d);
+
+    // Load instance methods
+    ObjCMethodList *Prev = 0;
+    for (unsigned I = 0; I != NumInstanceMethods; ++I) {
+      ObjCMethodDecl *Method
+        = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
+      if (!Result.Instance.Method) {
+        // This is the first method, which is the easy case.
+        Result.Instance.Method = Method;
+        Prev = &Result.Instance;
+        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.Factory.Method) {
+        // This is the first method, which is the easy case.
+        Result.Factory.Method = Method;
+        Prev = &Result.Factory;
+        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<ASTSelectorLookupTrait>
+  ASTSelectorLookupTable;
+
+namespace {
+class ASTIdentifierLookupTrait {
+  ASTReader &Reader;
+  llvm::BitstreamCursor &Stream;
+
+  // 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 AST 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;
+
+  ASTIdentifierLookupTrait(ASTReader &Reader, llvm::BitstreamCursor &Stream,
+                           IdentifierInfo *II = 0)
+    : Reader(Reader), Stream(Stream), 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;
+    IdentID ID = ReadUnalignedLE32(d);
+    bool IsInteresting = ID & 0x01;
+
+    // Wipe out the "is interesting" bit.
+    ID = ID >> 1;
+
+    if (!IsInteresting) {
+      // For uninteresting identifiers, just build the IdentifierInfo
+      // and associate it with the persistent ID.
+      IdentifierInfo *II = KnownII;
+      if (!II)
+        II = &Reader.getIdentifierTable().getOwn(k.first, k.first + k.second);
+      Reader.SetIdentifierInfo(ID, II);
+      II->setIsFromAST();
+      return II;
+    }
+
+    unsigned Bits = ReadUnalignedLE16(d);
+    bool CPlusPlusOperatorKeyword = Bits & 0x01;
+    Bits >>= 1;
+    bool HasRevertedTokenIDToIdentifier = 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().getOwn(k.first, k.first + k.second);
+    Reader.SetIdentifierInfo(ID, II);
+
+    // Set or check the various bits in the IdentifierInfo structure.
+    // Token IDs are read-only.
+    if (HasRevertedTokenIDToIdentifier)
+      II->RevertTokenIDToIdentifier();
+    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(Stream, 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);
+    }
+
+    II->setIsFromAST();
+    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<ASTIdentifierLookupTrait>
+  ASTIdentifierLookupTable;
+
+namespace {
+class ASTDeclContextNameLookupTrait {
+  ASTReader &Reader;
+
+public:
+  /// \brief Pair of begin/end iterators for DeclIDs.
+  typedef std::pair<DeclID *, DeclID *> data_type;
+
+  /// \brief Special internal key for declaration names.
+  /// The hash table creates keys for comparison; we do not create
+  /// a DeclarationName for the internal key to avoid deserializing types.
+  struct DeclNameKey {
+    DeclarationName::NameKind Kind;
+    uint64_t Data;
+    DeclNameKey() : Kind((DeclarationName::NameKind)0), Data(0) { }
+  };
+
+  typedef DeclarationName external_key_type;
+  typedef DeclNameKey internal_key_type;
+
+  explicit ASTDeclContextNameLookupTrait(ASTReader &Reader) : Reader(Reader) { }
+
+  static bool EqualKey(const internal_key_type& a,
+                       const internal_key_type& b) {
+    return a.Kind == b.Kind && a.Data == b.Data;
+  }
+
+  unsigned ComputeHash(const DeclNameKey &Key) const {
+    llvm::FoldingSetNodeID ID;
+    ID.AddInteger(Key.Kind);
+
+    switch (Key.Kind) {
+    case DeclarationName::Identifier:
+    case DeclarationName::CXXLiteralOperatorName:
+      ID.AddString(((IdentifierInfo*)Key.Data)->getName());
+      break;
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+      ID.AddInteger(serialization::ComputeHash(Selector(Key.Data)));
+      break;
+    case DeclarationName::CXXConstructorName:
+    case DeclarationName::CXXDestructorName:
+    case DeclarationName::CXXConversionFunctionName:
+      ID.AddInteger((TypeID)Key.Data);
+      break;
+    case DeclarationName::CXXOperatorName:
+      ID.AddInteger((OverloadedOperatorKind)Key.Data);
+      break;
+    case DeclarationName::CXXUsingDirective:
+      break;
+    }
+
+    return ID.ComputeHash();
+  }
+
+  internal_key_type GetInternalKey(const external_key_type& Name) const {
+    DeclNameKey Key;
+    Key.Kind = Name.getNameKind();
+    switch (Name.getNameKind()) {
+    case DeclarationName::Identifier:
+      Key.Data = (uint64_t)Name.getAsIdentifierInfo();
+      break;
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+      Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr();
+      break;
+    case DeclarationName::CXXConstructorName:
+    case DeclarationName::CXXDestructorName:
+    case DeclarationName::CXXConversionFunctionName:
+      Key.Data = Reader.GetTypeID(Name.getCXXNameType());
+      break;
+    case DeclarationName::CXXOperatorName:
+      Key.Data = Name.getCXXOverloadedOperator();
+      break;
+    case DeclarationName::CXXLiteralOperatorName:
+      Key.Data = (uint64_t)Name.getCXXLiteralIdentifier();
+      break;
+    case DeclarationName::CXXUsingDirective:
+      break;
+    }
+    
+    return Key;
+  }
+
+  external_key_type GetExternalKey(const internal_key_type& Key) const {
+    ASTContext *Context = Reader.getContext();
+    switch (Key.Kind) {
+    case DeclarationName::Identifier:
+      return DeclarationName((IdentifierInfo*)Key.Data);
+
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+      return DeclarationName(Selector(Key.Data));
+
+    case DeclarationName::CXXConstructorName:
+      return Context->DeclarationNames.getCXXConstructorName(
+                           Context->getCanonicalType(Reader.GetType(Key.Data)));
+
+    case DeclarationName::CXXDestructorName:
+      return Context->DeclarationNames.getCXXDestructorName(
+                           Context->getCanonicalType(Reader.GetType(Key.Data)));
+
+    case DeclarationName::CXXConversionFunctionName:
+      return Context->DeclarationNames.getCXXConversionFunctionName(
+                           Context->getCanonicalType(Reader.GetType(Key.Data)));
+
+    case DeclarationName::CXXOperatorName:
+      return Context->DeclarationNames.getCXXOperatorName(
+                                         (OverloadedOperatorKind)Key.Data);
+
+    case DeclarationName::CXXLiteralOperatorName:
+      return Context->DeclarationNames.getCXXLiteralOperatorName(
+                                                     (IdentifierInfo*)Key.Data);
+
+    case DeclarationName::CXXUsingDirective:
+      return DeclarationName::getUsingDirectiveName();
+    }
+
+    llvm_unreachable("Invalid Name Kind ?");
+  }
+
+  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;
+
+    DeclNameKey Key;
+    Key.Kind = (DeclarationName::NameKind)*d++;
+    switch (Key.Kind) {
+    case DeclarationName::Identifier:
+      Key.Data = (uint64_t)Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
+      break;
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+      Key.Data = 
+         (uint64_t)Reader.DecodeSelector(ReadUnalignedLE32(d)).getAsOpaquePtr();
+      break;
+    case DeclarationName::CXXConstructorName:
+    case DeclarationName::CXXDestructorName:
+    case DeclarationName::CXXConversionFunctionName:
+      Key.Data = ReadUnalignedLE32(d); // TypeID
+      break;
+    case DeclarationName::CXXOperatorName:
+      Key.Data = *d++; // OverloadedOperatorKind
+      break;
+    case DeclarationName::CXXLiteralOperatorName:
+      Key.Data = (uint64_t)Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
+      break;
+    case DeclarationName::CXXUsingDirective:
+      break;
+    }
+    
+    return Key;
+  }
+
+  data_type ReadData(internal_key_type, const unsigned char* d,
+                     unsigned DataLen) {
+    using namespace clang::io;
+    unsigned NumDecls = ReadUnalignedLE16(d);
+    DeclID *Start = (DeclID *)d;
+    return std::make_pair(Start, Start + NumDecls);
+  }
+};
+
+} // end anonymous namespace
+
+/// \brief The on-disk hash table used for the DeclContext's Name lookup table.
+typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
+  ASTDeclContextNameLookupTable;
+
+bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
+                                   const std::pair<uint64_t, uint64_t> &Offsets,
+                                       DeclContextInfo &Info) {
+  SavedStreamPosition SavedPosition(Cursor);
+  // First the lexical decls.
+  if (Offsets.first != 0) {
+    Cursor.JumpToBit(Offsets.first);
+
+    RecordData Record;
+    const char *Blob;
+    unsigned BlobLen;
+    unsigned Code = Cursor.ReadCode();
+    unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
+    if (RecCode != DECL_CONTEXT_LEXICAL) {
+      Error("Expected lexical block");
+      return true;
+    }
+
+    Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob);
+    Info.NumLexicalDecls = BlobLen / sizeof(DeclID);
+  } else {
+    Info.LexicalDecls = 0;
+    Info.NumLexicalDecls = 0;
+  }
+
+  // Now the lookup table.
+  if (Offsets.second != 0) {
+    Cursor.JumpToBit(Offsets.second);
+
+    RecordData Record;
+    const char *Blob;
+    unsigned BlobLen;
+    unsigned Code = Cursor.ReadCode();
+    unsigned RecCode = Cursor.ReadRecord(Code, Record, &Blob, &BlobLen);
+    if (RecCode != DECL_CONTEXT_VISIBLE) {
+      Error("Expected visible lookup table block");
+      return true;
+    }
+    Info.NameLookupTableData
+      = ASTDeclContextNameLookupTable::Create(
+                    (const unsigned char *)Blob + Record[0],
+                    (const unsigned char *)Blob,
+                    ASTDeclContextNameLookupTrait(*this));
+  } else {
+    Info.NameLookupTableData = 0;
+  }
+
+  return false;
+}
+
+void ASTReader::Error(const char *Msg) {
+  Diag(diag::err_fe_pch_malformed) << Msg;
+}
+
+/// \brief Tell the AST listener about the predefines buffers in the chain.
+bool ASTReader::CheckPredefinesBuffers() {
+  if (Listener)
+    return Listener->ReadPredefinesBuffer(PCHPredefinesBuffers,
+                                          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 ASTReader::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 = Record[Idx++];
+
+    // Extract the line entries
+    unsigned NumEntries = Record[Idx++];
+    assert(NumEntries && "Numentries is 00000");
+    Entries.clear();
+    Entries.reserve(NumEntries);
+    for (unsigned I = 0; I != NumEntries; ++I) {
+      unsigned FileOffset = Record[Idx++];
+      unsigned LineNo = Record[Idx++];
+      int FilenameID = FileIDs[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 ASTStatData {
+public:
+  const bool hasStat;
+  const ino_t ino;
+  const dev_t dev;
+  const mode_t mode;
+  const time_t mtime;
+  const off_t size;
+
+  ASTStatData(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) {}
+
+  ASTStatData()
+    : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
+};
+
+class ASTStatLookupTrait {
+ public:
+  typedef const char *external_key_type;
+  typedef const char *internal_key_type;
+
+  typedef ASTStatData 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 ASTStatCache : public StatSysCallCache {
+  typedef OnDiskChainedHashTable<ASTStatLookupTrait> CacheTy;
+  CacheTy *Cache;
+
+  unsigned &NumStatHits, &NumStatMisses;
+public:
+  ASTStatCache(const unsigned char *Buckets,
+               const unsigned char *Base,
+               unsigned &NumStatHits,
+               unsigned &NumStatMisses)
+    : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) {
+    Cache = CacheTy::Create(Buckets, Base);
+  }
+
+  ~ASTStatCache() { delete Cache; }
+
+  int stat(const char *path, struct stat *buf) {
+    // Do the lookup for the file's data in the AST file.
+    CacheTy::iterator I = Cache->find(path);
+
+    // If we don't get a hit in the AST file just forward to 'stat'.
+    if (I == Cache->end()) {
+      ++NumStatMisses;
+      return StatSysCallCache::stat(path, buf);
+    }
+
+    ++NumStatHits;
+    ASTStatData 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 a source manager block
+ASTReader::ASTReadResult ASTReader::ReadSourceManagerBlock(PerFileData &F) {
+  using namespace SrcMgr;
+
+  llvm::BitstreamCursor &SLocEntryCursor = F.SLocEntryCursor;
+
+  // 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 = F.Stream;
+
+  // The stream itself is going to skip over the source manager block.
+  if (F.Stream.SkipBlock()) {
+    Error("malformed block record in AST file");
+    return Failure;
+  }
+
+  // Enter the source manager block.
+  if (SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) {
+    Error("malformed source manager block record in AST 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 AST 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 AST 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 SM_LINE_TABLE:
+      if (ParseLineTable(Record))
+        return Failure;
+      break;
+
+    case SM_SLOC_FILE_ENTRY:
+    case SM_SLOC_BUFFER_ENTRY:
+    case SM_SLOC_INSTANTIATION_ENTRY:
+      // Once we hit one of the source location entries, we're done.
+      return Success;
+    }
+  }
+}
+
+/// \brief Get a cursor that's correctly positioned for reading the source
+/// location entry with the given ID.
+llvm::BitstreamCursor &ASTReader::SLocCursorForID(unsigned ID) {
+  assert(ID != 0 && ID <= TotalNumSLocEntries &&
+         "SLocCursorForID should only be called for real IDs.");
+
+  ID -= 1;
+  PerFileData *F = 0;
+  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+    F = Chain[N - I - 1];
+    if (ID < F->LocalNumSLocEntries)
+      break;
+    ID -= F->LocalNumSLocEntries;
+  }
+  assert(F && F->LocalNumSLocEntries > ID && "Chain corrupted");
+
+  F->SLocEntryCursor.JumpToBit(F->SLocOffsets[ID]);
+  return F->SLocEntryCursor;
+}
+
+/// \brief Read in the source location entry with the given ID.
+ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) {
+  if (ID == 0)
+    return Success;
+
+  if (ID > TotalNumSLocEntries) {
+    Error("source location entry ID out-of-range for AST file");
+    return Failure;
+  }
+
+  llvm::BitstreamCursor &SLocEntryCursor = SLocCursorForID(ID);
+
+  ++NumSLocEntriesRead;
+  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 AST 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 AST file");
+    return Failure;
+
+  case 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 AST file";
+      Error(ErrorStr.c_str());
+      return Failure;
+    }
+
+    if (Record.size() < 10) {
+      Error("source location entry is incorrect");
+      return Failure;
+    }
+
+    if (!DisableValidation &&
+        ((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 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 != SM_SLOC_BUFFER_BLOB) {
+      Error("AST 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) {
+      PCHPredefinesBlock Block = {
+        BufferID,
+        llvm::StringRef(BlobStart, BlobLen - 1)
+      };
+      PCHPredefinesBuffers.push_back(Block);
+    }
+
+    break;
+  }
+
+  case 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 ASTReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
+                                 unsigned BlockID) {
+  if (Cursor.EnterSubBlock(BlockID)) {
+    Error("malformed block record in AST 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 ASTReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, 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 AST file");
+        return;
+      }
+      continue;
+
+    case llvm::bitc::DEFINE_ABBREV:
+      Stream.ReadAbbrevRecord();
+      continue;
+    default: break;
+    }
+
+    // Read a record.
+    Record.clear();
+    PreprocessorRecordTypes RecType =
+      (PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
+    switch (RecType) {
+    case PP_MACRO_OBJECT_LIKE:
+    case 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 AST file");
+        return;
+      }
+      SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]);
+      bool isUsed = Record[2];
+
+      MacroInfo *MI = PP->AllocateMacroInfo(Loc);
+      MI->setIsUsed(isUsed);
+      MI->setIsFromAST();
+
+      unsigned NextIndex = 3;
+      if (RecType == 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 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 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 AST 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 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 AST 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 ASTReader::ReadDefinedMacros() {
+  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+    llvm::BitstreamCursor &MacroCursor = Chain[N - I - 1]->MacroCursor;
+
+    // If there was no preprocessor block, skip this file.
+    if (!MacroCursor.getBitStreamReader())
+      continue;
+
+    llvm::BitstreamCursor Cursor = MacroCursor;
+    if (Cursor.EnterSubBlock(PREPROCESSOR_BLOCK_ID)) {
+      Error("malformed preprocessor block record in AST 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 AST file");
+          return;
+        }
+        break;
+      }
+
+      if (Code == llvm::bitc::ENTER_SUBBLOCK) {
+        // No known subblocks, always skip them.
+        Cursor.ReadSubBlockID();
+        if (Cursor.SkipBlock()) {
+          Error("malformed block record in AST 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 PP_MACRO_OBJECT_LIKE:
+      case PP_MACRO_FUNCTION_LIKE:
+        DecodeIdentifierInfo(Record[0]);
+        break;
+
+      case PP_TOKEN:
+        // Ignore tokens.
+        break;
+        
+      case PP_MACRO_INSTANTIATION:
+      case PP_MACRO_DEFINITION:
+        // Read the macro record.
+        ReadMacroRecord(Chain[N - I - 1]->Stream, Cursor.GetCurrentBitNo());
+        break;
+      }
+    }
+  }
+}
+
+MacroDefinition *ASTReader::getMacroDefinition(IdentID ID) {
+  if (ID == 0 || ID >= MacroDefinitionsLoaded.size())
+    return 0;
+
+  if (!MacroDefinitionsLoaded[ID]) {
+    unsigned Index = ID;
+    for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+      PerFileData &F = *Chain[N - I - 1];
+      if (Index < F.LocalNumMacroDefinitions) {
+        ReadMacroRecord(F.Stream, F.MacroDefinitionOffsets[Index]);
+        break;
+      }
+      Index -= F.LocalNumMacroDefinitions;
+    }
+    assert(MacroDefinitionsLoaded[ID] && "Broken chain");
+  }
+
+  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 ASTReader::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);
+}
+
+ASTReader::ASTReadResult
+ASTReader::ReadASTBlock(PerFileData &F) {
+  llvm::BitstreamCursor &Stream = F.Stream;
+
+  if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
+    Error("malformed block record in AST file");
+    return Failure;
+  }
+
+  // Read all of the records and blocks for the ASt file.
+  RecordData Record;
+  bool First = true;
+  while (!Stream.AtEndOfStream()) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == llvm::bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd()) {
+        Error("error at end of module block in AST file");
+        return Failure;
+      }
+
+      return Success;
+    }
+
+    if (Code == llvm::bitc::ENTER_SUBBLOCK) {
+      switch (Stream.ReadSubBlockID()) {
+      case 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.
+        F.DeclsCursor = Stream;
+        if (Stream.SkipBlock() ||  // Skip with the main cursor.
+            // Read the abbrevs.
+            ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) {
+          Error("malformed block record in AST file");
+          return Failure;
+        }
+        break;
+
+      case PREPROCESSOR_BLOCK_ID:
+        F.MacroCursor = Stream;
+        if (PP)
+          PP->setExternalSource(this);
+
+        if (Stream.SkipBlock()) {
+          Error("malformed block record in AST file");
+          return Failure;
+        }
+        break;
+
+      case SOURCE_MANAGER_BLOCK_ID:
+        switch (ReadSourceManagerBlock(F)) {
+        case Success:
+          break;
+
+        case Failure:
+          Error("malformed source manager block in AST file");
+          return Failure;
+
+        case IgnorePCH:
+          return IgnorePCH;
+        }
+        break;
+      }
+      First = false;
+      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 ((ASTRecordTypes)Stream.ReadRecord(Code, Record,
+                                                   &BlobStart, &BlobLen)) {
+    default:  // Default behavior: ignore.
+      break;
+
+    case METADATA: {
+      if (Record[0] != VERSION_MAJOR && !DisableValidation) {
+        Diag(Record[0] < 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 CHAINED_METADATA: {
+      if (!First) {
+        Error("CHAINED_METADATA is not first record in block");
+        return Failure;
+      }
+      if (Record[0] != VERSION_MAJOR && !DisableValidation) {
+        Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
+                                           : diag::warn_pch_version_too_new);
+        return IgnorePCH;
+      }
+
+      // Load the chained file.
+      switch(ReadASTCore(llvm::StringRef(BlobStart, BlobLen))) {
+      case Failure: return Failure;
+        // If we have to ignore the dependency, we'll have to ignore this too.
+      case IgnorePCH: return IgnorePCH;
+      case Success: break;
+      }
+      break;
+    }
+
+    case TYPE_OFFSET:
+      if (F.LocalNumTypes != 0) {
+        Error("duplicate TYPE_OFFSET record in AST file");
+        return Failure;
+      }
+      F.TypeOffsets = (const uint32_t *)BlobStart;
+      F.LocalNumTypes = Record[0];
+      break;
+
+    case DECL_OFFSET:
+      if (F.LocalNumDecls != 0) {
+        Error("duplicate DECL_OFFSET record in AST file");
+        return Failure;
+      }
+      F.DeclOffsets = (const uint32_t *)BlobStart;
+      F.LocalNumDecls = Record[0];
+      break;
+
+    case TU_UPDATE_LEXICAL: {
+      DeclContextInfo Info = {
+        /* No visible information */ 0,
+        reinterpret_cast<const DeclID *>(BlobStart),
+        BlobLen / sizeof(DeclID)
+      };
+      DeclContextOffsets[Context->getTranslationUnitDecl()].push_back(Info);
+      break;
+    }
+
+    case UPDATE_VISIBLE: {
+      serialization::DeclID ID = Record[0];
+      void *Table = ASTDeclContextNameLookupTable::Create(
+                        (const unsigned char *)BlobStart + Record[1],
+                        (const unsigned char *)BlobStart,
+                        ASTDeclContextNameLookupTrait(*this));
+      if (ID == 1) { // Is it the TU?
+        DeclContextInfo Info = {
+          Table, /* No lexical inforamtion */ 0, 0
+        };
+        DeclContextOffsets[Context->getTranslationUnitDecl()].push_back(Info);
+      } else
+        PendingVisibleUpdates[ID].push_back(Table);
+      break;
+    }
+
+    case REDECLS_UPDATE_LATEST: {
+      assert(Record.size() % 2 == 0 && "Expected pairs of DeclIDs");
+      for (unsigned i = 0, e = Record.size(); i < e; i += 2) {
+        DeclID First = Record[i], Latest = Record[i+1];
+        assert((FirstLatestDeclIDs.find(First) == FirstLatestDeclIDs.end() ||
+                Latest > FirstLatestDeclIDs[First]) &&
+               "The new latest is supposed to come after the previous latest");
+        FirstLatestDeclIDs[First] = Latest;
+      }
+      break;
+    }
+
+    case LANGUAGE_OPTIONS:
+      if (ParseLanguageOptions(Record) && !DisableValidation)
+        return IgnorePCH;
+      break;
+
+    case IDENTIFIER_TABLE:
+      F.IdentifierTableData = BlobStart;
+      if (Record[0]) {
+        F.IdentifierLookupTable
+          = ASTIdentifierLookupTable::Create(
+                       (const unsigned char *)F.IdentifierTableData + Record[0],
+                       (const unsigned char *)F.IdentifierTableData,
+                       ASTIdentifierLookupTrait(*this, F.Stream));
+        if (PP)
+          PP->getIdentifierTable().setExternalIdentifierLookup(this);
+      }
+      break;
+
+    case IDENTIFIER_OFFSET:
+      if (F.LocalNumIdentifiers != 0) {
+        Error("duplicate IDENTIFIER_OFFSET record in AST file");
+        return Failure;
+      }
+      F.IdentifierOffsets = (const uint32_t *)BlobStart;
+      F.LocalNumIdentifiers = Record[0];
+      break;
+
+    case EXTERNAL_DEFINITIONS:
+      // Optimization for the first block.
+      if (ExternalDefinitions.empty())
+        ExternalDefinitions.swap(Record);
+      else
+        ExternalDefinitions.insert(ExternalDefinitions.end(),
+                                   Record.begin(), Record.end());
+      break;
+
+    case SPECIAL_TYPES:
+      // Optimization for the first block
+      if (SpecialTypes.empty())
+        SpecialTypes.swap(Record);
+      else
+        SpecialTypes.insert(SpecialTypes.end(), Record.begin(), Record.end());
+      break;
+
+    case STATISTICS:
+      TotalNumStatements += Record[0];
+      TotalNumMacros += Record[1];
+      TotalLexicalDeclContexts += Record[2];
+      TotalVisibleDeclContexts += Record[3];
+      break;
+
+    case TENTATIVE_DEFINITIONS:
+      // Optimization for the first block.
+      if (TentativeDefinitions.empty())
+        TentativeDefinitions.swap(Record);
+      else
+        TentativeDefinitions.insert(TentativeDefinitions.end(),
+                                    Record.begin(), Record.end());
+      break;
+
+    case UNUSED_FILESCOPED_DECLS:
+      // Optimization for the first block.
+      if (UnusedFileScopedDecls.empty())
+        UnusedFileScopedDecls.swap(Record);
+      else
+        UnusedFileScopedDecls.insert(UnusedFileScopedDecls.end(),
+                                     Record.begin(), Record.end());
+      break;
+
+    case WEAK_UNDECLARED_IDENTIFIERS:
+      // Later blocks overwrite earlier ones.
+      WeakUndeclaredIdentifiers.swap(Record);
+      break;
+
+    case LOCALLY_SCOPED_EXTERNAL_DECLS:
+      // Optimization for the first block.
+      if (LocallyScopedExternalDecls.empty())
+        LocallyScopedExternalDecls.swap(Record);
+      else
+        LocallyScopedExternalDecls.insert(LocallyScopedExternalDecls.end(),
+                                          Record.begin(), Record.end());
+      break;
+
+    case SELECTOR_OFFSETS:
+      F.SelectorOffsets = (const uint32_t *)BlobStart;
+      F.LocalNumSelectors = Record[0];
+      break;
+
+    case METHOD_POOL:
+      F.SelectorLookupTableData = (const unsigned char *)BlobStart;
+      if (Record[0])
+        F.SelectorLookupTable
+          = ASTSelectorLookupTable::Create(
+                        F.SelectorLookupTableData + Record[0],
+                        F.SelectorLookupTableData,
+                        ASTSelectorLookupTrait(*this));
+      TotalNumMethodPoolEntries += Record[1];
+      break;
+
+    case REFERENCED_SELECTOR_POOL: {
+      ReferencedSelectorsData.insert(ReferencedSelectorsData.end(),
+          Record.begin(), Record.end());
+      break;
+    }
+
+    case PP_COUNTER_VALUE:
+      if (!Record.empty() && Listener)
+        Listener->ReadCounter(Record[0]);
+      break;
+
+    case SOURCE_LOCATION_OFFSETS:
+      F.SLocOffsets = (const uint32_t *)BlobStart;
+      F.LocalNumSLocEntries = Record[0];
+      // We cannot delay this until the entire chain is loaded, because then
+      // source location preloads would also have to be delayed.
+      // FIXME: Is there a reason not to do that?
+      TotalNumSLocEntries += F.LocalNumSLocEntries;
+      SourceMgr.PreallocateSLocEntries(this, TotalNumSLocEntries, Record[1]);
+      break;
+
+    case SOURCE_LOCATION_PRELOADS:
+      for (unsigned I = 0, N = Record.size(); I != N; ++I) {
+        ASTReadResult Result = ReadSLocEntryRecord(Record[I]);
+        if (Result != Success)
+          return Result;
+      }
+      break;
+
+    case STAT_CACHE: {
+      ASTStatCache *MyStatCache =
+        new ASTStatCache((const unsigned char *)BlobStart + Record[0],
+                         (const unsigned char *)BlobStart,
+                         NumStatHits, NumStatMisses);
+      FileMgr.addStatCache(MyStatCache);
+      F.StatCache = MyStatCache;
+      break;
+    }
+
+    case EXT_VECTOR_DECLS:
+      // Optimization for the first block.
+      if (ExtVectorDecls.empty())
+        ExtVectorDecls.swap(Record);
+      else
+        ExtVectorDecls.insert(ExtVectorDecls.end(),
+                              Record.begin(), Record.end());
+      break;
+
+    case VTABLE_USES:
+      // Later tables overwrite earlier ones.
+      VTableUses.swap(Record);
+      break;
+
+    case DYNAMIC_CLASSES:
+      // Optimization for the first block.
+      if (DynamicClasses.empty())
+        DynamicClasses.swap(Record);
+      else
+        DynamicClasses.insert(DynamicClasses.end(),
+                              Record.begin(), Record.end());
+      break;
+
+    case PENDING_IMPLICIT_INSTANTIATIONS:
+      // Optimization for the first block.
+      if (PendingInstantiations.empty())
+        PendingInstantiations.swap(Record);
+      else
+        PendingInstantiations.insert(PendingInstantiations.end(),
+                                     Record.begin(), Record.end());
+      break;
+
+    case SEMA_DECL_REFS:
+      // Later tables overwrite earlier ones.
+      SemaDeclRefs.swap(Record);
+      break;
+
+    case ORIGINAL_FILE_NAME:
+      // The primary AST will be the last to get here, so it will be the one
+      // that's used.
+      ActualOriginalFileName.assign(BlobStart, BlobLen);
+      OriginalFileName = ActualOriginalFileName;
+      MaybeAddSystemRootToFilename(OriginalFileName);
+      break;
+
+    case VERSION_CONTROL_BRANCH_REVISION: {
+      const std::string &CurBranch = getClangFullRepositoryVersion();
+      llvm::StringRef ASTBranch(BlobStart, BlobLen);
+      if (llvm::StringRef(CurBranch) != ASTBranch && !DisableValidation) {
+        Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch;
+        return IgnorePCH;
+      }
+      break;
+    }
+
+    case MACRO_DEFINITION_OFFSETS:
+      F.MacroDefinitionOffsets = (const uint32_t *)BlobStart;
+      F.NumPreallocatedPreprocessingEntities = Record[0];
+      F.LocalNumMacroDefinitions = Record[1];
+      break;
+
+    case DECL_REPLACEMENTS: {
+      if (Record.size() % 2 != 0) {
+        Error("invalid DECL_REPLACEMENTS block in AST file");
+        return Failure;
+      }
+      for (unsigned I = 0, N = Record.size(); I != N; I += 2)
+        ReplacedDecls[static_cast<DeclID>(Record[I])] =
+            std::make_pair(&F, Record[I+1]);
+      break;
+    }
+
+    case ADDITIONAL_TEMPLATE_SPECIALIZATIONS: {
+      AdditionalTemplateSpecializations &ATS =
+          AdditionalTemplateSpecializationsPending[Record[0]];
+      ATS.insert(ATS.end(), Record.begin()+1, Record.end());
+      break;
+    }
+    }
+    First = false;
+  }
+  Error("premature end of bitstream in AST file");
+  return Failure;
+}
+
+ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName) {
+  switch(ReadASTCore(FileName)) {
+  case Failure: return Failure;
+  case IgnorePCH: return IgnorePCH;
+  case Success: break;
+  }
+
+  // Here comes stuff that we only do once the entire chain is loaded.
+
+  // Allocate space for loaded identifiers, decls and types.
+  unsigned TotalNumIdentifiers = 0, TotalNumTypes = 0, TotalNumDecls = 0,
+           TotalNumPreallocatedPreprocessingEntities = 0, TotalNumMacroDefs = 0,
+           TotalNumSelectors = 0;
+  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+    TotalNumIdentifiers += Chain[I]->LocalNumIdentifiers;
+    TotalNumTypes += Chain[I]->LocalNumTypes;
+    TotalNumDecls += Chain[I]->LocalNumDecls;
+    TotalNumPreallocatedPreprocessingEntities +=
+        Chain[I]->NumPreallocatedPreprocessingEntities;
+    TotalNumMacroDefs += Chain[I]->LocalNumMacroDefinitions;
+    TotalNumSelectors += Chain[I]->LocalNumSelectors;
+  }
+  IdentifiersLoaded.resize(TotalNumIdentifiers);
+  TypesLoaded.resize(TotalNumTypes);
+  DeclsLoaded.resize(TotalNumDecls);
+  MacroDefinitionsLoaded.resize(TotalNumMacroDefs);
+  if (PP) {
+    if (TotalNumIdentifiers > 0)
+      PP->getHeaderSearchInfo().SetExternalLookup(this);
+    if (TotalNumPreallocatedPreprocessingEntities > 0) {
+      if (!PP->getPreprocessingRecord())
+        PP->createPreprocessingRecord();
+      PP->getPreprocessingRecord()->SetExternalSource(*this,
+                                     TotalNumPreallocatedPreprocessingEntities);
+    }
+  }
+  SelectorsLoaded.resize(TotalNumSelectors);
+
+  // Check the predefines buffers.
+  if (!DisableValidation && CheckPredefinesBuffers())
+    return IgnorePCH;
+
+  if (PP) {
+    // Initialization of keywords and pragmas occurs before the
+    // AST 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);
+    // We need to search the tables in all files.
+    for (unsigned J = 0, M = Chain.size(); J != M; ++J) {
+      ASTIdentifierLookupTable *IdTable
+        = (ASTIdentifierLookupTable *)Chain[J]->IdentifierLookupTable;
+      // Not all AST files necessarily have identifier tables, only the useful
+      // ones.
+      if (!IdTable)
+        continue;
+      for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
+        IdentifierInfo *II = Identifiers[I];
+        // Look in the on-disk hash tables for an entry for this identifier
+        ASTIdentifierLookupTrait Info(*this, Chain[J]->Stream, II);
+        std::pair<const char*,unsigned> Key(II->getNameStart(),II->getLength());
+        ASTIdentifierLookupTable::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;
+}
+
+ASTReader::ASTReadResult ASTReader::ReadASTCore(llvm::StringRef FileName) {
+  Chain.push_back(new PerFileData());
+  PerFileData &F = *Chain.back();
+
+  // Set the AST file name.
+  F.FileName = FileName;
+
+  // Open the AST file.
+  //
+  // FIXME: This shouldn't be here, we should just take a raw_ostream.
+  std::string ErrStr;
+  F.Buffer.reset(llvm::MemoryBuffer::getFileOrSTDIN(FileName, &ErrStr));
+  if (!F.Buffer) {
+    Error(ErrStr.c_str());
+    return IgnorePCH;
+  }
+
+  // Initialize the stream
+  F.StreamFile.init((const unsigned char *)F.Buffer->getBufferStart(),
+                    (const unsigned char *)F.Buffer->getBufferEnd());
+  llvm::BitstreamCursor &Stream = F.Stream;
+  Stream.init(F.StreamFile);
+  F.SizeInBits = F.Buffer->getBufferSize() * 8;
+
+  // 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 AST file");
+      return Failure;
+    }
+
+    unsigned BlockID = Stream.ReadSubBlockID();
+
+    // We only know the AST subblock ID.
+    switch (BlockID) {
+    case llvm::bitc::BLOCKINFO_BLOCK_ID:
+      if (Stream.ReadBlockInfoBlock()) {
+        Error("malformed BlockInfoBlock in AST file");
+        return Failure;
+      }
+      break;
+    case AST_BLOCK_ID:
+      switch (ReadASTBlock(F)) {
+      case Success:
+        break;
+
+      case Failure:
+        return Failure;
+
+      case IgnorePCH:
+        // FIXME: We could consider reading through to the end of this
+        // AST block, skipping subblocks, to see if there are other
+        // AST 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 (F.StatCache)
+          FileMgr.removeStatCache((ASTStatCache*)F.StatCache);
+
+        return IgnorePCH;
+      }
+      break;
+    default:
+      if (Stream.SkipBlock()) {
+        Error("malformed block record in AST file");
+        return Failure;
+      }
+      break;
+    }
+  }
+
+  return Success;
+}
+
+void ASTReader::setPreprocessor(Preprocessor &pp) {
+  PP = &pp;
+
+  unsigned TotalNum = 0;
+  for (unsigned I = 0, N = Chain.size(); I != N; ++I)
+    TotalNum += Chain[I]->NumPreallocatedPreprocessingEntities;
+  if (TotalNum) {
+    if (!PP->getPreprocessingRecord())
+      PP->createPreprocessingRecord();
+    PP->getPreprocessingRecord()->SetExternalSource(*this, TotalNum);
+  }
+}
+
+void ASTReader::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
+  GetTranslationUnitDecl();
+
+  // Load the special types.
+  Context->setBuiltinVaListType(
+    GetType(SpecialTypes[SPECIAL_TYPE_BUILTIN_VA_LIST]));
+  if (unsigned Id = SpecialTypes[SPECIAL_TYPE_OBJC_ID])
+    Context->setObjCIdType(GetType(Id));
+  if (unsigned Sel = SpecialTypes[SPECIAL_TYPE_OBJC_SELECTOR])
+    Context->setObjCSelType(GetType(Sel));
+  if (unsigned Proto = SpecialTypes[SPECIAL_TYPE_OBJC_PROTOCOL])
+    Context->setObjCProtoType(GetType(Proto));
+  if (unsigned Class = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS])
+    Context->setObjCClassType(GetType(Class));
+
+  if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING])
+    Context->setCFConstantStringType(GetType(String));
+  if (unsigned FastEnum
+        = SpecialTypes[SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
+    Context->setObjCFastEnumerationStateType(GetType(FastEnum));
+  if (unsigned File = SpecialTypes[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 AST file");
+        return;
+      }
+      Context->setFILEDecl(Tag->getDecl());
+    }
+  }
+  if (unsigned Jmp_buf = SpecialTypes[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_buf type in AST file");
+        return;
+      }
+      Context->setjmp_bufDecl(Tag->getDecl());
+    }
+  }
+  if (unsigned Sigjmp_buf = SpecialTypes[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 AST file");
+      Context->setsigjmp_bufDecl(Tag->getDecl());
+    }
+  }
+  if (unsigned ObjCIdRedef
+        = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION])
+    Context->ObjCIdRedefinitionType = GetType(ObjCIdRedef);
+  if (unsigned ObjCClassRedef
+      = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION])
+    Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef);
+  if (unsigned String = SpecialTypes[SPECIAL_TYPE_BLOCK_DESCRIPTOR])
+    Context->setBlockDescriptorType(GetType(String));
+  if (unsigned String
+      = SpecialTypes[SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR])
+    Context->setBlockDescriptorExtendedType(GetType(String));
+  if (unsigned ObjCSelRedef
+      = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION])
+    Context->ObjCSelRedefinitionType = GetType(ObjCSelRedef);
+  if (unsigned String = SpecialTypes[SPECIAL_TYPE_NS_CONSTANT_STRING])
+    Context->setNSConstantStringType(GetType(String));
+
+  if (SpecialTypes[SPECIAL_TYPE_INT128_INSTALLED])
+    Context->setInt128Installed();
+}
+
+/// \brief Retrieve the name of the original source file name
+/// directly from the AST file, without actually loading the AST
+/// file.
+std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
+                                             Diagnostic &Diags) {
+  // Open the AST file.
+  std::string ErrStr;
+  llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
+  Buffer.reset(llvm::MemoryBuffer::getFile(ASTFileName.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) << ASTFileName;
+    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 AST subblock ID.
+      switch (BlockID) {
+      case AST_BLOCK_ID:
+        if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
+          Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
+          return std::string();
+        }
+        break;
+
+      default:
+        if (Stream.SkipBlock()) {
+          Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
+          return std::string();
+        }
+        break;
+      }
+      continue;
+    }
+
+    if (Code == llvm::bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd()) {
+        Diags.Report(diag::err_fe_pch_error_at_end_block) << ASTFileName;
+        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)
+          == ORIGINAL_FILE_NAME)
+      return std::string(BlobStart, BlobLen);
+  }
+
+  return std::string();
+}
+
+/// \brief Parse the record that corresponds to a LangOptions data
+/// structure.
+///
+/// This routine parses the language options from the AST file and then gives
+/// them to the AST listener if one is set.
+///
+/// \returns true if the listener deems the file unacceptable, false otherwise.
+bool ASTReader::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);
+    LangOpts.setSignedOverflowBehavior((LangOptions::SignedOverflowBehaviorTy)
+                                       Record[Idx++]);
+    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++]);
+    LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx++]);
+    LangOpts.setStackProtectorMode((LangOptions::StackProtectorMode)
+                                   Record[Idx++]);
+    PARSE_LANGOPT(InstantiationDepth);
+    PARSE_LANGOPT(OpenCL);
+    PARSE_LANGOPT(CatchUndefined);
+    // FIXME: Missing ElideConstructors?!
+  #undef PARSE_LANGOPT
+
+    return Listener->ReadLanguageOptions(LangOpts);
+  }
+
+  return false;
+}
+
+void ASTReader::ReadPreprocessedEntities() {
+  ReadDefinedMacros();
+}
+
+/// \brief Get the correct cursor and offset for loading a type.
+ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {
+  PerFileData *F = 0;
+  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+    F = Chain[N - I - 1];
+    if (Index < F->LocalNumTypes)
+      break;
+    Index -= F->LocalNumTypes;
+  }
+  assert(F && F->LocalNumTypes > Index && "Broken chain");
+  return RecordLocation(&F->DeclsCursor, F->TypeOffsets[Index]);
+}
+
+/// \brief Read and return the type with the given index..
+///
+/// The index is the type ID, shifted and minus the number of predefs. This
+/// routine actually reads the record corresponding to the type at the given
+/// location. It is a helper routine for GetType, which deals with reading type
+/// IDs.
+QualType ASTReader::ReadTypeRecord(unsigned Index) {
+  RecordLocation Loc = TypeCursorForIndex(Index);
+  llvm::BitstreamCursor &DeclsCursor = *Loc.first;
+
+  // Keep track of where we are in the stream, then jump back there
+  // after reading this type.
+  SavedStreamPosition SavedPosition(DeclsCursor);
+
+  ReadingKindTracker ReadingKind(Read_Type, *this);
+
+  // Note that we are loading a type record.
+  Deserializing AType(this);
+
+  DeclsCursor.JumpToBit(Loc.second);
+  RecordData Record;
+  unsigned Code = DeclsCursor.ReadCode();
+  switch ((TypeCode)DeclsCursor.ReadRecord(Code, Record)) {
+  case 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 TYPE_COMPLEX: {
+    if (Record.size() != 1) {
+      Error("Incorrect encoding of complex type");
+      return QualType();
+    }
+    QualType ElemType = GetType(Record[0]);
+    return Context->getComplexType(ElemType);
+  }
+
+  case TYPE_POINTER: {
+    if (Record.size() != 1) {
+      Error("Incorrect encoding of pointer type");
+      return QualType();
+    }
+    QualType PointeeType = GetType(Record[0]);
+    return Context->getPointerType(PointeeType);
+  }
+
+  case 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 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 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 TYPE_MEMBER_POINTER: {
+    if (Record.size() != 2) {
+      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 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 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 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, ReadExpr(DeclsCursor),
+                                         ASM, IndexTypeQuals,
+                                         SourceRange(LBLoc, RBLoc));
+  }
+
+  case TYPE_VECTOR: {
+    if (Record.size() != 3) {
+      Error("incorrect encoding of vector type in AST file");
+      return QualType();
+    }
+
+    QualType ElementType = GetType(Record[0]);
+    unsigned NumElements = Record[1];
+    unsigned AltiVecSpec = Record[2];
+    return Context->getVectorType(ElementType, NumElements,
+                                  (VectorType::AltiVecSpecific)AltiVecSpec);
+  }
+
+  case TYPE_EXT_VECTOR: {
+    if (Record.size() != 3) {
+      Error("incorrect encoding of extended vector type in AST file");
+      return QualType();
+    }
+
+    QualType ElementType = GetType(Record[0]);
+    unsigned NumElements = Record[1];
+    return Context->getExtVectorType(ElementType, NumElements);
+  }
+
+  case 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 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 TYPE_UNRESOLVED_USING:
+    return Context->getTypeDeclType(
+             cast<UnresolvedUsingTypenameDecl>(GetDecl(Record[0])));
+
+  case TYPE_TYPEDEF: {
+    if (Record.size() != 2) {
+      Error("incorrect encoding of typedef type");
+      return QualType();
+    }
+    TypedefDecl *Decl = cast<TypedefDecl>(GetDecl(Record[0]));
+    QualType Canonical = GetType(Record[1]);
+    return Context->getTypedefType(Decl, Canonical);
+  }
+
+  case TYPE_TYPEOF_EXPR:
+    return Context->getTypeOfExprType(ReadExpr(DeclsCursor));
+
+  case TYPE_TYPEOF: {
+    if (Record.size() != 1) {
+      Error("incorrect encoding of typeof(type) in AST file");
+      return QualType();
+    }
+    QualType UnderlyingType = GetType(Record[0]);
+    return Context->getTypeOfType(UnderlyingType);
+  }
+
+  case TYPE_DECLTYPE:
+    return Context->getDecltypeType(ReadExpr(DeclsCursor));
+
+  case TYPE_RECORD: {
+    if (Record.size() != 2) {
+      Error("incorrect encoding of record type");
+      return QualType();
+    }
+    bool IsDependent = Record[0];
+    QualType T = Context->getRecordType(cast<RecordDecl>(GetDecl(Record[1])));
+    T->Dependent = IsDependent;
+    return T;
+  }
+
+  case TYPE_ENUM: {
+    if (Record.size() != 2) {
+      Error("incorrect encoding of enum type");
+      return QualType();
+    }
+    bool IsDependent = Record[0];
+    QualType T = Context->getEnumType(cast<EnumDecl>(GetDecl(Record[1])));
+    T->Dependent = IsDependent;
+    return T;
+  }
+
+  case TYPE_ELABORATED: {
+    unsigned Idx = 0;
+    ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
+    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
+    QualType NamedType = GetType(Record[Idx++]);
+    return Context->getElaboratedType(Keyword, NNS, NamedType);
+  }
+
+  case TYPE_OBJC_INTERFACE: {
+    unsigned Idx = 0;
+    ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
+    return Context->getObjCInterfaceType(ItfD);
+  }
+
+  case TYPE_OBJC_OBJECT: {
+    unsigned Idx = 0;
+    QualType Base = 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->getObjCObjectType(Base, Protos.data(), NumProtos);    
+  }
+
+  case TYPE_OBJC_OBJECT_POINTER: {
+    unsigned Idx = 0;
+    QualType Pointee = GetType(Record[Idx++]);
+    return Context->getObjCObjectPointerType(Pointee);
+  }
+
+  case 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 TYPE_INJECTED_CLASS_NAME: {
+    CXXRecordDecl *D = cast<CXXRecordDecl>(GetDecl(Record[0]));
+    QualType TST = GetType(Record[1]); // probably derivable
+    // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
+    // for AST reading, too much interdependencies.
+    return
+      QualType(new (*Context, TypeAlignment) InjectedClassNameType(D, TST), 0);
+  }
+  
+  case TYPE_TEMPLATE_TYPE_PARM: {
+    unsigned Idx = 0;
+    unsigned Depth = Record[Idx++];
+    unsigned Index = Record[Idx++];
+    bool Pack = Record[Idx++];
+    IdentifierInfo *Name = GetIdentifierInfo(Record, Idx);
+    return Context->getTemplateTypeParmType(Depth, Index, Pack, Name);
+  }
+  
+  case TYPE_DEPENDENT_NAME: {
+    unsigned Idx = 0;
+    ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
+    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
+    const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
+    QualType Canon = GetType(Record[Idx++]);
+    return Context->getDependentNameType(Keyword, NNS, Name, Canon);
+  }
+  
+  case TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION: {
+    unsigned Idx = 0;
+    ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
+    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
+    const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
+    unsigned NumArgs = Record[Idx++];
+    llvm::SmallVector<TemplateArgument, 8> Args;
+    Args.reserve(NumArgs);
+    while (NumArgs--)
+      Args.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
+    return Context->getDependentTemplateSpecializationType(Keyword, NNS, Name,
+                                                      Args.size(), Args.data());
+  }
+  
+  case TYPE_DEPENDENT_SIZED_ARRAY: {
+    unsigned Idx = 0;
+
+    // ArrayType
+    QualType ElementType = GetType(Record[Idx++]);
+    ArrayType::ArraySizeModifier ASM
+      = (ArrayType::ArraySizeModifier)Record[Idx++];
+    unsigned IndexTypeQuals = Record[Idx++];
+
+    // DependentSizedArrayType
+    Expr *NumElts = ReadExpr(DeclsCursor);
+    SourceRange Brackets = ReadSourceRange(Record, Idx);
+
+    return Context->getDependentSizedArrayType(ElementType, NumElts, ASM,
+                                               IndexTypeQuals, Brackets);
+  }
+
+  case TYPE_TEMPLATE_SPECIALIZATION: {
+    unsigned Idx = 0;
+    bool IsDependent = Record[Idx++];
+    TemplateName Name = ReadTemplateName(Record, Idx);
+    llvm::SmallVector<TemplateArgument, 8> Args;
+    ReadTemplateArgumentList(Args, DeclsCursor, Record, Idx);
+    QualType Canon = GetType(Record[Idx++]);
+    QualType T;
+    if (Canon.isNull())
+      T = Context->getCanonicalTemplateSpecializationType(Name, Args.data(),
+                                                          Args.size());
+    else
+      T = Context->getTemplateSpecializationType(Name, Args.data(),
+                                                 Args.size(), Canon);
+    T->Dependent = IsDependent;
+    return T;
+  }
+  }
+  // Suppress a GCC warning
+  return QualType();
+}
+
+namespace {
+
+class TypeLocReader : public TypeLocVisitor<TypeLocReader> {
+  ASTReader &Reader;
+  llvm::BitstreamCursor &DeclsCursor;
+  const ASTReader::RecordData &Record;
+  unsigned &Idx;
+
+public:
+  TypeLocReader(ASTReader &Reader, llvm::BitstreamCursor &Cursor,
+                const ASTReader::RecordData &Record, unsigned &Idx)
+    : Reader(Reader), DeclsCursor(Cursor), 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.ReadExpr(DeclsCursor));
+  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(DeclsCursor, 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::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(),
+                                          DeclsCursor, Record, Idx));
+}
+void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
+  TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
+}
+void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
+  TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(
+       DependentTemplateSpecializationTypeLoc TL) {
+  TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
+  TL.setNameLoc(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(),
+                                          DeclsCursor, Record, Idx));
+}
+void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
+  TL.setHasBaseTypeAsWritten(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++]));
+}
+
+TypeSourceInfo *ASTReader::GetTypeSourceInfo(llvm::BitstreamCursor &DeclsCursor,
+                                             const RecordData &Record,
+                                             unsigned &Idx) {
+  QualType InfoTy = GetType(Record[Idx++]);
+  if (InfoTy.isNull())
+    return 0;
+
+  TypeSourceInfo *TInfo = getContext()->CreateTypeSourceInfo(InfoTy);
+  TypeLocReader TLR(*this, DeclsCursor, Record, Idx);
+  for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
+    TLR.Visit(TL);
+  return TInfo;
+}
+
+QualType ASTReader::GetType(TypeID ID) {
+  unsigned FastQuals = ID & Qualifiers::FastMask;
+  unsigned Index = ID >> Qualifiers::FastWidth;
+
+  if (Index < NUM_PREDEF_TYPE_IDS) {
+    QualType T;
+    switch ((PredefinedTypeIDs)Index) {
+    case PREDEF_TYPE_NULL_ID: return QualType();
+    case PREDEF_TYPE_VOID_ID: T = Context->VoidTy; break;
+    case PREDEF_TYPE_BOOL_ID: T = Context->BoolTy; break;
+
+    case PREDEF_TYPE_CHAR_U_ID:
+    case PREDEF_TYPE_CHAR_S_ID:
+      // FIXME: Check that the signedness of CharTy is correct!
+      T = Context->CharTy;
+      break;
+
+    case PREDEF_TYPE_UCHAR_ID:      T = Context->UnsignedCharTy;     break;
+    case PREDEF_TYPE_USHORT_ID:     T = Context->UnsignedShortTy;    break;
+    case PREDEF_TYPE_UINT_ID:       T = Context->UnsignedIntTy;      break;
+    case PREDEF_TYPE_ULONG_ID:      T = Context->UnsignedLongTy;     break;
+    case PREDEF_TYPE_ULONGLONG_ID:  T = Context->UnsignedLongLongTy; break;
+    case PREDEF_TYPE_UINT128_ID:    T = Context->UnsignedInt128Ty;   break;
+    case PREDEF_TYPE_SCHAR_ID:      T = Context->SignedCharTy;       break;
+    case PREDEF_TYPE_WCHAR_ID:      T = Context->WCharTy;            break;
+    case PREDEF_TYPE_SHORT_ID:      T = Context->ShortTy;            break;
+    case PREDEF_TYPE_INT_ID:        T = Context->IntTy;              break;
+    case PREDEF_TYPE_LONG_ID:       T = Context->LongTy;             break;
+    case PREDEF_TYPE_LONGLONG_ID:   T = Context->LongLongTy;         break;
+    case PREDEF_TYPE_INT128_ID:     T = Context->Int128Ty;           break;
+    case PREDEF_TYPE_FLOAT_ID:      T = Context->FloatTy;            break;
+    case PREDEF_TYPE_DOUBLE_ID:     T = Context->DoubleTy;           break;
+    case PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy;       break;
+    case PREDEF_TYPE_OVERLOAD_ID:   T = Context->OverloadTy;         break;
+    case PREDEF_TYPE_DEPENDENT_ID:  T = Context->DependentTy;        break;
+    case PREDEF_TYPE_NULLPTR_ID:    T = Context->NullPtrTy;          break;
+    case PREDEF_TYPE_CHAR16_ID:     T = Context->Char16Ty;           break;
+    case PREDEF_TYPE_CHAR32_ID:     T = Context->Char32Ty;           break;
+    case PREDEF_TYPE_OBJC_ID:       T = Context->ObjCBuiltinIdTy;    break;
+    case PREDEF_TYPE_OBJC_CLASS:    T = Context->ObjCBuiltinClassTy; break;
+    case PREDEF_TYPE_OBJC_SEL:      T = Context->ObjCBuiltinSelTy;   break;
+    }
+
+    assert(!T.isNull() && "Unknown predefined type");
+    return T.withFastQualifiers(FastQuals);
+  }
+
+  Index -= NUM_PREDEF_TYPE_IDS;
+  assert(Index < TypesLoaded.size() && "Type index out-of-range");
+  if (TypesLoaded[Index].isNull()) {
+    TypesLoaded[Index] = ReadTypeRecord(Index);
+    TypesLoaded[Index]->setFromAST();
+    TypeIdxs[TypesLoaded[Index]] = TypeIdx::fromTypeID(ID);
+    if (DeserializationListener)
+      DeserializationListener->TypeRead(TypeIdx::fromTypeID(ID),
+                                        TypesLoaded[Index]);
+  }
+
+  return TypesLoaded[Index].withFastQualifiers(FastQuals);
+}
+
+TypeID ASTReader::GetTypeID(QualType T) const {
+  return MakeTypeID(T,
+              std::bind1st(std::mem_fun(&ASTReader::GetTypeIdx), this));
+}
+
+TypeIdx ASTReader::GetTypeIdx(QualType T) const {
+  if (T.isNull())
+    return TypeIdx();
+  assert(!T.getLocalFastQualifiers());
+
+  TypeIdxMap::const_iterator I = TypeIdxs.find(T);
+  // GetTypeIdx is mostly used for computing the hash of DeclarationNames and
+  // comparing keys of ASTDeclContextNameLookupTable.
+  // If the type didn't come from the AST file use a specially marked index
+  // so that any hash/key comparison fail since no such index is stored
+  // in a AST file.
+  if (I == TypeIdxs.end())
+    return TypeIdx(-1);
+  return I->second;
+}
+
+TemplateArgumentLocInfo
+ASTReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
+                                      llvm::BitstreamCursor &DeclsCursor,
+                                      const RecordData &Record,
+                                      unsigned &Index) {
+  switch (Kind) {
+  case TemplateArgument::Expression:
+    return ReadExpr(DeclsCursor);
+  case TemplateArgument::Type:
+    return GetTypeSourceInfo(DeclsCursor, Record, Index);
+  case TemplateArgument::Template: {
+    SourceRange QualifierRange = ReadSourceRange(Record, Index);
+    SourceLocation TemplateNameLoc = ReadSourceLocation(Record, Index);
+    return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc);
+  }
+  case TemplateArgument::Null:
+  case TemplateArgument::Integral:
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Pack:
+    return TemplateArgumentLocInfo();
+  }
+  llvm_unreachable("unexpected template argument loc");
+  return TemplateArgumentLocInfo();
+}
+
+TemplateArgumentLoc
+ASTReader::ReadTemplateArgumentLoc(llvm::BitstreamCursor &DeclsCursor,
+                                   const RecordData &Record, unsigned &Index) {
+  TemplateArgument Arg = ReadTemplateArgument(DeclsCursor, Record, Index);
+
+  if (Arg.getKind() == TemplateArgument::Expression) {
+    if (Record[Index++]) // bool InfoHasSameExpr.
+      return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo(Arg.getAsExpr()));
+  }
+  return TemplateArgumentLoc(Arg, GetTemplateArgumentLocInfo(Arg.getKind(),
+                                                             DeclsCursor,
+                                                             Record, Index));
+}
+
+Decl *ASTReader::GetExternalDecl(uint32_t ID) {
+  return GetDecl(ID);
+}
+
+TranslationUnitDecl *ASTReader::GetTranslationUnitDecl() {
+  if (!DeclsLoaded[0]) {
+    ReadDeclRecord(0, 1);
+    if (DeserializationListener)
+      DeserializationListener->DeclRead(1, DeclsLoaded[0]);
+  }
+
+  return cast<TranslationUnitDecl>(DeclsLoaded[0]);
+}
+
+Decl *ASTReader::GetDecl(DeclID ID) {
+  if (ID == 0)
+    return 0;
+
+  if (ID > DeclsLoaded.size()) {
+    Error("declaration ID out-of-range for AST file");
+    return 0;
+  }
+
+  unsigned Index = ID - 1;
+  if (!DeclsLoaded[Index]) {
+    ReadDeclRecord(Index, ID);
+    if (DeserializationListener)
+      DeserializationListener->DeclRead(ID, DeclsLoaded[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 *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
+  // Offset here is a global offset across the entire chain.
+  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+    PerFileData &F = *Chain[N - I - 1];
+    if (Offset < F.SizeInBits) {
+      // Since we know that this statement is part of a decl, make sure to use
+      // the decl cursor to read it.
+      F.DeclsCursor.JumpToBit(Offset);
+      return ReadStmtFromStream(F.DeclsCursor);
+    }
+    Offset -= F.SizeInBits;
+  }
+  llvm_unreachable("Broken chain");
+}
+
+bool ASTReader::FindExternalLexicalDecls(const DeclContext *DC,
+                                         llvm::SmallVectorImpl<Decl*> &Decls) {
+  assert(DC->hasExternalLexicalStorage() &&
+         "DeclContext has no lexical decls in storage");
+
+  // There might be lexical decls in multiple parts of the chain, for the TU
+  // at least.
+  DeclContextInfos &Infos = DeclContextOffsets[DC];
+  for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
+       I != E; ++I) {
+    // IDs can be 0 if this context doesn't contain declarations.
+    if (!I->LexicalDecls)
+      continue;
+
+    // Load all of the declaration IDs
+    for (const DeclID *ID = I->LexicalDecls,
+                           *IDE = ID + I->NumLexicalDecls;
+         ID != IDE; ++ID)
+      Decls.push_back(GetDecl(*ID));
+  }
+
+  ++NumLexicalDeclContextsRead;
+  return false;
+}
+
+DeclContext::lookup_result
+ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
+                                          DeclarationName Name) {
+  assert(DC->hasExternalVisibleStorage() &&
+         "DeclContext has no visible decls in storage");
+  if (!Name)
+    return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
+                                      DeclContext::lookup_iterator(0));
+
+  llvm::SmallVector<NamedDecl *, 64> Decls;
+  // There might be visible decls in multiple parts of the chain, for the TU
+  // and namespaces. For any given name, the last available results replace
+  // all earlier ones. For this reason, we walk in reverse.
+  DeclContextInfos &Infos = DeclContextOffsets[DC];
+  for (DeclContextInfos::reverse_iterator I = Infos.rbegin(), E = Infos.rend();
+       I != E; ++I) {
+    if (!I->NameLookupTableData)
+      continue;
+
+    ASTDeclContextNameLookupTable *LookupTable =
+        (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
+    ASTDeclContextNameLookupTable::iterator Pos = LookupTable->find(Name);
+    if (Pos == LookupTable->end())
+      continue;
+
+    ASTDeclContextNameLookupTrait::data_type Data = *Pos;
+    for (; Data.first != Data.second; ++Data.first)
+      Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
+    break;
+  }
+
+  ++NumVisibleDeclContextsRead;
+
+  SetExternalVisibleDeclsForName(DC, Name, Decls);
+  return const_cast<DeclContext*>(DC)->lookup(Name);
+}
+
+void ASTReader::MaterializeVisibleDecls(const DeclContext *DC) {
+  assert(DC->hasExternalVisibleStorage() &&
+         "DeclContext has no visible decls in storage");
+
+  llvm::SmallVector<NamedDecl *, 64> Decls;
+  // There might be visible decls in multiple parts of the chain, for the TU
+  // and namespaces.
+  DeclContextInfos &Infos = DeclContextOffsets[DC];
+  for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
+       I != E; ++I) {
+    if (!I->NameLookupTableData)
+      continue;
+
+    ASTDeclContextNameLookupTable *LookupTable =
+        (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
+    for (ASTDeclContextNameLookupTable::item_iterator
+           ItemI = LookupTable->item_begin(),
+           ItemEnd = LookupTable->item_end() ; ItemI != ItemEnd; ++ItemI) {
+      ASTDeclContextNameLookupTable::item_iterator::value_type Val
+          = *ItemI;
+      ASTDeclContextNameLookupTrait::data_type Data = Val.second;
+      Decls.clear();
+      for (; Data.first != Data.second; ++Data.first)
+        Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
+      MaterializeVisibleDeclsForName(DC, Val.first, Decls);
+    }
+  }
+}
+
+void ASTReader::PassInterestingDeclsToConsumer() {
+  assert(Consumer);
+  while (!InterestingDecls.empty()) {
+    DeclGroupRef DG(InterestingDecls.front());
+    InterestingDecls.pop_front();
+    Consumer->HandleInterestingDecl(DG);
+  }
+}
+
+void ASTReader::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 queued for
+    // passing to the consumer.
+    GetDecl(ExternalDefinitions[I]);
+  }
+
+  PassInterestingDeclsToConsumer();
+}
+
+void ASTReader::PrintStats() {
+  std::fprintf(stderr, "*** AST File 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 (!SelectorsLoaded.empty())
+    std::fprintf(stderr, "  %u/%u selectors read (%f%%)\n",
+                 NumSelectorsLoaded, (unsigned)SelectorsLoaded.size(),
+                 ((float)NumSelectorsLoaded/SelectorsLoaded.size() * 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 (TotalNumMethodPoolEntries) {
+    std::fprintf(stderr, "  %u/%u method pool entries read (%f%%)\n",
+                 NumMethodPoolEntriesRead, TotalNumMethodPoolEntries,
+                 ((float)NumMethodPoolEntriesRead/TotalNumMethodPoolEntries
+                  * 100));
+    std::fprintf(stderr, "  %u method pool misses\n", NumMethodPoolMisses);
+  }
+  std::fprintf(stderr, "\n");
+}
+
+void ASTReader::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.
+  if (SemaObj->TUScope) {
+    for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
+      SemaObj->TUScope->AddDecl(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 file scoped decls, deserialize them and add to
+  // Sema's list of unused file scoped decls.
+  for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) {
+    DeclaratorDecl *D = cast<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I]));
+    SemaObj->UnusedFileScopedDecls.push_back(D);
+  }
+
+  // If there were any weak undeclared identifiers, deserialize them and add to
+  // Sema's list of weak undeclared identifiers.
+  if (!WeakUndeclaredIdentifiers.empty()) {
+    unsigned Idx = 0;
+    for (unsigned I = 0, N = WeakUndeclaredIdentifiers[Idx++]; I != N; ++I) {
+      IdentifierInfo *WeakId = GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx);
+      IdentifierInfo *AliasId=GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx);
+      SourceLocation Loc = ReadSourceLocation(WeakUndeclaredIdentifiers, Idx);
+      bool Used = WeakUndeclaredIdentifiers[Idx++];
+      Sema::WeakInfo WI(AliasId, Loc);
+      WI.setUsed(Used);
+      SemaObj->WeakUndeclaredIdentifiers.insert(std::make_pair(WeakId, WI));
+    }
+  }
+
+  // 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])));
+
+  // FIXME: Do VTable uses and dynamic classes deserialize too much ?
+  // Can we cut them down before writing them ?
+
+  // If there were any VTable uses, deserialize the information and add it
+  // to Sema's vector and map of VTable uses.
+  if (!VTableUses.empty()) {
+    unsigned Idx = 0;
+    for (unsigned I = 0, N = VTableUses[Idx++]; I != N; ++I) {
+      CXXRecordDecl *Class = cast<CXXRecordDecl>(GetDecl(VTableUses[Idx++]));
+      SourceLocation Loc = ReadSourceLocation(VTableUses, Idx);
+      bool DefinitionRequired = VTableUses[Idx++];
+      SemaObj->VTableUses.push_back(std::make_pair(Class, Loc));
+      SemaObj->VTablesUsed[Class] = DefinitionRequired;
+    }
+  }
+
+  // If there were any dynamic classes declarations, deserialize them
+  // and add them to Sema's vector of such declarations.
+  for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I)
+    SemaObj->DynamicClasses.push_back(
+                               cast<CXXRecordDecl>(GetDecl(DynamicClasses[I])));
+
+  // If there were any pending implicit instantiations, deserialize them
+  // and add them to Sema's queue of such instantiations.
+  assert(PendingInstantiations.size() % 2 == 0 && "Expected pairs of entries");
+  for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) {
+    ValueDecl *D=cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++]));
+    SourceLocation Loc = ReadSourceLocation(PendingInstantiations, Idx);
+    SemaObj->PendingInstantiations.push_back(std::make_pair(D, Loc));
+  }
+
+  // Load the offsets of the declarations that Sema references.
+  // They will be lazily deserialized when needed.
+  if (!SemaDeclRefs.empty()) {
+    assert(SemaDeclRefs.size() == 2 && "More decl refs than expected!");
+    SemaObj->StdNamespace = SemaDeclRefs[0];
+    SemaObj->StdBadAlloc = SemaDeclRefs[1];
+  }
+
+  // If there are @selector references added them to its pool. This is for
+  // implementation of -Wselector.
+  if (!ReferencedSelectorsData.empty()) {
+    unsigned int DataSize = ReferencedSelectorsData.size()-1;
+    unsigned I = 0;
+    while (I < DataSize) {
+      Selector Sel = DecodeSelector(ReferencedSelectorsData[I++]);
+      SourceLocation SelLoc = 
+        SourceLocation::getFromRawEncoding(ReferencedSelectorsData[I++]);
+      SemaObj->ReferencedSelectors.insert(std::make_pair(Sel, SelLoc));
+    }
+  }
+}
+
+IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
+  // Try to find this name within our on-disk hash tables. We start with the
+  // most recent one, since that one contains the most up-to-date info.
+  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+    ASTIdentifierLookupTable *IdTable
+        = (ASTIdentifierLookupTable *)Chain[I]->IdentifierLookupTable;
+    if (!IdTable)
+      continue;
+    std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
+    ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key);
+    if (Pos == IdTable->end())
+      continue;
+
+    // Dereferencing the iterator has the effect of building the
+    // IdentifierInfo node and populating it with the various
+    // declarations it needs.
+    return *Pos;
+  }
+  return 0;
+}
+
+std::pair<ObjCMethodList, ObjCMethodList>
+ASTReader::ReadMethodPool(Selector Sel) {
+  // Find this selector in a hash table. We want to find the most recent entry.
+  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+    PerFileData &F = *Chain[I];
+    if (!F.SelectorLookupTable)
+      continue;
+
+    ASTSelectorLookupTable *PoolTable
+      = (ASTSelectorLookupTable*)F.SelectorLookupTable;
+    ASTSelectorLookupTable::iterator Pos = PoolTable->find(Sel);
+    if (Pos != PoolTable->end()) {
+      ++NumSelectorsRead;
+      // FIXME: Not quite happy with the statistics here. We probably should
+      // disable this tracking when called via LoadSelector.
+      // Also, should entries without methods count as misses?
+      ++NumMethodPoolEntriesRead;
+      ASTSelectorLookupTrait::data_type Data = *Pos;
+      if (DeserializationListener)
+        DeserializationListener->SelectorRead(Data.ID, Sel);
+      return std::make_pair(Data.Instance, Data.Factory);
+    }
+  }
+
+  ++NumMethodPoolMisses;
+  return std::pair<ObjCMethodList, ObjCMethodList>();
+}
+
+void ASTReader::LoadSelector(Selector Sel) {
+  // It would be complicated to avoid reading the methods anyway. So don't.
+  ReadMethodPool(Sel);
+}
+
+void ASTReader::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;
+  if (DeserializationListener)
+    DeserializationListener->IdentifierRead(ID, II);
+}
+
+/// \brief Set the globally-visible declarations associated with the given
+/// identifier.
+///
+/// If the AST 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
+ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
+                              const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
+                                   bool Nonrecursive) {
+  if (NumCurrentElementsDeserializing && !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) {
+      if (SemaObj->TUScope) {
+        // 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(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 *ASTReader::DecodeIdentifierInfo(unsigned ID) {
+  if (ID == 0)
+    return 0;
+
+  if (IdentifiersLoaded.empty()) {
+    Error("no identifier table in AST file");
+    return 0;
+  }
+
+  assert(PP && "Forgot to set Preprocessor ?");
+  ID -= 1;
+  if (!IdentifiersLoaded[ID]) {
+    unsigned Index = ID;
+    const char *Str = 0;
+    for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+      PerFileData *F = Chain[N - I - 1];
+      if (Index < F->LocalNumIdentifiers) {
+         uint32_t Offset = F->IdentifierOffsets[Index];
+         Str = F->IdentifierTableData + Offset;
+         break;
+      }
+      Index -= F->LocalNumIdentifiers;
+    }
+    assert(Str && "Broken Chain");
+
+    // All of the strings in the AST 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]
+      = &PP->getIdentifierTable().get(Str, StrLen);
+    if (DeserializationListener)
+      DeserializationListener->IdentifierRead(ID + 1, IdentifiersLoaded[ID]);
+  }
+
+  return IdentifiersLoaded[ID];
+}
+
+void ASTReader::ReadSLocEntry(unsigned ID) {
+  ReadSLocEntryRecord(ID);
+}
+
+Selector ASTReader::DecodeSelector(unsigned ID) {
+  if (ID == 0)
+    return Selector();
+
+  if (ID > SelectorsLoaded.size()) {
+    Error("selector ID out of range in AST file");
+    return Selector();
+  }
+
+  if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == 0) {
+    // Load this selector from the selector table.
+    unsigned Idx = ID - 1;
+    for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+      PerFileData &F = *Chain[N - I - 1];
+      if (Idx < F.LocalNumSelectors) {
+        ASTSelectorLookupTrait Trait(*this);
+        SelectorsLoaded[ID - 1] =
+           Trait.ReadKey(F.SelectorLookupTableData + F.SelectorOffsets[Idx], 0);
+        if (DeserializationListener)
+          DeserializationListener->SelectorRead(ID, SelectorsLoaded[ID - 1]);
+        break;
+      }
+      Idx -= F.LocalNumSelectors;
+    }
+  }
+
+  return SelectorsLoaded[ID - 1];
+}
+
+Selector ASTReader::GetExternalSelector(uint32_t ID) { 
+  return DecodeSelector(ID);
+}
+
+uint32_t ASTReader::GetNumExternalSelectors() {
+  // ID 0 (the null selector) is considered an external selector.
+  return getTotalNumSelectors() + 1;
+}
+
+DeclarationName
+ASTReader::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();
+}
+
+TemplateName
+ASTReader::ReadTemplateName(const RecordData &Record, unsigned &Idx) {
+  TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++]; 
+  switch (Kind) {
+  case TemplateName::Template:
+    return TemplateName(cast_or_null<TemplateDecl>(GetDecl(Record[Idx++])));
+
+  case TemplateName::OverloadedTemplate: {
+    unsigned size = Record[Idx++];
+    UnresolvedSet<8> Decls;
+    while (size--)
+      Decls.addDecl(cast<NamedDecl>(GetDecl(Record[Idx++])));
+
+    return Context->getOverloadedTemplateName(Decls.begin(), Decls.end());
+  }
+    
+  case TemplateName::QualifiedTemplate: {
+    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
+    bool hasTemplKeyword = Record[Idx++];
+    TemplateDecl *Template = cast<TemplateDecl>(GetDecl(Record[Idx++]));
+    return Context->getQualifiedTemplateName(NNS, hasTemplKeyword, Template);
+  }
+    
+  case TemplateName::DependentTemplate: {
+    NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
+    if (Record[Idx++])  // isIdentifier
+      return Context->getDependentTemplateName(NNS,
+                                               GetIdentifierInfo(Record, Idx));
+    return Context->getDependentTemplateName(NNS,
+                                         (OverloadedOperatorKind)Record[Idx++]);
+  }
+  }
+  
+  assert(0 && "Unhandled template name kind!");
+  return TemplateName();
+}
+
+TemplateArgument
+ASTReader::ReadTemplateArgument(llvm::BitstreamCursor &DeclsCursor,
+                                const RecordData &Record, unsigned &Idx) {
+  switch ((TemplateArgument::ArgKind)Record[Idx++]) {
+  case TemplateArgument::Null:
+    return TemplateArgument();
+  case TemplateArgument::Type:
+    return TemplateArgument(GetType(Record[Idx++]));
+  case TemplateArgument::Declaration:
+    return TemplateArgument(GetDecl(Record[Idx++]));
+  case TemplateArgument::Integral: {
+    llvm::APSInt Value = ReadAPSInt(Record, Idx);
+    QualType T = GetType(Record[Idx++]);
+    return TemplateArgument(Value, T);
+  }
+  case TemplateArgument::Template:
+    return TemplateArgument(ReadTemplateName(Record, Idx));
+  case TemplateArgument::Expression:
+    return TemplateArgument(ReadExpr(DeclsCursor));
+  case TemplateArgument::Pack: {
+    unsigned NumArgs = Record[Idx++];
+    llvm::SmallVector<TemplateArgument, 8> Args;
+    Args.reserve(NumArgs);
+    while (NumArgs--)
+      Args.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
+    TemplateArgument TemplArg;
+    TemplArg.setArgumentPack(Args.data(), Args.size(), /*CopyArgs=*/true);
+    return TemplArg;
+  }
+  }
+  
+  assert(0 && "Unhandled template argument kind!");
+  return TemplateArgument();
+}
+
+TemplateParameterList *
+ASTReader::ReadTemplateParameterList(const RecordData &Record, unsigned &Idx) {
+  SourceLocation TemplateLoc = ReadSourceLocation(Record, Idx);
+  SourceLocation LAngleLoc = ReadSourceLocation(Record, Idx);
+  SourceLocation RAngleLoc = ReadSourceLocation(Record, Idx);
+
+  unsigned NumParams = Record[Idx++];
+  llvm::SmallVector<NamedDecl *, 16> Params;
+  Params.reserve(NumParams);
+  while (NumParams--)
+    Params.push_back(cast<NamedDecl>(GetDecl(Record[Idx++])));
+    
+  TemplateParameterList* TemplateParams = 
+    TemplateParameterList::Create(*Context, TemplateLoc, LAngleLoc,
+                                  Params.data(), Params.size(), RAngleLoc);
+  return TemplateParams;
+}
+
+void
+ASTReader::
+ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs,
+                         llvm::BitstreamCursor &DeclsCursor,
+                         const RecordData &Record, unsigned &Idx) {
+  unsigned NumTemplateArgs = Record[Idx++];
+  TemplArgs.reserve(NumTemplateArgs);
+  while (NumTemplateArgs--)
+    TemplArgs.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx));
+}
+
+/// \brief Read a UnresolvedSet structure.
+void ASTReader::ReadUnresolvedSet(UnresolvedSetImpl &Set,
+                                  const RecordData &Record, unsigned &Idx) {
+  unsigned NumDecls = Record[Idx++];
+  while (NumDecls--) {
+    NamedDecl *D = cast<NamedDecl>(GetDecl(Record[Idx++]));
+    AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
+    Set.addDecl(D, AS);
+  }
+}
+
+CXXBaseSpecifier
+ASTReader::ReadCXXBaseSpecifier(llvm::BitstreamCursor &DeclsCursor,
+                                const RecordData &Record, unsigned &Idx) {
+  bool isVirtual = static_cast<bool>(Record[Idx++]);
+  bool isBaseOfClass = static_cast<bool>(Record[Idx++]);
+  AccessSpecifier AS = static_cast<AccessSpecifier>(Record[Idx++]);
+  TypeSourceInfo *TInfo = GetTypeSourceInfo(DeclsCursor, Record, Idx);
+  SourceRange Range = ReadSourceRange(Record, Idx);
+  return CXXBaseSpecifier(Range, isVirtual, isBaseOfClass, AS, TInfo);
+}
+
+std::pair<CXXBaseOrMemberInitializer **, unsigned>
+ASTReader::ReadCXXBaseOrMemberInitializers(llvm::BitstreamCursor &Cursor,
+                                           const RecordData &Record,
+                                           unsigned &Idx) {
+  CXXBaseOrMemberInitializer **BaseOrMemberInitializers = 0;
+  unsigned NumInitializers = Record[Idx++];
+  if (NumInitializers) {
+    ASTContext &C = *getContext();
+
+    BaseOrMemberInitializers
+        = new (C) CXXBaseOrMemberInitializer*[NumInitializers];
+    for (unsigned i=0; i != NumInitializers; ++i) {
+      TypeSourceInfo *BaseClassInfo = 0;
+      bool IsBaseVirtual = false;
+      FieldDecl *Member = 0;
+  
+      bool IsBaseInitializer = Record[Idx++];
+      if (IsBaseInitializer) {
+        BaseClassInfo = GetTypeSourceInfo(Cursor, Record, Idx);
+        IsBaseVirtual = Record[Idx++];
+      } else {
+        Member = cast<FieldDecl>(GetDecl(Record[Idx++]));
+      }
+      SourceLocation MemberLoc = ReadSourceLocation(Record, Idx);
+      Expr *Init = ReadExpr(Cursor);
+      FieldDecl *AnonUnionMember
+          = cast_or_null<FieldDecl>(GetDecl(Record[Idx++]));
+      SourceLocation LParenLoc = ReadSourceLocation(Record, Idx);
+      SourceLocation RParenLoc = ReadSourceLocation(Record, Idx);
+      bool IsWritten = Record[Idx++];
+      unsigned SourceOrderOrNumArrayIndices;
+      llvm::SmallVector<VarDecl *, 8> Indices;
+      if (IsWritten) {
+        SourceOrderOrNumArrayIndices = Record[Idx++];
+      } else {
+        SourceOrderOrNumArrayIndices = Record[Idx++];
+        Indices.reserve(SourceOrderOrNumArrayIndices);
+        for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i)
+          Indices.push_back(cast<VarDecl>(GetDecl(Record[Idx++])));
+      }
+      
+      CXXBaseOrMemberInitializer *BOMInit;
+      if (IsBaseInitializer) {
+        BOMInit = new (C) CXXBaseOrMemberInitializer(C, BaseClassInfo,
+                                                     IsBaseVirtual, LParenLoc,
+                                                     Init, RParenLoc);
+      } else if (IsWritten) {
+        BOMInit = new (C) CXXBaseOrMemberInitializer(C, Member, MemberLoc,
+                                                     LParenLoc, Init, RParenLoc);
+      } else {
+        BOMInit = CXXBaseOrMemberInitializer::Create(C, Member, MemberLoc,
+                                                     LParenLoc, Init, RParenLoc,
+                                                     Indices.data(),
+                                                     Indices.size());
+      }
+
+      BOMInit->setAnonUnionMember(AnonUnionMember);
+      BaseOrMemberInitializers[i] = BOMInit;
+    }
+  }
+
+  return std::make_pair(BaseOrMemberInitializers, NumInitializers);
+}
+
+NestedNameSpecifier *
+ASTReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
+  unsigned N = Record[Idx++];
+  NestedNameSpecifier *NNS = 0, *Prev = 0;
+  for (unsigned I = 0; I != N; ++I) {
+    NestedNameSpecifier::SpecifierKind Kind
+      = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
+    switch (Kind) {
+    case NestedNameSpecifier::Identifier: {
+      IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
+      NNS = NestedNameSpecifier::Create(*Context, Prev, II);
+      break;
+    }
+
+    case NestedNameSpecifier::Namespace: {
+      NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++]));
+      NNS = NestedNameSpecifier::Create(*Context, Prev, NS);
+      break;
+    }
+
+    case NestedNameSpecifier::TypeSpec:
+    case NestedNameSpecifier::TypeSpecWithTemplate: {
+      Type *T = GetType(Record[Idx++]).getTypePtr();
+      bool Template = Record[Idx++];
+      NNS = NestedNameSpecifier::Create(*Context, Prev, Template, T);
+      break;
+    }
+
+    case NestedNameSpecifier::Global: {
+      NNS = NestedNameSpecifier::GlobalSpecifier(*Context);
+      // No associated value, and there can't be a prefix.
+      break;
+    }
+    }
+    Prev = NNS;
+  }
+  return NNS;
+}
+
+SourceRange
+ASTReader::ReadSourceRange(const RecordData &Record, unsigned &Idx) {
+  SourceLocation beg = SourceLocation::getFromRawEncoding(Record[Idx++]);
+  SourceLocation end = SourceLocation::getFromRawEncoding(Record[Idx++]);
+  return SourceRange(beg, end);
+}
+
+/// \brief Read an integral value
+llvm::APInt ASTReader::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 ASTReader::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 ASTReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
+  return llvm::APFloat(ReadAPInt(Record, Idx));
+}
+
+// \brief Read a string
+std::string ASTReader::ReadString(const RecordData &Record, unsigned &Idx) {
+  unsigned Len = Record[Idx++];
+  std::string Result(Record.data() + Idx, Record.data() + Idx + Len);
+  Idx += Len;
+  return Result;
+}
+
+CXXTemporary *ASTReader::ReadCXXTemporary(const RecordData &Record,
+                                          unsigned &Idx) {
+  CXXDestructorDecl *Decl = cast<CXXDestructorDecl>(GetDecl(Record[Idx++]));
+  return CXXTemporary::Create(*Context, Decl);
+}
+
+DiagnosticBuilder ASTReader::Diag(unsigned DiagID) {
+  return Diag(SourceLocation(), DiagID);
+}
+
+DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) {
+  return Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
+}
+
+/// \brief Retrieve the identifier table associated with the
+/// preprocessor.
+IdentifierTable &ASTReader::getIdentifierTable() {
+  assert(PP && "Forgot to set Preprocessor ?");
+  return PP->getIdentifierTable();
+}
+
+/// \brief Record that the given ID maps to the given switch-case
+/// statement.
+void ASTReader::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 *ASTReader::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 ASTReader::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 ASTReader::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 ASTReader::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));
+  }
+}
+
+void ASTReader::FinishedDeserializing() {
+  assert(NumCurrentElementsDeserializing &&
+         "FinishedDeserializing not paired with StartedDeserializing");
+  if (NumCurrentElementsDeserializing == 1) {
+    // If any identifiers with corresponding top-level declarations have
+    // been loaded, load those declarations now.
+    while (!PendingIdentifierInfos.empty()) {
+      SetGloballyVisibleDecls(PendingIdentifierInfos.front().II,
+                              PendingIdentifierInfos.front().DeclIDs, true);
+      PendingIdentifierInfos.pop_front();
+    }
+
+    // We are not in recursive loading, so it's safe to pass the "interesting"
+    // decls to the consumer.
+    if (Consumer)
+      PassInterestingDeclsToConsumer();
+  }
+  --NumCurrentElementsDeserializing;
+}
+
+ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
+                     const char *isysroot, bool DisableValidation)
+  : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
+    SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
+    Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context),
+    Consumer(0), isysroot(isysroot), DisableValidation(DisableValidation),
+    NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0),
+    TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0),
+    NumMacrosRead(0), TotalNumMacros(0), NumSelectorsRead(0),
+    NumMethodPoolEntriesRead(0), NumMethodPoolMisses(0),
+    TotalNumMethodPoolEntries(0), NumLexicalDeclContextsRead(0),
+    TotalLexicalDeclContexts(0), NumVisibleDeclContextsRead(0),
+    TotalVisibleDeclContexts(0), NumCurrentElementsDeserializing(0) {
+  RelocatablePCH = false;
+}
+
+ASTReader::ASTReader(SourceManager &SourceMgr, FileManager &FileMgr,
+                     Diagnostic &Diags, const char *isysroot,
+                     bool DisableValidation)
+  : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr),
+    Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0),
+    isysroot(isysroot), DisableValidation(DisableValidation), NumStatHits(0),
+    NumStatMisses(0), NumSLocEntriesRead(0), TotalNumSLocEntries(0),
+    NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0),
+    TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0),
+    NumMethodPoolMisses(0), TotalNumMethodPoolEntries(0),
+    NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0),
+    NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
+    NumCurrentElementsDeserializing(0) {
+  RelocatablePCH = false;
+}
+
+ASTReader::~ASTReader() {
+  for (unsigned i = 0, e = Chain.size(); i != e; ++i)
+    delete Chain[e - i - 1];
+  // Delete all visible decl lookup tables
+  for (DeclContextOffsetsMap::iterator I = DeclContextOffsets.begin(),
+                                       E = DeclContextOffsets.end();
+       I != E; ++I) {
+    for (DeclContextInfos::iterator J = I->second.begin(), F = I->second.end();
+         J != F; ++J) {
+      if (J->NameLookupTableData)
+        delete static_cast<ASTDeclContextNameLookupTable*>(
+            J->NameLookupTableData);
+    }
+  }
+  for (DeclContextVisibleUpdatesPending::iterator
+           I = PendingVisibleUpdates.begin(),
+           E = PendingVisibleUpdates.end();
+       I != E; ++I) {
+    for (DeclContextVisibleUpdates::iterator J = I->second.begin(),
+                                             F = I->second.end();
+         J != F; ++J)
+      delete static_cast<ASTDeclContextNameLookupTable*>(*J);
+  }
+}
+
+ASTReader::PerFileData::PerFileData()
+  : StatCache(0), LocalNumSLocEntries(0), LocalNumTypes(0), TypeOffsets(0),
+    LocalNumDecls(0), DeclOffsets(0), LocalNumIdentifiers(0),
+    IdentifierOffsets(0), IdentifierTableData(0), IdentifierLookupTable(0),
+    LocalNumMacroDefinitions(0), MacroDefinitionOffsets(0),
+    NumPreallocatedPreprocessingEntities(0), SelectorLookupTable(0),
+    SelectorLookupTableData(0), SelectorOffsets(0), LocalNumSelectors(0)
+{}
+
+ASTReader::PerFileData::~PerFileData() {
+  delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
+  delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
+}
+
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
new file mode 100644
index 0000000..053b91a
--- /dev/null
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -0,0 +1,1451 @@
+//===--- ASTReaderDecl.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 ASTReader::ReadDeclRecord method, which is the
+// entrypoint for loading a decl.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Serialization/ASTReader.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+using namespace clang;
+using namespace clang::serialization;
+
+//===----------------------------------------------------------------------===//
+// Declaration deserialization
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+  class ASTDeclReader : public DeclVisitor<ASTDeclReader, void> {
+    ASTReader &Reader;
+    llvm::BitstreamCursor &Cursor;
+    const DeclID ThisDeclID;
+    const ASTReader::RecordData &Record;
+    unsigned &Idx;
+    TypeID TypeIDForTypeDecl;
+
+    uint64_t GetCurrentCursorOffset();
+
+  public:
+    ASTDeclReader(ASTReader &Reader, llvm::BitstreamCursor &Cursor,
+                  DeclID thisDeclID, const ASTReader::RecordData &Record,
+                  unsigned &Idx)
+      : Reader(Reader), Cursor(Cursor), ThisDeclID(thisDeclID), Record(Record),
+        Idx(Idx), TypeIDForTypeDecl(0) { }
+
+    void Visit(Decl *D);
+
+    void VisitDecl(Decl *D);
+    void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
+    void VisitNamedDecl(NamedDecl *ND);
+    void VisitNamespaceDecl(NamespaceDecl *D);
+    void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
+    void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
+    void VisitTypeDecl(TypeDecl *TD);
+    void VisitTypedefDecl(TypedefDecl *TD);
+    void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
+    void VisitTagDecl(TagDecl *TD);
+    void VisitEnumDecl(EnumDecl *ED);
+    void VisitRecordDecl(RecordDecl *RD);
+    void VisitCXXRecordDecl(CXXRecordDecl *D);
+    void VisitClassTemplateSpecializationDecl(
+                                            ClassTemplateSpecializationDecl *D);
+    void VisitClassTemplatePartialSpecializationDecl(
+                                     ClassTemplatePartialSpecializationDecl *D);
+    void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
+    void VisitValueDecl(ValueDecl *VD);
+    void VisitEnumConstantDecl(EnumConstantDecl *ECD);
+    void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
+    void VisitDeclaratorDecl(DeclaratorDecl *DD);
+    void VisitFunctionDecl(FunctionDecl *FD);
+    void VisitCXXMethodDecl(CXXMethodDecl *D);
+    void VisitCXXConstructorDecl(CXXConstructorDecl *D);
+    void VisitCXXDestructorDecl(CXXDestructorDecl *D);
+    void VisitCXXConversionDecl(CXXConversionDecl *D);
+    void VisitFieldDecl(FieldDecl *FD);
+    void VisitVarDecl(VarDecl *VD);
+    void VisitImplicitParamDecl(ImplicitParamDecl *PD);
+    void VisitParmVarDecl(ParmVarDecl *PD);
+    void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
+    void VisitTemplateDecl(TemplateDecl *D);
+    void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
+    void VisitClassTemplateDecl(ClassTemplateDecl *D);
+    void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
+    void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
+    void VisitUsingDecl(UsingDecl *D);
+    void VisitUsingShadowDecl(UsingShadowDecl *D);
+    void VisitLinkageSpecDecl(LinkageSpecDecl *D);
+    void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
+    void VisitAccessSpecDecl(AccessSpecDecl *D);
+    void VisitFriendDecl(FriendDecl *D);
+    void VisitFriendTemplateDecl(FriendTemplateDecl *D);
+    void VisitStaticAssertDecl(StaticAssertDecl *D);
+    void VisitBlockDecl(BlockDecl *BD);
+
+    std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
+    template <typename T> void VisitRedeclarable(Redeclarable<T> *D);
+
+    // FIXME: Reorder according to DeclNodes.td?
+    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);
+  };
+}
+
+uint64_t ASTDeclReader::GetCurrentCursorOffset() {
+  uint64_t Off = 0;
+  for (unsigned I = 0, N = Reader.Chain.size(); I != N; ++I) {
+    ASTReader::PerFileData &F = *Reader.Chain[N - I - 1];
+    if (&Cursor == &F.DeclsCursor) {
+      Off += F.DeclsCursor.GetCurrentBitNo();
+      break;
+    }
+    Off += F.SizeInBits;
+  }
+  return Off;
+}
+
+void ASTDeclReader::Visit(Decl *D) {
+  DeclVisitor<ASTDeclReader, void>::Visit(D);
+
+  if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
+    // if we have a fully initialized TypeDecl, we can safely read its type now.
+    TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtr());
+  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    // FunctionDecl's body was written last after all other Stmts/Exprs.
+    if (Record[Idx++])
+      FD->setLazyBody(GetCurrentCursorOffset());
+  }
+}
+
+void ASTDeclReader::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++]) {
+    AttrVec Attrs;
+    Reader.ReadAttributes(Cursor, Attrs);
+    D->setAttrs(Attrs);
+  }
+  D->setImplicit(Record[Idx++]);
+  D->setUsed(Record[Idx++]);
+  D->setAccess((AccessSpecifier)Record[Idx++]);
+  D->setPCHLevel(Record[Idx++] + 1);
+}
+
+void ASTDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
+  VisitDecl(TU);
+  TU->setAnonymousNamespace(
+                    cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void ASTDeclReader::VisitNamedDecl(NamedDecl *ND) {
+  VisitDecl(ND);
+  ND->setDeclName(Reader.ReadDeclarationName(Record, Idx));
+}
+
+void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) {
+  VisitNamedDecl(TD);
+  // Delay type reading until after we have fully initialized the decl.
+  TypeIDForTypeDecl = Record[Idx++];
+}
+
+void ASTDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
+  VisitTypeDecl(TD);
+  TD->setTypeSourceInfo(Reader.GetTypeSourceInfo(Cursor, Record, Idx));
+}
+
+void ASTDeclReader::VisitTagDecl(TagDecl *TD) {
+  VisitTypeDecl(TD);
+  TD->IdentifierNamespace = Record[Idx++];
+  VisitRedeclarable(TD);
+  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 ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
+  VisitTagDecl(ED);
+  ED->setIntegerType(Reader.GetType(Record[Idx++]));
+  ED->setPromotionType(Reader.GetType(Record[Idx++]));
+  ED->setNumPositiveBits(Record[Idx++]);
+  ED->setNumNegativeBits(Record[Idx++]);
+  ED->setInstantiationOfMemberEnum(
+                         cast_or_null<EnumDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) {
+  VisitTagDecl(RD);
+  RD->setHasFlexibleArrayMember(Record[Idx++]);
+  RD->setAnonymousStructOrUnion(Record[Idx++]);
+  RD->setHasObjectMember(Record[Idx++]);
+}
+
+void ASTDeclReader::VisitValueDecl(ValueDecl *VD) {
+  VisitNamedDecl(VD);
+  VD->setType(Reader.GetType(Record[Idx++]));
+}
+
+void ASTDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
+  VisitValueDecl(ECD);
+  if (Record[Idx++])
+    ECD->setInitExpr(Reader.ReadExpr(Cursor));
+  ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));
+}
+
+void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {
+  VisitValueDecl(DD);
+  TypeSourceInfo *TInfo = Reader.GetTypeSourceInfo(Cursor, Record, Idx);
+  if (TInfo)
+    DD->setTypeSourceInfo(TInfo);
+  // FIXME: read optional qualifier and its range.
+}
+
+void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
+  VisitDeclaratorDecl(FD);
+  // FIXME: read DeclarationNameLoc.
+
+  FD->IdentifierNamespace = Record[Idx++];
+  switch ((FunctionDecl::TemplatedKind)Record[Idx++]) {
+  default: assert(false && "Unhandled TemplatedKind!");
+    break;
+  case FunctionDecl::TK_NonTemplate:
+    break;
+  case FunctionDecl::TK_FunctionTemplate:
+    FD->setDescribedFunctionTemplate(
+                     cast<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++])));
+    break;
+  case FunctionDecl::TK_MemberSpecialization: {
+    FunctionDecl *InstFD = cast<FunctionDecl>(Reader.GetDecl(Record[Idx++]));
+    TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
+    SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
+    FD->setInstantiationOfMemberFunction(InstFD, TSK);
+    FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
+    break;
+  }
+  case FunctionDecl::TK_FunctionTemplateSpecialization: {
+    FunctionTemplateDecl *Template
+      = cast<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++]));
+    TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
+    
+    // Template arguments.
+    llvm::SmallVector<TemplateArgument, 8> TemplArgs;
+    Reader.ReadTemplateArgumentList(TemplArgs, Cursor, Record, Idx);
+    
+    // Template args as written.
+    llvm::SmallVector<TemplateArgumentLoc, 8> TemplArgLocs;
+    SourceLocation LAngleLoc, RAngleLoc;
+    if (Record[Idx++]) {  // TemplateArgumentsAsWritten != 0
+      unsigned NumTemplateArgLocs = Record[Idx++];
+      TemplArgLocs.reserve(NumTemplateArgLocs);
+      for (unsigned i=0; i != NumTemplateArgLocs; ++i)
+        TemplArgLocs.push_back(
+            Reader.ReadTemplateArgumentLoc(Cursor, Record, Idx));
+  
+      LAngleLoc = Reader.ReadSourceLocation(Record, Idx);
+      RAngleLoc = Reader.ReadSourceLocation(Record, Idx);
+    }
+    
+    SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
+
+    if (FD->isCanonicalDecl()) // if canonical add to template's set.
+      FD->setFunctionTemplateSpecialization(Template, TemplArgs.size(),
+                                            TemplArgs.data(), TSK,
+                                            TemplArgLocs.size(),
+                                            TemplArgLocs.data(),
+                                            LAngleLoc, RAngleLoc, POI);
+    break;
+  }
+  case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
+    // Templates.
+    UnresolvedSet<8> TemplDecls;
+    unsigned NumTemplates = Record[Idx++];
+    while (NumTemplates--)
+      TemplDecls.addDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
+    
+    // Templates args.
+    TemplateArgumentListInfo TemplArgs;
+    unsigned NumArgs = Record[Idx++];
+    while (NumArgs--)
+      TemplArgs.addArgument(Reader.ReadTemplateArgumentLoc(Cursor,Record, Idx));
+    TemplArgs.setLAngleLoc(Reader.ReadSourceLocation(Record, Idx));
+    TemplArgs.setRAngleLoc(Reader.ReadSourceLocation(Record, Idx));
+    
+    FD->setDependentTemplateSpecialization(*Reader.getContext(),
+                                           TemplDecls, TemplArgs);
+    break;
+  }
+  }
+
+  // FunctionDecl's body is handled last at ASTDeclReader::Visit,
+  // after everything else is read.
+
+  VisitRedeclarable(FD);
+  FD->setStorageClass((StorageClass)Record[Idx++]);
+  FD->setStorageClassAsWritten((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++]));
+
+  // Read in the parameters.
+  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);
+}
+
+void ASTDeclReader::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.ReadStmt(Cursor));
+    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->setDefined(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(Cursor, 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 ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
+  VisitNamedDecl(CD);
+  SourceLocation A = SourceLocation::getFromRawEncoding(Record[Idx++]);
+  SourceLocation B = SourceLocation::getFromRawEncoding(Record[Idx++]);
+  CD->setAtEndRange(SourceRange(A, B));
+}
+
+void ASTDeclReader::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++])));
+  // We will rebuild this list lazily.
+  ID->setIvarList(0);
+  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 ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
+  VisitFieldDecl(IVD);
+  IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record[Idx++]);
+  // This field will be built lazily.
+  IVD->setNextIvar(0);
+  bool synth = Record[Idx++];
+  IVD->setSynthesize(synth);
+}
+
+void ASTDeclReader::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 ASTDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) {
+  VisitFieldDecl(FD);
+}
+
+void ASTDeclReader::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 ASTDeclReader::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 ASTDeclReader::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->setHasSynthBitfield(Record[Idx++]);
+  CD->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  CD->setCategoryNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
+  VisitNamedDecl(CAD);
+  CAD->setClassInterface(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+  VisitNamedDecl(D);
+  D->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  D->setType(Reader.GetTypeSourceInfo(Cursor, Record, Idx));
+  // FIXME: stable encoding
+  D->setPropertyAttributes(
+                      (ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
+  D->setPropertyAttributesAsWritten(
+                      (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 ASTDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
+  VisitObjCContainerDecl(D);
+  D->setClassInterface(
+              cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void ASTDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+  VisitObjCImplDecl(D);
+  D->setIdentifier(Reader.GetIdentifierInfo(Record, Idx));
+}
+
+void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+  VisitObjCImplDecl(D);
+  D->setSuperClass(
+              cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+  llvm::tie(D->IvarInitializers, D->NumIvarInitializers)
+      = Reader.ReadCXXBaseOrMemberInitializers(Cursor, Record, Idx);
+  D->setHasSynthBitfield(Record[Idx++]);
+}
+
+
+void ASTDeclReader::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++])));
+  D->setGetterCXXConstructor(Reader.ReadExpr(Cursor));
+  D->setSetterCXXAssignment(Reader.ReadExpr(Cursor));
+}
+
+void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) {
+  VisitDeclaratorDecl(FD);
+  FD->setMutable(Record[Idx++]);
+  if (Record[Idx++])
+    FD->setBitWidth(Reader.ReadExpr(Cursor));
+  if (!FD->getDeclName()) {
+    FieldDecl *Tmpl = cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++]));
+    if (Tmpl)
+      Reader.getContext()->setInstantiatedFromUnnamedFieldDecl(FD, Tmpl);
+  }
+}
+
+void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
+  VisitDeclaratorDecl(VD);
+  VD->setStorageClass((StorageClass)Record[Idx++]);
+  VD->setStorageClassAsWritten((StorageClass)Record[Idx++]);
+  VD->setThreadSpecified(Record[Idx++]);
+  VD->setCXXDirectInitializer(Record[Idx++]);
+  VD->setExceptionVariable(Record[Idx++]);
+  VD->setNRVOVariable(Record[Idx++]);
+  VisitRedeclarable(VD);
+  if (Record[Idx++])
+    VD->setInit(Reader.ReadExpr(Cursor));
+
+  if (Record[Idx++]) { // HasMemberSpecializationInfo.
+    VarDecl *Tmpl = cast<VarDecl>(Reader.GetDecl(Record[Idx++]));
+    TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
+    SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
+    Reader.getContext()->setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI);
+  }
+}
+
+void ASTDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {
+  VisitVarDecl(PD);
+}
+
+void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
+  VisitVarDecl(PD);
+  PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
+  PD->setHasInheritedDefaultArg(Record[Idx++]);
+  if (Record[Idx++]) // hasUninstantiatedDefaultArg.
+    PD->setUninstantiatedDefaultArg(Reader.ReadExpr(Cursor));
+}
+
+void ASTDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {
+  VisitDecl(AD);
+  AD->setAsmString(cast<StringLiteral>(Reader.ReadExpr(Cursor)));
+}
+
+void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) {
+  VisitDecl(BD);
+  BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadStmt(Cursor)));
+  BD->setSignatureAsWritten(Reader.GetTypeSourceInfo(Cursor, 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++])));
+  BD->setParams(Params.data(), NumParams);
+}
+
+void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
+  VisitDecl(D);
+  D->setLanguage((LinkageSpecDecl::LanguageIDs)Record[Idx++]);
+  D->setHasBraces(Record[Idx++]);
+}
+
+void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
+  VisitNamedDecl(D);
+  D->setLBracLoc(Reader.ReadSourceLocation(Record, Idx));
+  D->setRBracLoc(Reader.ReadSourceLocation(Record, Idx));
+  D->setNextNamespace(
+                    cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
+
+  bool IsOriginal = Record[Idx++];
+  D->OrigOrAnonNamespace.setInt(IsOriginal);
+  D->OrigOrAnonNamespace.setPointer(
+                    cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
+  VisitNamedDecl(D);
+
+  D->setAliasLoc(Reader.ReadSourceLocation(Record, Idx));
+  D->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
+  D->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+  D->setTargetNameLoc(Reader.ReadSourceLocation(Record, Idx));
+  D->setAliasedNamespace(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void ASTDeclReader::VisitUsingDecl(UsingDecl *D) {
+  VisitNamedDecl(D);
+  D->setUsingLocation(Reader.ReadSourceLocation(Record, Idx));
+  D->setNestedNameRange(Reader.ReadSourceRange(Record, Idx));
+  D->setTargetNestedNameDecl(Reader.ReadNestedNameSpecifier(Record, Idx));
+  // FIXME: read the DNLoc component.
+
+  // FIXME: It would probably be more efficient to read these into a vector
+  // and then re-cosntruct the shadow decl set over that vector since it
+  // would avoid existence checks.
+  unsigned NumShadows = Record[Idx++];
+  for(unsigned I = 0; I != NumShadows; ++I) {
+    // Avoid invariant checking of UsingDecl::addShadowDecl, the decl may still
+    // be initializing.
+    D->Shadows.insert(cast<UsingShadowDecl>(Reader.GetDecl(Record[Idx++])));
+  }
+  D->setTypeName(Record[Idx++]);
+  NamedDecl *Pattern = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+  if (Pattern)
+    Reader.getContext()->setInstantiatedFromUsingDecl(D, Pattern);
+}
+
+void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) {
+  VisitNamedDecl(D);
+  D->setTargetDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
+  D->setUsingDecl(cast<UsingDecl>(Reader.GetDecl(Record[Idx++])));
+  UsingShadowDecl *Pattern
+      = cast_or_null<UsingShadowDecl>(Reader.GetDecl(Record[Idx++]));
+  if (Pattern)
+    Reader.getContext()->setInstantiatedFromUsingShadowDecl(D, Pattern);
+}
+
+void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+  VisitNamedDecl(D);
+  D->setNamespaceKeyLocation(Reader.ReadSourceLocation(Record, Idx));
+  D->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
+  D->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+  D->setIdentLocation(Reader.ReadSourceLocation(Record, Idx));
+  D->setNominatedNamespace(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
+  D->setCommonAncestor(cast_or_null<DeclContext>(
+                                                Reader.GetDecl(Record[Idx++])));
+}
+
+void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
+  VisitValueDecl(D);
+  D->setTargetNestedNameRange(Reader.ReadSourceRange(Record, Idx));
+  D->setUsingLoc(Reader.ReadSourceLocation(Record, Idx));
+  D->setTargetNestedNameSpecifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+  // FIXME: read the DNLoc component.
+}
+
+void ASTDeclReader::VisitUnresolvedUsingTypenameDecl(
+                                               UnresolvedUsingTypenameDecl *D) {
+  VisitTypeDecl(D);
+  D->setTargetNestedNameRange(Reader.ReadSourceRange(Record, Idx));
+  D->setUsingLoc(Reader.ReadSourceLocation(Record, Idx));
+  D->setTypenameLoc(Reader.ReadSourceLocation(Record, Idx));
+  D->setTargetNestedNameSpecifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+}
+
+void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) {
+  ASTContext &C = *Reader.getContext();
+
+  // We need to allocate the DefinitionData struct ahead of VisitRecordDecl
+  // so that the other CXXRecordDecls can get a pointer even when the owner
+  // is still initializing.
+  bool OwnsDefinitionData = false;
+  enum DataOwnership { Data_NoDefData, Data_Owner, Data_NotOwner };
+  switch ((DataOwnership)Record[Idx++]) {
+  default:
+    assert(0 && "Out of sync with ASTDeclWriter or messed up reading");
+  case Data_NoDefData:
+    break;
+  case Data_Owner:
+    OwnsDefinitionData = true;
+    D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D);
+    break;
+  case Data_NotOwner:
+    D->DefinitionData
+        = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]))->DefinitionData;
+    break;
+  }
+
+  VisitRecordDecl(D);
+
+  if (OwnsDefinitionData) {
+    assert(D->DefinitionData);
+    struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData;
+
+    Data.UserDeclaredConstructor = Record[Idx++];
+    Data.UserDeclaredCopyConstructor = Record[Idx++];
+    Data.UserDeclaredCopyAssignment = Record[Idx++];
+    Data.UserDeclaredDestructor = Record[Idx++];
+    Data.Aggregate = Record[Idx++];
+    Data.PlainOldData = Record[Idx++];
+    Data.Empty = Record[Idx++];
+    Data.Polymorphic = Record[Idx++];
+    Data.Abstract = Record[Idx++];
+    Data.HasTrivialConstructor = Record[Idx++];
+    Data.HasTrivialCopyConstructor = Record[Idx++];
+    Data.HasTrivialCopyAssignment = Record[Idx++];
+    Data.HasTrivialDestructor = Record[Idx++];
+    Data.ComputedVisibleConversions = Record[Idx++];
+    Data.DeclaredDefaultConstructor = Record[Idx++];
+    Data.DeclaredCopyConstructor = Record[Idx++];
+    Data.DeclaredCopyAssignment = Record[Idx++];
+    Data.DeclaredDestructor = Record[Idx++];
+
+    // setBases() is unsuitable since it may try to iterate the bases of an
+    // uninitialized base.
+    Data.NumBases = Record[Idx++];
+    Data.Bases = new(C) CXXBaseSpecifier [Data.NumBases];
+    for (unsigned i = 0; i != Data.NumBases; ++i)
+      Data.Bases[i] = Reader.ReadCXXBaseSpecifier(Cursor, Record, Idx);
+
+    // FIXME: Make VBases lazily computed when needed to avoid storing them.
+    Data.NumVBases = Record[Idx++];
+    Data.VBases = new(C) CXXBaseSpecifier [Data.NumVBases];
+    for (unsigned i = 0; i != Data.NumVBases; ++i)
+      Data.VBases[i] = Reader.ReadCXXBaseSpecifier(Cursor, Record, Idx);
+
+    Reader.ReadUnresolvedSet(Data.Conversions, Record, Idx);
+    Reader.ReadUnresolvedSet(Data.VisibleConversions, Record, Idx);
+    assert(Data.Definition && "Data.Definition should be already set!");
+    Data.FirstFriend
+        = cast_or_null<FriendDecl>(Reader.GetDecl(Record[Idx++]));
+  }
+
+  enum CXXRecKind {
+    CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
+  };
+  switch ((CXXRecKind)Record[Idx++]) {
+  default:
+    assert(false && "Out of sync with ASTDeclWriter::VisitCXXRecordDecl?");
+  case CXXRecNotTemplate:
+    break;
+  case CXXRecTemplate:
+    D->setDescribedClassTemplate(
+                        cast<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++])));
+    break;
+  case CXXRecMemberSpecialization: {
+    CXXRecordDecl *RD = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]));
+    TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
+    SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
+    D->setInstantiationOfMemberClass(RD, TSK);
+    D->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
+    break;
+  }
+  }
+}
+
+void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
+  VisitFunctionDecl(D);
+  unsigned NumOverridenMethods = Record[Idx++];
+  while (NumOverridenMethods--) {
+    CXXMethodDecl *MD = cast<CXXMethodDecl>(Reader.GetDecl(Record[Idx++]));
+    // Avoid invariant checking of CXXMethodDecl::addOverriddenMethod,
+    // MD may be initializing.
+    Reader.getContext()->addOverriddenMethod(D, MD);
+  }
+}
+
+void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
+  VisitCXXMethodDecl(D);
+  
+  D->IsExplicitSpecified = Record[Idx++];
+  D->ImplicitlyDefined = Record[Idx++];
+  llvm::tie(D->BaseOrMemberInitializers, D->NumBaseOrMemberInitializers)
+      = Reader.ReadCXXBaseOrMemberInitializers(Cursor, Record, Idx);
+}
+
+void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
+  VisitCXXMethodDecl(D);
+
+  D->ImplicitlyDefined = Record[Idx++];
+  D->OperatorDelete = cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++]));
+}
+
+void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
+  VisitCXXMethodDecl(D);
+  D->IsExplicitSpecified = Record[Idx++];
+}
+
+void ASTDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) {
+  VisitDecl(D);
+  D->setColonLoc(Reader.ReadSourceLocation(Record, Idx));
+}
+
+void ASTDeclReader::VisitFriendDecl(FriendDecl *D) {
+  VisitDecl(D);
+  if (Record[Idx++])
+    D->Friend = Reader.GetTypeSourceInfo(Cursor, Record, Idx);
+  else
+    D->Friend = cast<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+  D->NextFriend = cast_or_null<FriendDecl>(Reader.GetDecl(Record[Idx++]));
+  D->FriendLoc = Reader.ReadSourceLocation(Record, Idx);
+}
+
+void ASTDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
+  VisitDecl(D);
+  unsigned NumParams = Record[Idx++];
+  D->NumParams = NumParams;
+  D->Params = new TemplateParameterList*[NumParams];
+  for (unsigned i = 0; i != NumParams; ++i)
+    D->Params[i] = Reader.ReadTemplateParameterList(Record, Idx);
+  if (Record[Idx++]) // HasFriendDecl
+    D->Friend = cast<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+  else
+    D->Friend = Reader.GetTypeSourceInfo(Cursor, Record, Idx);
+  D->FriendLoc = Reader.ReadSourceLocation(Record, Idx);
+}
+
+void ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {
+  VisitNamedDecl(D);
+
+  NamedDecl *TemplatedDecl
+    = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+  TemplateParameterList* TemplateParams
+      = Reader.ReadTemplateParameterList(Record, Idx); 
+  D->init(TemplatedDecl, TemplateParams);
+}
+
+void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
+  VisitTemplateDecl(D);
+
+  D->IdentifierNamespace = Record[Idx++];
+  RedeclarableTemplateDecl *PrevDecl =
+      cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]));
+  assert((PrevDecl == 0 || PrevDecl->getKind() == D->getKind()) &&
+         "PrevDecl kind mismatch");
+  if (PrevDecl)
+    D->CommonOrPrev = PrevDecl;
+  if (PrevDecl == 0) {
+    if (RedeclarableTemplateDecl *RTD
+          = cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]))) {
+      assert(RTD->getKind() == D->getKind() &&
+             "InstantiatedFromMemberTemplate kind mismatch");
+      D->setInstantiatedFromMemberTemplateImpl(RTD);
+      if (Record[Idx++])
+        D->setMemberSpecialization();
+    }
+
+    RedeclarableTemplateDecl *LatestDecl = 
+        cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]));
+  
+    // This decl is a first one and the latest declaration that it points to is
+    // in the same AST file. However, if this actually needs to point to a
+    // redeclaration in another AST file, we need to update it by checking
+    // the FirstLatestDeclIDs map which tracks this kind of decls.
+    assert(Reader.GetDecl(ThisDeclID) == D && "Invalid ThisDeclID ?");
+    ASTReader::FirstLatestDeclIDMap::iterator I
+        = Reader.FirstLatestDeclIDs.find(ThisDeclID);
+    if (I != Reader.FirstLatestDeclIDs.end()) {
+      Decl *NewLatest = Reader.GetDecl(I->second);
+      assert((LatestDecl->getLocation().isInvalid() ||
+              NewLatest->getLocation().isInvalid()  ||
+              Reader.SourceMgr.isBeforeInTranslationUnit(
+                                                   LatestDecl->getLocation(),
+                                                   NewLatest->getLocation())) &&
+             "The new latest is supposed to come after the previous latest");
+      LatestDecl = cast<RedeclarableTemplateDecl>(NewLatest);
+    }
+
+    assert(LatestDecl->getKind() == D->getKind() && "Latest kind mismatch");
+    D->getCommonPtr()->Latest = LatestDecl;
+  }
+}
+
+void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+  VisitRedeclarableTemplateDecl(D);
+
+  if (D->getPreviousDeclaration() == 0) {
+    // This ClassTemplateDecl owns a CommonPtr; read it.
+
+    // FoldingSets are filled in VisitClassTemplateSpecializationDecl.
+    unsigned size = Record[Idx++];
+    while (size--)
+      cast<ClassTemplateSpecializationDecl>(Reader.GetDecl(Record[Idx++]));
+
+    size = Record[Idx++];
+    while (size--)
+      cast<ClassTemplatePartialSpecializationDecl>(
+                                                 Reader.GetDecl(Record[Idx++]));
+
+    // InjectedClassNameType is computed.
+  }
+}
+
+void ASTDeclReader::VisitClassTemplateSpecializationDecl(
+                                           ClassTemplateSpecializationDecl *D) {
+  VisitCXXRecordDecl(D);
+
+  if (Decl *InstD = Reader.GetDecl(Record[Idx++])) {
+    if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(InstD)) {
+      D->setInstantiationOf(CTD);
+    } else {
+      llvm::SmallVector<TemplateArgument, 8> TemplArgs;
+      Reader.ReadTemplateArgumentList(TemplArgs, Cursor, Record, Idx);
+      D->setInstantiationOf(cast<ClassTemplatePartialSpecializationDecl>(InstD),
+                            TemplArgs.data(), TemplArgs.size());
+    }
+  }
+
+  // Explicit info.
+  if (TypeSourceInfo *TyInfo = Reader.GetTypeSourceInfo(Cursor, Record, Idx)) {
+    D->setTypeAsWritten(TyInfo);
+    D->setExternLoc(Reader.ReadSourceLocation(Record, Idx));
+    D->setTemplateKeywordLoc(Reader.ReadSourceLocation(Record, Idx));
+  }
+
+  llvm::SmallVector<TemplateArgument, 8> TemplArgs;
+  Reader.ReadTemplateArgumentList(TemplArgs, Cursor, Record, Idx);
+  D->initTemplateArgs(TemplArgs.data(), TemplArgs.size());
+  SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
+  if (POI.isValid())
+    D->setPointOfInstantiation(POI);
+  D->setSpecializationKind((TemplateSpecializationKind)Record[Idx++]);
+
+  if (D->isCanonicalDecl()) { // It's kept in the folding set.
+    ClassTemplateDecl *CanonPattern
+                       = cast<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]));
+    if (ClassTemplatePartialSpecializationDecl *Partial
+            = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
+      CanonPattern->getPartialSpecializations().InsertNode(Partial);
+    } else {
+      CanonPattern->getSpecializations().InsertNode(D);
+    }
+  }
+}
+
+void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl(
+                                    ClassTemplatePartialSpecializationDecl *D) {
+  VisitClassTemplateSpecializationDecl(D);
+
+  D->initTemplateParameters(Reader.ReadTemplateParameterList(Record, Idx));
+  
+  TemplateArgumentListInfo ArgInfos;
+  unsigned NumArgs = Record[Idx++];
+  while (NumArgs--)
+    ArgInfos.addArgument(Reader.ReadTemplateArgumentLoc(Cursor, Record, Idx));
+  D->initTemplateArgsAsWritten(ArgInfos);
+  
+  D->setSequenceNumber(Record[Idx++]);
+
+  // These are read/set from/to the first declaration.
+  if (D->getPreviousDeclaration() == 0) {
+    D->setInstantiatedFromMember(
+        cast_or_null<ClassTemplatePartialSpecializationDecl>(
+                                                Reader.GetDecl(Record[Idx++])));
+    if (Record[Idx++])
+      D->setMemberSpecialization();
+  }
+}
+
+void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+  VisitRedeclarableTemplateDecl(D);
+
+  if (D->getPreviousDeclaration() == 0) {
+    // This FunctionTemplateDecl owns a CommonPtr; read it.
+
+    // Read the function specialization declarations.
+    // FunctionTemplateDecl's FunctionTemplateSpecializationInfos are filled
+    // through the specialized FunctionDecl's setFunctionTemplateSpecialization.
+    unsigned NumSpecs = Record[Idx++];
+    while (NumSpecs--)
+      Reader.GetDecl(Record[Idx++]);
+  }
+}
+
+void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+  VisitTypeDecl(D);
+
+  D->setDeclaredWithTypename(Record[Idx++]);
+  D->setParameterPack(Record[Idx++]);
+
+  bool Inherited = Record[Idx++];
+  TypeSourceInfo *DefArg = Reader.GetTypeSourceInfo(Cursor, Record, Idx);
+  D->setDefaultArgument(DefArg, Inherited);
+}
+
+void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
+  VisitVarDecl(D);
+  // TemplateParmPosition.
+  D->setDepth(Record[Idx++]);
+  D->setPosition(Record[Idx++]);
+  // Rest of NonTypeTemplateParmDecl.
+  if (Record[Idx++]) {
+    Expr *DefArg = Reader.ReadExpr(Cursor);
+    bool Inherited = Record[Idx++];
+    D->setDefaultArgument(DefArg, Inherited);
+ }
+}
+
+void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
+  VisitTemplateDecl(D);
+  // TemplateParmPosition.
+  D->setDepth(Record[Idx++]);
+  D->setPosition(Record[Idx++]);
+  // Rest of TemplateTemplateParmDecl.
+  TemplateArgumentLoc Arg = Reader.ReadTemplateArgumentLoc(Cursor, Record, Idx);
+  bool IsInherited = Record[Idx++];
+  D->setDefaultArgument(Arg, IsInherited);
+}
+
+void ASTDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) {
+  VisitDecl(D);
+  D->AssertExpr = Reader.ReadExpr(Cursor);
+  D->Message = cast<StringLiteral>(Reader.ReadExpr(Cursor));
+}
+
+std::pair<uint64_t, uint64_t>
+ASTDeclReader::VisitDeclContext(DeclContext *DC) {
+  uint64_t LexicalOffset = Record[Idx++];
+  uint64_t VisibleOffset = Record[Idx++];
+  return std::make_pair(LexicalOffset, VisibleOffset);
+}
+
+template <typename T>
+void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
+  enum RedeclKind { NoRedeclaration = 0, PointsToPrevious, PointsToLatest };
+  RedeclKind Kind = (RedeclKind)Record[Idx++];
+  switch (Kind) {
+  default:
+    assert(0 && "Out of sync with ASTDeclWriter::VisitRedeclarable or messed up"
+                " reading");
+  case NoRedeclaration:
+    break;
+  case PointsToPrevious:
+    D->RedeclLink = typename Redeclarable<T>::PreviousDeclLink(
+                                cast_or_null<T>(Reader.GetDecl(Record[Idx++])));
+    break;
+  case PointsToLatest:
+    D->RedeclLink = typename Redeclarable<T>::LatestDeclLink(
+                                cast_or_null<T>(Reader.GetDecl(Record[Idx++])));
+    break;
+  }
+
+  assert(!(Kind == PointsToPrevious &&
+           Reader.FirstLatestDeclIDs.find(ThisDeclID) !=
+               Reader.FirstLatestDeclIDs.end()) &&
+         "This decl is not first, it should not be in the map");
+  if (Kind == PointsToPrevious)
+    return;
+
+  // This decl is a first one and the latest declaration that it points to is in
+  // the same AST file. However, if this actually needs to point to a
+  // redeclaration in another AST file, we need to update it by checking the
+  // FirstLatestDeclIDs map which tracks this kind of decls.
+  assert(Reader.GetDecl(ThisDeclID) == static_cast<T*>(D) &&
+         "Invalid ThisDeclID ?");
+  ASTReader::FirstLatestDeclIDMap::iterator I
+      = Reader.FirstLatestDeclIDs.find(ThisDeclID);
+  if (I != Reader.FirstLatestDeclIDs.end()) {
+    Decl *NewLatest = Reader.GetDecl(I->second);
+    assert((D->getMostRecentDeclaration()->getLocation().isInvalid() ||
+            NewLatest->getLocation().isInvalid() ||
+            Reader.SourceMgr.isBeforeInTranslationUnit(
+                                   D->getMostRecentDeclaration()->getLocation(),
+                                   NewLatest->getLocation())) &&
+           "The new latest is supposed to come after the previous latest");
+    D->RedeclLink
+        = typename Redeclarable<T>::LatestDeclLink(cast_or_null<T>(NewLatest));
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Attribute Reading
+//===----------------------------------------------------------------------===//
+
+/// \brief Reads attributes from the current stream position.
+void ASTReader::ReadAttributes(llvm::BitstreamCursor &DeclsCursor,
+                               AttrVec &Attrs) {
+  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 == DECL_ATTR && "Expected attribute record");
+  (void)RecCode;
+
+  while (Idx < Record.size()) {
+    Attr *New = 0;
+    attr::Kind Kind = (attr::Kind)Record[Idx++];
+    SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[Idx++]);
+    bool isInherited = Record[Idx++];
+
+#include "clang/Serialization/AttrPCHRead.inc"
+
+    assert(New && "Unable to decode attribute?");
+    New->setInherited(isInherited);
+    Attrs.push_back(New);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// ASTReader 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 ASTReader::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->isThisDeclarationADefinition() == VarDecl::Definition;
+  if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D))
+    return Func->isThisDeclarationADefinition();
+  return isa<ObjCProtocolDecl>(D) || isa<ObjCImplementationDecl>(D);
+}
+
+/// \brief Get the correct cursor and offset for loading a type.
+ASTReader::RecordLocation
+ASTReader::DeclCursorForIndex(unsigned Index, DeclID ID) {
+  // See if there's an override.
+  DeclReplacementMap::iterator It = ReplacedDecls.find(ID);
+  if (It != ReplacedDecls.end())
+    return RecordLocation(&It->second.first->DeclsCursor, It->second.second);
+
+  PerFileData *F = 0;
+  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+    F = Chain[N - I - 1];
+    if (Index < F->LocalNumDecls)
+      break;
+    Index -= F->LocalNumDecls;
+  }
+  assert(F && F->LocalNumDecls > Index && "Broken chain");
+  return RecordLocation(&F->DeclsCursor, F->DeclOffsets[Index]);
+}
+
+/// \brief Read the declaration at the given offset from the AST file.
+Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
+  RecordLocation Loc = DeclCursorForIndex(Index, ID);
+  llvm::BitstreamCursor &DeclsCursor = *Loc.first;
+  // Keep track of where we are in the stream, then jump back there
+  // after reading this declaration.
+  SavedStreamPosition SavedPosition(DeclsCursor);
+
+  ReadingKindTracker ReadingKind(Read_Decl, *this);
+
+  // Note that we are loading a declaration record.
+  Deserializing ADecl(this);
+
+  DeclsCursor.JumpToBit(Loc.second);
+  RecordData Record;
+  unsigned Code = DeclsCursor.ReadCode();
+  unsigned Idx = 0;
+  ASTDeclReader Reader(*this, DeclsCursor, ID, Record, Idx);
+
+  Decl *D = 0;
+  switch ((DeclCode)DeclsCursor.ReadRecord(Code, Record)) {
+  case DECL_ATTR:
+  case DECL_CONTEXT_LEXICAL:
+  case DECL_CONTEXT_VISIBLE:
+    assert(false && "Record cannot be de-serialized with ReadDeclRecord");
+    break;
+  case DECL_TRANSLATION_UNIT:
+    assert(Index == 0 && "Translation unit must be at index 0");
+    D = Context->getTranslationUnitDecl();
+    break;
+  case DECL_TYPEDEF:
+    D = TypedefDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+    break;
+  case DECL_ENUM:
+    D = EnumDecl::Create(*Context, Decl::EmptyShell());
+    break;
+  case DECL_RECORD:
+    D = RecordDecl::Create(*Context, Decl::EmptyShell());
+    break;
+  case DECL_ENUM_CONSTANT:
+    D = EnumConstantDecl::Create(*Context, 0, SourceLocation(), 0, QualType(),
+                                 0, llvm::APSInt());
+    break;
+  case DECL_FUNCTION:
+    D = FunctionDecl::Create(*Context, 0, SourceLocation(), DeclarationName(),
+                             QualType(), 0);
+    break;
+  case DECL_LINKAGE_SPEC:
+    D = LinkageSpecDecl::Create(*Context, 0, SourceLocation(),
+                                (LinkageSpecDecl::LanguageIDs)0,
+                                false);
+    break;
+  case DECL_NAMESPACE:
+    D = NamespaceDecl::Create(*Context, 0, SourceLocation(), 0);
+    break;
+  case DECL_NAMESPACE_ALIAS:
+    D = NamespaceAliasDecl::Create(*Context, 0, SourceLocation(),
+                                   SourceLocation(), 0, SourceRange(), 0,
+                                   SourceLocation(), 0);
+    break;
+  case DECL_USING:
+    D = UsingDecl::Create(*Context, 0, SourceRange(), SourceLocation(),
+                          0, DeclarationNameInfo(), false);
+    break;
+  case DECL_USING_SHADOW:
+    D = UsingShadowDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+    break;
+  case DECL_USING_DIRECTIVE:
+    D = UsingDirectiveDecl::Create(*Context, 0, SourceLocation(),
+                                   SourceLocation(), SourceRange(), 0,
+                                   SourceLocation(), 0, 0);
+    break;
+  case DECL_UNRESOLVED_USING_VALUE:
+    D = UnresolvedUsingValueDecl::Create(*Context, 0, SourceLocation(),
+                                         SourceRange(), 0,
+                                         DeclarationNameInfo());
+    break;
+  case DECL_UNRESOLVED_USING_TYPENAME:
+    D = UnresolvedUsingTypenameDecl::Create(*Context, 0, SourceLocation(),
+                                            SourceLocation(), SourceRange(),
+                                            0, SourceLocation(),
+                                            DeclarationName());
+    break;
+  case DECL_CXX_RECORD:
+    D = CXXRecordDecl::Create(*Context, Decl::EmptyShell());
+    break;
+  case DECL_CXX_METHOD:
+    D = CXXMethodDecl::Create(*Context, 0, DeclarationNameInfo(),
+                              QualType(), 0);
+    break;
+  case DECL_CXX_CONSTRUCTOR:
+    D = CXXConstructorDecl::Create(*Context, Decl::EmptyShell());
+    break;
+  case DECL_CXX_DESTRUCTOR:
+    D = CXXDestructorDecl::Create(*Context, Decl::EmptyShell());
+    break;
+  case DECL_CXX_CONVERSION:
+    D = CXXConversionDecl::Create(*Context, Decl::EmptyShell());
+    break;
+  case DECL_ACCESS_SPEC:
+    D = AccessSpecDecl::Create(*Context, AS_none, 0, SourceLocation(),
+                               SourceLocation());
+    break;
+  case DECL_FRIEND:
+    D = FriendDecl::Create(*Context, Decl::EmptyShell());
+    break;
+  case DECL_FRIEND_TEMPLATE:
+    D = FriendTemplateDecl::Create(*Context, Decl::EmptyShell());
+    break;
+  case DECL_CLASS_TEMPLATE:
+    D = ClassTemplateDecl::Create(*Context, 0, SourceLocation(),
+                                  DeclarationName(), 0, 0, 0);
+    break;
+  case DECL_CLASS_TEMPLATE_SPECIALIZATION:
+    D = ClassTemplateSpecializationDecl::Create(*Context, Decl::EmptyShell());
+    break;
+  case DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION:
+    D = ClassTemplatePartialSpecializationDecl::Create(*Context,
+                                                            Decl::EmptyShell());
+    break;
+  case DECL_FUNCTION_TEMPLATE:
+    D = FunctionTemplateDecl::Create(*Context, 0, SourceLocation(),
+                                     DeclarationName(), 0, 0);
+    break;
+  case DECL_TEMPLATE_TYPE_PARM:
+    D = TemplateTypeParmDecl::Create(*Context, Decl::EmptyShell());
+    break;
+  case DECL_NON_TYPE_TEMPLATE_PARM:
+    D = NonTypeTemplateParmDecl::Create(*Context, 0, SourceLocation(), 0,0,0,
+                                        QualType(),0);
+    break;
+  case DECL_TEMPLATE_TEMPLATE_PARM:
+    D = TemplateTemplateParmDecl::Create(*Context, 0, SourceLocation(),0,0,0,0);
+    break;
+  case DECL_STATIC_ASSERT:
+    D = StaticAssertDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+    break;
+
+  case DECL_OBJC_METHOD:
+    D = ObjCMethodDecl::Create(*Context, SourceLocation(), SourceLocation(),
+                               Selector(), QualType(), 0, 0);
+    break;
+  case DECL_OBJC_INTERFACE:
+    D = ObjCInterfaceDecl::Create(*Context, 0, SourceLocation(), 0);
+    break;
+  case DECL_OBJC_IVAR:
+    D = ObjCIvarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0,
+                             ObjCIvarDecl::None);
+    break;
+  case DECL_OBJC_PROTOCOL:
+    D = ObjCProtocolDecl::Create(*Context, 0, SourceLocation(), 0);
+    break;
+  case DECL_OBJC_AT_DEFS_FIELD:
+    D = ObjCAtDefsFieldDecl::Create(*Context, 0, SourceLocation(), 0,
+                                    QualType(), 0);
+    break;
+  case DECL_OBJC_CLASS:
+    D = ObjCClassDecl::Create(*Context, 0, SourceLocation());
+    break;
+  case DECL_OBJC_FORWARD_PROTOCOL:
+    D = ObjCForwardProtocolDecl::Create(*Context, 0, SourceLocation());
+    break;
+  case DECL_OBJC_CATEGORY:
+    D = ObjCCategoryDecl::Create(*Context, 0, SourceLocation(), 
+                                 SourceLocation(), SourceLocation(), 0);
+    break;
+  case DECL_OBJC_CATEGORY_IMPL:
+    D = ObjCCategoryImplDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+    break;
+  case DECL_OBJC_IMPLEMENTATION:
+    D = ObjCImplementationDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+    break;
+  case DECL_OBJC_COMPATIBLE_ALIAS:
+    D = ObjCCompatibleAliasDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+    break;
+  case DECL_OBJC_PROPERTY:
+    D = ObjCPropertyDecl::Create(*Context, 0, SourceLocation(), 0, SourceLocation(),
+                                 0);
+    break;
+  case DECL_OBJC_PROPERTY_IMPL:
+    D = ObjCPropertyImplDecl::Create(*Context, 0, SourceLocation(),
+                                     SourceLocation(), 0,
+                                     ObjCPropertyImplDecl::Dynamic, 0);
+    break;
+  case DECL_FIELD:
+    D = FieldDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0, 0,
+                          false);
+    break;
+  case DECL_VAR:
+    D = VarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0,
+                        SC_None, SC_None);
+    break;
+
+  case DECL_IMPLICIT_PARAM:
+    D = ImplicitParamDecl::Create(*Context, 0, SourceLocation(), 0, QualType());
+    break;
+
+  case DECL_PARM_VAR:
+    D = ParmVarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0,
+                            SC_None, SC_None, 0);
+    break;
+  case DECL_FILE_SCOPE_ASM:
+    D = FileScopeAsmDecl::Create(*Context, 0, SourceLocation(), 0);
+    break;
+  case DECL_BLOCK:
+    D = BlockDecl::Create(*Context, 0, SourceLocation());
+    break;
+  }
+
+  assert(D && "Unknown declaration reading AST 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);
+      DeclContextInfo Info;
+      if (ReadDeclContextStorage(DeclsCursor, Offsets, Info))
+        return 0;
+      DeclContextInfos &Infos = DeclContextOffsets[DC];
+      // Reading the TU will happen after reading its lexical update blocks,
+      // so we need to make sure we insert in front. For all other contexts,
+      // the vector is empty here anyway, so there's no loss in efficiency.
+      Infos.insert(Infos.begin(), Info);
+
+      // Now add the pending visible updates for this decl context, if it has
+      // any.
+      DeclContextVisibleUpdatesPending::iterator I =
+          PendingVisibleUpdates.find(ID);
+      if (I != PendingVisibleUpdates.end()) {
+        DeclContextVisibleUpdates &U = I->second;
+        Info.LexicalDecls = 0;
+        Info.NumLexicalDecls = 0;
+        for (DeclContextVisibleUpdates::iterator UI = U.begin(), UE = U.end();
+             UI != UE; ++UI) {
+          Info.NameLookupTableData = *UI;
+          Infos.push_back(Info);
+        }
+        PendingVisibleUpdates.erase(I);
+      }
+    }
+  }
+
+  // If this is a template, read additional specializations that may be in a
+  // different part of the chain.
+  if (isa<RedeclarableTemplateDecl>(D)) {
+    AdditionalTemplateSpecializationsMap::iterator F =
+        AdditionalTemplateSpecializationsPending.find(ID);
+    if (F != AdditionalTemplateSpecializationsPending.end()) {
+      for (AdditionalTemplateSpecializations::iterator I = F->second.begin(),
+                                                       E = F->second.end();
+           I != E; ++I)
+        GetDecl(*I);
+      AdditionalTemplateSpecializationsPending.erase(F);
+    }
+  }
+  assert(Idx == Record.size());
+
+  // If we have deserialized a declaration that has a definition the
+  // AST consumer might need to know about, queue it.
+  // We don't pass it to the consumer immediately because we may be in recursive
+  // loading, and some declarations may still be initializing.
+  if (isConsumerInterestedIn(D))
+    InterestingDecls.push_back(D);
+
+  return D;
+}
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
new file mode 100644
index 0000000..ec227e2
--- /dev/null
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -0,0 +1,1776 @@
+//===--- ASTReaderStmt.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
+// ASTReader::ReadStmt method.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Serialization/ASTReader.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/StmtVisitor.h"
+using namespace clang;
+using namespace clang::serialization;
+
+namespace clang {
+
+  class ASTStmtReader : public StmtVisitor<ASTStmtReader> {
+    ASTReader &Reader;
+    llvm::BitstreamCursor &DeclsCursor;
+    const ASTReader::RecordData &Record;
+    unsigned &Idx;
+
+  public:
+    ASTStmtReader(ASTReader &Reader, llvm::BitstreamCursor &Cursor,
+                  const ASTReader::RecordData &Record, unsigned &Idx)
+      : Reader(Reader), DeclsCursor(Cursor), Record(Record), Idx(Idx) { }
+
+    /// \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;
+    
+    /// \brief Read and initialize a ExplicitTemplateArgumentList structure.
+    void ReadExplicitTemplateArgumentList(ExplicitTemplateArgumentList &ArgList,
+                                          unsigned NumTemplateArgs);
+
+    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 VisitParenListExpr(ParenListExpr *E);
+    void VisitUnaryOperator(UnaryOperator *E);
+    void VisitOffsetOfExpr(OffsetOfExpr *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);
+    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);
+
+    void VisitObjCForCollectionStmt(ObjCForCollectionStmt *);
+    void VisitObjCAtCatchStmt(ObjCAtCatchStmt *);
+    void VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *);
+    void VisitObjCAtTryStmt(ObjCAtTryStmt *);
+    void VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *);
+    void VisitObjCAtThrowStmt(ObjCAtThrowStmt *);
+
+    // C++ Statements
+    void VisitCXXCatchStmt(CXXCatchStmt *S);
+    void VisitCXXTryStmt(CXXTryStmt *S);
+
+    void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
+    void VisitCXXConstructExpr(CXXConstructExpr *E);
+    void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *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 VisitCXXTypeidExpr(CXXTypeidExpr *E);
+    void VisitCXXThisExpr(CXXThisExpr *E);
+    void VisitCXXThrowExpr(CXXThrowExpr *E);
+    void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
+    void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
+    void VisitCXXBindReferenceExpr(CXXBindReferenceExpr *E);
+    
+    void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
+    void VisitCXXNewExpr(CXXNewExpr *E);
+    void VisitCXXDeleteExpr(CXXDeleteExpr *E);
+    void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
+    
+    void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
+    
+    void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
+    void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
+    void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
+
+    void VisitOverloadExpr(OverloadExpr *E);
+    void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E);
+    void VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E);
+
+    void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
+  };
+}
+
+void ASTStmtReader::
+ReadExplicitTemplateArgumentList(ExplicitTemplateArgumentList &ArgList,
+                                 unsigned NumTemplateArgs) {
+  TemplateArgumentListInfo ArgInfo;
+  ArgInfo.setLAngleLoc(Reader.ReadSourceLocation(Record, Idx));
+  ArgInfo.setRAngleLoc(Reader.ReadSourceLocation(Record, Idx));
+  for (unsigned i = 0; i != NumTemplateArgs; ++i)
+    ArgInfo.addArgument(
+        Reader.ReadTemplateArgumentLoc(DeclsCursor, Record, Idx));
+  ArgList.initializeFrom(ArgInfo);
+}
+
+void ASTStmtReader::VisitStmt(Stmt *S) {
+  assert(Idx == NumStmtFields && "Incorrect statement field count");
+}
+
+void ASTStmtReader::VisitNullStmt(NullStmt *S) {
+  VisitStmt(S);
+  S->setSemiLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) {
+  VisitStmt(S);
+  llvm::SmallVector<Stmt *, 16> Stmts;
+  unsigned NumStmts = Record[Idx++];
+  while (NumStmts--)
+    Stmts.push_back(Reader.ReadSubStmt());
+  S->setStmts(*Reader.getContext(), Stmts.data(), Stmts.size());
+  S->setLBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setRBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitSwitchCase(SwitchCase *S) {
+  VisitStmt(S);
+  Reader.RecordSwitchCaseID(S, Record[Idx++]);
+}
+
+void ASTStmtReader::VisitCaseStmt(CaseStmt *S) {
+  VisitSwitchCase(S);
+  S->setLHS(Reader.ReadSubExpr());
+  S->setRHS(Reader.ReadSubExpr());
+  S->setSubStmt(Reader.ReadSubStmt());
+  S->setCaseLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setEllipsisLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitDefaultStmt(DefaultStmt *S) {
+  VisitSwitchCase(S);
+  S->setSubStmt(Reader.ReadSubStmt());
+  S->setDefaultLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitLabelStmt(LabelStmt *S) {
+  VisitStmt(S);
+  S->setID(Reader.GetIdentifierInfo(Record, Idx));
+  S->setSubStmt(Reader.ReadSubStmt());
+  S->setIdentLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  Reader.RecordLabelStmt(S, Record[Idx++]);
+}
+
+void ASTStmtReader::VisitIfStmt(IfStmt *S) {
+  VisitStmt(S);
+  S->setConditionVariable(*Reader.getContext(),
+                          cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+  S->setCond(Reader.ReadSubExpr());
+  S->setThen(Reader.ReadSubStmt());
+  S->setElse(Reader.ReadSubStmt());
+  S->setIfLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setElseLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) {
+  VisitStmt(S);
+  S->setConditionVariable(*Reader.getContext(),
+                          cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+  S->setCond(Reader.ReadSubExpr());
+  S->setBody(Reader.ReadSubStmt());
+  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;
+  }
+}
+
+void ASTStmtReader::VisitWhileStmt(WhileStmt *S) {
+  VisitStmt(S);
+  S->setConditionVariable(*Reader.getContext(),
+                          cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+  S->setCond(Reader.ReadSubExpr());
+  S->setBody(Reader.ReadSubStmt());
+  S->setWhileLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitDoStmt(DoStmt *S) {
+  VisitStmt(S);
+  S->setCond(Reader.ReadSubExpr());
+  S->setBody(Reader.ReadSubStmt());
+  S->setDoLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setWhileLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitForStmt(ForStmt *S) {
+  VisitStmt(S);
+  S->setInit(Reader.ReadSubStmt());
+  S->setCond(Reader.ReadSubExpr());
+  S->setConditionVariable(*Reader.getContext(),
+                          cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+  S->setInc(Reader.ReadSubExpr());
+  S->setBody(Reader.ReadSubStmt());
+  S->setForLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitGotoStmt(GotoStmt *S) {
+  VisitStmt(S);
+  Reader.SetLabelOf(S, Record[Idx++]);
+  S->setGotoLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setLabelLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
+  VisitStmt(S);
+  S->setGotoLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setTarget(Reader.ReadSubExpr());
+}
+
+void ASTStmtReader::VisitContinueStmt(ContinueStmt *S) {
+  VisitStmt(S);
+  S->setContinueLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitBreakStmt(BreakStmt *S) {
+  VisitStmt(S);
+  S->setBreakLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitReturnStmt(ReturnStmt *S) {
+  VisitStmt(S);
+  S->setRetValue(Reader.ReadSubExpr());
+  S->setReturnLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setNRVOCandidate(cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void ASTStmtReader::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())));
+  }
+}
+
+void ASTStmtReader::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++]);
+
+  S->setAsmString(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
+
+  // 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>(Reader.ReadSubStmt()));
+    Exprs.push_back(Reader.ReadSubStmt());
+  }
+
+  // Constraints
+  llvm::SmallVector<StringLiteral*, 16> Clobbers;
+  for (unsigned I = 0; I != NumClobbers; ++I)
+    Clobbers.push_back(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
+
+  S->setOutputsAndInputsAndClobbers(*Reader.getContext(),
+                                    Names.data(), Constraints.data(), 
+                                    Exprs.data(), NumOutputs, NumInputs, 
+                                    Clobbers.data(), NumClobbers);
+}
+
+void ASTStmtReader::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");
+}
+
+void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) {
+  VisitExpr(E);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setIdentType((PredefinedExpr::IdentType)Record[Idx++]);
+}
+
+void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
+  VisitExpr(E);
+
+  bool HasQualifier = Record[Idx++];
+  unsigned NumTemplateArgs = Record[Idx++];
+  
+  E->DecoratedD.setInt((HasQualifier? DeclRefExpr::HasQualifierFlag : 0) |
+      (NumTemplateArgs ? DeclRefExpr::HasExplicitTemplateArgumentListFlag : 0));
+  
+  if (HasQualifier) {
+    E->getNameQualifier()->NNS = Reader.ReadNestedNameSpecifier(Record, Idx);
+    E->getNameQualifier()->Range = Reader.ReadSourceRange(Record, Idx);
+  }
+
+  if (NumTemplateArgs)
+    ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(),
+                                     NumTemplateArgs);
+
+  E->setDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++])));
+  // FIXME: read DeclarationNameLoc.
+  E->setLocation(Reader.ReadSourceLocation(Record, Idx));
+}
+
+void ASTStmtReader::VisitIntegerLiteral(IntegerLiteral *E) {
+  VisitExpr(E);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setValue(*Reader.getContext(), Reader.ReadAPInt(Record, Idx));
+}
+
+void ASTStmtReader::VisitFloatingLiteral(FloatingLiteral *E) {
+  VisitExpr(E);
+  E->setValue(*Reader.getContext(), Reader.ReadAPFloat(Record, Idx));
+  E->setExact(Record[Idx++]);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitImaginaryLiteral(ImaginaryLiteral *E) {
+  VisitExpr(E);
+  E->setSubExpr(Reader.ReadSubExpr());
+}
+
+void ASTStmtReader::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++]));
+}
+
+void ASTStmtReader::VisitCharacterLiteral(CharacterLiteral *E) {
+  VisitExpr(E);
+  E->setValue(Record[Idx++]);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setWide(Record[Idx++]);
+}
+
+void ASTStmtReader::VisitParenExpr(ParenExpr *E) {
+  VisitExpr(E);
+  E->setLParen(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParen(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setSubExpr(Reader.ReadSubExpr());
+}
+
+void ASTStmtReader::VisitParenListExpr(ParenListExpr *E) {
+  VisitExpr(E);
+  unsigned NumExprs = Record[Idx++];
+  E->Exprs = new (*Reader.getContext()) Stmt*[NumExprs];
+  for (unsigned i = 0; i != NumExprs; ++i)
+    E->Exprs[i] = Reader.ReadSubStmt();
+  E->NumExprs = NumExprs;
+  E->LParenLoc = Reader.ReadSourceLocation(Record, Idx);
+  E->RParenLoc = Reader.ReadSourceLocation(Record, Idx);
+}
+
+void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) {
+  VisitExpr(E);
+  E->setSubExpr(Reader.ReadSubExpr());
+  E->setOpcode((UnaryOperator::Opcode)Record[Idx++]);
+  E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) {
+  typedef OffsetOfExpr::OffsetOfNode Node;
+  VisitExpr(E);
+  assert(E->getNumComponents() == Record[Idx]);
+  ++Idx;
+  assert(E->getNumExpressions() == Record[Idx]);
+  ++Idx;
+  E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setTypeSourceInfo(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
+  for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
+    Node::Kind Kind = static_cast<Node::Kind>(Record[Idx++]);
+    SourceLocation Start = SourceLocation::getFromRawEncoding(Record[Idx++]);
+    SourceLocation End = SourceLocation::getFromRawEncoding(Record[Idx++]);
+    switch (Kind) {
+    case Node::Array:
+      E->setComponent(I, Node(Start, Record[Idx++], End));
+      break;
+        
+    case Node::Field:
+      E->setComponent(I, 
+             Node(Start,  
+                  dyn_cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++])),
+                  End));
+      break;
+
+    case Node::Identifier:
+      E->setComponent(I, Node(Start, Reader.GetIdentifier(Record[Idx++]), End));
+      break;
+        
+    case Node::Base: {
+      CXXBaseSpecifier *Base = new (*Reader.getContext()) CXXBaseSpecifier();
+      *Base = Reader.ReadCXXBaseSpecifier(DeclsCursor, Record, Idx);
+      E->setComponent(I, Node(Base));
+      break;
+    }
+    }
+  }
+  
+  for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
+    E->setIndexExpr(I, Reader.ReadSubExpr());
+}
+
+void ASTStmtReader::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
+  VisitExpr(E);
+  E->setSizeof(Record[Idx++]);
+  if (Record[Idx] == 0) {
+    E->setArgument(Reader.ReadSubExpr());
+    ++Idx;
+  } else {
+    E->setArgument(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
+  }
+  E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+  VisitExpr(E);
+  E->setLHS(Reader.ReadSubExpr());
+  E->setRHS(Reader.ReadSubExpr());
+  E->setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitCallExpr(CallExpr *E) {
+  VisitExpr(E);
+  E->setNumArgs(*Reader.getContext(), Record[Idx++]);
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setCallee(Reader.ReadSubExpr());
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
+    E->setArg(I, Reader.ReadSubExpr());
+}
+
+void ASTStmtReader::VisitMemberExpr(MemberExpr *E) {
+  // Don't call VisitExpr, this is fully initialized at creation.
+  assert(E->getStmtClass() == Stmt::MemberExprClass &&
+         "It's a subclass, we must advance Idx!");
+}
+
+void ASTStmtReader::VisitObjCIsaExpr(ObjCIsaExpr *E) {
+  VisitExpr(E);
+  E->setBase(Reader.ReadSubExpr());
+  E->setIsaMemberLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setArrow(Record[Idx++]);
+}
+
+void ASTStmtReader::VisitCastExpr(CastExpr *E) {
+  VisitExpr(E);
+  unsigned NumBaseSpecs = Record[Idx++];
+  assert(NumBaseSpecs == E->path_size());
+  E->setSubExpr(Reader.ReadSubExpr());
+  E->setCastKind((CastExpr::CastKind)Record[Idx++]);
+  CastExpr::path_iterator BaseI = E->path_begin();
+  while (NumBaseSpecs--) {
+    CXXBaseSpecifier *BaseSpec = new (*Reader.getContext()) CXXBaseSpecifier;
+    *BaseSpec = Reader.ReadCXXBaseSpecifier(DeclsCursor, Record, Idx);
+    *BaseI++ = BaseSpec;
+  }
+}
+
+void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) {
+  VisitExpr(E);
+  E->setLHS(Reader.ReadSubExpr());
+  E->setRHS(Reader.ReadSubExpr());
+  E->setOpcode((BinaryOperator::Opcode)Record[Idx++]);
+  E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
+  VisitBinaryOperator(E);
+  E->setComputationLHSType(Reader.GetType(Record[Idx++]));
+  E->setComputationResultType(Reader.GetType(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitConditionalOperator(ConditionalOperator *E) {
+  VisitExpr(E);
+  E->setCond(Reader.ReadSubExpr());
+  E->setLHS(Reader.ReadSubExpr());
+  E->setRHS(Reader.ReadSubExpr());
+  E->setQuestionLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) {
+  VisitCastExpr(E);
+  E->setValueKind(static_cast<ExprValueKind>(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) {
+  VisitCastExpr(E);
+  E->setTypeInfoAsWritten(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
+}
+
+void ASTStmtReader::VisitCStyleCastExpr(CStyleCastExpr *E) {
+  VisitExplicitCastExpr(E);
+  E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+  VisitExpr(E);
+  E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setTypeSourceInfo(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
+  E->setInitializer(Reader.ReadSubExpr());
+  E->setFileScope(Record[Idx++]);
+}
+
+void ASTStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
+  VisitExpr(E);
+  E->setBase(Reader.ReadSubExpr());
+  E->setAccessor(Reader.GetIdentifierInfo(Record, Idx));
+  E->setAccessorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::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, Reader.ReadSubExpr());
+  E->setSyntacticForm(cast_or_null<InitListExpr>(Reader.ReadSubStmt()));
+  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++]);
+}
+
+void ASTStmtReader::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, Reader.ReadSubExpr());
+  E->setEqualOrColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setGNUSyntax(Record[Idx++]);
+
+  llvm::SmallVector<Designator, 4> Designators;
+  while (Idx < Record.size()) {
+    switch ((DesignatorTypes)Record[Idx++]) {
+    case 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 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 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 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());
+}
+
+void ASTStmtReader::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
+  VisitExpr(E);
+}
+
+void ASTStmtReader::VisitVAArgExpr(VAArgExpr *E) {
+  VisitExpr(E);
+  E->setSubExpr(Reader.ReadSubExpr());
+  E->setWrittenTypeInfo(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
+  E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitAddrLabelExpr(AddrLabelExpr *E) {
+  VisitExpr(E);
+  E->setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setLabelLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  Reader.SetLabelOf(E, Record[Idx++]);
+}
+
+void ASTStmtReader::VisitStmtExpr(StmtExpr *E) {
+  VisitExpr(E);
+  E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setSubStmt(cast_or_null<CompoundStmt>(Reader.ReadSubStmt()));
+}
+
+void ASTStmtReader::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) {
+  VisitExpr(E);
+  E->setArgTInfo1(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
+  E->setArgTInfo2(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
+  E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitChooseExpr(ChooseExpr *E) {
+  VisitExpr(E);
+  E->setCond(Reader.ReadSubExpr());
+  E->setLHS(Reader.ReadSubExpr());
+  E->setRHS(Reader.ReadSubExpr());
+  E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitGNUNullExpr(GNUNullExpr *E) {
+  VisitExpr(E);
+  E->setTokenLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
+  VisitExpr(E);
+  llvm::SmallVector<Expr *, 16> Exprs;
+  unsigned NumExprs = Record[Idx++];
+  while (NumExprs--)
+    Exprs.push_back(Reader.ReadSubExpr());
+  E->setExprs(*Reader.getContext(), Exprs.data(), Exprs.size());
+  E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitBlockExpr(BlockExpr *E) {
+  VisitExpr(E);
+  E->setBlockDecl(cast_or_null<BlockDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setHasBlockDeclRefExprs(Record[Idx++]);
+}
+
+void ASTStmtReader::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++]);
+  E->setCopyConstructorExpr(Reader.ReadSubExpr());
+}
+
+//===----------------------------------------------------------------------===//
+// Objective-C Expressions and Statements
+
+void ASTStmtReader::VisitObjCStringLiteral(ObjCStringLiteral *E) {
+  VisitExpr(E);
+  E->setString(cast<StringLiteral>(Reader.ReadSubStmt()));
+  E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+  VisitExpr(E);
+  E->setEncodedTypeSourceInfo(Reader.GetTypeSourceInfo(DeclsCursor,Record,Idx));
+  E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
+  VisitExpr(E);
+  E->setSelector(Reader.GetSelector(Record, Idx));
+  E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::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++]));
+}
+
+void ASTStmtReader::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+  VisitExpr(E);
+  E->setDecl(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setBase(Reader.ReadSubExpr());
+  E->setIsArrow(Record[Idx++]);
+  E->setIsFreeIvar(Record[Idx++]);
+}
+
+void ASTStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+  VisitExpr(E);
+  E->setProperty(cast<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setBase(Reader.ReadSubExpr());
+}
+
+void ASTStmtReader::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(Reader.ReadSubExpr());
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::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(Reader.ReadSubExpr());
+    break;
+
+  case ObjCMessageExpr::Class:
+    E->setClassReceiver(Reader.GetTypeSourceInfo(DeclsCursor, 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, Reader.ReadSubExpr());
+}
+
+void ASTStmtReader::VisitObjCSuperExpr(ObjCSuperExpr *E) {
+  VisitExpr(E);
+  E->setLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
+  VisitStmt(S);
+  S->setElement(Reader.ReadSubStmt());
+  S->setCollection(Reader.ReadSubExpr());
+  S->setBody(Reader.ReadSubStmt());
+  S->setForLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
+  VisitStmt(S);
+  S->setCatchBody(Reader.ReadSubStmt());
+  S->setCatchParamDecl(cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+  S->setAtCatchLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
+  VisitStmt(S);
+  S->setFinallyBody(Reader.ReadSubStmt());
+  S->setAtFinallyLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
+  VisitStmt(S);
+  assert(Record[Idx] == S->getNumCatchStmts());
+  ++Idx;
+  bool HasFinally = Record[Idx++];
+  S->setTryBody(Reader.ReadSubStmt());
+  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
+    S->setCatchStmt(I, cast_or_null<ObjCAtCatchStmt>(Reader.ReadSubStmt()));
+
+  if (HasFinally)
+    S->setFinallyStmt(Reader.ReadSubStmt());
+  S->setAtTryLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
+  VisitStmt(S);
+  S->setSynchExpr(Reader.ReadSubStmt());
+  S->setSynchBody(Reader.ReadSubStmt());
+  S->setAtSynchronizedLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
+  VisitStmt(S);
+  S->setThrowExpr(Reader.ReadSubStmt());
+  S->setThrowLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+//===----------------------------------------------------------------------===//
+// C++ Expressions and Statements
+//===----------------------------------------------------------------------===//
+
+void ASTStmtReader::VisitCXXCatchStmt(CXXCatchStmt *S) {
+  VisitStmt(S);
+  S->CatchLoc = Reader.ReadSourceLocation(Record, Idx);
+  S->ExceptionDecl = cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++]));
+  S->HandlerBlock = Reader.ReadSubStmt();
+}
+
+void ASTStmtReader::VisitCXXTryStmt(CXXTryStmt *S) {
+  VisitStmt(S);
+  assert(Record[Idx] == S->getNumHandlers() && "NumStmtFields is wrong ?");
+  ++Idx;
+  S->TryLoc = Reader.ReadSourceLocation(Record, Idx);
+  S->getStmts()[0] = Reader.ReadSubStmt();
+  for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
+    S->getStmts()[i + 1] = Reader.ReadSubStmt();
+}
+
+void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+  VisitCallExpr(E);
+  E->setOperator((OverloadedOperatorKind)Record[Idx++]);
+}
+
+void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
+  VisitExpr(E);
+  E->NumArgs = Record[Idx++];
+  if (E->NumArgs)
+    E->Args = new (*Reader.getContext()) Stmt*[E->NumArgs];
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
+    E->setArg(I, Reader.ReadSubExpr());
+  E->setConstructor(cast<CXXConstructorDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setElidable(Record[Idx++]);  
+  E->setRequiresZeroInitialization(Record[Idx++]);
+  E->setConstructionKind((CXXConstructExpr::ConstructionKind)Record[Idx++]);
+}
+
+void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
+  VisitCXXConstructExpr(E);
+  E->TyBeginLoc = Reader.ReadSourceLocation(Record, Idx);
+  E->RParenLoc = Reader.ReadSourceLocation(Record, Idx);
+}
+
+void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
+  VisitExplicitCastExpr(E);
+  E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
+  return VisitCXXNamedCastExpr(E);
+}
+
+void ASTStmtReader::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
+  return VisitCXXNamedCastExpr(E);
+}
+
+void ASTStmtReader::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
+  return VisitCXXNamedCastExpr(E);
+}
+
+void ASTStmtReader::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
+  return VisitCXXNamedCastExpr(E);
+}
+
+void ASTStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
+  VisitExplicitCastExpr(E);
+  E->setTypeBeginLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
+  VisitExpr(E);
+  E->setValue(Record[Idx++]);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
+  VisitExpr(E);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
+  VisitExpr(E);
+  E->setSourceRange(Reader.ReadSourceRange(Record, Idx));
+  if (E->isTypeOperand()) { // typeid(int)
+    E->setTypeOperandSourceInfo(
+        Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
+    return;
+  }
+  
+  // typeid(42+2)
+  E->setExprOperand(Reader.ReadSubExpr());
+}
+
+void ASTStmtReader::VisitCXXThisExpr(CXXThisExpr *E) {
+  VisitExpr(E);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setImplicit(Record[Idx++]);
+}
+
+void ASTStmtReader::VisitCXXThrowExpr(CXXThrowExpr *E) {
+  VisitExpr(E);
+  E->setThrowLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setSubExpr(Reader.ReadSubExpr());
+}
+
+void ASTStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
+  VisitExpr(E);
+
+  assert(Record[Idx] == E->Param.getInt() && "We messed up at creation ?");
+  ++Idx; // HasOtherExprStored and SubExpr was handled during creation.
+  E->Param.setPointer(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
+  E->Loc = Reader.ReadSourceLocation(Record, Idx);
+}
+
+void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
+  VisitExpr(E);
+  E->setTemporary(Reader.ReadCXXTemporary(Record, Idx));
+  E->setSubExpr(Reader.ReadSubExpr());
+}
+
+void ASTStmtReader::VisitCXXBindReferenceExpr(CXXBindReferenceExpr *E) {
+  VisitExpr(E);
+  E->SubExpr = Reader.ReadSubExpr();
+  E->ExtendsLifetime = Record[Idx++];
+  E->RequiresTemporaryCopy = Record[Idx++];
+}
+
+void ASTStmtReader::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
+  VisitExpr(E);
+  E->setTypeBeginLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
+  VisitExpr(E);
+  E->setGlobalNew(Record[Idx++]);
+  E->setHasInitializer(Record[Idx++]);
+  bool isArray = Record[Idx++];
+  unsigned NumPlacementArgs = Record[Idx++];
+  unsigned NumCtorArgs = Record[Idx++];
+  E->setOperatorNew(cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setOperatorDelete(
+                    cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setConstructor(
+               cast_or_null<CXXConstructorDecl>(Reader.GetDecl(Record[Idx++])));
+  SourceRange TypeIdParens;
+  TypeIdParens.setBegin(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TypeIdParens.setEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->TypeIdParens = TypeIdParens;
+  E->setStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  
+  E->AllocateArgsArray(*Reader.getContext(), isArray, NumPlacementArgs,
+                       NumCtorArgs);
+
+  // Install all the subexpressions.
+  for (CXXNewExpr::raw_arg_iterator I = E->raw_arg_begin(),e = E->raw_arg_end();
+       I != e; ++I)
+    *I = Reader.ReadSubStmt();
+}
+
+void ASTStmtReader::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
+  VisitExpr(E);
+  E->setGlobalDelete(Record[Idx++]);
+  E->setArrayForm(Record[Idx++]);
+  E->setOperatorDelete(
+                     cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setArgument(Reader.ReadSubExpr());
+  E->setStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void ASTStmtReader::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
+  VisitExpr(E);
+
+  E->setBase(Reader.ReadSubExpr());
+  E->setArrow(Record[Idx++]);
+  E->setOperatorLoc(Reader.ReadSourceLocation(Record, Idx));
+  E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+  E->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
+  E->setScopeTypeInfo(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
+  E->setColonColonLoc(Reader.ReadSourceLocation(Record, Idx));
+  E->setTildeLoc(Reader.ReadSourceLocation(Record, Idx));
+  
+  IdentifierInfo *II = Reader.GetIdentifierInfo(Record, Idx);
+  if (II)
+    E->setDestroyedType(II, Reader.ReadSourceLocation(Record, Idx));
+  else
+    E->setDestroyedType(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx));
+}
+
+void ASTStmtReader::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
+  VisitExpr(E);
+  unsigned NumTemps = Record[Idx++];
+  if (NumTemps) {
+    E->setNumTemporaries(*Reader.getContext(), NumTemps);
+    for (unsigned i = 0; i != NumTemps; ++i)
+      E->setTemporary(i, Reader.ReadCXXTemporary(Record, Idx));
+  }
+  E->setSubExpr(Reader.ReadSubExpr());
+}
+
+void
+ASTStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
+  VisitExpr(E);
+  
+  unsigned NumTemplateArgs = Record[Idx++];
+  assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
+         "Read wrong record during creation ?");
+  if (E->hasExplicitTemplateArgs())
+    ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(),
+                                     NumTemplateArgs);
+
+  E->setBase(Reader.ReadSubExpr());
+  E->setBaseType(Reader.GetType(Record[Idx++]));
+  E->setArrow(Record[Idx++]);
+  E->setOperatorLoc(Reader.ReadSourceLocation(Record, Idx));
+  E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+  E->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
+  E->setFirstQualifierFoundInScope(
+                        cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++])));
+  // FIXME: read whole DeclarationNameInfo.
+  E->setMember(Reader.ReadDeclarationName(Record, Idx));
+  E->setMemberLoc(Reader.ReadSourceLocation(Record, Idx));
+}
+
+void
+ASTStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+  VisitExpr(E);
+  
+  unsigned NumTemplateArgs = Record[Idx++];
+  assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
+         "Read wrong record during creation ?");
+  if (E->hasExplicitTemplateArgs())
+    ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(),
+                                     NumTemplateArgs);
+
+  // FIXME: read whole DeclarationNameInfo.
+  E->setDeclName(Reader.ReadDeclarationName(Record, Idx));
+  E->setLocation(Reader.ReadSourceLocation(Record, Idx));
+  E->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
+  E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+}
+
+void
+ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
+  VisitExpr(E);
+  assert(Record[Idx] == E->arg_size() && "Read wrong record during creation ?");
+  ++Idx; // NumArgs;
+  for (unsigned I = 0, N = E->arg_size(); I != N; ++I)
+    E->setArg(I, Reader.ReadSubExpr());
+  E->setTypeBeginLoc(Reader.ReadSourceLocation(Record, Idx));
+  E->setTypeAsWritten(Reader.GetType(Record[Idx++]));
+  E->setLParenLoc(Reader.ReadSourceLocation(Record, Idx));
+  E->setRParenLoc(Reader.ReadSourceLocation(Record, Idx));
+}
+
+void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
+  VisitExpr(E);
+  
+  unsigned NumTemplateArgs = Record[Idx++];
+  assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
+         "Read wrong record during creation ?");
+  if (E->hasExplicitTemplateArgs())
+    ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(),
+                                     NumTemplateArgs);
+
+  unsigned NumDecls = Record[Idx++];
+  UnresolvedSet<8> Decls;
+  for (unsigned i = 0; i != NumDecls; ++i) {
+    NamedDecl *D = cast<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+    AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
+    Decls.addDecl(D, AS);
+  }
+  E->initializeResults(*Reader.getContext(), Decls.begin(), Decls.end());
+
+  // FIXME: read whole DeclarationNameInfo.
+  E->setName(Reader.ReadDeclarationName(Record, Idx));
+  E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+  E->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
+  E->setNameLoc(Reader.ReadSourceLocation(Record, Idx));
+}
+
+void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
+  VisitOverloadExpr(E);
+  E->setArrow(Record[Idx++]);
+  E->setHasUnresolvedUsing(Record[Idx++]);
+  E->setBase(Reader.ReadSubExpr());
+  E->setBaseType(Reader.GetType(Record[Idx++]));
+  E->setOperatorLoc(Reader.ReadSourceLocation(Record, Idx));
+}
+
+void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
+  VisitOverloadExpr(E);
+  E->setRequiresADL(Record[Idx++]);
+  E->setOverloaded(Record[Idx++]);
+  E->setNamingClass(cast_or_null<CXXRecordDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void ASTStmtReader::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
+  VisitExpr(E);
+  E->UTT = (UnaryTypeTrait)Record[Idx++];
+  SourceRange Range = Reader.ReadSourceRange(Record, Idx);
+  E->Loc = Range.getBegin();
+  E->RParen = Range.getEnd();
+  E->QueriedType = Reader.GetType(Record[Idx++]);
+}
+
+Stmt *ASTReader::ReadStmt(llvm::BitstreamCursor &Cursor) {
+  switch (ReadingKind) {
+  case Read_Decl:
+  case Read_Type:
+    return ReadStmtFromStream(Cursor);
+  case Read_Stmt:
+    return ReadSubStmt();
+  }
+
+  llvm_unreachable("ReadingKind not set ?");
+  return 0;
+}
+
+Expr *ASTReader::ReadExpr(llvm::BitstreamCursor &Cursor) {
+  return cast_or_null<Expr>(ReadStmt(Cursor));
+}
+
+Expr *ASTReader::ReadSubExpr() {
+  return cast_or_null<Expr>(ReadSubStmt());
+}
+
+// Within the bitstream, expressions are stored in Reverse Polish
+// Notation, with each of the subexpressions preceding the
+// expression they are stored in. Subexpressions are stored from last to first.
+// 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 *ASTReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) {
+
+  ReadingKindTracker ReadingKind(Read_Stmt, *this);
+  
+#ifndef NDEBUG
+  unsigned PrevNumStmts = StmtStack.size();
+#endif
+
+  RecordData Record;
+  unsigned Idx;
+  ASTStmtReader Reader(*this, Cursor, Record, Idx);
+  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 AST 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 AST file");
+        return 0;
+      }
+      continue;
+    }
+
+    if (Code == llvm::bitc::DEFINE_ABBREV) {
+      Cursor.ReadAbbrevRecord();
+      continue;
+    }
+
+    Stmt *S = 0;
+    Idx = 0;
+    Record.clear();
+    bool Finished = false;
+    switch ((StmtCode)Cursor.ReadRecord(Code, Record)) {
+    case STMT_STOP:
+      Finished = true;
+      break;
+
+    case STMT_NULL_PTR:
+      S = 0;
+      break;
+
+    case STMT_NULL:
+      S = new (Context) NullStmt(Empty);
+      break;
+
+    case STMT_COMPOUND:
+      S = new (Context) CompoundStmt(Empty);
+      break;
+
+    case STMT_CASE:
+      S = new (Context) CaseStmt(Empty);
+      break;
+
+    case STMT_DEFAULT:
+      S = new (Context) DefaultStmt(Empty);
+      break;
+
+    case STMT_LABEL:
+      S = new (Context) LabelStmt(Empty);
+      break;
+
+    case STMT_IF:
+      S = new (Context) IfStmt(Empty);
+      break;
+
+    case STMT_SWITCH:
+      S = new (Context) SwitchStmt(Empty);
+      break;
+
+    case STMT_WHILE:
+      S = new (Context) WhileStmt(Empty);
+      break;
+
+    case STMT_DO:
+      S = new (Context) DoStmt(Empty);
+      break;
+
+    case STMT_FOR:
+      S = new (Context) ForStmt(Empty);
+      break;
+
+    case STMT_GOTO:
+      S = new (Context) GotoStmt(Empty);
+      break;
+
+    case STMT_INDIRECT_GOTO:
+      S = new (Context) IndirectGotoStmt(Empty);
+      break;
+
+    case STMT_CONTINUE:
+      S = new (Context) ContinueStmt(Empty);
+      break;
+
+    case STMT_BREAK:
+      S = new (Context) BreakStmt(Empty);
+      break;
+
+    case STMT_RETURN:
+      S = new (Context) ReturnStmt(Empty);
+      break;
+
+    case STMT_DECL:
+      S = new (Context) DeclStmt(Empty);
+      break;
+
+    case STMT_ASM:
+      S = new (Context) AsmStmt(Empty);
+      break;
+
+    case EXPR_PREDEFINED:
+      S = new (Context) PredefinedExpr(Empty);
+      break;
+
+    case EXPR_DECL_REF:
+      S = DeclRefExpr::CreateEmpty(*Context,
+                         /*HasQualifier=*/Record[ASTStmtReader::NumExprFields],
+                  /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1]);
+      break;
+
+    case EXPR_INTEGER_LITERAL:
+      S = IntegerLiteral::Create(*Context, Empty);
+      break;
+
+    case EXPR_FLOATING_LITERAL:
+      S = FloatingLiteral::Create(*Context, Empty);
+      break;
+
+    case EXPR_IMAGINARY_LITERAL:
+      S = new (Context) ImaginaryLiteral(Empty);
+      break;
+
+    case EXPR_STRING_LITERAL:
+      S = StringLiteral::CreateEmpty(*Context,
+                                     Record[ASTStmtReader::NumExprFields + 1]);
+      break;
+
+    case EXPR_CHARACTER_LITERAL:
+      S = new (Context) CharacterLiteral(Empty);
+      break;
+
+    case EXPR_PAREN:
+      S = new (Context) ParenExpr(Empty);
+      break;
+
+    case EXPR_PAREN_LIST:
+      S = new (Context) ParenListExpr(Empty);
+      break;
+
+    case EXPR_UNARY_OPERATOR:
+      S = new (Context) UnaryOperator(Empty);
+      break;
+
+    case EXPR_OFFSETOF:
+      S = OffsetOfExpr::CreateEmpty(*Context, 
+                                    Record[ASTStmtReader::NumExprFields],
+                                    Record[ASTStmtReader::NumExprFields + 1]);
+      break;
+        
+    case EXPR_SIZEOF_ALIGN_OF:
+      S = new (Context) SizeOfAlignOfExpr(Empty);
+      break;
+
+    case EXPR_ARRAY_SUBSCRIPT:
+      S = new (Context) ArraySubscriptExpr(Empty);
+      break;
+
+    case EXPR_CALL:
+      S = new (Context) CallExpr(*Context, Stmt::CallExprClass, Empty);
+      break;
+
+    case EXPR_MEMBER: {
+      // We load everything here and fully initialize it at creation.
+      // That way we can use MemberExpr::Create and don't have to duplicate its
+      // logic with a MemberExpr::CreateEmpty.
+
+      assert(Idx == 0);
+      NestedNameSpecifier *NNS = 0;
+      SourceRange QualifierRange;
+      if (Record[Idx++]) { // HasQualifier.
+        NNS = ReadNestedNameSpecifier(Record, Idx);
+        QualifierRange = ReadSourceRange(Record, Idx);
+      }
+
+      TemplateArgumentListInfo ArgInfo;
+      unsigned NumTemplateArgs = Record[Idx++];
+      if (NumTemplateArgs) {
+        ArgInfo.setLAngleLoc(ReadSourceLocation(Record, Idx));
+        ArgInfo.setRAngleLoc(ReadSourceLocation(Record, Idx));
+        for (unsigned i = 0; i != NumTemplateArgs; ++i)
+          ArgInfo.addArgument(ReadTemplateArgumentLoc(Cursor, Record, Idx));
+      }
+      
+      NamedDecl *FoundD = cast_or_null<NamedDecl>(GetDecl(Record[Idx++]));
+      AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
+      DeclAccessPair FoundDecl = DeclAccessPair::make(FoundD, AS);
+
+      QualType T = GetType(Record[Idx++]);
+      Expr *Base = ReadSubExpr();
+      ValueDecl *MemberD = cast<ValueDecl>(GetDecl(Record[Idx++]));
+      // FIXME: read DeclarationNameLoc.
+      SourceLocation MemberLoc = ReadSourceLocation(Record, Idx);
+      DeclarationNameInfo MemberNameInfo(MemberD->getDeclName(), MemberLoc);
+      bool IsArrow = Record[Idx++];
+
+      S = MemberExpr::Create(*Context, Base, IsArrow, NNS, QualifierRange,
+                             MemberD, FoundDecl, MemberNameInfo,
+                             NumTemplateArgs ? &ArgInfo : 0, T);
+      break;
+    }
+
+    case EXPR_BINARY_OPERATOR:
+      S = new (Context) BinaryOperator(Empty);
+      break;
+
+    case EXPR_COMPOUND_ASSIGN_OPERATOR:
+      S = new (Context) CompoundAssignOperator(Empty);
+      break;
+
+    case EXPR_CONDITIONAL_OPERATOR:
+      S = new (Context) ConditionalOperator(Empty);
+      break;
+
+    case EXPR_IMPLICIT_CAST:
+      S = ImplicitCastExpr::CreateEmpty(*Context,
+                       /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
+      break;
+
+    case EXPR_CSTYLE_CAST:
+      S = CStyleCastExpr::CreateEmpty(*Context,
+                       /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
+      break;
+
+    case EXPR_COMPOUND_LITERAL:
+      S = new (Context) CompoundLiteralExpr(Empty);
+      break;
+
+    case EXPR_EXT_VECTOR_ELEMENT:
+      S = new (Context) ExtVectorElementExpr(Empty);
+      break;
+
+    case EXPR_INIT_LIST:
+      S = new (Context) InitListExpr(*getContext(), Empty);
+      break;
+
+    case EXPR_DESIGNATED_INIT:
+      S = DesignatedInitExpr::CreateEmpty(*Context,
+                                     Record[ASTStmtReader::NumExprFields] - 1);
+
+      break;
+
+    case EXPR_IMPLICIT_VALUE_INIT:
+      S = new (Context) ImplicitValueInitExpr(Empty);
+      break;
+
+    case EXPR_VA_ARG:
+      S = new (Context) VAArgExpr(Empty);
+      break;
+
+    case EXPR_ADDR_LABEL:
+      S = new (Context) AddrLabelExpr(Empty);
+      break;
+
+    case EXPR_STMT:
+      S = new (Context) StmtExpr(Empty);
+      break;
+
+    case EXPR_TYPES_COMPATIBLE:
+      S = new (Context) TypesCompatibleExpr(Empty);
+      break;
+
+    case EXPR_CHOOSE:
+      S = new (Context) ChooseExpr(Empty);
+      break;
+
+    case EXPR_GNU_NULL:
+      S = new (Context) GNUNullExpr(Empty);
+      break;
+
+    case EXPR_SHUFFLE_VECTOR:
+      S = new (Context) ShuffleVectorExpr(Empty);
+      break;
+
+    case EXPR_BLOCK:
+      S = new (Context) BlockExpr(Empty);
+      break;
+
+    case EXPR_BLOCK_DECL_REF:
+      S = new (Context) BlockDeclRefExpr(Empty);
+      break;
+
+    case EXPR_OBJC_STRING_LITERAL:
+      S = new (Context) ObjCStringLiteral(Empty);
+      break;
+    case EXPR_OBJC_ENCODE:
+      S = new (Context) ObjCEncodeExpr(Empty);
+      break;
+    case EXPR_OBJC_SELECTOR_EXPR:
+      S = new (Context) ObjCSelectorExpr(Empty);
+      break;
+    case EXPR_OBJC_PROTOCOL_EXPR:
+      S = new (Context) ObjCProtocolExpr(Empty);
+      break;
+    case EXPR_OBJC_IVAR_REF_EXPR:
+      S = new (Context) ObjCIvarRefExpr(Empty);
+      break;
+    case EXPR_OBJC_PROPERTY_REF_EXPR:
+      S = new (Context) ObjCPropertyRefExpr(Empty);
+      break;
+    case EXPR_OBJC_KVC_REF_EXPR:
+      S = new (Context) ObjCImplicitSetterGetterRefExpr(Empty);
+      break;
+    case EXPR_OBJC_MESSAGE_EXPR:
+      S = ObjCMessageExpr::CreateEmpty(*Context,
+                                     Record[ASTStmtReader::NumExprFields]);
+      break;
+    case EXPR_OBJC_SUPER_EXPR:
+      S = new (Context) ObjCSuperExpr(Empty);
+      break;
+    case EXPR_OBJC_ISA:
+      S = new (Context) ObjCIsaExpr(Empty);
+      break;
+    case STMT_OBJC_FOR_COLLECTION:
+      S = new (Context) ObjCForCollectionStmt(Empty);
+      break;
+    case STMT_OBJC_CATCH:
+      S = new (Context) ObjCAtCatchStmt(Empty);
+      break;
+    case STMT_OBJC_FINALLY:
+      S = new (Context) ObjCAtFinallyStmt(Empty);
+      break;
+    case STMT_OBJC_AT_TRY:
+      S = ObjCAtTryStmt::CreateEmpty(*Context, 
+                                     Record[ASTStmtReader::NumStmtFields],
+                                     Record[ASTStmtReader::NumStmtFields + 1]);
+      break;
+    case STMT_OBJC_AT_SYNCHRONIZED:
+      S = new (Context) ObjCAtSynchronizedStmt(Empty);
+      break;
+    case STMT_OBJC_AT_THROW:
+      S = new (Context) ObjCAtThrowStmt(Empty);
+      break;
+
+    case STMT_CXX_CATCH:
+      S = new (Context) CXXCatchStmt(Empty);
+      break;
+
+    case STMT_CXX_TRY:
+      S = CXXTryStmt::Create(*Context, Empty,
+             /*NumHandlers=*/Record[ASTStmtReader::NumStmtFields]);
+      break;
+
+    case EXPR_CXX_OPERATOR_CALL:
+      S = new (Context) CXXOperatorCallExpr(*Context, Empty);
+      break;
+
+    case EXPR_CXX_MEMBER_CALL:
+      S = new (Context) CXXMemberCallExpr(*Context, Empty);
+      break;
+        
+    case EXPR_CXX_CONSTRUCT:
+      S = new (Context) CXXConstructExpr(Empty);
+      break;
+      
+    case EXPR_CXX_TEMPORARY_OBJECT:
+      S = new (Context) CXXTemporaryObjectExpr(Empty);
+      break;
+
+    case EXPR_CXX_STATIC_CAST:
+      S = CXXStaticCastExpr::CreateEmpty(*Context,
+                       /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
+      break;
+
+    case EXPR_CXX_DYNAMIC_CAST:
+      S = CXXDynamicCastExpr::CreateEmpty(*Context,
+                       /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
+      break;
+
+    case EXPR_CXX_REINTERPRET_CAST:
+      S = CXXReinterpretCastExpr::CreateEmpty(*Context,
+                       /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
+      break;
+
+    case EXPR_CXX_CONST_CAST:
+      S = CXXConstCastExpr::CreateEmpty(*Context);
+      break;
+
+    case EXPR_CXX_FUNCTIONAL_CAST:
+      S = CXXFunctionalCastExpr::CreateEmpty(*Context,
+                       /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
+      break;
+
+    case EXPR_CXX_BOOL_LITERAL:
+      S = new (Context) CXXBoolLiteralExpr(Empty);
+      break;
+
+    case EXPR_CXX_NULL_PTR_LITERAL:
+      S = new (Context) CXXNullPtrLiteralExpr(Empty);
+      break;
+    case EXPR_CXX_TYPEID_EXPR:
+      S = new (Context) CXXTypeidExpr(Empty, true);
+      break;
+    case EXPR_CXX_TYPEID_TYPE:
+      S = new (Context) CXXTypeidExpr(Empty, false);
+      break;
+    case EXPR_CXX_THIS:
+      S = new (Context) CXXThisExpr(Empty);
+      break;
+    case EXPR_CXX_THROW:
+      S = new (Context) CXXThrowExpr(Empty);
+      break;
+    case EXPR_CXX_DEFAULT_ARG: {
+      bool HasOtherExprStored = Record[ASTStmtReader::NumExprFields];
+      if (HasOtherExprStored) {
+        Expr *SubExpr = ReadSubExpr();
+        S = CXXDefaultArgExpr::Create(*Context, SourceLocation(), 0, SubExpr);
+      } else
+        S = new (Context) CXXDefaultArgExpr(Empty);
+      break;
+    }
+    case EXPR_CXX_BIND_TEMPORARY:
+      S = new (Context) CXXBindTemporaryExpr(Empty);
+      break;
+    case EXPR_CXX_BIND_REFERENCE:
+      S = new (Context) CXXBindReferenceExpr(Empty);
+      break;
+
+    case EXPR_CXX_SCALAR_VALUE_INIT:
+      S = new (Context) CXXScalarValueInitExpr(Empty);
+      break;
+    case EXPR_CXX_NEW:
+      S = new (Context) CXXNewExpr(Empty);
+      break;
+    case EXPR_CXX_DELETE:
+      S = new (Context) CXXDeleteExpr(Empty);
+      break;
+    case EXPR_CXX_PSEUDO_DESTRUCTOR:
+      S = new (Context) CXXPseudoDestructorExpr(Empty);
+      break;
+        
+    case EXPR_CXX_EXPR_WITH_TEMPORARIES:
+      S = new (Context) CXXExprWithTemporaries(Empty);
+      break;
+      
+    case EXPR_CXX_DEPENDENT_SCOPE_MEMBER:
+      S = CXXDependentScopeMemberExpr::CreateEmpty(*Context,
+                      /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]);
+      break;
+      
+    case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF:
+      S = DependentScopeDeclRefExpr::CreateEmpty(*Context,
+                      /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]);
+      break;
+      
+    case EXPR_CXX_UNRESOLVED_CONSTRUCT:
+      S = CXXUnresolvedConstructExpr::CreateEmpty(*Context,
+                              /*NumArgs=*/Record[ASTStmtReader::NumExprFields]);
+      break;
+      
+    case EXPR_CXX_UNRESOLVED_MEMBER:
+      S = UnresolvedMemberExpr::CreateEmpty(*Context,
+                      /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]);
+      break;
+      
+    case EXPR_CXX_UNRESOLVED_LOOKUP:
+      S = UnresolvedLookupExpr::CreateEmpty(*Context,
+                      /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]);
+      break;
+      
+    case EXPR_CXX_UNARY_TYPE_TRAIT:
+      S = new (Context) UnaryTypeTraitExpr(Empty);
+      break;
+    }
+    
+    // We hit a STMT_STOP, so we're done with this expression.
+    if (Finished)
+      break;
+
+    ++NumStatementsRead;
+
+    if (S)
+      Reader.Visit(S);
+
+    assert(Idx == Record.size() && "Invalid deserialization of statement");
+    StmtStack.push_back(S);
+  }
+
+#ifndef NDEBUG
+  assert(StmtStack.size() > PrevNumStmts && "Read too many sub stmts!");
+  assert(StmtStack.size() == PrevNumStmts + 1 && "Extra expressions on stack!");
+#endif
+
+  return StmtStack.pop_back_val();
+}
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
new file mode 100644
index 0000000..efc7da7
--- /dev/null
+++ b/lib/Serialization/ASTWriter.cpp
@@ -0,0 +1,3119 @@
+//===--- ASTWriter.cpp - AST File 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 ASTWriter class, which writes AST files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Serialization/ASTWriter.h"
+#include "ASTCommon.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/IdentifierResolver.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclContextInternals.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLocVisitor.h"
+#include "clang/Serialization/ASTReader.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;
+using namespace clang::serialization;
+
+template <typename T, typename Allocator>
+T *data(std::vector<T, Allocator> &v) {
+  return v.empty() ? 0 : &v.front();
+}
+template <typename T, typename Allocator>
+const T *data(const std::vector<T, Allocator> &v) {
+  return v.empty() ? 0 : &v.front();
+}
+
+//===----------------------------------------------------------------------===//
+// Type serialization
+//===----------------------------------------------------------------------===//
+
+namespace {
+  class ASTTypeWriter {
+    ASTWriter &Writer;
+    ASTWriter::RecordData &Record;
+
+  public:
+    /// \brief Type code that corresponds to the record generated.
+    TypeCode Code;
+
+    ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
+      : Writer(Writer), Record(Record), Code(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)
+#include "clang/AST/TypeNodes.def"
+  };
+}
+
+void ASTTypeWriter::VisitBuiltinType(const BuiltinType *T) {
+  assert(false && "Built-in types are never serialized");
+}
+
+void ASTTypeWriter::VisitComplexType(const ComplexType *T) {
+  Writer.AddTypeRef(T->getElementType(), Record);
+  Code = TYPE_COMPLEX;
+}
+
+void ASTTypeWriter::VisitPointerType(const PointerType *T) {
+  Writer.AddTypeRef(T->getPointeeType(), Record);
+  Code = TYPE_POINTER;
+}
+
+void ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) {
+  Writer.AddTypeRef(T->getPointeeType(), Record);
+  Code = TYPE_BLOCK_POINTER;
+}
+
+void ASTTypeWriter::VisitLValueReferenceType(const LValueReferenceType *T) {
+  Writer.AddTypeRef(T->getPointeeType(), Record);
+  Code = TYPE_LVALUE_REFERENCE;
+}
+
+void ASTTypeWriter::VisitRValueReferenceType(const RValueReferenceType *T) {
+  Writer.AddTypeRef(T->getPointeeType(), Record);
+  Code = TYPE_RVALUE_REFERENCE;
+}
+
+void ASTTypeWriter::VisitMemberPointerType(const MemberPointerType *T) {
+  Writer.AddTypeRef(T->getPointeeType(), Record);
+  Writer.AddTypeRef(QualType(T->getClass(), 0), Record);
+  Code = TYPE_MEMBER_POINTER;
+}
+
+void ASTTypeWriter::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 ASTTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) {
+  VisitArrayType(T);
+  Writer.AddAPInt(T->getSize(), Record);
+  Code = TYPE_CONSTANT_ARRAY;
+}
+
+void ASTTypeWriter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
+  VisitArrayType(T);
+  Code = TYPE_INCOMPLETE_ARRAY;
+}
+
+void ASTTypeWriter::VisitVariableArrayType(const VariableArrayType *T) {
+  VisitArrayType(T);
+  Writer.AddSourceLocation(T->getLBracketLoc(), Record);
+  Writer.AddSourceLocation(T->getRBracketLoc(), Record);
+  Writer.AddStmt(T->getSizeExpr());
+  Code = TYPE_VARIABLE_ARRAY;
+}
+
+void ASTTypeWriter::VisitVectorType(const VectorType *T) {
+  Writer.AddTypeRef(T->getElementType(), Record);
+  Record.push_back(T->getNumElements());
+  Record.push_back(T->getAltiVecSpecific());
+  Code = TYPE_VECTOR;
+}
+
+void ASTTypeWriter::VisitExtVectorType(const ExtVectorType *T) {
+  VisitVectorType(T);
+  Code = TYPE_EXT_VECTOR;
+}
+
+void ASTTypeWriter::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 ASTTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
+  VisitFunctionType(T);
+  Code = TYPE_FUNCTION_NO_PROTO;
+}
+
+void ASTTypeWriter::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 = TYPE_FUNCTION_PROTO;
+}
+
+void ASTTypeWriter::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
+  Writer.AddDeclRef(T->getDecl(), Record);
+  Code = TYPE_UNRESOLVED_USING;
+}
+
+void ASTTypeWriter::VisitTypedefType(const TypedefType *T) {
+  Writer.AddDeclRef(T->getDecl(), Record);
+  assert(!T->isCanonicalUnqualified() && "Invalid typedef ?");
+  Writer.AddTypeRef(T->getCanonicalTypeInternal(), Record);
+  Code = TYPE_TYPEDEF;
+}
+
+void ASTTypeWriter::VisitTypeOfExprType(const TypeOfExprType *T) {
+  Writer.AddStmt(T->getUnderlyingExpr());
+  Code = TYPE_TYPEOF_EXPR;
+}
+
+void ASTTypeWriter::VisitTypeOfType(const TypeOfType *T) {
+  Writer.AddTypeRef(T->getUnderlyingType(), Record);
+  Code = TYPE_TYPEOF;
+}
+
+void ASTTypeWriter::VisitDecltypeType(const DecltypeType *T) {
+  Writer.AddStmt(T->getUnderlyingExpr());
+  Code = TYPE_DECLTYPE;
+}
+
+void ASTTypeWriter::VisitTagType(const TagType *T) {
+  Record.push_back(T->isDependentType());
+  Writer.AddDeclRef(T->getDecl(), Record);
+  assert(!T->isBeingDefined() &&
+         "Cannot serialize in the middle of a type definition");
+}
+
+void ASTTypeWriter::VisitRecordType(const RecordType *T) {
+  VisitTagType(T);
+  Code = TYPE_RECORD;
+}
+
+void ASTTypeWriter::VisitEnumType(const EnumType *T) {
+  VisitTagType(T);
+  Code = TYPE_ENUM;
+}
+
+void
+ASTTypeWriter::VisitSubstTemplateTypeParmType(
+                                        const SubstTemplateTypeParmType *T) {
+  Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record);
+  Writer.AddTypeRef(T->getReplacementType(), Record);
+  Code = TYPE_SUBST_TEMPLATE_TYPE_PARM;
+}
+
+void
+ASTTypeWriter::VisitTemplateSpecializationType(
+                                       const TemplateSpecializationType *T) {
+  Record.push_back(T->isDependentType());
+  Writer.AddTemplateName(T->getTemplateName(), Record);
+  Record.push_back(T->getNumArgs());
+  for (TemplateSpecializationType::iterator ArgI = T->begin(), ArgE = T->end();
+         ArgI != ArgE; ++ArgI)
+    Writer.AddTemplateArgument(*ArgI, Record);
+  Writer.AddTypeRef(T->isCanonicalUnqualified() ? QualType()
+                                                : T->getCanonicalTypeInternal(),
+                    Record);
+  Code = TYPE_TEMPLATE_SPECIALIZATION;
+}
+
+void
+ASTTypeWriter::VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
+  VisitArrayType(T);
+  Writer.AddStmt(T->getSizeExpr());
+  Writer.AddSourceRange(T->getBracketsRange(), Record);
+  Code = TYPE_DEPENDENT_SIZED_ARRAY;
+}
+
+void
+ASTTypeWriter::VisitDependentSizedExtVectorType(
+                                        const DependentSizedExtVectorType *T) {
+  // FIXME: Serialize this type (C++ only)
+  assert(false && "Cannot serialize dependent sized extended vector types");
+}
+
+void
+ASTTypeWriter::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
+  Record.push_back(T->getDepth());
+  Record.push_back(T->getIndex());
+  Record.push_back(T->isParameterPack());
+  Writer.AddIdentifierRef(T->getName(), Record);
+  Code = TYPE_TEMPLATE_TYPE_PARM;
+}
+
+void
+ASTTypeWriter::VisitDependentNameType(const DependentNameType *T) {
+  Record.push_back(T->getKeyword());
+  Writer.AddNestedNameSpecifier(T->getQualifier(), Record);
+  Writer.AddIdentifierRef(T->getIdentifier(), Record);
+  Writer.AddTypeRef(T->isCanonicalUnqualified() ? QualType()
+                                                : T->getCanonicalTypeInternal(),
+                    Record);
+  Code = TYPE_DEPENDENT_NAME;
+}
+
+void
+ASTTypeWriter::VisitDependentTemplateSpecializationType(
+                                const DependentTemplateSpecializationType *T) {
+  Record.push_back(T->getKeyword());
+  Writer.AddNestedNameSpecifier(T->getQualifier(), Record);
+  Writer.AddIdentifierRef(T->getIdentifier(), Record);
+  Record.push_back(T->getNumArgs());
+  for (DependentTemplateSpecializationType::iterator
+         I = T->begin(), E = T->end(); I != E; ++I)
+    Writer.AddTemplateArgument(*I, Record);
+  Code = TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION;
+}
+
+void ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) {
+  Record.push_back(T->getKeyword());
+  Writer.AddNestedNameSpecifier(T->getQualifier(), Record);
+  Writer.AddTypeRef(T->getNamedType(), Record);
+  Code = TYPE_ELABORATED;
+}
+
+void ASTTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) {
+  Writer.AddDeclRef(T->getDecl(), Record);
+  Writer.AddTypeRef(T->getInjectedSpecializationType(), Record);
+  Code = TYPE_INJECTED_CLASS_NAME;
+}
+
+void ASTTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
+  Writer.AddDeclRef(T->getDecl(), Record);
+  Code = TYPE_OBJC_INTERFACE;
+}
+
+void ASTTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) {
+  Writer.AddTypeRef(T->getBaseType(), Record);
+  Record.push_back(T->getNumProtocols());
+  for (ObjCObjectType::qual_iterator I = T->qual_begin(),
+       E = T->qual_end(); I != E; ++I)
+    Writer.AddDeclRef(*I, Record);
+  Code = TYPE_OBJC_OBJECT;
+}
+
+void
+ASTTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
+  Writer.AddTypeRef(T->getPointeeType(), Record);
+  Code = TYPE_OBJC_OBJECT_POINTER;
+}
+
+namespace {
+
+class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> {
+  ASTWriter &Writer;
+  ASTWriter::RecordData &Record;
+
+public:
+  TypeLocWriter(ASTWriter &Writer, ASTWriter::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::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.AddTemplateArgumentLocInfo(TL.getArgLoc(i).getArgument().getKind(),
+                                      TL.getArgLoc(i).getLocInfo(), Record);
+}
+void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getKeywordLoc(), Record);
+  Writer.AddSourceRange(TL.getQualifierRange(), Record);
+}
+void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getKeywordLoc(), Record);
+  Writer.AddSourceRange(TL.getQualifierRange(), Record);
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc(
+       DependentTemplateSpecializationTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getKeywordLoc(), Record);
+  Writer.AddSourceRange(TL.getQualifierRange(), Record);
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+  Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
+  Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
+  for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
+    Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(I).getArgument().getKind(),
+                                      TL.getArgLoc(I).getLocInfo(), Record);
+}
+void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
+  Record.push_back(TL.hasBaseTypeAsWritten());
+  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);
+}
+
+//===----------------------------------------------------------------------===//
+// ASTWriter Implementation
+//===----------------------------------------------------------------------===//
+
+static void EmitBlockID(unsigned ID, const char *Name,
+                        llvm::BitstreamWriter &Stream,
+                        ASTWriter::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,
+                         ASTWriter::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,
+                          ASTWriter::RecordData &Record) {
+#define RECORD(X) EmitRecordID(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 ASTWriter::WriteBlockInfoBlock() {
+  RecordData Record;
+  Stream.EnterSubblock(llvm::bitc::BLOCKINFO_BLOCK_ID, 3);
+
+#define BLOCK(X) EmitBlockID(X ## _ID, #X, Stream, Record)
+#define RECORD(X) EmitRecordID(X, #X, Stream, Record)
+
+  // AST Top-Level Block.
+  BLOCK(AST_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_FILESCOPED_DECLS);
+  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(MACRO_DEFINITION_OFFSETS);
+  RECORD(CHAINED_METADATA);
+  RECORD(REFERENCED_SELECTOR_POOL);
+  
+  // 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);
+  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 AST metadata (e.g., i686-apple-darwin9).
+void ASTWriter::WriteMetadata(ASTContext &Context, const char *isysroot) {
+  using namespace llvm;
+
+  // Metadata
+  const TargetInfo &Target = Context.Target;
+  BitCodeAbbrev *MetaAbbrev = new BitCodeAbbrev();
+  MetaAbbrev->Add(BitCodeAbbrevOp(
+                    Chain ? CHAINED_METADATA : METADATA));
+  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST major
+  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST minor
+  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major
+  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor
+  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable
+  // Target triple or chained PCH name
+  MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+  unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev);
+
+  RecordData Record;
+  Record.push_back(Chain ? CHAINED_METADATA : METADATA);
+  Record.push_back(VERSION_MAJOR);
+  Record.push_back(VERSION_MINOR);
+  Record.push_back(CLANG_VERSION_MAJOR);
+  Record.push_back(CLANG_VERSION_MINOR);
+  Record.push_back(isysroot != 0);
+  // FIXME: This writes the absolute path for chained headers.
+  const std::string &BlobStr = Chain ? Chain->getFileName() : Target.getTriple().getTriple();
+  Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, BlobStr);
+
+  // Original file name
+  SourceManager &SM = Context.getSourceManager();
+  if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
+    BitCodeAbbrev *FileAbbrev = new BitCodeAbbrev();
+    FileAbbrev->Add(BitCodeAbbrevOp(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(ORIGINAL_FILE_NAME);
+    Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileNameStr);
+  }
+
+  // Repository branch/version information.
+  BitCodeAbbrev *RepoAbbrev = new BitCodeAbbrev();
+  RepoAbbrev->Add(BitCodeAbbrevOp(VERSION_CONTROL_BRANCH_REVISION));
+  RepoAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag
+  unsigned RepoAbbrevCode = Stream.EmitAbbrev(RepoAbbrev);
+  Record.clear();
+  Record.push_back(VERSION_CONTROL_BRANCH_REVISION);
+  Stream.EmitRecordWithBlob(RepoAbbrevCode, Record,
+                            getClangFullRepositoryVersion());
+}
+
+/// \brief Write the LangOptions structure.
+void ASTWriter::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.getSignedOverflowBehavior());
+  Record.push_back(LangOpts.HeinousExtensions);
+
+  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);
+  Record.push_back(LangOpts.SpellChecking);
+  Stream.EmitRecord(LANGUAGE_OPTIONS, Record);
+}
+
+//===----------------------------------------------------------------------===//
+// stat cache Serialization
+//===----------------------------------------------------------------------===//
+
+namespace {
+// Trait used for the on-disk hash table of stat cache results.
+class ASTStatCacheTrait {
+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 AST file.
+void ASTWriter::WriteStatCache(MemorizeStatCalls &StatCalls) {
+  // Build the on-disk hash table containing information about every
+  // stat() call.
+  OnDiskChainedHashTableGenerator<ASTStatCacheTrait> Generator;
+  unsigned NumStatEntries = 0;
+  for (MemorizeStatCalls::iterator Stat = StatCalls.begin(),
+                                StatEnd = StatCalls.end();
+       Stat != StatEnd; ++Stat, ++NumStatEntries) {
+    const char *Filename = Stat->first();
+    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(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(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(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(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(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(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 ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
+                                        const Preprocessor &PP,
+                                        const char *isysroot) {
+  RecordData Record;
+
+  // Enter the source manager block.
+  Stream.EnterSubblock(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(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;
+  unsigned BaseSLocID = Chain ? Chain->getTotalNumSLocs() : 0;
+  SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1 - BaseSLocID);
+  for (unsigned I = BaseSLocID + 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 = SM_SLOC_FILE_ENTRY;
+      else
+        Code = SM_SLOC_BUFFER_ENTRY;
+    } else
+      Code = 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(BaseSLocID + 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(SM_SLOC_BUFFER_BLOB);
+        Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record,
+                                  llvm::StringRef(Buffer->getBufferStart(),
+                                                  Buffer->getBufferSize() + 1));
+
+        if (strcmp(Name, "<built-in>") == 0)
+          PreloadSLocs.push_back(BaseSLocID + 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 AST block. This
+  // table is used for lazily loading source-location information.
+  using namespace llvm;
+  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+  Abbrev->Add(BitCodeAbbrevOp(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(SOURCE_LOCATION_OFFSETS);
+  Record.push_back(SLocEntryOffsets.size());
+  Record.push_back(SourceMgr.getNextOffset());
+  Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record,
+                            (const char *)data(SLocEntryOffsets),
+                           SLocEntryOffsets.size()*sizeof(SLocEntryOffsets[0]));
+
+  // Write the source location entry preloads array, telling the AST
+  // reader which source locations entries it should load eagerly.
+  Stream.EmitRecord(SOURCE_LOCATION_PRELOADS, PreloadSLocs);
+}
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Serialization
+//===----------------------------------------------------------------------===//
+
+/// \brief Writes the block containing the serialized form of the
+/// preprocessor.
+///
+void ASTWriter::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(PP_COUNTER_VALUE, Record);
+    Record.clear();
+  }
+
+  // Enter the preprocessor block.
+  Stream.EnterSubblock(PREPROCESSOR_BLOCK_ID, 2);
+
+  // If the AST 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 AST file unless they have
+    // been redefined by the header (in which case they are not isBuiltinMacro).
+    // Also skip macros from a AST file if we're chaining.
+    if (MI->isBuiltinMacro() || (Chain && MI->isFromAST()))
+      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 = PP_MACRO_OBJECT_LIKE;
+    } else {
+      Code = 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(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(PP_MACRO_INSTANTIATION, Record);
+        continue;
+      }
+      
+      if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
+        // Record this macro definition's location.
+        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(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(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(MACRO_DEFINITION_OFFSETS);
+    Record.push_back(NumPreprocessingRecords);
+    Record.push_back(MacroDefinitionOffsets.size());
+    Stream.EmitRecordWithBlob(MacroDefOffsetAbbrev, Record,
+                              (const char *)data(MacroDefinitionOffsets),
+                              MacroDefinitionOffsets.size() * sizeof(uint32_t));
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Type Serialization
+//===----------------------------------------------------------------------===//
+
+/// \brief Write the representation of a type to the AST stream.
+void ASTWriter::WriteType(QualType T) {
+  TypeIdx &Idx = TypeIdxs[T];
+  if (Idx.getIndex() == 0) // we haven't seen this type before.
+    Idx = TypeIdx(NextTypeID++);
+
+  // Record the offset for this type.
+  unsigned Index = Idx.getIndex() - FirstTypeID;
+  if (TypeOffsets.size() == Index)
+    TypeOffsets.push_back(Stream.GetCurrentBitNo());
+  else if (TypeOffsets.size() < Index) {
+    TypeOffsets.resize(Index + 1);
+    TypeOffsets[Index] = Stream.GetCurrentBitNo();
+  }
+
+  RecordData Record;
+
+  // Emit the type's representation.
+  ASTTypeWriter W(*this, Record);
+
+  if (T.hasLocalNonFastQualifiers()) {
+    Qualifiers Qs = T.getLocalQualifiers();
+    AddTypeRef(T.getLocalUnqualifiedType(), Record);
+    Record.push_back(Qs.getAsOpaqueValue());
+    W.Code = 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)
+#include "clang/AST/TypeNodes.def"
+    }
+  }
+
+  // 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 ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
+                                                 DeclContext *DC) {
+  if (DC->decls_empty())
+    return 0;
+
+  uint64_t Offset = Stream.GetCurrentBitNo();
+  RecordData Record;
+  Record.push_back(DECL_CONTEXT_LEXICAL);
+  llvm::SmallVector<DeclID, 64> Decls;
+  for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
+         D != DEnd; ++D)
+    Decls.push_back(GetDeclRef(*D));
+
+  ++NumLexicalDeclContexts;
+  Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record,
+     reinterpret_cast<char*>(Decls.data()), Decls.size() * sizeof(DeclID));
+  return Offset;
+}
+
+void ASTWriter::WriteTypeDeclOffsets() {
+  using namespace llvm;
+  RecordData Record;
+
+  // Write the type offsets array
+  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+  Abbrev->Add(BitCodeAbbrevOp(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(TYPE_OFFSET);
+  Record.push_back(TypeOffsets.size());
+  Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record,
+                            (const char *)data(TypeOffsets),
+                            TypeOffsets.size() * sizeof(TypeOffsets[0]));
+
+  // Write the declaration offsets array
+  Abbrev = new BitCodeAbbrev();
+  Abbrev->Add(BitCodeAbbrevOp(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(DECL_OFFSET);
+  Record.push_back(DeclOffsets.size());
+  Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record,
+                            (const char *)data(DeclOffsets),
+                            DeclOffsets.size() * sizeof(DeclOffsets[0]));
+}
+
+//===----------------------------------------------------------------------===//
+// Global Method Pool and Selector Serialization
+//===----------------------------------------------------------------------===//
+
+namespace {
+// Trait used for the on-disk hash table used in the method pool.
+class ASTMethodPoolTrait {
+  ASTWriter &Writer;
+
+public:
+  typedef Selector key_type;
+  typedef key_type key_type_ref;
+
+  struct data_type {
+    SelectorID ID;
+    ObjCMethodList Instance, Factory;
+  };
+  typedef const data_type& data_type_ref;
+
+  explicit ASTMethodPoolTrait(ASTWriter &Writer) : Writer(Writer) { }
+
+  static unsigned ComputeHash(Selector Sel) {
+    return serialization::ComputeHash(Sel);
+  }
+
+  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 = 4 + 2 + 2; // 2 bytes for each of the method counts
+    for (const ObjCMethodList *Method = &Methods.Instance; Method;
+         Method = Method->Next)
+      if (Method->Method)
+        DataLen += 4;
+    for (const ObjCMethodList *Method = &Methods.Factory; 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;
+    clang::io::Emit32(Out, Methods.ID);
+    unsigned NumInstanceMethods = 0;
+    for (const ObjCMethodList *Method = &Methods.Instance; Method;
+         Method = Method->Next)
+      if (Method->Method)
+        ++NumInstanceMethods;
+
+    unsigned NumFactoryMethods = 0;
+    for (const ObjCMethodList *Method = &Methods.Factory; Method;
+         Method = Method->Next)
+      if (Method->Method)
+        ++NumFactoryMethods;
+
+    clang::io::Emit16(Out, NumInstanceMethods);
+    clang::io::Emit16(Out, NumFactoryMethods);
+    for (const ObjCMethodList *Method = &Methods.Instance; Method;
+         Method = Method->Next)
+      if (Method->Method)
+        clang::io::Emit32(Out, Writer.getDeclID(Method->Method));
+    for (const ObjCMethodList *Method = &Methods.Factory; 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 ObjC data: selectors and the method pool.
+///
+/// The method pool contains both instance and factory methods, stored
+/// in an on-disk hash table indexed by the selector. The hash table also
+/// contains an empty entry for every other selector known to Sema.
+void ASTWriter::WriteSelectors(Sema &SemaRef) {
+  using namespace llvm;
+
+  // Do we have to do anything at all?
+  if (SemaRef.MethodPool.empty() && SelectorIDs.empty())
+    return;
+  unsigned NumTableEntries = 0;
+  // Create and write out the blob that contains selectors and the method pool.
+  {
+    OnDiskChainedHashTableGenerator<ASTMethodPoolTrait> Generator;
+    ASTMethodPoolTrait Trait(*this);
+
+    // Create the on-disk hash table representation. We walk through every
+    // selector we've seen and look it up in the method pool.
+    SelectorOffsets.resize(NextSelectorID - FirstSelectorID);
+    for (llvm::DenseMap<Selector, SelectorID>::iterator
+             I = SelectorIDs.begin(), E = SelectorIDs.end();
+         I != E; ++I) {
+      Selector S = I->first;
+      Sema::GlobalMethodPool::iterator F = SemaRef.MethodPool.find(S);
+      ASTMethodPoolTrait::data_type Data = {
+        I->second,
+        ObjCMethodList(),
+        ObjCMethodList()
+      };
+      if (F != SemaRef.MethodPool.end()) {
+        Data.Instance = F->second.first;
+        Data.Factory = F->second.second;
+      }
+      // Only write this selector if it's not in an existing AST or something
+      // changed.
+      if (Chain && I->second < FirstSelectorID) {
+        // Selector already exists. Did it change?
+        bool changed = false;
+        for (ObjCMethodList *M = &Data.Instance; !changed && M && M->Method;
+             M = M->Next) {
+          if (M->Method->getPCHLevel() == 0)
+            changed = true;
+        }
+        for (ObjCMethodList *M = &Data.Factory; !changed && M && M->Method;
+             M = M->Next) {
+          if (M->Method->getPCHLevel() == 0)
+            changed = true;
+        }
+        if (!changed)
+          continue;
+      } else if (Data.Instance.Method || Data.Factory.Method) {
+        // A new method pool entry.
+        ++NumTableEntries;
+      }
+      Generator.insert(S, Data, Trait);
+    }
+
+    // Create the on-disk hash table in a buffer.
+    llvm::SmallString<4096> MethodPool;
+    uint32_t BucketOffset;
+    {
+      ASTMethodPoolTrait 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);
+    }
+
+    // Create a blob abbreviation
+    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+    Abbrev->Add(BitCodeAbbrevOp(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(METHOD_POOL);
+    Record.push_back(BucketOffset);
+    Record.push_back(NumTableEntries);
+    Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool.str());
+
+    // Create a blob abbreviation for the selector table offsets.
+    Abbrev = new BitCodeAbbrev();
+    Abbrev->Add(BitCodeAbbrevOp(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(SELECTOR_OFFSETS);
+    Record.push_back(SelectorOffsets.size());
+    Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record,
+                              (const char *)data(SelectorOffsets),
+                              SelectorOffsets.size() * 4);
+  }
+}
+
+/// \brief Write the selectors referenced in @selector expression into AST file.
+void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) {
+  using namespace llvm;
+  if (SemaRef.ReferencedSelectors.empty())
+    return;
+
+  RecordData Record;
+
+  // Note: this writes out all references even for a dependent AST. But it is
+  // very tricky to fix, and given that @selector shouldn't really appear in
+  // headers, probably not worth it. It's not a correctness issue.
+  for (DenseMap<Selector, SourceLocation>::iterator S =
+       SemaRef.ReferencedSelectors.begin(),
+       E = SemaRef.ReferencedSelectors.end(); S != E; ++S) {
+    Selector Sel = (*S).first;
+    SourceLocation Loc = (*S).second;
+    AddSelectorRef(Sel, Record);
+    AddSourceLocation(Loc, Record);
+  }
+  Stream.EmitRecord(REFERENCED_SELECTOR_POOL, Record);
+}
+
+//===----------------------------------------------------------------------===//
+// Identifier Table Serialization
+//===----------------------------------------------------------------------===//
+
+namespace {
+class ASTIdentifierTableTrait {
+  ASTWriter &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 IdentID data_type;
+  typedef data_type data_type_ref;
+
+  ASTIdentifierTableTrait(ASTWriter &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,
+                      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(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,
+                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->hasRevertedTokenIDToIdentifier());
+    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").
+    // Only emit declarations that aren't from a chained PCH, though.
+    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 AST 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 ASTWriter::WriteIdentifierTable(Preprocessor &PP) {
+  using namespace llvm;
+
+  // Create and write out the blob that contains the identifier
+  // strings.
+  {
+    OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator;
+    ASTIdentifierTableTrait Trait(*this, PP);
+
+    // 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 AST
+    // 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. We only store offsets
+    // for identifiers that appear here for the first time.
+    IdentifierOffsets.resize(NextIdentID - FirstIdentID);
+    for (llvm::DenseMap<const IdentifierInfo *, IdentID>::iterator
+           ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end();
+         ID != IDEnd; ++ID) {
+      assert(ID->first && "NULL identifier in identifier table");
+      if (!Chain || !ID->first->isFromAST())
+        Generator.insert(ID->first, ID->second, Trait);
+    }
+
+    // Create the on-disk hash table in a buffer.
+    llvm::SmallString<4096> IdentifierTable;
+    uint32_t BucketOffset;
+    {
+      ASTIdentifierTableTrait 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(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(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(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(IDENTIFIER_OFFSET);
+  Record.push_back(IdentifierOffsets.size());
+  Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record,
+                            (const char *)data(IdentifierOffsets),
+                            IdentifierOffsets.size() * sizeof(uint32_t));
+}
+
+//===----------------------------------------------------------------------===//
+// DeclContext's Name Lookup Table Serialization
+//===----------------------------------------------------------------------===//
+
+namespace {
+// Trait used for the on-disk hash table used in the method pool.
+class ASTDeclContextNameLookupTrait {
+  ASTWriter &Writer;
+
+public:
+  typedef DeclarationName key_type;
+  typedef key_type key_type_ref;
+
+  typedef DeclContext::lookup_result data_type;
+  typedef const data_type& data_type_ref;
+
+  explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) { }
+
+  unsigned ComputeHash(DeclarationName Name) {
+    llvm::FoldingSetNodeID ID;
+    ID.AddInteger(Name.getNameKind());
+
+    switch (Name.getNameKind()) {
+    case DeclarationName::Identifier:
+      ID.AddString(Name.getAsIdentifierInfo()->getName());
+      break;
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+      ID.AddInteger(serialization::ComputeHash(Name.getObjCSelector()));
+      break;
+    case DeclarationName::CXXConstructorName:
+    case DeclarationName::CXXDestructorName:
+    case DeclarationName::CXXConversionFunctionName:
+      ID.AddInteger(Writer.GetOrCreateTypeID(Name.getCXXNameType()));
+      break;
+    case DeclarationName::CXXOperatorName:
+      ID.AddInteger(Name.getCXXOverloadedOperator());
+      break;
+    case DeclarationName::CXXLiteralOperatorName:
+      ID.AddString(Name.getCXXLiteralIdentifier()->getName());
+    case DeclarationName::CXXUsingDirective:
+      break;
+    }
+
+    return ID.ComputeHash();
+  }
+
+  std::pair<unsigned,unsigned>
+    EmitKeyDataLength(llvm::raw_ostream& Out, DeclarationName Name,
+                      data_type_ref Lookup) {
+    unsigned KeyLen = 1;
+    switch (Name.getNameKind()) {
+    case DeclarationName::Identifier:
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+    case DeclarationName::CXXConstructorName:
+    case DeclarationName::CXXDestructorName:
+    case DeclarationName::CXXConversionFunctionName:
+    case DeclarationName::CXXLiteralOperatorName:
+      KeyLen += 4;
+      break;
+    case DeclarationName::CXXOperatorName:
+      KeyLen += 1;
+      break;
+    case DeclarationName::CXXUsingDirective:
+      break;
+    }
+    clang::io::Emit16(Out, KeyLen);
+
+    // 2 bytes for num of decls and 4 for each DeclID.
+    unsigned DataLen = 2 + 4 * (Lookup.second - Lookup.first);
+    clang::io::Emit16(Out, DataLen);
+
+    return std::make_pair(KeyLen, DataLen);
+  }
+
+  void EmitKey(llvm::raw_ostream& Out, DeclarationName Name, unsigned) {
+    using namespace clang::io;
+
+    assert(Name.getNameKind() < 0x100 && "Invalid name kind ?");
+    Emit8(Out, Name.getNameKind());
+    switch (Name.getNameKind()) {
+    case DeclarationName::Identifier:
+      Emit32(Out, Writer.getIdentifierRef(Name.getAsIdentifierInfo()));
+      break;
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+      Emit32(Out, Writer.getSelectorRef(Name.getObjCSelector()));
+      break;
+    case DeclarationName::CXXConstructorName:
+    case DeclarationName::CXXDestructorName:
+    case DeclarationName::CXXConversionFunctionName:
+      Emit32(Out, Writer.getTypeID(Name.getCXXNameType()));
+      break;
+    case DeclarationName::CXXOperatorName:
+      assert(Name.getCXXOverloadedOperator() < 0x100 && "Invalid operator ?");
+      Emit8(Out, Name.getCXXOverloadedOperator());
+      break;
+    case DeclarationName::CXXLiteralOperatorName:
+      Emit32(Out, Writer.getIdentifierRef(Name.getCXXLiteralIdentifier()));
+      break;
+    case DeclarationName::CXXUsingDirective:
+      break;
+    }
+  }
+
+  void EmitData(llvm::raw_ostream& Out, key_type_ref,
+                data_type Lookup, unsigned DataLen) {
+    uint64_t Start = Out.tell(); (void)Start;
+    clang::io::Emit16(Out, Lookup.second - Lookup.first);
+    for (; Lookup.first != Lookup.second; ++Lookup.first)
+      clang::io::Emit32(Out, Writer.GetDeclRef(*Lookup.first));
+
+    assert(Out.tell() - Start == DataLen && "Data length is wrong");
+  }
+};
+} // end anonymous namespace
+
+/// \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
+/// bitstream, or 0 if no block was written.
+uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
+                                                 DeclContext *DC) {
+  if (DC->getPrimaryContext() != DC)
+    return 0;
+
+  // Since there is no name lookup into functions or methods, don't bother to
+  // build a visible-declarations table for these entities.
+  if (DC->isFunctionOrMethod())
+    return 0;
+
+  // If not in C++, we perform name lookup for the translation unit via the
+  // IdentifierInfo chains, don't bother to build a visible-declarations table.
+  // FIXME: In C++ we need the visible declarations in order to "see" the
+  // friend declarations, is there a way to do this without writing the table ?
+  if (DC->isTranslationUnit() && !Context.getLangOptions().CPlusPlus)
+    return 0;
+
+  // Force the DeclContext to build a its name-lookup table.
+  if (DC->hasExternalVisibleStorage())
+    DC->MaterializeVisibleDeclsFromExternalStorage();
+  else
+    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();
+  StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
+  if (!Map || Map->empty())
+    return 0;
+
+  OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator;
+  ASTDeclContextNameLookupTrait Trait(*this);
+
+  // Create the on-disk hash table representation.
+  for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
+       D != DEnd; ++D) {
+    DeclarationName Name = D->first;
+    DeclContext::lookup_result Result = D->second.getLookupResult();
+    Generator.insert(Name, Result, Trait);
+  }
+
+  // Create the on-disk hash table in a buffer.
+  llvm::SmallString<4096> LookupTable;
+  uint32_t BucketOffset;
+  {
+    llvm::raw_svector_ostream Out(LookupTable);
+    // Make sure that no bucket is at offset 0
+    clang::io::Emit32(Out, 0);
+    BucketOffset = Generator.Emit(Out, Trait);
+  }
+
+  // Write the lookup table
+  RecordData Record;
+  Record.push_back(DECL_CONTEXT_VISIBLE);
+  Record.push_back(BucketOffset);
+  Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record,
+                            LookupTable.str());
+
+  Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record);
+  ++NumVisibleDeclContexts;
+  return Offset;
+}
+
+/// \brief Write an UPDATE_VISIBLE block for the given context.
+///
+/// UPDATE_VISIBLE blocks contain the declarations that are added to an existing
+/// DeclContext in a dependent AST file. As such, they only exist for the TU
+/// (in C++) and for namespaces.
+void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
+  assert((DC->isTranslationUnit() || DC->isNamespace()) &&
+         "Only TU and namespaces should have visible decl updates.");
+
+  // Make the context build its lookup table, but don't make it load external
+  // decls.
+  DC->lookup(DeclarationName());
+
+  StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
+  if (!Map || Map->empty())
+    return;
+
+  OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator;
+  ASTDeclContextNameLookupTrait Trait(*this);
+
+  // Create the hash table.
+  for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
+       D != DEnd; ++D) {
+    DeclarationName Name = D->first;
+    DeclContext::lookup_result Result = D->second.getLookupResult();
+    // For any name that appears in this table, the results are complete, i.e.
+    // they overwrite results from previous PCHs. Merging is always a mess.
+    Generator.insert(Name, Result, Trait);
+  }
+
+  // Create the on-disk hash table in a buffer.
+  llvm::SmallString<4096> LookupTable;
+  uint32_t BucketOffset;
+  {
+    llvm::raw_svector_ostream Out(LookupTable);
+    // Make sure that no bucket is at offset 0
+    clang::io::Emit32(Out, 0);
+    BucketOffset = Generator.Emit(Out, Trait);
+  }
+
+  // Write the lookup table
+  RecordData Record;
+  Record.push_back(UPDATE_VISIBLE);
+  Record.push_back(getDeclID(cast<Decl>(DC)));
+  Record.push_back(BucketOffset);
+  Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable.str());
+}
+
+/// \brief Write ADDITIONAL_TEMPLATE_SPECIALIZATIONS blocks for all templates
+/// that have new specializations in the current AST file.
+void ASTWriter::WriteAdditionalTemplateSpecializations() {
+  RecordData Record;
+  for (AdditionalTemplateSpecializationsMap::iterator
+           I = AdditionalTemplateSpecializations.begin(),
+           E = AdditionalTemplateSpecializations.end();
+       I != E; ++I) {
+    Record.clear();
+    Record.push_back(I->first);
+    Record.insert(Record.end(), I->second.begin(), I->second.end());
+    Stream.EmitRecord(ADDITIONAL_TEMPLATE_SPECIALIZATIONS, Record);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// General Serialization Routines
+//===----------------------------------------------------------------------===//
+
+/// \brief Write a record containing the given attributes.
+void ASTWriter::WriteAttributeRecord(const AttrVec &Attrs) {
+  RecordData Record;
+  for (AttrVec::const_iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i){
+    const Attr * A = *i;
+    Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs
+    AddSourceLocation(A->getLocation(), Record);
+    Record.push_back(A->isInherited());
+
+#include "clang/Serialization/AttrPCHWrite.inc"
+
+  }
+
+  Stream.EmitRecord(DECL_ATTR, Record);
+}
+
+void ASTWriter::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 ASTWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) {
+  IdentID ID = IdentifierIDs[II];
+  // Only store offsets new to this AST file. Other identifier names are looked
+  // up earlier in the chain and thus don't need an offset.
+  if (ID >= FirstIdentID)
+    IdentifierOffsets[ID - FirstIdentID] = Offset;
+}
+
+/// \brief Note that the selector Sel occurs at the given offset
+/// within the method pool/selector table.
+void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
+  unsigned ID = SelectorIDs[Sel];
+  assert(ID && "Unknown selector");
+  // Don't record offsets for selectors that are also available in a different
+  // file.
+  if (ID < FirstSelectorID)
+    return;
+  SelectorOffsets[ID - FirstSelectorID] = Offset;
+}
+
+ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)
+  : Stream(Stream), Chain(0), FirstDeclID(1), NextDeclID(FirstDeclID),
+    FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
+    FirstIdentID(1), NextIdentID(FirstIdentID), FirstSelectorID(1),
+    NextSelectorID(FirstSelectorID), CollectedStmts(&StmtsToEmit),
+    NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
+    NumVisibleDeclContexts(0) {
+}
+
+void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+                         const char *isysroot) {
+  // 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();
+
+  if (Chain)
+    WriteASTChain(SemaRef, StatCalls, isysroot);
+  else
+    WriteASTCore(SemaRef, StatCalls, isysroot);
+}
+
+void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+                             const char *isysroot) {
+  using namespace llvm;
+
+  ASTContext &Context = SemaRef.Context;
+  Preprocessor &PP = SemaRef.PP;
+
+  // The translation unit is the first declaration we'll emit.
+  DeclIDs[Context.getTranslationUnitDecl()] = 1;
+  ++NextDeclID;
+  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 file scoped decls in this file.
+  RecordData UnusedFileScopedDecls;
+  for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i)
+    AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls);
+
+  RecordData WeakUndeclaredIdentifiers;
+  if (!SemaRef.WeakUndeclaredIdentifiers.empty()) {
+    WeakUndeclaredIdentifiers.push_back(
+                                      SemaRef.WeakUndeclaredIdentifiers.size());
+    for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator
+         I = SemaRef.WeakUndeclaredIdentifiers.begin(),
+         E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) {
+      AddIdentifierRef(I->first, WeakUndeclaredIdentifiers);
+      AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers);
+      AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers);
+      WeakUndeclaredIdentifiers.push_back(I->second.getUsed());
+    }
+  }
+
+  // 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 AST 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);
+
+  // Build a record containing all of the VTable uses information.
+  RecordData VTableUses;
+  if (!SemaRef.VTableUses.empty()) {
+    VTableUses.push_back(SemaRef.VTableUses.size());
+    for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) {
+      AddDeclRef(SemaRef.VTableUses[I].first, VTableUses);
+      AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses);
+      VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]);
+    }
+  }
+
+  // Build a record containing all of dynamic classes declarations.
+  RecordData DynamicClasses;
+  for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I)
+    AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses);
+
+  // Build a record containing all of pending implicit instantiations.
+  RecordData PendingInstantiations;
+  for (std::deque<Sema::PendingImplicitInstantiation>::iterator
+         I = SemaRef.PendingInstantiations.begin(),
+         N = SemaRef.PendingInstantiations.end(); I != N; ++I) {
+    AddDeclRef(I->first, PendingInstantiations);
+    AddSourceLocation(I->second, PendingInstantiations);
+  }
+  assert(SemaRef.PendingLocalImplicitInstantiations.empty() &&
+         "There are local ones at end of translation unit!");
+
+  // Build a record containing some declaration references.
+  RecordData SemaDeclRefs;
+  if (SemaRef.StdNamespace || SemaRef.StdBadAlloc) {
+    AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs);
+    AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs);
+  }
+
+  // Write the remaining AST contents.
+  RecordData Record;
+  Stream.EnterSubblock(AST_BLOCK_ID, 5);
+  WriteMetadata(Context, isysroot);
+  WriteLanguageOptions(Context.getLangOptions());
+  if (StatCalls && !isysroot)
+    WriteStatCache(*StatCalls);
+  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);
+  Record.push_back(Context.isInt128Installed());
+  Stream.EmitRecord(SPECIAL_TYPES, Record);
+
+  // Keep writing types and declarations until all types and
+  // declarations have been written.
+  Stream.EnterSubblock(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);
+  WriteSelectors(SemaRef);
+  WriteReferencedSelectorsPool(SemaRef);
+  WriteIdentifierTable(PP);
+
+  WriteTypeDeclOffsets();
+
+  // Write the record containing external, unnamed definitions.
+  if (!ExternalDefinitions.empty())
+    Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions);
+
+  // Write the record containing tentative definitions.
+  if (!TentativeDefinitions.empty())
+    Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions);
+
+  // Write the record containing unused file scoped decls.
+  if (!UnusedFileScopedDecls.empty())
+    Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls);
+
+  // Write the record containing weak undeclared identifiers.
+  if (!WeakUndeclaredIdentifiers.empty())
+    Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS,
+                      WeakUndeclaredIdentifiers);
+
+  // Write the record containing locally-scoped external definitions.
+  if (!LocallyScopedExternalDecls.empty())
+    Stream.EmitRecord(LOCALLY_SCOPED_EXTERNAL_DECLS,
+                      LocallyScopedExternalDecls);
+
+  // Write the record containing ext_vector type names.
+  if (!ExtVectorDecls.empty())
+    Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls);
+
+  // Write the record containing VTable uses information.
+  if (!VTableUses.empty())
+    Stream.EmitRecord(VTABLE_USES, VTableUses);
+
+  // Write the record containing dynamic classes declarations.
+  if (!DynamicClasses.empty())
+    Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses);
+
+  // Write the record containing pending implicit instantiations.
+  if (!PendingInstantiations.empty())
+    Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations);
+
+  // Write the record containing declaration references of Sema.
+  if (!SemaDeclRefs.empty())
+    Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs);
+
+  // Some simple statistics
+  Record.clear();
+  Record.push_back(NumStatements);
+  Record.push_back(NumMacros);
+  Record.push_back(NumLexicalDeclContexts);
+  Record.push_back(NumVisibleDeclContexts);
+  Stream.EmitRecord(STATISTICS, Record);
+  Stream.ExitBlock();
+}
+
+void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+                              const char *isysroot) {
+  using namespace llvm;
+
+  FirstDeclID += Chain->getTotalNumDecls();
+  FirstTypeID += Chain->getTotalNumTypes();
+  FirstIdentID += Chain->getTotalNumIdentifiers();
+  FirstSelectorID += Chain->getTotalNumSelectors();
+  NextDeclID = FirstDeclID;
+  NextTypeID = FirstTypeID;
+  NextIdentID = FirstIdentID;
+  NextSelectorID = FirstSelectorID;
+
+  ASTContext &Context = SemaRef.Context;
+  Preprocessor &PP = SemaRef.PP;
+
+  RecordData Record;
+  Stream.EnterSubblock(AST_BLOCK_ID, 5);
+  WriteMetadata(Context, isysroot);
+  if (StatCalls && !isysroot)
+    WriteStatCache(*StatCalls);
+  // FIXME: Source manager block should only write new stuff, which could be
+  // done by tracking the largest ID in the chain
+  WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
+
+  // The special types are in the chained PCH.
+
+  // We don't start with the translation unit, but with its decls that
+  // don't come from the chained PCH.
+  const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
+  llvm::SmallVector<DeclID, 64> NewGlobalDecls;
+  for (DeclContext::decl_iterator I = TU->noload_decls_begin(),
+                                  E = TU->noload_decls_end();
+       I != E; ++I) {
+    if ((*I)->getPCHLevel() == 0)
+      NewGlobalDecls.push_back(GetDeclRef(*I));
+    else if ((*I)->isChangedSinceDeserialization())
+      (void)GetDeclRef(*I); // Make sure it's written, but don't record it.
+  }
+  // We also need to write a lexical updates block for the TU.
+  llvm::BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev();
+  Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL));
+  Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
+  unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(Abv);
+  Record.clear();
+  Record.push_back(TU_UPDATE_LEXICAL);
+  Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
+                          reinterpret_cast<const char*>(NewGlobalDecls.data()),
+                          NewGlobalDecls.size() * sizeof(DeclID));
+  // And in C++, a visible updates block for the TU.
+  if (Context.getLangOptions().CPlusPlus) {
+    Abv = new llvm::BitCodeAbbrev();
+    Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
+    Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
+    Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 32));
+    Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
+    UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv);
+    WriteDeclContextVisibleUpdate(TU);
+  }
+
+  // Build a record containing all of the new tentative definitions in this
+  // file, in TentativeDefinitions order.
+  RecordData TentativeDefinitions;
+  for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) {
+    if (SemaRef.TentativeDefinitions[i]->getPCHLevel() == 0)
+      AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions);
+  }
+
+  // Build a record containing all of the file scoped decls in this file.
+  RecordData UnusedFileScopedDecls;
+  for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i) {
+    if (SemaRef.UnusedFileScopedDecls[i]->getPCHLevel() == 0)
+      AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls);
+  }
+
+  // We write the entire table, overwriting the tables from the chain.
+  RecordData WeakUndeclaredIdentifiers;
+  if (!SemaRef.WeakUndeclaredIdentifiers.empty()) {
+    WeakUndeclaredIdentifiers.push_back(
+                                      SemaRef.WeakUndeclaredIdentifiers.size());
+    for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator
+         I = SemaRef.WeakUndeclaredIdentifiers.begin(),
+         E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) {
+      AddIdentifierRef(I->first, WeakUndeclaredIdentifiers);
+      AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers);
+      AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers);
+      WeakUndeclaredIdentifiers.push_back(I->second.getUsed());
+    }
+  }
+
+  // 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 AST file in densemap order which is
+  // nondeterminstic!
+  for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator
+         TD = SemaRef.LocallyScopedExternalDecls.begin(),
+         TDEnd = SemaRef.LocallyScopedExternalDecls.end();
+       TD != TDEnd; ++TD) {
+    if (TD->second->getPCHLevel() == 0)
+      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) {
+    if (SemaRef.ExtVectorDecls[I]->getPCHLevel() == 0)
+      AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls);
+  }
+
+  // Build a record containing all of the VTable uses information.
+  // We write everything here, because it's too hard to determine whether
+  // a use is new to this part.
+  RecordData VTableUses;
+  if (!SemaRef.VTableUses.empty()) {
+    VTableUses.push_back(SemaRef.VTableUses.size());
+    for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) {
+      AddDeclRef(SemaRef.VTableUses[I].first, VTableUses);
+      AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses);
+      VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]);
+    }
+  }
+
+  // Build a record containing all of dynamic classes declarations.
+  RecordData DynamicClasses;
+  for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I)
+    if (SemaRef.DynamicClasses[I]->getPCHLevel() == 0)
+      AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses);
+
+  // Build a record containing all of pending implicit instantiations.
+  RecordData PendingInstantiations;
+  for (std::deque<Sema::PendingImplicitInstantiation>::iterator
+         I = SemaRef.PendingInstantiations.begin(),
+         N = SemaRef.PendingInstantiations.end(); I != N; ++I) {
+    if (I->first->getPCHLevel() == 0) {
+      AddDeclRef(I->first, PendingInstantiations);
+      AddSourceLocation(I->second, PendingInstantiations);
+    }
+  }
+  assert(SemaRef.PendingLocalImplicitInstantiations.empty() &&
+         "There are local ones at end of translation unit!");
+
+  // Build a record containing some declaration references.
+  // It's not worth the effort to avoid duplication here.
+  RecordData SemaDeclRefs;
+  if (SemaRef.StdNamespace || SemaRef.StdBadAlloc) {
+    AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs);
+    AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs);
+  }
+
+  Stream.EnterSubblock(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);
+  WriteSelectors(SemaRef);
+  WriteReferencedSelectorsPool(SemaRef);
+  WriteIdentifierTable(PP);
+  WriteTypeDeclOffsets();
+
+  /// Build a record containing first declarations from a chained PCH and the
+  /// most recent declarations in this AST that they point to.
+  RecordData FirstLatestDeclIDs;
+  for (FirstLatestDeclMap::iterator
+        I = FirstLatestDecls.begin(), E = FirstLatestDecls.end(); I != E; ++I) {
+    assert(I->first->getPCHLevel() > I->second->getPCHLevel() &&
+           "Expected first & second to be in different PCHs");
+    AddDeclRef(I->first, FirstLatestDeclIDs);
+    AddDeclRef(I->second, FirstLatestDeclIDs);
+  }
+  if (!FirstLatestDeclIDs.empty())
+    Stream.EmitRecord(REDECLS_UPDATE_LATEST, FirstLatestDeclIDs);
+
+  // Write the record containing external, unnamed definitions.
+  if (!ExternalDefinitions.empty())
+    Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions);
+
+  // Write the record containing tentative definitions.
+  if (!TentativeDefinitions.empty())
+    Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions);
+
+  // Write the record containing unused file scoped decls.
+  if (!UnusedFileScopedDecls.empty())
+    Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls);
+
+  // Write the record containing weak undeclared identifiers.
+  if (!WeakUndeclaredIdentifiers.empty())
+    Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS,
+                      WeakUndeclaredIdentifiers);
+
+  // Write the record containing locally-scoped external definitions.
+  if (!LocallyScopedExternalDecls.empty())
+    Stream.EmitRecord(LOCALLY_SCOPED_EXTERNAL_DECLS,
+                      LocallyScopedExternalDecls);
+
+  // Write the record containing ext_vector type names.
+  if (!ExtVectorDecls.empty())
+    Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls);
+
+  // Write the record containing VTable uses information.
+  if (!VTableUses.empty())
+    Stream.EmitRecord(VTABLE_USES, VTableUses);
+
+  // Write the record containing dynamic classes declarations.
+  if (!DynamicClasses.empty())
+    Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses);
+
+  // Write the record containing pending implicit instantiations.
+  if (!PendingInstantiations.empty())
+    Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations);
+
+  // Write the record containing declaration references of Sema.
+  if (!SemaDeclRefs.empty())
+    Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs);
+
+  // Write the updates to C++ namespaces.
+  for (llvm::SmallPtrSet<const NamespaceDecl *, 16>::iterator
+           I = UpdatedNamespaces.begin(),
+           E = UpdatedNamespaces.end();
+         I != E; ++I)
+    WriteDeclContextVisibleUpdate(*I);
+
+  // Write the updates to C++ template specialization lists.
+  if (!AdditionalTemplateSpecializations.empty())
+    WriteAdditionalTemplateSpecializations();
+
+  Record.clear();
+  Record.push_back(NumStatements);
+  Record.push_back(NumMacros);
+  Record.push_back(NumLexicalDeclContexts);
+  Record.push_back(NumVisibleDeclContexts);
+  WriteDeclUpdateBlock();
+  Stream.EmitRecord(STATISTICS, Record);
+  Stream.ExitBlock();
+}
+
+void ASTWriter::WriteDeclUpdateBlock() {
+  if (ReplacedDecls.empty())
+    return;
+
+  RecordData Record;
+  for (llvm::SmallVector<std::pair<DeclID, uint64_t>, 16>::iterator
+           I = ReplacedDecls.begin(), E = ReplacedDecls.end(); I != E; ++I) {
+    Record.push_back(I->first);
+    Record.push_back(I->second);
+  }
+  Stream.EmitRecord(DECL_REPLACEMENTS, Record);
+}
+
+void ASTWriter::AddSourceLocation(SourceLocation Loc, RecordData &Record) {
+  Record.push_back(Loc.getRawEncoding());
+}
+
+void ASTWriter::AddSourceRange(SourceRange Range, RecordData &Record) {
+  AddSourceLocation(Range.getBegin(), Record);
+  AddSourceLocation(Range.getEnd(), Record);
+}
+
+void ASTWriter::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 ASTWriter::AddAPSInt(const llvm::APSInt &Value, RecordData &Record) {
+  Record.push_back(Value.isUnsigned());
+  AddAPInt(Value, Record);
+}
+
+void ASTWriter::AddAPFloat(const llvm::APFloat &Value, RecordData &Record) {
+  AddAPInt(Value.bitcastToAPInt(), Record);
+}
+
+void ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) {
+  Record.push_back(getIdentifierRef(II));
+}
+
+IdentID ASTWriter::getIdentifierRef(const IdentifierInfo *II) {
+  if (II == 0)
+    return 0;
+
+  IdentID &ID = IdentifierIDs[II];
+  if (ID == 0)
+    ID = NextIdentID++;
+  return ID;
+}
+
+IdentID ASTWriter::getMacroDefinitionID(MacroDefinition *MD) {
+  if (MD == 0)
+    return 0;
+  
+  IdentID &ID = MacroDefinitions[MD];
+  if (ID == 0)
+    ID = MacroDefinitions.size();
+  return ID;
+}
+
+void ASTWriter::AddSelectorRef(const Selector SelRef, RecordData &Record) {
+  Record.push_back(getSelectorRef(SelRef));
+}
+
+SelectorID ASTWriter::getSelectorRef(Selector Sel) {
+  if (Sel.getAsOpaquePtr() == 0) {
+    return 0;
+  }
+
+  SelectorID &SID = SelectorIDs[Sel];
+  if (SID == 0 && Chain) {
+    // This might trigger a ReadSelector callback, which will set the ID for
+    // this selector.
+    Chain->LoadSelector(Sel);
+  }
+  if (SID == 0) {
+    SID = NextSelectorID++;
+  }
+  return SID;
+}
+
+void ASTWriter::AddCXXTemporary(const CXXTemporary *Temp, RecordData &Record) {
+  AddDeclRef(Temp->getDestructor(), Record);
+}
+
+void ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
+                                           const TemplateArgumentLocInfo &Arg,
+                                           RecordData &Record) {
+  switch (Kind) {
+  case TemplateArgument::Expression:
+    AddStmt(Arg.getAsExpr());
+    break;
+  case TemplateArgument::Type:
+    AddTypeSourceInfo(Arg.getAsTypeSourceInfo(), Record);
+    break;
+  case TemplateArgument::Template:
+    AddSourceRange(Arg.getTemplateQualifierRange(), Record);
+    AddSourceLocation(Arg.getTemplateNameLoc(), Record);
+    break;
+  case TemplateArgument::Null:
+  case TemplateArgument::Integral:
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Pack:
+    break;
+  }
+}
+
+void ASTWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
+                                       RecordData &Record) {
+  AddTemplateArgument(Arg.getArgument(), Record);
+
+  if (Arg.getArgument().getKind() == TemplateArgument::Expression) {
+    bool InfoHasSameExpr
+      = Arg.getArgument().getAsExpr() == Arg.getLocInfo().getAsExpr();
+    Record.push_back(InfoHasSameExpr);
+    if (InfoHasSameExpr)
+      return; // Avoid storing the same expr twice.
+  }
+  AddTemplateArgumentLocInfo(Arg.getArgument().getKind(), Arg.getLocInfo(),
+                             Record);
+}
+
+void ASTWriter::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 ASTWriter::AddTypeRef(QualType T, RecordData &Record) {
+  Record.push_back(GetOrCreateTypeID(T));
+}
+
+TypeID ASTWriter::GetOrCreateTypeID(QualType T) {
+  return MakeTypeID(T,
+              std::bind1st(std::mem_fun(&ASTWriter::GetOrCreateTypeIdx), this));
+}
+
+TypeID ASTWriter::getTypeID(QualType T) const {
+  return MakeTypeID(T,
+              std::bind1st(std::mem_fun(&ASTWriter::getTypeIdx), this));
+}
+
+TypeIdx ASTWriter::GetOrCreateTypeIdx(QualType T) {
+  if (T.isNull())
+    return TypeIdx();
+  assert(!T.getLocalFastQualifiers());
+
+  TypeIdx &Idx = TypeIdxs[T];
+  if (Idx.getIndex() == 0) {
+    // We haven't seen this type before. Assign it a new ID and put it
+    // into the queue of types to emit.
+    Idx = TypeIdx(NextTypeID++);
+    DeclTypesToEmit.push(T);
+  }
+  return Idx;
+}
+
+TypeIdx ASTWriter::getTypeIdx(QualType T) const {
+  if (T.isNull())
+    return TypeIdx();
+  assert(!T.getLocalFastQualifiers());
+
+  TypeIdxMap::const_iterator I = TypeIdxs.find(T);
+  assert(I != TypeIdxs.end() && "Type not emitted!");
+  return I->second;
+}
+
+void ASTWriter::AddDeclRef(const Decl *D, RecordData &Record) {
+  Record.push_back(GetDeclRef(D));
+}
+
+DeclID ASTWriter::GetDeclRef(const Decl *D) {
+  if (D == 0) {
+    return 0;
+  }
+
+  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 = NextDeclID++;
+    DeclTypesToEmit.push(const_cast<Decl *>(D));
+  } else if (ID < FirstDeclID && D->isChangedSinceDeserialization()) {
+    // We don't add it to the replacement collection here, because we don't
+    // have the offset yet.
+    DeclTypesToEmit.push(const_cast<Decl *>(D));
+    // Reset the flag, so that we don't add this decl multiple times.
+    const_cast<Decl *>(D)->setChangedSinceDeserialization(false);
+  }
+
+  return ID;
+}
+
+DeclID ASTWriter::getDeclID(const Decl *D) {
+  if (D == 0)
+    return 0;
+
+  assert(DeclIDs.find(D) != DeclIDs.end() && "Declaration not emitted!");
+  return DeclIDs[D];
+}
+
+void ASTWriter::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;
+  }
+}
+
+void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS,
+                                       RecordData &Record) {
+  // Nested name specifiers usually aren't too long. I think that 8 would
+  // typically accomodate the vast majority.
+  llvm::SmallVector<NestedNameSpecifier *, 8> NestedNames;
+
+  // Push each of the NNS's onto a stack for serialization in reverse order.
+  while (NNS) {
+    NestedNames.push_back(NNS);
+    NNS = NNS->getPrefix();
+  }
+
+  Record.push_back(NestedNames.size());
+  while(!NestedNames.empty()) {
+    NNS = NestedNames.pop_back_val();
+    NestedNameSpecifier::SpecifierKind Kind = NNS->getKind();
+    Record.push_back(Kind);
+    switch (Kind) {
+    case NestedNameSpecifier::Identifier:
+      AddIdentifierRef(NNS->getAsIdentifier(), Record);
+      break;
+
+    case NestedNameSpecifier::Namespace:
+      AddDeclRef(NNS->getAsNamespace(), Record);
+      break;
+
+    case NestedNameSpecifier::TypeSpec:
+    case NestedNameSpecifier::TypeSpecWithTemplate:
+      AddTypeRef(QualType(NNS->getAsType(), 0), Record);
+      Record.push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate);
+      break;
+
+    case NestedNameSpecifier::Global:
+      // Don't need to write an associated value.
+      break;
+    }
+  }
+}
+
+void ASTWriter::AddTemplateName(TemplateName Name, RecordData &Record) {
+  TemplateName::NameKind Kind = Name.getKind(); 
+  Record.push_back(Kind);
+  switch (Kind) {
+  case TemplateName::Template:
+    AddDeclRef(Name.getAsTemplateDecl(), Record);
+    break;
+
+  case TemplateName::OverloadedTemplate: {
+    OverloadedTemplateStorage *OvT = Name.getAsOverloadedTemplate();
+    Record.push_back(OvT->size());
+    for (OverloadedTemplateStorage::iterator I = OvT->begin(), E = OvT->end();
+           I != E; ++I)
+      AddDeclRef(*I, Record);
+    break;
+  }
+    
+  case TemplateName::QualifiedTemplate: {
+    QualifiedTemplateName *QualT = Name.getAsQualifiedTemplateName();
+    AddNestedNameSpecifier(QualT->getQualifier(), Record);
+    Record.push_back(QualT->hasTemplateKeyword());
+    AddDeclRef(QualT->getTemplateDecl(), Record);
+    break;
+  }
+    
+  case TemplateName::DependentTemplate: {
+    DependentTemplateName *DepT = Name.getAsDependentTemplateName();
+    AddNestedNameSpecifier(DepT->getQualifier(), Record);
+    Record.push_back(DepT->isIdentifier());
+    if (DepT->isIdentifier())
+      AddIdentifierRef(DepT->getIdentifier(), Record);
+    else
+      Record.push_back(DepT->getOperator());
+    break;
+  }
+  }
+}
+
+void ASTWriter::AddTemplateArgument(const TemplateArgument &Arg, 
+                                    RecordData &Record) {
+  Record.push_back(Arg.getKind());
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+    break;
+  case TemplateArgument::Type:
+    AddTypeRef(Arg.getAsType(), Record);
+    break;
+  case TemplateArgument::Declaration:
+    AddDeclRef(Arg.getAsDecl(), Record);
+    break;
+  case TemplateArgument::Integral:
+    AddAPSInt(*Arg.getAsIntegral(), Record);
+    AddTypeRef(Arg.getIntegralType(), Record);
+    break;
+  case TemplateArgument::Template:
+    AddTemplateName(Arg.getAsTemplate(), Record);
+    break;
+  case TemplateArgument::Expression:
+    AddStmt(Arg.getAsExpr());
+    break;
+  case TemplateArgument::Pack:
+    Record.push_back(Arg.pack_size());
+    for (TemplateArgument::pack_iterator I=Arg.pack_begin(), E=Arg.pack_end();
+           I != E; ++I)
+      AddTemplateArgument(*I, Record);
+    break;
+  }
+}
+
+void
+ASTWriter::AddTemplateParameterList(const TemplateParameterList *TemplateParams,
+                                    RecordData &Record) {
+  assert(TemplateParams && "No TemplateParams!");
+  AddSourceLocation(TemplateParams->getTemplateLoc(), Record);
+  AddSourceLocation(TemplateParams->getLAngleLoc(), Record);
+  AddSourceLocation(TemplateParams->getRAngleLoc(), Record);
+  Record.push_back(TemplateParams->size());
+  for (TemplateParameterList::const_iterator
+         P = TemplateParams->begin(), PEnd = TemplateParams->end();
+         P != PEnd; ++P)
+    AddDeclRef(*P, Record);
+}
+
+/// \brief Emit a template argument list.
+void
+ASTWriter::AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs,
+                                   RecordData &Record) {
+  assert(TemplateArgs && "No TemplateArgs!");
+  Record.push_back(TemplateArgs->flat_size());
+  for (int i=0, e = TemplateArgs->flat_size(); i != e; ++i)
+    AddTemplateArgument(TemplateArgs->get(i), Record);
+}
+
+
+void
+ASTWriter::AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordData &Record) {
+  Record.push_back(Set.size());
+  for (UnresolvedSetImpl::const_iterator
+         I = Set.begin(), E = Set.end(); I != E; ++I) {
+    AddDeclRef(I.getDecl(), Record);
+    Record.push_back(I.getAccess());
+  }
+}
+
+void ASTWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base,
+                                    RecordData &Record) {
+  Record.push_back(Base.isVirtual());
+  Record.push_back(Base.isBaseOfClass());
+  Record.push_back(Base.getAccessSpecifierAsWritten());
+  AddTypeSourceInfo(Base.getTypeSourceInfo(), Record);
+  AddSourceRange(Base.getSourceRange(), Record);
+}
+
+void ASTWriter::AddCXXBaseOrMemberInitializers(
+                        const CXXBaseOrMemberInitializer * const *BaseOrMembers,
+                        unsigned NumBaseOrMembers, RecordData &Record) {
+  Record.push_back(NumBaseOrMembers);
+  for (unsigned i=0; i != NumBaseOrMembers; ++i) {
+    const CXXBaseOrMemberInitializer *Init = BaseOrMembers[i];
+
+    Record.push_back(Init->isBaseInitializer());
+    if (Init->isBaseInitializer()) {
+      AddTypeSourceInfo(Init->getBaseClassInfo(), Record);
+      Record.push_back(Init->isBaseVirtual());
+    } else {
+      AddDeclRef(Init->getMember(), Record);
+    }
+    AddSourceLocation(Init->getMemberLocation(), Record);
+    AddStmt(Init->getInit());
+    AddDeclRef(Init->getAnonUnionMember(), Record);
+    AddSourceLocation(Init->getLParenLoc(), Record);
+    AddSourceLocation(Init->getRParenLoc(), Record);
+    Record.push_back(Init->isWritten());
+    if (Init->isWritten()) {
+      Record.push_back(Init->getSourceOrder());
+    } else {
+      Record.push_back(Init->getNumArrayIndices());
+      for (unsigned i=0, e=Init->getNumArrayIndices(); i != e; ++i)
+        AddDeclRef(Init->getArrayIndex(i), Record);
+    }
+  }
+}
+
+void ASTWriter::SetReader(ASTReader *Reader) {
+  assert(Reader && "Cannot remove chain");
+  assert(FirstDeclID == NextDeclID &&
+         FirstTypeID == NextTypeID &&
+         FirstIdentID == NextIdentID &&
+         FirstSelectorID == NextSelectorID &&
+         "Setting chain after writing has started.");
+  Chain = Reader;
+}
+
+void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) {
+  IdentifierIDs[II] = ID;
+}
+
+void ASTWriter::TypeRead(TypeIdx Idx, QualType T) {
+  TypeIdxs[T] = Idx;
+}
+
+void ASTWriter::DeclRead(DeclID ID, const Decl *D) {
+  DeclIDs[D] = ID;
+}
+
+void ASTWriter::SelectorRead(SelectorID ID, Selector S) {
+  SelectorIDs[S] = ID;
+}
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
new file mode 100644
index 0000000..413f544
--- /dev/null
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -0,0 +1,1190 @@
+//===--- ASTWriterDecl.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/Serialization/ASTWriter.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.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 clang {
+  class ASTDeclWriter : public DeclVisitor<ASTDeclWriter, void> {
+
+    ASTWriter &Writer;
+    ASTContext &Context;
+    ASTWriter::RecordData &Record;
+
+  public:
+    serialization::DeclCode Code;
+    unsigned AbbrevToUse;
+
+    ASTDeclWriter(ASTWriter &Writer, ASTContext &Context,
+                  ASTWriter::RecordData &Record)
+      : Writer(Writer), Context(Context), Record(Record) {
+    }
+    
+    void Visit(Decl *D);
+
+    void VisitDecl(Decl *D);
+    void VisitTranslationUnitDecl(TranslationUnitDecl *D);
+    void VisitNamedDecl(NamedDecl *D);
+    void VisitNamespaceDecl(NamespaceDecl *D);
+    void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
+    void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
+    void VisitTypeDecl(TypeDecl *D);
+    void VisitTypedefDecl(TypedefDecl *D);
+    void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
+    void VisitTagDecl(TagDecl *D);
+    void VisitEnumDecl(EnumDecl *D);
+    void VisitRecordDecl(RecordDecl *D);
+    void VisitCXXRecordDecl(CXXRecordDecl *D);
+    void VisitClassTemplateSpecializationDecl(
+                                            ClassTemplateSpecializationDecl *D);
+    void VisitClassTemplatePartialSpecializationDecl(
+                                     ClassTemplatePartialSpecializationDecl *D);
+    void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
+    void VisitValueDecl(ValueDecl *D);
+    void VisitEnumConstantDecl(EnumConstantDecl *D);
+    void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
+    void VisitDeclaratorDecl(DeclaratorDecl *D);
+    void VisitFunctionDecl(FunctionDecl *D);
+    void VisitCXXMethodDecl(CXXMethodDecl *D);
+    void VisitCXXConstructorDecl(CXXConstructorDecl *D);
+    void VisitCXXDestructorDecl(CXXDestructorDecl *D);
+    void VisitCXXConversionDecl(CXXConversionDecl *D);
+    void VisitFieldDecl(FieldDecl *D);
+    void VisitVarDecl(VarDecl *D);
+    void VisitImplicitParamDecl(ImplicitParamDecl *D);
+    void VisitParmVarDecl(ParmVarDecl *D);
+    void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
+    void VisitTemplateDecl(TemplateDecl *D);
+    void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
+    void VisitClassTemplateDecl(ClassTemplateDecl *D);
+    void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
+    void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
+    void VisitUsingDecl(UsingDecl *D);
+    void VisitUsingShadowDecl(UsingShadowDecl *D);
+    void VisitLinkageSpecDecl(LinkageSpecDecl *D);
+    void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
+    void VisitAccessSpecDecl(AccessSpecDecl *D);
+    void VisitFriendDecl(FriendDecl *D);
+    void VisitFriendTemplateDecl(FriendTemplateDecl *D);
+    void VisitStaticAssertDecl(StaticAssertDecl *D);
+    void VisitBlockDecl(BlockDecl *D);
+
+    void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
+                          uint64_t VisibleOffset);
+    template <typename T> void VisitRedeclarable(Redeclarable<T> *D);
+
+
+    // FIXME: Put in the same order is DeclNodes.td?
+    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 ASTDeclWriter::Visit(Decl *D) {
+  DeclVisitor<ASTDeclWriter>::Visit(D);
+
+  // Handle FunctionDecl's body here and write it after all other Stmts/Exprs
+  // have been written. We want it last because we will not read it back when
+  // retrieving it from the AST, we'll just lazily set the offset. 
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    Record.push_back(FD->isThisDeclarationADefinition());
+    if (FD->isThisDeclarationADefinition())
+      Writer.AddStmt(FD->getBody());
+  }
+}
+
+void ASTDeclWriter::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(false));
+  Record.push_back(D->getAccess());
+  Record.push_back(D->getPCHLevel());
+}
+
+void ASTDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
+  VisitDecl(D);
+  Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
+  Code = serialization::DECL_TRANSLATION_UNIT;
+}
+
+void ASTDeclWriter::VisitNamedDecl(NamedDecl *D) {
+  VisitDecl(D);
+  Writer.AddDeclarationName(D->getDeclName(), Record);
+}
+
+void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
+}
+
+void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
+  VisitTypeDecl(D);
+  Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
+  Code = serialization::DECL_TYPEDEF;
+}
+
+void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
+  VisitTypeDecl(D);
+  Record.push_back(D->getIdentifierNamespace());
+  VisitRedeclarable(D);
+  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 ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
+  VisitTagDecl(D);
+  Writer.AddTypeRef(D->getIntegerType(), Record);
+  Writer.AddTypeRef(D->getPromotionType(), Record);
+  Record.push_back(D->getNumPositiveBits());
+  Record.push_back(D->getNumNegativeBits());
+  Writer.AddDeclRef(D->getInstantiatedFromMemberEnum(), Record);
+  Code = serialization::DECL_ENUM;
+}
+
+void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
+  VisitTagDecl(D);
+  Record.push_back(D->hasFlexibleArrayMember());
+  Record.push_back(D->isAnonymousStructOrUnion());
+  Record.push_back(D->hasObjectMember());
+  Code = serialization::DECL_RECORD;
+}
+
+void ASTDeclWriter::VisitValueDecl(ValueDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddTypeRef(D->getType(), Record);
+}
+
+void ASTDeclWriter::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 = serialization::DECL_ENUM_CONSTANT;
+}
+
+void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
+  VisitValueDecl(D);
+  Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
+  // FIXME: write optional qualifier and its range.
+}
+
+void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
+  VisitDeclaratorDecl(D);
+  // FIXME: write DeclarationNameLoc.
+
+  Record.push_back(D->getIdentifierNamespace());
+  Record.push_back(D->getTemplatedKind());
+  switch (D->getTemplatedKind()) {
+  default: assert(false && "Unhandled TemplatedKind!");
+    break;
+  case FunctionDecl::TK_NonTemplate:
+    break;
+  case FunctionDecl::TK_FunctionTemplate:
+    Writer.AddDeclRef(D->getDescribedFunctionTemplate(), Record);
+    break;
+  case FunctionDecl::TK_MemberSpecialization: {
+    MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo();
+    Writer.AddDeclRef(MemberInfo->getInstantiatedFrom(), Record);
+    Record.push_back(MemberInfo->getTemplateSpecializationKind());
+    Writer.AddSourceLocation(MemberInfo->getPointOfInstantiation(), Record);
+    break;
+  }
+  case FunctionDecl::TK_FunctionTemplateSpecialization: {
+    FunctionTemplateSpecializationInfo *
+      FTSInfo = D->getTemplateSpecializationInfo();
+    // We want it canonical to guarantee that it has a Common*.
+    Writer.AddDeclRef(FTSInfo->getTemplate()->getCanonicalDecl(), Record);
+    Record.push_back(FTSInfo->getTemplateSpecializationKind());
+    
+    // Template arguments.
+    Writer.AddTemplateArgumentList(FTSInfo->TemplateArguments, Record);
+    
+    // Template args as written.
+    Record.push_back(FTSInfo->TemplateArgumentsAsWritten != 0);
+    if (FTSInfo->TemplateArgumentsAsWritten) {
+      Record.push_back(FTSInfo->TemplateArgumentsAsWritten->size());
+      for (int i=0, e = FTSInfo->TemplateArgumentsAsWritten->size(); i!=e; ++i)
+        Writer.AddTemplateArgumentLoc((*FTSInfo->TemplateArgumentsAsWritten)[i],
+                                      Record);
+      Writer.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->getLAngleLoc(),
+                               Record);
+      Writer.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->getRAngleLoc(),
+                               Record);
+    }
+    
+    Writer.AddSourceLocation(FTSInfo->getPointOfInstantiation(), Record);
+    break;
+  }
+  case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
+    DependentFunctionTemplateSpecializationInfo *
+      DFTSInfo = D->getDependentSpecializationInfo();
+    
+    // Templates.
+    Record.push_back(DFTSInfo->getNumTemplates());
+    for (int i=0, e = DFTSInfo->getNumTemplates(); i != e; ++i)
+      Writer.AddDeclRef(DFTSInfo->getTemplate(i), Record);
+    
+    // Templates args.
+    Record.push_back(DFTSInfo->getNumTemplateArgs());
+    for (int i=0, e = DFTSInfo->getNumTemplateArgs(); i != e; ++i)
+      Writer.AddTemplateArgumentLoc(DFTSInfo->getTemplateArg(i), Record);
+    Writer.AddSourceLocation(DFTSInfo->getLAngleLoc(), Record);
+    Writer.AddSourceLocation(DFTSInfo->getRAngleLoc(), Record);
+    break;
+  }
+  }
+
+  // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
+  // after everything else is written.
+
+  VisitRedeclarable(D);
+  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);
+
+  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 = serialization::DECL_FUNCTION;
+}
+
+void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
+  VisitNamedDecl(D);
+  // FIXME: convert to LazyStmtPtr?
+  // Unlike C/C++, method bodies will never be in header files.
+  bool HasBodyStuff = D->getBody() != 0     ||
+                      D->getSelfDecl() != 0 || D->getCmdDecl() != 0;
+  Record.push_back(HasBodyStuff);
+  if (HasBodyStuff) {
+    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());
+  Record.push_back(D->isDefined());
+  // 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 = serialization::DECL_OBJC_METHOD;
+}
+
+void ASTDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddSourceRange(D->getAtEndRange(), Record);
+  // Abstract class (no need to define a stable serialization::DECL code).
+}
+
+void ASTDeclWriter::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 = serialization::DECL_OBJC_INTERFACE;
+}
+
+void ASTDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
+  VisitFieldDecl(D);
+  // FIXME: stable encoding for @public/@private/@protected/@package
+  Record.push_back(D->getAccessControl());
+  Record.push_back(D->getSynthesize());
+  Code = serialization::DECL_OBJC_IVAR;
+}
+
+void ASTDeclWriter::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 = serialization::DECL_OBJC_PROTOCOL;
+}
+
+void ASTDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) {
+  VisitFieldDecl(D);
+  Code = serialization::DECL_OBJC_AT_DEFS_FIELD;
+}
+
+void ASTDeclWriter::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 = serialization::DECL_OBJC_CLASS;
+}
+
+void ASTDeclWriter::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 = serialization::DECL_OBJC_FORWARD_PROTOCOL;
+}
+
+void ASTDeclWriter::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);
+  Record.push_back(D->hasSynthBitfield());
+  Writer.AddSourceLocation(D->getAtLoc(), Record);
+  Writer.AddSourceLocation(D->getCategoryNameLoc(), Record);
+  Code = serialization::DECL_OBJC_CATEGORY;
+}
+
+void ASTDeclWriter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddDeclRef(D->getClassInterface(), Record);
+  Code = serialization::DECL_OBJC_COMPATIBLE_ALIAS;
+}
+
+void ASTDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddSourceLocation(D->getAtLoc(), Record);
+  Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
+  // FIXME: stable encoding
+  Record.push_back((unsigned)D->getPropertyAttributes());
+  Record.push_back((unsigned)D->getPropertyAttributesAsWritten());
+  // 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 = serialization::DECL_OBJC_PROPERTY;
+}
+
+void ASTDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
+  VisitObjCContainerDecl(D);
+  Writer.AddDeclRef(D->getClassInterface(), Record);
+  // Abstract class (no need to define a stable serialization::DECL code).
+}
+
+void ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+  VisitObjCImplDecl(D);
+  Writer.AddIdentifierRef(D->getIdentifier(), Record);
+  Code = serialization::DECL_OBJC_CATEGORY_IMPL;
+}
+
+void ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+  VisitObjCImplDecl(D);
+  Writer.AddDeclRef(D->getSuperClass(), Record);
+  Writer.AddCXXBaseOrMemberInitializers(D->IvarInitializers,
+                                        D->NumIvarInitializers, Record);
+  Record.push_back(D->hasSynthBitfield());
+  Code = serialization::DECL_OBJC_IMPLEMENTATION;
+}
+
+void ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+  VisitDecl(D);
+  Writer.AddSourceLocation(D->getLocStart(), Record);
+  Writer.AddDeclRef(D->getPropertyDecl(), Record);
+  Writer.AddDeclRef(D->getPropertyIvarDecl(), Record);
+  Writer.AddStmt(D->getGetterCXXConstructor());
+  Writer.AddStmt(D->getSetterCXXAssignment());
+  Code = serialization::DECL_OBJC_PROPERTY_IMPL;
+}
+
+void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
+  VisitDeclaratorDecl(D);
+  Record.push_back(D->isMutable());
+  Record.push_back(D->getBitWidth()? 1 : 0);
+  if (D->getBitWidth())
+    Writer.AddStmt(D->getBitWidth());
+  if (!D->getDeclName())
+    Writer.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D), Record);
+  Code = serialization::DECL_FIELD;
+}
+
+void ASTDeclWriter::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->isExceptionVariable());
+  Record.push_back(D->isNRVOVariable());
+  VisitRedeclarable(D);
+  Record.push_back(D->getInit() ? 1 : 0);
+  if (D->getInit())
+    Writer.AddStmt(D->getInit());
+
+  MemberSpecializationInfo *SpecInfo
+    = D->isStaticDataMember() ? D->getMemberSpecializationInfo() : 0;
+  Record.push_back(SpecInfo != 0);
+  if (SpecInfo) {
+    Writer.AddDeclRef(SpecInfo->getInstantiatedFrom(), Record);
+    Record.push_back(SpecInfo->getTemplateSpecializationKind());
+    Writer.AddSourceLocation(SpecInfo->getPointOfInstantiation(), Record);
+  }
+
+  Code = serialization::DECL_VAR;
+}
+
+void ASTDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
+  VisitVarDecl(D);
+  Code = serialization::DECL_IMPLICIT_PARAM;
+}
+
+void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
+  VisitVarDecl(D);
+  Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
+  Record.push_back(D->hasInheritedDefaultArg());
+  Record.push_back(D->hasUninstantiatedDefaultArg());
+  if (D->hasUninstantiatedDefaultArg())
+    Writer.AddStmt(D->getUninstantiatedDefaultArg());
+  Code = serialization::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(false) &&
+      D->getAccess() == AS_none &&
+      D->getPCHLevel() == 0 &&
+      D->getStorageClass() == 0 &&
+      !D->hasCXXDirectInitializer() && // Can params have this ever?
+      D->getObjCDeclQualifier() == 0 &&
+      !D->hasInheritedDefaultArg() &&
+      D->getInit() == 0 &&
+      !D->hasUninstantiatedDefaultArg())  // No default expr.
+    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->isExceptionVariable() && "PARM_VAR_DECL can't be exception var");
+  assert(D->getPreviousDeclaration() == 0 && "PARM_VAR_DECL can't be redecl");
+  assert(!D->isStaticDataMember() &&
+         "PARM_VAR_DECL can't be static data member");
+}
+
+void ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
+  VisitDecl(D);
+  Writer.AddStmt(D->getAsmString());
+  Code = serialization::DECL_FILE_SCOPE_ASM;
+}
+
+void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
+  VisitDecl(D);
+  Writer.AddStmt(D->getBody());
+  Writer.AddTypeSourceInfo(D->getSignatureAsWritten(), Record);
+  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 = serialization::DECL_BLOCK;
+}
+
+void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
+  VisitDecl(D);
+  // FIXME: It might be nice to serialize the brace locations for this
+  // declaration, which don't seem to be readily available in the AST.
+  Record.push_back(D->getLanguage());
+  Record.push_back(D->hasBraces());
+  Code = serialization::DECL_LINKAGE_SPEC;
+}
+
+void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddSourceLocation(D->getLBracLoc(), Record);
+  Writer.AddSourceLocation(D->getRBracLoc(), Record);
+  Writer.AddDeclRef(D->getNextNamespace(), Record);
+
+  // Only write one reference--original or anonymous
+  Record.push_back(D->isOriginalNamespace());
+  if (D->isOriginalNamespace())
+    Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
+  else
+    Writer.AddDeclRef(D->getOriginalNamespace(), Record);
+  Code = serialization::DECL_NAMESPACE;
+
+  if (Writer.hasChain() && !D->isOriginalNamespace() &&
+      D->getOriginalNamespace()->getPCHLevel() > 0) {
+    Writer.AddUpdatedNamespace(D->getOriginalNamespace());
+  }
+}
+
+void ASTDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddSourceLocation(D->getAliasLoc(), Record);
+  Writer.AddSourceRange(D->getQualifierRange(), Record);
+  Writer.AddNestedNameSpecifier(D->getQualifier(), Record);
+  Writer.AddSourceLocation(D->getTargetNameLoc(), Record);
+  Writer.AddDeclRef(D->getNamespace(), Record);
+  Code = serialization::DECL_NAMESPACE_ALIAS;
+}
+
+void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddSourceRange(D->getNestedNameRange(), Record);
+  Writer.AddSourceLocation(D->getUsingLocation(), Record);
+  Writer.AddNestedNameSpecifier(D->getTargetNestedNameDecl(), Record);
+  Record.push_back(D->getNumShadowDecls());
+  for (UsingDecl::shadow_iterator P = D->shadow_begin(),
+       PEnd = D->shadow_end(); P != PEnd; ++P)
+    Writer.AddDeclRef(*P, Record);
+  Record.push_back(D->isTypeName());
+  Writer.AddDeclRef(Context.getInstantiatedFromUsingDecl(D), Record);
+  Code = serialization::DECL_USING;
+}
+
+void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddDeclRef(D->getTargetDecl(), Record);
+  Writer.AddDeclRef(D->getUsingDecl(), Record);
+  Writer.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D), Record);
+  Code = serialization::DECL_USING_SHADOW;
+}
+
+void ASTDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddSourceLocation(D->getNamespaceKeyLocation(), Record);
+  Writer.AddSourceRange(D->getQualifierRange(), Record);
+  Writer.AddNestedNameSpecifier(D->getQualifier(), Record);
+  Writer.AddSourceLocation(D->getIdentLocation(), Record);
+  Writer.AddDeclRef(D->getNominatedNamespace(), Record);
+  Writer.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()), Record);
+  Code = serialization::DECL_USING_DIRECTIVE;
+}
+
+void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
+  VisitValueDecl(D);
+  Writer.AddSourceRange(D->getTargetNestedNameRange(), Record);
+  Writer.AddSourceLocation(D->getUsingLoc(), Record);
+  Writer.AddNestedNameSpecifier(D->getTargetNestedNameSpecifier(), Record);
+  Code = serialization::DECL_UNRESOLVED_USING_VALUE;
+}
+
+void ASTDeclWriter::VisitUnresolvedUsingTypenameDecl(
+                                               UnresolvedUsingTypenameDecl *D) {
+  VisitTypeDecl(D);
+  Writer.AddSourceRange(D->getTargetNestedNameRange(), Record);
+  Writer.AddSourceLocation(D->getUsingLoc(), Record);
+  Writer.AddSourceLocation(D->getTypenameLoc(), Record);
+  Writer.AddNestedNameSpecifier(D->getTargetNestedNameSpecifier(), Record);
+  Code = serialization::DECL_UNRESOLVED_USING_TYPENAME;
+}
+
+void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
+  // See comments at ASTDeclReader::VisitCXXRecordDecl about why this happens
+  // before VisitRecordDecl.
+  enum { Data_NoDefData, Data_Owner, Data_NotOwner };
+  bool OwnsDefinitionData = false;
+  if (D->DefinitionData) {
+    assert(D->DefinitionData->Definition &&
+           "DefinitionData don't point to a definition decl!");
+    OwnsDefinitionData = D->DefinitionData->Definition == D;
+    if (OwnsDefinitionData) {
+      Record.push_back(Data_Owner);
+    } else {
+      Record.push_back(Data_NotOwner);
+      Writer.AddDeclRef(D->DefinitionData->Definition, Record);
+    }
+  } else
+    Record.push_back(Data_NoDefData);
+
+  VisitRecordDecl(D);
+
+  if (OwnsDefinitionData) {
+    assert(D->DefinitionData);
+    struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData;
+
+    Record.push_back(Data.UserDeclaredConstructor);
+    Record.push_back(Data.UserDeclaredCopyConstructor);
+    Record.push_back(Data.UserDeclaredCopyAssignment);
+    Record.push_back(Data.UserDeclaredDestructor);
+    Record.push_back(Data.Aggregate);
+    Record.push_back(Data.PlainOldData);
+    Record.push_back(Data.Empty);
+    Record.push_back(Data.Polymorphic);
+    Record.push_back(Data.Abstract);
+    Record.push_back(Data.HasTrivialConstructor);
+    Record.push_back(Data.HasTrivialCopyConstructor);
+    Record.push_back(Data.HasTrivialCopyAssignment);
+    Record.push_back(Data.HasTrivialDestructor);
+    Record.push_back(Data.ComputedVisibleConversions);
+    Record.push_back(Data.DeclaredDefaultConstructor);
+    Record.push_back(Data.DeclaredCopyConstructor);
+    Record.push_back(Data.DeclaredCopyAssignment);
+    Record.push_back(Data.DeclaredDestructor);
+
+    Record.push_back(D->getNumBases());
+    for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
+           E = D->bases_end(); I != E; ++I)
+      Writer.AddCXXBaseSpecifier(*I, Record);
+
+    // FIXME: Make VBases lazily computed when needed to avoid storing them.
+    Record.push_back(D->getNumVBases());
+    for (CXXRecordDecl::base_class_iterator I = D->vbases_begin(),
+           E = D->vbases_end(); I != E; ++I)
+      Writer.AddCXXBaseSpecifier(*I, Record);
+
+    Writer.AddUnresolvedSet(Data.Conversions, Record);
+    Writer.AddUnresolvedSet(Data.VisibleConversions, Record);
+    // Data.Definition is written at the top. 
+    Writer.AddDeclRef(Data.FirstFriend, Record);
+  }
+
+  enum {
+    CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
+  };
+  if (ClassTemplateDecl *TemplD = D->getDescribedClassTemplate()) {
+    Record.push_back(CXXRecTemplate);
+    Writer.AddDeclRef(TemplD, Record);
+  } else if (MemberSpecializationInfo *MSInfo
+               = D->getMemberSpecializationInfo()) {
+    Record.push_back(CXXRecMemberSpecialization);
+    Writer.AddDeclRef(MSInfo->getInstantiatedFrom(), Record);
+    Record.push_back(MSInfo->getTemplateSpecializationKind());
+    Writer.AddSourceLocation(MSInfo->getPointOfInstantiation(), Record);
+  } else {
+    Record.push_back(CXXRecNotTemplate);
+  }
+
+  Code = serialization::DECL_CXX_RECORD;
+}
+
+void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
+  VisitFunctionDecl(D);
+  Record.push_back(D->size_overridden_methods());
+  for (CXXMethodDecl::method_iterator
+         I = D->begin_overridden_methods(), E = D->end_overridden_methods();
+         I != E; ++I)
+    Writer.AddDeclRef(*I, Record);
+  Code = serialization::DECL_CXX_METHOD;
+}
+
+void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
+  VisitCXXMethodDecl(D);
+
+  Record.push_back(D->IsExplicitSpecified);
+  Record.push_back(D->ImplicitlyDefined);
+  Writer.AddCXXBaseOrMemberInitializers(D->BaseOrMemberInitializers,
+                                        D->NumBaseOrMemberInitializers, Record);
+
+  Code = serialization::DECL_CXX_CONSTRUCTOR;
+}
+
+void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
+  VisitCXXMethodDecl(D);
+
+  Record.push_back(D->ImplicitlyDefined);
+  Writer.AddDeclRef(D->OperatorDelete, Record);
+
+  Code = serialization::DECL_CXX_DESTRUCTOR;
+}
+
+void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
+  VisitCXXMethodDecl(D);
+  Record.push_back(D->IsExplicitSpecified);
+  Code = serialization::DECL_CXX_CONVERSION;
+}
+
+void ASTDeclWriter::VisitAccessSpecDecl(AccessSpecDecl *D) {
+  VisitDecl(D);
+  Writer.AddSourceLocation(D->getColonLoc(), Record);
+  Code = serialization::DECL_ACCESS_SPEC;
+}
+
+void ASTDeclWriter::VisitFriendDecl(FriendDecl *D) {
+  VisitDecl(D);
+  Record.push_back(D->Friend.is<TypeSourceInfo*>());
+  if (D->Friend.is<TypeSourceInfo*>())
+    Writer.AddTypeSourceInfo(D->Friend.get<TypeSourceInfo*>(), Record);
+  else
+    Writer.AddDeclRef(D->Friend.get<NamedDecl*>(), Record);
+  Writer.AddDeclRef(D->NextFriend, Record);
+  Writer.AddSourceLocation(D->FriendLoc, Record);
+  Code = serialization::DECL_FRIEND;
+}
+
+void ASTDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
+  VisitDecl(D);
+  Record.push_back(D->getNumTemplateParameters());
+  for (unsigned i = 0, e = D->getNumTemplateParameters(); i != e; ++i)
+    Writer.AddTemplateParameterList(D->getTemplateParameterList(i), Record);
+  Record.push_back(D->getFriendDecl() != 0);
+  if (D->getFriendDecl())
+    Writer.AddDeclRef(D->getFriendDecl(), Record);
+  else
+    Writer.AddTypeSourceInfo(D->getFriendType(), Record);
+  Writer.AddSourceLocation(D->getFriendLoc(), Record);
+  Code = serialization::DECL_FRIEND_TEMPLATE;
+}
+
+void ASTDeclWriter::VisitTemplateDecl(TemplateDecl *D) {
+  VisitNamedDecl(D);
+
+  Writer.AddDeclRef(D->getTemplatedDecl(), Record);
+  Writer.AddTemplateParameterList(D->getTemplateParameters(), Record);
+}
+
+void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
+  VisitTemplateDecl(D);
+
+  Record.push_back(D->getIdentifierNamespace());
+  Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
+  if (D->getPreviousDeclaration() == 0) {
+    // This TemplateDecl owns the CommonPtr; write it.
+    assert(D->isCanonicalDecl());
+
+    Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record);
+    if (D->getInstantiatedFromMemberTemplate())
+      Record.push_back(D->isMemberSpecialization());
+
+    Writer.AddDeclRef(D->getCommonPtr()->Latest, Record);
+  } else {
+    RedeclarableTemplateDecl *First = D->getFirstDeclaration();
+    assert(First != D);
+    // If this is a most recent redeclaration that is pointed to by a first decl
+    // in a chained PCH, keep track of the association with the map so we can
+    // update the first decl during AST reading.
+    if (First->getMostRecentDeclaration() == D &&
+        First->getPCHLevel() > D->getPCHLevel()) {
+      assert(Writer.FirstLatestDecls.find(First)==Writer.FirstLatestDecls.end()
+             && "The latest is already set");
+      Writer.FirstLatestDecls[First] = D;
+    }
+  }
+}
+
+void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+  VisitRedeclarableTemplateDecl(D);
+
+  if (D->getPreviousDeclaration() == 0) {
+    typedef llvm::FoldingSet<ClassTemplateSpecializationDecl> CTSDSetTy;
+    CTSDSetTy &CTSDSet = D->getSpecializations();
+    Record.push_back(CTSDSet.size());
+    for (CTSDSetTy::iterator I=CTSDSet.begin(), E = CTSDSet.end(); I!=E; ++I) {
+      assert(I->isCanonicalDecl() && "Expected only canonical decls in set");
+      Writer.AddDeclRef(&*I, Record);
+    }
+
+    typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> CTPSDSetTy;
+    CTPSDSetTy &CTPSDSet = D->getPartialSpecializations();
+    Record.push_back(CTPSDSet.size());
+    for (CTPSDSetTy::iterator I=CTPSDSet.begin(), E=CTPSDSet.end(); I!=E; ++I) {
+      assert(I->isCanonicalDecl() && "Expected only canonical decls in set");
+      Writer.AddDeclRef(&*I, Record); 
+    }
+
+    // InjectedClassNameType is computed, no need to write it.
+  }
+  Code = serialization::DECL_CLASS_TEMPLATE;
+}
+
+void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
+                                           ClassTemplateSpecializationDecl *D) {
+  VisitCXXRecordDecl(D);
+
+  llvm::PointerUnion<ClassTemplateDecl *,
+                     ClassTemplatePartialSpecializationDecl *> InstFrom
+    = D->getSpecializedTemplateOrPartial();
+  Decl *InstFromD;
+  if (InstFrom.is<ClassTemplateDecl *>()) {
+    InstFromD = InstFrom.get<ClassTemplateDecl *>();
+    Writer.AddDeclRef(InstFromD, Record);
+  } else {
+    InstFromD = InstFrom.get<ClassTemplatePartialSpecializationDecl *>();
+    Writer.AddDeclRef(InstFromD, Record);
+    Writer.AddTemplateArgumentList(&D->getTemplateInstantiationArgs(), Record);
+    InstFromD = cast<ClassTemplatePartialSpecializationDecl>(InstFromD)->
+                    getSpecializedTemplate();
+  }
+  // Is this a specialization of an already-serialized template?
+  if (InstFromD->getCanonicalDecl()->getPCHLevel() != 0)
+    Writer.AddAdditionalTemplateSpecialization(Writer.getDeclID(InstFromD),
+                                               Writer.getDeclID(D));
+
+  // Explicit info.
+  Writer.AddTypeSourceInfo(D->getTypeAsWritten(), Record);
+  if (D->getTypeAsWritten()) {
+    Writer.AddSourceLocation(D->getExternLoc(), Record);
+    Writer.AddSourceLocation(D->getTemplateKeywordLoc(), Record);
+  }
+
+  Writer.AddTemplateArgumentList(&D->getTemplateArgs(), Record);
+  Writer.AddSourceLocation(D->getPointOfInstantiation(), Record);
+  Record.push_back(D->getSpecializationKind());
+
+  if (D->isCanonicalDecl()) {
+    // When reading, we'll add it to the folding set of the following template. 
+    Writer.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl(), Record);
+  }
+
+  Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION;
+}
+
+void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl(
+                                    ClassTemplatePartialSpecializationDecl *D) {
+  VisitClassTemplateSpecializationDecl(D);
+
+  Writer.AddTemplateParameterList(D->getTemplateParameters(), Record);
+
+  Record.push_back(D->getNumTemplateArgsAsWritten());
+  for (int i = 0, e = D->getNumTemplateArgsAsWritten(); i != e; ++i)
+    Writer.AddTemplateArgumentLoc(D->getTemplateArgsAsWritten()[i], Record);
+
+  Record.push_back(D->getSequenceNumber());
+
+  // These are read/set from/to the first declaration.
+  if (D->getPreviousDeclaration() == 0) {
+    Writer.AddDeclRef(D->getInstantiatedFromMember(), Record);
+    Record.push_back(D->isMemberSpecialization());
+  }
+
+  Code = serialization::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION;
+}
+
+void ASTDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+  VisitRedeclarableTemplateDecl(D);
+
+  if (D->getPreviousDeclaration() == 0) {
+    // This FunctionTemplateDecl owns the CommonPtr; write it.
+
+    // Write the function specialization declarations.
+    Record.push_back(D->getSpecializations().size());
+    for (llvm::FoldingSet<FunctionTemplateSpecializationInfo>::iterator
+           I = D->getSpecializations().begin(),
+           E = D->getSpecializations().end()   ; I != E; ++I) {
+      assert(I->Function->isCanonicalDecl() &&
+             "Expected only canonical decls in set");
+      Writer.AddDeclRef(I->Function, Record);
+    }
+  }
+  Code = serialization::DECL_FUNCTION_TEMPLATE;
+}
+
+void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+  VisitTypeDecl(D);
+
+  Record.push_back(D->wasDeclaredWithTypename());
+  Record.push_back(D->isParameterPack());
+  Record.push_back(D->defaultArgumentWasInherited());
+  Writer.AddTypeSourceInfo(D->getDefaultArgumentInfo(), Record);
+
+  Code = serialization::DECL_TEMPLATE_TYPE_PARM;
+}
+
+void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
+  VisitVarDecl(D);
+  // TemplateParmPosition.
+  Record.push_back(D->getDepth());
+  Record.push_back(D->getPosition());
+  // Rest of NonTypeTemplateParmDecl.
+  Record.push_back(D->getDefaultArgument() != 0);
+  if (D->getDefaultArgument()) {
+    Writer.AddStmt(D->getDefaultArgument());
+    Record.push_back(D->defaultArgumentWasInherited());
+  }
+  Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
+}
+
+void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
+  VisitTemplateDecl(D);
+  // TemplateParmPosition.
+  Record.push_back(D->getDepth());
+  Record.push_back(D->getPosition());
+  // Rest of TemplateTemplateParmDecl.
+  Writer.AddTemplateArgumentLoc(D->getDefaultArgument(), Record);
+  Record.push_back(D->defaultArgumentWasInherited());
+  Code = serialization::DECL_TEMPLATE_TEMPLATE_PARM;
+}
+
+void ASTDeclWriter::VisitStaticAssertDecl(StaticAssertDecl *D) {
+  VisitDecl(D);
+  Writer.AddStmt(D->getAssertExpr());
+  Writer.AddStmt(D->getMessage());
+  Code = serialization::DECL_STATIC_ASSERT;
+}
+
+/// \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 ASTDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
+                                     uint64_t VisibleOffset) {
+  Record.push_back(LexicalOffset);
+  Record.push_back(VisibleOffset);
+}
+
+template <typename T>
+void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
+  enum { NoRedeclaration = 0, PointsToPrevious, PointsToLatest };
+  if (D->RedeclLink.getNext() == D) {
+    Record.push_back(NoRedeclaration);
+  } else {
+    Record.push_back(D->RedeclLink.NextIsPrevious() ? PointsToPrevious
+                                                    : PointsToLatest);
+    Writer.AddDeclRef(D->RedeclLink.getPointer(), Record);
+  }
+
+  T *First = D->getFirstDeclaration();
+  T *ThisDecl = static_cast<T*>(D);
+  // If this is a most recent redeclaration that is pointed to by a first decl
+  // in a chained PCH, keep track of the association with the map so we can
+  // update the first decl during AST reading.
+  if (ThisDecl != First && First->getMostRecentDeclaration() == ThisDecl &&
+      First->getPCHLevel() > ThisDecl->getPCHLevel()) {
+    assert(Writer.FirstLatestDecls.find(First) == Writer.FirstLatestDecls.end()
+           && "The latest is already set");
+    Writer.FirstLatestDecls[First] = ThisDecl;
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// ASTWriter Implementation
+//===----------------------------------------------------------------------===//
+
+void ASTWriter::WriteDeclsBlockAbbrevs() {
+  using namespace llvm;
+  // Abbreviation for DECL_PARM_VAR.
+  BitCodeAbbrev *Abv = new BitCodeAbbrev();
+  Abv->Add(BitCodeAbbrevOp(serialization::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(serialization::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));                       // isExceptionVariable
+  Abv->Add(BitCodeAbbrevOp(0));                       // isNRVOVariable
+  Abv->Add(BitCodeAbbrevOp(0));                       // PrevDecl
+  Abv->Add(BitCodeAbbrevOp(0));                       // HasInit
+  Abv->Add(BitCodeAbbrevOp(0));                   // HasMemberSpecializationInfo
+  // ParmVarDecl
+  Abv->Add(BitCodeAbbrevOp(0));                       // ObjCDeclQualifier
+  Abv->Add(BitCodeAbbrevOp(0));                       // HasInheritedDefaultArg
+  Abv->Add(BitCodeAbbrevOp(0));                   // HasUninstantiatedDefaultArg
+
+  ParmVarDeclAbbrev = Stream.EmitAbbrev(Abv);
+
+  Abv = new BitCodeAbbrev();
+  Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL));
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+  DeclContextLexicalAbbrev = Stream.EmitAbbrev(Abv);
+
+  Abv = new BitCodeAbbrev();
+  Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE));
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+  DeclContextVisibleLookupAbbrev = 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 AST 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.
+static bool isRequiredDecl(const Decl *D, ASTContext &Context) {
+  // File scoped assembly or obj-c implementation must be seen.
+  if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplementationDecl>(D))
+    return true;
+
+  return Context.DeclMustBeEmitted(D);
+}
+
+void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
+  RecordData Record;
+  ASTDeclWriter 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
+  serialization::DeclID &IDR = DeclIDs[D];
+  if (IDR == 0)
+    IDR = NextDeclID++;
+  serialization::DeclID ID = IDR;
+
+  if (ID < FirstDeclID) {
+    // We're replacing a decl in a previous file.
+    ReplacedDecls.push_back(std::make_pair(ID, Stream.GetCurrentBitNo()));
+  } else {
+    unsigned Index = ID - FirstDeclID;
+
+    // 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 = (serialization::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
+  // AST file later.
+  //
+  // FIXME: This should be renamed, the predicate is much more complicated.
+  if (isRequiredDecl(D, Context))
+    ExternalDefinitions.push_back(ID);
+}
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
new file mode 100644
index 0000000..4bde550
--- /dev/null
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -0,0 +1,1369 @@
+//===--- ASTWriterStmt.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/Serialization/ASTWriter.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 clang {
+  class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
+    ASTWriter &Writer;
+    ASTWriter::RecordData &Record;
+
+  public:
+    serialization::StmtCode Code;
+
+    ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
+      : Writer(Writer), Record(Record) { }
+    
+    void
+    AddExplicitTemplateArgumentList(const ExplicitTemplateArgumentList &Args);
+
+    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 VisitParenListExpr(ParenListExpr *E);
+    void VisitUnaryOperator(UnaryOperator *E);
+    void VisitOffsetOfExpr(OffsetOfExpr *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 VisitCXXCatchStmt(CXXCatchStmt *S);
+    void VisitCXXTryStmt(CXXTryStmt *S);
+
+    void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
+    void VisitCXXMemberCallExpr(CXXMemberCallExpr *E);
+    void VisitCXXConstructExpr(CXXConstructExpr *E);
+    void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *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 VisitCXXTypeidExpr(CXXTypeidExpr *E);
+    void VisitCXXThisExpr(CXXThisExpr *E);
+    void VisitCXXThrowExpr(CXXThrowExpr *E);
+    void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
+    void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
+    void VisitCXXBindReferenceExpr(CXXBindReferenceExpr *E);
+
+    void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
+    void VisitCXXNewExpr(CXXNewExpr *E);
+    void VisitCXXDeleteExpr(CXXDeleteExpr *E);
+    void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
+
+    void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
+    void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
+    void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
+    void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
+
+    void VisitOverloadExpr(OverloadExpr *E);
+    void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E);
+    void VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E);
+
+    void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
+  };
+}
+
+void ASTStmtWriter::
+AddExplicitTemplateArgumentList(const ExplicitTemplateArgumentList &Args) {
+  Writer.AddSourceLocation(Args.LAngleLoc, Record);
+  Writer.AddSourceLocation(Args.RAngleLoc, Record);
+  for (unsigned i=0; i != Args.NumTemplateArgs; ++i)
+    Writer.AddTemplateArgumentLoc(Args.getTemplateArgs()[i], Record);
+}
+
+void ASTStmtWriter::VisitStmt(Stmt *S) {
+}
+
+void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
+  VisitStmt(S);
+  Writer.AddSourceLocation(S->getSemiLoc(), Record);
+  Code = serialization::STMT_NULL;
+}
+
+void ASTStmtWriter::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.AddStmt(*CS);
+  Writer.AddSourceLocation(S->getLBracLoc(), Record);
+  Writer.AddSourceLocation(S->getRBracLoc(), Record);
+  Code = serialization::STMT_COMPOUND;
+}
+
+void ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
+  VisitStmt(S);
+  Record.push_back(Writer.getSwitchCaseID(S));
+}
+
+void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
+  VisitSwitchCase(S);
+  Writer.AddStmt(S->getLHS());
+  Writer.AddStmt(S->getRHS());
+  Writer.AddStmt(S->getSubStmt());
+  Writer.AddSourceLocation(S->getCaseLoc(), Record);
+  Writer.AddSourceLocation(S->getEllipsisLoc(), Record);
+  Writer.AddSourceLocation(S->getColonLoc(), Record);
+  Code = serialization::STMT_CASE;
+}
+
+void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
+  VisitSwitchCase(S);
+  Writer.AddStmt(S->getSubStmt());
+  Writer.AddSourceLocation(S->getDefaultLoc(), Record);
+  Writer.AddSourceLocation(S->getColonLoc(), Record);
+  Code = serialization::STMT_DEFAULT;
+}
+
+void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
+  VisitStmt(S);
+  Writer.AddIdentifierRef(S->getID(), Record);
+  Writer.AddStmt(S->getSubStmt());
+  Writer.AddSourceLocation(S->getIdentLoc(), Record);
+  Record.push_back(Writer.GetLabelID(S));
+  Code = serialization::STMT_LABEL;
+}
+
+void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
+  VisitStmt(S);
+  Writer.AddDeclRef(S->getConditionVariable(), Record);
+  Writer.AddStmt(S->getCond());
+  Writer.AddStmt(S->getThen());
+  Writer.AddStmt(S->getElse());
+  Writer.AddSourceLocation(S->getIfLoc(), Record);
+  Writer.AddSourceLocation(S->getElseLoc(), Record);
+  Code = serialization::STMT_IF;
+}
+
+void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
+  VisitStmt(S);
+  Writer.AddDeclRef(S->getConditionVariable(), Record);
+  Writer.AddStmt(S->getCond());
+  Writer.AddStmt(S->getBody());
+  Writer.AddSourceLocation(S->getSwitchLoc(), Record);
+  for (SwitchCase *SC = S->getSwitchCaseList(); SC;
+       SC = SC->getNextSwitchCase())
+    Record.push_back(Writer.RecordSwitchCaseID(SC));
+  Code = serialization::STMT_SWITCH;
+}
+
+void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
+  VisitStmt(S);
+  Writer.AddDeclRef(S->getConditionVariable(), Record);
+  Writer.AddStmt(S->getCond());
+  Writer.AddStmt(S->getBody());
+  Writer.AddSourceLocation(S->getWhileLoc(), Record);
+  Code = serialization::STMT_WHILE;
+}
+
+void ASTStmtWriter::VisitDoStmt(DoStmt *S) {
+  VisitStmt(S);
+  Writer.AddStmt(S->getCond());
+  Writer.AddStmt(S->getBody());
+  Writer.AddSourceLocation(S->getDoLoc(), Record);
+  Writer.AddSourceLocation(S->getWhileLoc(), Record);
+  Writer.AddSourceLocation(S->getRParenLoc(), Record);
+  Code = serialization::STMT_DO;
+}
+
+void ASTStmtWriter::VisitForStmt(ForStmt *S) {
+  VisitStmt(S);
+  Writer.AddStmt(S->getInit());
+  Writer.AddStmt(S->getCond());
+  Writer.AddDeclRef(S->getConditionVariable(), Record);
+  Writer.AddStmt(S->getInc());
+  Writer.AddStmt(S->getBody());
+  Writer.AddSourceLocation(S->getForLoc(), Record);
+  Writer.AddSourceLocation(S->getLParenLoc(), Record);
+  Writer.AddSourceLocation(S->getRParenLoc(), Record);
+  Code = serialization::STMT_FOR;
+}
+
+void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
+  VisitStmt(S);
+  Record.push_back(Writer.GetLabelID(S->getLabel()));
+  Writer.AddSourceLocation(S->getGotoLoc(), Record);
+  Writer.AddSourceLocation(S->getLabelLoc(), Record);
+  Code = serialization::STMT_GOTO;
+}
+
+void ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
+  VisitStmt(S);
+  Writer.AddSourceLocation(S->getGotoLoc(), Record);
+  Writer.AddSourceLocation(S->getStarLoc(), Record);
+  Writer.AddStmt(S->getTarget());
+  Code = serialization::STMT_INDIRECT_GOTO;
+}
+
+void ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
+  VisitStmt(S);
+  Writer.AddSourceLocation(S->getContinueLoc(), Record);
+  Code = serialization::STMT_CONTINUE;
+}
+
+void ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
+  VisitStmt(S);
+  Writer.AddSourceLocation(S->getBreakLoc(), Record);
+  Code = serialization::STMT_BREAK;
+}
+
+void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
+  VisitStmt(S);
+  Writer.AddStmt(S->getRetValue());
+  Writer.AddSourceLocation(S->getReturnLoc(), Record);
+  Writer.AddDeclRef(S->getNRVOCandidate(), Record);
+  Code = serialization::STMT_RETURN;
+}
+
+void ASTStmtWriter::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 = serialization::STMT_DECL;
+}
+
+void ASTStmtWriter::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.AddStmt(S->getAsmString());
+
+  // Outputs
+  for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {      
+    Writer.AddIdentifierRef(S->getOutputIdentifier(I), Record);
+    Writer.AddStmt(S->getOutputConstraintLiteral(I));
+    Writer.AddStmt(S->getOutputExpr(I));
+  }
+
+  // Inputs
+  for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
+    Writer.AddIdentifierRef(S->getInputIdentifier(I), Record);
+    Writer.AddStmt(S->getInputConstraintLiteral(I));
+    Writer.AddStmt(S->getInputExpr(I));
+  }
+
+  // Clobbers
+  for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
+    Writer.AddStmt(S->getClobber(I));
+
+  Code = serialization::STMT_ASM;
+}
+
+void ASTStmtWriter::VisitExpr(Expr *E) {
+  VisitStmt(E);
+  Writer.AddTypeRef(E->getType(), Record);
+  Record.push_back(E->isTypeDependent());
+  Record.push_back(E->isValueDependent());
+}
+
+void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Record.push_back(E->getIdentType()); // FIXME: stable encoding
+  Code = serialization::EXPR_PREDEFINED;
+}
+
+void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
+  VisitExpr(E);
+
+  Record.push_back(E->hasQualifier());
+  unsigned NumTemplateArgs = E->getNumTemplateArgs();
+  assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
+         "Template args list with no args ?");
+  Record.push_back(NumTemplateArgs);
+
+  if (E->hasQualifier()) {
+    Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
+    Writer.AddSourceRange(E->getQualifierRange(), Record);
+  }
+
+  if (NumTemplateArgs)
+    AddExplicitTemplateArgumentList(E->getExplicitTemplateArgs());
+
+  Writer.AddDeclRef(E->getDecl(), Record);
+  // FIXME: write DeclarationNameLoc.
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Code = serialization::EXPR_DECL_REF;
+}
+
+void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Writer.AddAPInt(E->getValue(), Record);
+  Code = serialization::EXPR_INTEGER_LITERAL;
+}
+
+void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
+  VisitExpr(E);
+  Writer.AddAPFloat(E->getValue(), Record);
+  Record.push_back(E->isExact());
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Code = serialization::EXPR_FLOATING_LITERAL;
+}
+
+void ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
+  VisitExpr(E);
+  Writer.AddStmt(E->getSubExpr());
+  Code = serialization::EXPR_IMAGINARY_LITERAL;
+}
+
+void ASTStmtWriter::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 AST file during deserialization.
+  Record.append(E->getString().begin(), E->getString().end());
+  for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
+    Writer.AddSourceLocation(E->getStrTokenLoc(I), Record);
+  Code = serialization::EXPR_STRING_LITERAL;
+}
+
+void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
+  VisitExpr(E);
+  Record.push_back(E->getValue());
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Record.push_back(E->isWide());
+  Code = serialization::EXPR_CHARACTER_LITERAL;
+}
+
+void ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLParen(), Record);
+  Writer.AddSourceLocation(E->getRParen(), Record);
+  Writer.AddStmt(E->getSubExpr());
+  Code = serialization::EXPR_PAREN;
+}
+
+void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->NumExprs);
+  for (unsigned i=0; i != E->NumExprs; ++i)
+    Writer.AddStmt(E->Exprs[i]);
+  Writer.AddSourceLocation(E->LParenLoc, Record);
+  Writer.AddSourceLocation(E->RParenLoc, Record);
+  Code = serialization::EXPR_PAREN_LIST;
+}
+
+void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
+  VisitExpr(E);
+  Writer.AddStmt(E->getSubExpr());
+  Record.push_back(E->getOpcode()); // FIXME: stable encoding
+  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
+  Code = serialization::EXPR_UNARY_OPERATOR;
+}
+
+void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumComponents());
+  Record.push_back(E->getNumExpressions());
+  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
+  for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
+    const OffsetOfExpr::OffsetOfNode &ON = E->getComponent(I);
+    Record.push_back(ON.getKind()); // FIXME: Stable encoding
+    Writer.AddSourceLocation(ON.getRange().getBegin(), Record);
+    Writer.AddSourceLocation(ON.getRange().getEnd(), Record);
+    switch (ON.getKind()) {
+    case OffsetOfExpr::OffsetOfNode::Array:
+      Record.push_back(ON.getArrayExprIndex());
+      break;
+        
+    case OffsetOfExpr::OffsetOfNode::Field:
+      Writer.AddDeclRef(ON.getField(), Record);
+      break;
+        
+    case OffsetOfExpr::OffsetOfNode::Identifier:
+      Writer.AddIdentifierRef(ON.getFieldName(), Record);
+      break;
+        
+    case OffsetOfExpr::OffsetOfNode::Base:
+      Writer.AddCXXBaseSpecifier(*ON.getBase(), Record);
+      break;
+    }
+  }
+  for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
+    Writer.AddStmt(E->getIndexExpr(I));
+  Code = serialization::EXPR_OFFSETOF;
+}
+
+void ASTStmtWriter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->isSizeOf());
+  if (E->isArgumentType())
+    Writer.AddTypeSourceInfo(E->getArgumentTypeInfo(), Record);
+  else {
+    Record.push_back(0);
+    Writer.AddStmt(E->getArgumentExpr());
+  }
+  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = serialization::EXPR_SIZEOF_ALIGN_OF;
+}
+
+void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+  VisitExpr(E);
+  Writer.AddStmt(E->getLHS());
+  Writer.AddStmt(E->getRHS());
+  Writer.AddSourceLocation(E->getRBracketLoc(), Record);
+  Code = serialization::EXPR_ARRAY_SUBSCRIPT;
+}
+
+void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumArgs());
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Writer.AddStmt(E->getCallee());
+  for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
+       Arg != ArgEnd; ++Arg)
+    Writer.AddStmt(*Arg);
+  Code = serialization::EXPR_CALL;
+}
+
+void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
+  // Don't call VisitExpr, we'll write everything here.
+
+  Record.push_back(E->hasQualifier());
+  if (E->hasQualifier()) {
+    Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
+    Writer.AddSourceRange(E->getQualifierRange(), Record);
+  }
+
+  unsigned NumTemplateArgs = E->getNumTemplateArgs();
+  assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
+         "Template args list with no args ?");
+  Record.push_back(NumTemplateArgs);
+  if (NumTemplateArgs) {
+    Writer.AddSourceLocation(E->getLAngleLoc(), Record);
+    Writer.AddSourceLocation(E->getRAngleLoc(), Record);
+    for (unsigned i=0; i != NumTemplateArgs; ++i)
+      Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
+  }
+  
+  DeclAccessPair FoundDecl = E->getFoundDecl();
+  Writer.AddDeclRef(FoundDecl.getDecl(), Record);
+  Record.push_back(FoundDecl.getAccess());
+
+  Writer.AddTypeRef(E->getType(), Record);
+  Writer.AddStmt(E->getBase());
+  Writer.AddDeclRef(E->getMemberDecl(), Record);
+  // FIXME: write DeclarationNameLoc.
+  Writer.AddSourceLocation(E->getMemberLoc(), Record);
+  Record.push_back(E->isArrow());
+  Code = serialization::EXPR_MEMBER;
+}
+
+void ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
+  VisitExpr(E);
+  Writer.AddStmt(E->getBase());
+  Writer.AddSourceLocation(E->getIsaMemberLoc(), Record);
+  Record.push_back(E->isArrow());
+  Code = serialization::EXPR_OBJC_ISA;
+}
+
+void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->path_size());
+  Writer.AddStmt(E->getSubExpr());
+  Record.push_back(E->getCastKind()); // FIXME: stable encoding
+
+  for (CastExpr::path_iterator
+         PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
+    Writer.AddCXXBaseSpecifier(**PI, Record);
+}
+
+void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
+  VisitExpr(E);
+  Writer.AddStmt(E->getLHS());
+  Writer.AddStmt(E->getRHS());
+  Record.push_back(E->getOpcode()); // FIXME: stable encoding
+  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
+  Code = serialization::EXPR_BINARY_OPERATOR;
+}
+
+void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
+  VisitBinaryOperator(E);
+  Writer.AddTypeRef(E->getComputationLHSType(), Record);
+  Writer.AddTypeRef(E->getComputationResultType(), Record);
+  Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
+}
+
+void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
+  VisitExpr(E);
+  Writer.AddStmt(E->getCond());
+  Writer.AddStmt(E->getLHS());
+  Writer.AddStmt(E->getRHS());
+  Writer.AddSourceLocation(E->getQuestionLoc(), Record);
+  Writer.AddSourceLocation(E->getColonLoc(), Record);
+  Code = serialization::EXPR_CONDITIONAL_OPERATOR;
+}
+
+void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
+  VisitCastExpr(E);
+  Record.push_back(E->getValueKind());
+  Code = serialization::EXPR_IMPLICIT_CAST;
+}
+
+void ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
+  VisitCastExpr(E);
+  Writer.AddTypeSourceInfo(E->getTypeInfoAsWritten(), Record);
+}
+
+void ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
+  VisitExplicitCastExpr(E);
+  Writer.AddSourceLocation(E->getLParenLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = serialization::EXPR_CSTYLE_CAST;
+}
+
+void ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLParenLoc(), Record);
+  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
+  Writer.AddStmt(E->getInitializer());
+  Record.push_back(E->isFileScope());
+  Code = serialization::EXPR_COMPOUND_LITERAL;
+}
+
+void ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
+  VisitExpr(E);
+  Writer.AddStmt(E->getBase());
+  Writer.AddIdentifierRef(&E->getAccessor(), Record);
+  Writer.AddSourceLocation(E->getAccessorLoc(), Record);
+  Code = serialization::EXPR_EXT_VECTOR_ELEMENT;
+}
+
+void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumInits());
+  for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
+    Writer.AddStmt(E->getInit(I));
+  Writer.AddStmt(E->getSyntacticForm());
+  Writer.AddSourceLocation(E->getLBraceLoc(), Record);
+  Writer.AddSourceLocation(E->getRBraceLoc(), Record);
+  Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record);
+  Record.push_back(E->hadArrayRangeDesignator());
+  Code = serialization::EXPR_INIT_LIST;
+}
+
+void ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumSubExprs());
+  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
+    Writer.AddStmt(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(serialization::DESIG_FIELD_DECL);
+        Writer.AddDeclRef(Field, Record);
+      } else {
+        Record.push_back(serialization::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(serialization::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(serialization::DESIG_ARRAY_RANGE);
+      Record.push_back(D->getFirstExprIndex());
+      Writer.AddSourceLocation(D->getLBracketLoc(), Record);
+      Writer.AddSourceLocation(D->getEllipsisLoc(), Record);
+      Writer.AddSourceLocation(D->getRBracketLoc(), Record);
+    }
+  }
+  Code = serialization::EXPR_DESIGNATED_INIT;
+}
+
+void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
+  VisitExpr(E);
+  Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
+}
+
+void ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
+  VisitExpr(E);
+  Writer.AddStmt(E->getSubExpr());
+  Writer.AddTypeSourceInfo(E->getWrittenTypeInfo(), Record);
+  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = serialization::EXPR_VA_ARG;
+}
+
+void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getAmpAmpLoc(), Record);
+  Writer.AddSourceLocation(E->getLabelLoc(), Record);
+  Record.push_back(Writer.GetLabelID(E->getLabel()));
+  Code = serialization::EXPR_ADDR_LABEL;
+}
+
+void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
+  VisitExpr(E);
+  Writer.AddStmt(E->getSubStmt());
+  Writer.AddSourceLocation(E->getLParenLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = serialization::EXPR_STMT;
+}
+
+void ASTStmtWriter::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) {
+  VisitExpr(E);
+  Writer.AddTypeSourceInfo(E->getArgTInfo1(), Record);
+  Writer.AddTypeSourceInfo(E->getArgTInfo2(), Record);
+  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = serialization::EXPR_TYPES_COMPATIBLE;
+}
+
+void ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) {
+  VisitExpr(E);
+  Writer.AddStmt(E->getCond());
+  Writer.AddStmt(E->getLHS());
+  Writer.AddStmt(E->getRHS());
+  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = serialization::EXPR_CHOOSE;
+}
+
+void ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getTokenLocation(), Record);
+  Code = serialization::EXPR_GNU_NULL;
+}
+
+void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumSubExprs());
+  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
+    Writer.AddStmt(E->getExpr(I));
+  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = serialization::EXPR_SHUFFLE_VECTOR;
+}
+
+void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getBlockDecl(), Record);
+  Record.push_back(E->hasBlockDeclRefExprs());
+  Code = serialization::EXPR_BLOCK;
+}
+
+void ASTStmtWriter::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());
+  Writer.AddStmt(E->getCopyConstructorExpr());
+  Code = serialization::EXPR_BLOCK_DECL_REF;
+}
+
+//===----------------------------------------------------------------------===//
+// Objective-C Expressions and Statements.
+//===----------------------------------------------------------------------===//
+
+void ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
+  VisitExpr(E);
+  Writer.AddStmt(E->getString());
+  Writer.AddSourceLocation(E->getAtLoc(), Record);
+  Code = serialization::EXPR_OBJC_STRING_LITERAL;
+}
+
+void ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+  VisitExpr(E);
+  Writer.AddTypeSourceInfo(E->getEncodedTypeSourceInfo(), Record);
+  Writer.AddSourceLocation(E->getAtLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = serialization::EXPR_OBJC_ENCODE;
+}
+
+void ASTStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
+  VisitExpr(E);
+  Writer.AddSelectorRef(E->getSelector(), Record);
+  Writer.AddSourceLocation(E->getAtLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = serialization::EXPR_OBJC_SELECTOR_EXPR;
+}
+
+void ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getProtocol(), Record);
+  Writer.AddSourceLocation(E->getAtLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
+}
+
+void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getDecl(), Record);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Writer.AddStmt(E->getBase());
+  Record.push_back(E->isArrow());
+  Record.push_back(E->isFreeIvar());
+  Code = serialization::EXPR_OBJC_IVAR_REF_EXPR;
+}
+
+void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getProperty(), Record);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Writer.AddStmt(E->getBase());
+  Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
+}
+
+void ASTStmtWriter::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.AddStmt(E->getBase());
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Writer.AddSourceLocation(E->getClassLoc(), Record);
+  Code = serialization::EXPR_OBJC_KVC_REF_EXPR;
+}
+
+void ASTStmtWriter::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.AddStmt(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.AddStmt(*Arg);
+  Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
+}
+
+void ASTStmtWriter::VisitObjCSuperExpr(ObjCSuperExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLoc(), Record);
+  Code = serialization::EXPR_OBJC_SUPER_EXPR;
+}
+
+void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
+  VisitStmt(S);
+  Writer.AddStmt(S->getElement());
+  Writer.AddStmt(S->getCollection());
+  Writer.AddStmt(S->getBody());
+  Writer.AddSourceLocation(S->getForLoc(), Record);
+  Writer.AddSourceLocation(S->getRParenLoc(), Record);
+  Code = serialization::STMT_OBJC_FOR_COLLECTION;
+}
+
+void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
+  Writer.AddStmt(S->getCatchBody());
+  Writer.AddDeclRef(S->getCatchParamDecl(), Record);
+  Writer.AddSourceLocation(S->getAtCatchLoc(), Record);
+  Writer.AddSourceLocation(S->getRParenLoc(), Record);
+  Code = serialization::STMT_OBJC_CATCH;
+}
+
+void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
+  Writer.AddStmt(S->getFinallyBody());
+  Writer.AddSourceLocation(S->getAtFinallyLoc(), Record);
+  Code = serialization::STMT_OBJC_FINALLY;
+}
+
+void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
+  Record.push_back(S->getNumCatchStmts());
+  Record.push_back(S->getFinallyStmt() != 0);
+  Writer.AddStmt(S->getTryBody());
+  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
+    Writer.AddStmt(S->getCatchStmt(I));
+  if (S->getFinallyStmt())
+    Writer.AddStmt(S->getFinallyStmt());
+  Writer.AddSourceLocation(S->getAtTryLoc(), Record);
+  Code = serialization::STMT_OBJC_AT_TRY;
+}
+
+void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
+  Writer.AddStmt(S->getSynchExpr());
+  Writer.AddStmt(S->getSynchBody());
+  Writer.AddSourceLocation(S->getAtSynchronizedLoc(), Record);
+  Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
+}
+
+void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
+  Writer.AddStmt(S->getThrowExpr());
+  Writer.AddSourceLocation(S->getThrowLoc(), Record);
+  Code = serialization::STMT_OBJC_AT_THROW;
+}
+
+//===----------------------------------------------------------------------===//
+// C++ Expressions and Statements.
+//===----------------------------------------------------------------------===//
+
+void ASTStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
+  VisitStmt(S);
+  Writer.AddSourceLocation(S->getCatchLoc(), Record);
+  Writer.AddDeclRef(S->getExceptionDecl(), Record);
+  Writer.AddStmt(S->getHandlerBlock());
+  Code = serialization::STMT_CXX_CATCH;
+}
+
+void ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
+  VisitStmt(S);
+  Record.push_back(S->getNumHandlers());
+  Writer.AddSourceLocation(S->getTryLoc(), Record);
+  Writer.AddStmt(S->getTryBlock());
+  for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
+    Writer.AddStmt(S->getHandler(i));
+  Code = serialization::STMT_CXX_TRY;
+}
+
+void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+  VisitCallExpr(E);
+  Record.push_back(E->getOperator());
+  Code = serialization::EXPR_CXX_OPERATOR_CALL;
+}
+
+void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
+  VisitCallExpr(E);
+  Code = serialization::EXPR_CXX_MEMBER_CALL;
+}
+
+void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumArgs());
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
+    Writer.AddStmt(E->getArg(I));
+  Writer.AddDeclRef(E->getConstructor(), Record);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Record.push_back(E->isElidable());
+  Record.push_back(E->requiresZeroInitialization());
+  Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
+  Code = serialization::EXPR_CXX_CONSTRUCT;
+}
+
+void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
+  VisitCXXConstructExpr(E);
+  Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
+}
+
+void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
+  VisitExplicitCastExpr(E);
+  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
+}
+
+void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
+  VisitCXXNamedCastExpr(E);
+  Code = serialization::EXPR_CXX_STATIC_CAST;
+}
+
+void ASTStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
+  VisitCXXNamedCastExpr(E);
+  Code = serialization::EXPR_CXX_DYNAMIC_CAST;
+}
+
+void ASTStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
+  VisitCXXNamedCastExpr(E);
+  Code = serialization::EXPR_CXX_REINTERPRET_CAST;
+}
+
+void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
+  VisitCXXNamedCastExpr(E);
+  Code = serialization::EXPR_CXX_CONST_CAST;
+}
+
+void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
+  VisitExplicitCastExpr(E);
+  Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
+}
+
+void ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getValue());
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Code = serialization::EXPR_CXX_BOOL_LITERAL;
+}
+
+void ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
+}
+
+void ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceRange(E->getSourceRange(), Record);
+  if (E->isTypeOperand()) {
+    Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
+    Code = serialization::EXPR_CXX_TYPEID_TYPE;
+  } else {
+    Writer.AddStmt(E->getExprOperand());
+    Code = serialization::EXPR_CXX_TYPEID_EXPR;
+  }
+}
+
+void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Record.push_back(E->isImplicit());
+  Code = serialization::EXPR_CXX_THIS;
+}
+
+void ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getThrowLoc(), Record);
+  Writer.AddStmt(E->getSubExpr());
+  Code = serialization::EXPR_CXX_THROW;
+}
+
+void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
+  VisitExpr(E);
+
+  bool HasOtherExprStored = E->Param.getInt();
+  // Store these first, the reader reads them before creation.
+  Record.push_back(HasOtherExprStored);
+  if (HasOtherExprStored)
+    Writer.AddStmt(E->getExpr());
+  Writer.AddDeclRef(E->getParam(), Record);
+  Writer.AddSourceLocation(E->getUsedLocation(), Record);
+
+  Code = serialization::EXPR_CXX_DEFAULT_ARG;
+}
+
+void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
+  VisitExpr(E);
+  Writer.AddCXXTemporary(E->getTemporary(), Record);
+  Writer.AddStmt(E->getSubExpr());
+  Code = serialization::EXPR_CXX_BIND_TEMPORARY;
+}
+
+void ASTStmtWriter::VisitCXXBindReferenceExpr(CXXBindReferenceExpr *E) {
+  VisitExpr(E);
+  Writer.AddStmt(E->getSubExpr());
+  Record.push_back(E->extendsLifetime());
+  Record.push_back(E->requiresTemporaryCopy());
+  Code = serialization::EXPR_CXX_BIND_REFERENCE;
+}
+
+void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
+}
+
+void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->isGlobalNew());
+  Record.push_back(E->hasInitializer());
+  Record.push_back(E->isArray());
+  Record.push_back(E->getNumPlacementArgs());
+  Record.push_back(E->getNumConstructorArgs());
+  Writer.AddDeclRef(E->getOperatorNew(), Record);
+  Writer.AddDeclRef(E->getOperatorDelete(), Record);
+  Writer.AddDeclRef(E->getConstructor(), Record);
+  Writer.AddSourceRange(E->getTypeIdParens(), Record);
+  Writer.AddSourceLocation(E->getStartLoc(), Record);
+  Writer.AddSourceLocation(E->getEndLoc(), Record);
+  for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end();
+       I != e; ++I)
+    Writer.AddStmt(*I);
+  
+  Code = serialization::EXPR_CXX_NEW;
+}
+
+void ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->isGlobalDelete());
+  Record.push_back(E->isArrayForm());
+  Writer.AddDeclRef(E->getOperatorDelete(), Record);
+  Writer.AddStmt(E->getArgument());
+  Writer.AddSourceLocation(E->getSourceRange().getBegin(), Record);
+  
+  Code = serialization::EXPR_CXX_DELETE;
+}
+
+void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
+  VisitExpr(E);
+
+  Writer.AddStmt(E->getBase());
+  Record.push_back(E->isArrow());
+  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
+  Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
+  Writer.AddSourceRange(E->getQualifierRange(), Record);
+  Writer.AddTypeSourceInfo(E->getScopeTypeInfo(), Record);
+  Writer.AddSourceLocation(E->getColonColonLoc(), Record);
+  Writer.AddSourceLocation(E->getTildeLoc(), Record);
+
+  // PseudoDestructorTypeStorage.
+  Writer.AddIdentifierRef(E->getDestroyedTypeIdentifier(), Record);
+  if (E->getDestroyedTypeIdentifier())
+    Writer.AddSourceLocation(E->getDestroyedTypeLoc(), Record);
+  else
+    Writer.AddTypeSourceInfo(E->getDestroyedTypeInfo(), Record);
+
+  Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
+}
+
+void ASTStmtWriter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumTemporaries());
+  for (unsigned i = 0, e = E->getNumTemporaries(); i != e; ++i)
+    Writer.AddCXXTemporary(E->getTemporary(i), Record);
+  
+  Writer.AddStmt(E->getSubExpr());
+  Code = serialization::EXPR_CXX_EXPR_WITH_TEMPORARIES;
+}
+
+void
+ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
+  VisitExpr(E);
+  
+  // Don't emit anything here, NumTemplateArgs must be emitted first.
+
+  if (E->hasExplicitTemplateArgs()) {
+    const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
+    assert(Args.NumTemplateArgs &&
+           "Num of template args was zero! AST reading will mess up!");
+    Record.push_back(Args.NumTemplateArgs);
+    AddExplicitTemplateArgumentList(Args);
+  } else {
+    Record.push_back(0);
+  }
+  
+  if (!E->isImplicitAccess())
+    Writer.AddStmt(E->getBase());
+  else
+    Writer.AddStmt(0);
+  Writer.AddTypeRef(E->getBaseType(), Record);
+  Record.push_back(E->isArrow());
+  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
+  Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
+  Writer.AddSourceRange(E->getQualifierRange(), Record);
+  Writer.AddDeclRef(E->getFirstQualifierFoundInScope(), Record);
+  // FIXME: write whole DeclarationNameInfo.
+  Writer.AddDeclarationName(E->getMember(), Record);
+  Writer.AddSourceLocation(E->getMemberLoc(), Record);
+  Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
+}
+
+void
+ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+  VisitExpr(E);
+  
+  // Don't emit anything here, NumTemplateArgs must be emitted first.
+
+  if (E->hasExplicitTemplateArgs()) {
+    const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
+    assert(Args.NumTemplateArgs &&
+           "Num of template args was zero! AST reading will mess up!");
+    Record.push_back(Args.NumTemplateArgs);
+    AddExplicitTemplateArgumentList(Args);
+  } else {
+    Record.push_back(0);
+  }
+
+  // FIXME: write whole DeclarationNameInfo.
+  Writer.AddDeclarationName(E->getDeclName(), Record);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Writer.AddSourceRange(E->getQualifierRange(), Record);
+  Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
+  Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
+}
+
+void
+ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->arg_size());
+  for (CXXUnresolvedConstructExpr::arg_iterator
+         ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
+    Writer.AddStmt(*ArgI);
+  Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
+  Writer.AddTypeRef(E->getTypeAsWritten(), Record);
+  Writer.AddSourceLocation(E->getLParenLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
+}
+
+void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
+  VisitExpr(E);
+  
+  // Don't emit anything here, NumTemplateArgs must be emitted first.
+
+  if (E->hasExplicitTemplateArgs()) {
+    const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
+    assert(Args.NumTemplateArgs &&
+           "Num of template args was zero! AST reading will mess up!");
+    Record.push_back(Args.NumTemplateArgs);
+    AddExplicitTemplateArgumentList(Args);
+  } else {
+    Record.push_back(0);
+  }
+
+  Record.push_back(E->getNumDecls());
+  for (OverloadExpr::decls_iterator
+         OvI = E->decls_begin(), OvE = E->decls_end(); OvI != OvE; ++OvI) {
+    Writer.AddDeclRef(OvI.getDecl(), Record);
+    Record.push_back(OvI.getAccess());
+  }
+
+  // FIXME: write whole DeclarationNameInfo.
+  Writer.AddDeclarationName(E->getName(), Record);
+  Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
+  Writer.AddSourceRange(E->getQualifierRange(), Record);
+  Writer.AddSourceLocation(E->getNameLoc(), Record);
+}
+
+void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
+  VisitOverloadExpr(E);
+  Record.push_back(E->isArrow());
+  Record.push_back(E->hasUnresolvedUsing());
+  Writer.AddStmt(!E->isImplicitAccess() ? E->getBase() : 0);
+  Writer.AddTypeRef(E->getBaseType(), Record);
+  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
+  Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
+}
+
+void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
+  VisitOverloadExpr(E);
+  Record.push_back(E->requiresADL());
+  Record.push_back(E->isOverloaded());
+  Writer.AddDeclRef(E->getNamingClass(), Record);
+  Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
+}
+
+void ASTStmtWriter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getTrait());
+  Writer.AddSourceRange(E->getSourceRange(), Record);
+  Writer.AddTypeRef(E->getQueriedType(), Record);
+  Code = serialization::EXPR_CXX_UNARY_TYPE_TRAIT;
+}
+
+//===----------------------------------------------------------------------===//
+// ASTWriter Implementation
+//===----------------------------------------------------------------------===//
+
+unsigned ASTWriter::RecordSwitchCaseID(SwitchCase *S) {
+  assert(SwitchCaseIDs.find(S) == SwitchCaseIDs.end() &&
+         "SwitchCase recorded twice");
+  unsigned NextID = SwitchCaseIDs.size();
+  SwitchCaseIDs[S] = NextID;
+  return NextID;
+}
+
+unsigned ASTWriter::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 ASTWriter::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 ASTWriter::WriteSubStmt(Stmt *S) {
+  RecordData Record;
+  ASTStmtWriter Writer(*this, Record);
+  ++NumStatements;
+  
+  if (!S) {
+    Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
+    return;
+  }
+
+  // Redirect ASTWriter::AddStmt to collect sub stmts.
+  llvm::SmallVector<Stmt *, 16> SubStmts;
+  CollectedStmts = &SubStmts;
+
+  Writer.Code = serialization::STMT_NULL_PTR;
+  Writer.Visit(S);
+  
+#ifndef NDEBUG
+  if (Writer.Code == serialization::STMT_NULL_PTR) {
+    SourceManager &SrcMgr
+      = DeclIDs.begin()->first->getASTContext().getSourceManager();
+    S->dump(SrcMgr);
+    assert(0 && "Unhandled sub statement writing AST file");
+  }
+#endif
+
+  // Revert ASTWriter::AddStmt.
+  CollectedStmts = &StmtsToEmit;
+
+  // Write the sub stmts in reverse order, last to first. When reading them back
+  // we will read them in correct order by "pop"ing them from the Stmts stack.
+  // This simplifies reading and allows to store a variable number of sub stmts
+  // without knowing it in advance.
+  while (!SubStmts.empty())
+    WriteSubStmt(SubStmts.pop_back_val());
+  
+  Stream.EmitRecord(Writer.Code, Record);
+}
+
+/// \brief Flush all of the statements that have been added to the
+/// queue via AddStmt().
+void ASTWriter::FlushStmts() {
+  RecordData Record;
+
+  for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
+    WriteSubStmt(StmtsToEmit[I]);
+    
+    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.
+    Stream.EmitRecord(serialization::STMT_STOP, Record);
+  }
+
+  StmtsToEmit.clear();
+}
diff --git a/lib/Serialization/CMakeLists.txt b/lib/Serialization/CMakeLists.txt
new file mode 100644
index 0000000..d863c17
--- /dev/null
+++ b/lib/Serialization/CMakeLists.txt
@@ -0,0 +1,23 @@
+set(LLVM_NO_RTTI 1)
+
+add_clang_library(clangSerialization
+  GeneratePCH.cpp
+  ASTCommon.cpp
+  ASTReader.cpp
+  ASTReaderDecl.cpp
+  ASTReaderStmt.cpp
+  ASTWriter.cpp
+  ASTWriterDecl.cpp
+  ASTWriterStmt.cpp
+  )
+
+add_dependencies(clangSerialization
+  ClangAttrClasses
+  ClangAttrList
+  ClangAttrPCHRead
+  ClangAttrPCHWrite
+  ClangDiagnosticFrontend
+  ClangDiagnosticLex
+  ClangDiagnosticSema
+  ClangDeclNodes
+  ClangStmtNodes)
diff --git a/lib/Serialization/GeneratePCH.cpp b/lib/Serialization/GeneratePCH.cpp
new file mode 100644
index 0000000..5329b6c
--- /dev/null
+++ b/lib/Serialization/GeneratePCH.cpp
@@ -0,0 +1,64 @@
+//===--- 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
+//  ASTConsumer that generates a PCH file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Serialization/ASTWriter.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;
+
+PCHGenerator::PCHGenerator(const Preprocessor &PP,
+                           bool Chaining,
+                           const char *isysroot,
+                           llvm::raw_ostream *OS)
+  : PP(PP), isysroot(isysroot), Out(OS), SemaPtr(0),
+    StatCalls(0), Stream(Buffer), Writer(Stream) {
+
+  // Install a stat() listener to keep track of all of the stat()
+  // calls.
+  StatCalls = new MemorizeStatCalls;
+  // If we have a chain, we want new stat calls only, so install the memorizer
+  // *after* the already installed ASTReader's stat cache.
+  PP.getFileManager().addStatCache(StatCalls,
+    /*AtBeginning=*/!Chaining);
+}
+
+void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
+  if (PP.getDiagnostics().hasErrorOccurred())
+    return;
+
+  // Emit the PCH file
+  assert(SemaPtr && "No Sema?");
+  Writer.WriteAST(*SemaPtr, StatCalls, isysroot);
+
+  // Write the generated bitstream to "Out".
+  Out->write((char *)&Buffer.front(), Buffer.size());
+
+  // Make sure it hits disk now.
+  Out->flush();
+
+  // Free up some memory, in case the process is kept alive.
+  Buffer.clear();
+}
+
+ASTDeserializationListener *PCHGenerator::GetASTDeserializationListener() {
+  return &Writer;
+}
diff --git a/lib/Serialization/Makefile b/lib/Serialization/Makefile
new file mode 100644
index 0000000..e89ddc3
--- /dev/null
+++ b/lib/Serialization/Makefile
@@ -0,0 +1,19 @@
+##===- clang/lib/Serialization/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.
+#
+##===----------------------------------------------------------------------===##
+
+CLANG_LEVEL := ../..
+LIBRARYNAME := clangSerialization
+
+include $(CLANG_LEVEL)/Makefile
+
diff --git a/runtime/Makefile b/runtime/Makefile
new file mode 100644
index 0000000..0e8b359
--- /dev/null
+++ b/runtime/Makefile
@@ -0,0 +1,104 @@
+##===- clang/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).
+#
+##===----------------------------------------------------------------------===##
+
+CLANG_LEVEL := ..
+include $(CLANG_LEVEL)/Makefile
+
+CLANG_VERSION := $(word 3,$(shell grep "CLANG_VERSION " \
+	$(PROJ_OBJ_DIR)/$(CLANG_LEVEL)/include/clang/Basic/Version.inc))
+
+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
+
+ifndef CLANG_NO_RUNTIME
+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) \
+	  CC="$(ToolDir)/clang -no-integrated-as" \
+	  $(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
+endif
diff --git a/test/ASTMerge/Inputs/class1.cpp b/test/ASTMerge/Inputs/class1.cpp
new file mode 100644
index 0000000..e13faf0
--- /dev/null
+++ b/test/ASTMerge/Inputs/class1.cpp
@@ -0,0 +1,8 @@
+struct A {
+  int x;
+};
+
+struct B : A {
+  float y;
+  float foo();
+};
diff --git a/test/ASTMerge/Inputs/class2.cpp b/test/ASTMerge/Inputs/class2.cpp
new file mode 100644
index 0000000..91b84dc
--- /dev/null
+++ b/test/ASTMerge/Inputs/class2.cpp
@@ -0,0 +1,8 @@
+struct A {
+  int x;
+};
+
+struct B : A {
+  int y;
+  int foo();
+};
diff --git a/test/ASTMerge/class.cpp b/test/ASTMerge/class.cpp
new file mode 100644
index 0000000..114687f
--- /dev/null
+++ b/test/ASTMerge/class.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/class1.cpp
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/class2.cpp
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: class1.cpp:5:8: warning: type 'B' has incompatible definitions in different translation units
+// CHECK: class1.cpp:6:9: note: field 'y' has type 'float' here
+// CHECK: class2.cpp:6:7: note: field 'y' has type 'int' here
+
+// FIXME: we should also complain about mismatched types on the method
diff --git a/test/Analysis/PR7218.c b/test/Analysis/PR7218.c
new file mode 100644
index 0000000..635e56f
--- /dev/null
+++ b/test/Analysis/PR7218.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store region -verify %s
+char PR7218(char a) {
+    char buf[2];
+    buf[0] = a;
+    return buf[1]; // expected-warning {{Undefined or garbage value returned to caller}}
+}
diff --git a/test/Analysis/additive-folding-range-constraints.c b/test/Analysis/additive-folding-range-constraints.c
new file mode 100644
index 0000000..a8ca5d2
--- /dev/null
+++ b/test/Analysis/additive-folding-range-constraints.c
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-experimental-checks -verify -analyzer-constraints=range %s
+
+// These are used to trigger warnings.
+typedef typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void free(void *);
+#define NULL ((void*)0)
+#define UINT_MAX (__INT_MAX__  *2U +1U)
+
+// Each of these adjusted ranges has an adjustment small enough to split the
+// solution range across an overflow boundary (Min for <, Max for >).
+// This corresponds to one set of branches in RangeConstraintManager.
+void smallAdjustmentGT (unsigned a) {
+  char* b = NULL;
+  if (a+2 > 1)
+    b = malloc(1);
+  if (a == UINT_MAX-1 || a == UINT_MAX)
+    return; // no-warning
+  else if (a < UINT_MAX-1)
+    free(b);
+  return; // no-warning
+}
+
+void smallAdjustmentGE (unsigned a) {
+  char* b = NULL;
+  if (a+2 >= 1)
+    b = malloc(1);
+  if (a == UINT_MAX-1)
+    return; // no-warning
+  else if (a < UINT_MAX-1 || a == UINT_MAX)
+    free(b);
+  return; // no-warning
+}
+
+void smallAdjustmentLT (unsigned a) {
+  char* b = NULL;
+  if (a+1 < 2)
+    b = malloc(1);
+  if (a == 0 || a == UINT_MAX)
+    free(b);
+  return; // no-warning
+}
+
+void smallAdjustmentLE (unsigned a) {
+  char* b = NULL;
+  if (a+1 <= 2)
+    b = malloc(1);
+  if (a == 0 || a == 1 || a == UINT_MAX)
+    free(b);
+  return; // no-warning
+}
+
+
+// Each of these adjusted ranges has an adjustment large enough to push the
+// comparison value over an overflow boundary (Min for <, Max for >).
+// This corresponds to one set of branches in RangeConstraintManager.
+void largeAdjustmentGT (unsigned a) {
+  char* b = NULL;
+  if (a-2 > UINT_MAX-1)
+    b = malloc(1);
+  if (a == 1 || a == 0)
+    free(b);
+  else if (a > 1)
+    free(b);
+  return; // no-warning
+}
+
+void largeAdjustmentGE (unsigned a) {
+  char* b = NULL;
+  if (a-2 >= UINT_MAX-1)
+    b = malloc(1);
+  if (a > 1)
+    return; // no-warning
+  else if (a == 1 || a == 0)
+    free(b);
+  return; // no-warning
+}
+
+void largeAdjustmentLT (unsigned a) {
+  char* b = NULL;
+  if (a+2 < 1)
+    b = malloc(1);
+  if (a == UINT_MAX-1 || a == UINT_MAX)
+    free(b);
+  else if (a < UINT_MAX-1)
+    return; // no-warning
+  return; // no-warning
+}
+
+void largeAdjustmentLE (unsigned a) {
+  char* b = NULL;
+  if (a+2 <= 1)
+    b = malloc(1);
+  if (a < UINT_MAX-1)
+    return; // no-warning
+  else if (a == UINT_MAX-1 || a == UINT_MAX)
+    free(b);
+  return; // no-warning
+}
diff --git a/test/Analysis/additive-folding.c b/test/Analysis/additive-folding.c
new file mode 100644
index 0000000..e4a5651
--- /dev/null
+++ b/test/Analysis/additive-folding.c
@@ -0,0 +1,203 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-experimental-checks -verify -analyzer-constraints=basic %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-experimental-checks -verify -analyzer-constraints=range %s
+
+// These are used to trigger warnings.
+typedef typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void free(void *);
+#define NULL ((void*)0)
+#define UINT_MAX -1U
+
+//---------------
+//  Plus/minus
+//---------------
+
+void separateExpressions (int a) {
+  int b = a + 1;
+  --b;
+
+  char* buf = malloc(1);
+  if (a != 0 && b == 0)
+    return; // expected-warning{{never executed}}
+  free(buf);
+}
+
+void oneLongExpression (int a) {
+  // Expression canonicalization should still allow this to work, even though
+  // the first term is on the left.
+  int b = 15 + a + 15 - 10 - 20;
+
+  char* buf = malloc(1);
+  if (a != 0 && b == 0)
+    return; // expected-warning{{never executed}}
+  free(buf);
+}
+
+void mixedTypes (int a) {
+  char* buf = malloc(1);
+
+  // Different additive types should not cause crashes when constant-folding.
+  // This is part of PR7406.
+  int b = a + 1LL;
+  if (a != 0 && (b-1) == 0) // not crash
+    return; // expected-warning{{never executed}}
+
+  int c = a + 1U;
+  if (a != 0 && (c-1) == 0) // not crash
+    return; // expected-warning{{never executed}}
+
+  free(buf);
+}
+
+//---------------
+//  Comparisons
+//---------------
+
+// Equality and inequality only
+void eq_ne (unsigned a) {
+  char* b = NULL;
+  if (a == UINT_MAX)
+    b = malloc(1);
+  if (a+1 != 0)
+    return; // no-warning
+  if (a-1 != UINT_MAX-1)
+    return; // no-warning
+  free(b);
+}
+
+void ne_eq (unsigned a) {
+  char* b = NULL;
+  if (a != UINT_MAX)
+    b = malloc(1);
+  if (a+1 == 0)
+    return; // no-warning
+  if (a-1 == UINT_MAX-1)
+    return; // no-warning
+  free(b);
+}
+
+// Mixed typed inequalities (part of PR7406)
+// These should not crash.
+void mixed_eq_ne (int a) {
+  char* b = NULL;
+  if (a == 1)
+    b = malloc(1);
+  if (a+1U != 2)
+    return; // no-warning
+  if (a-1U != 0)
+    return; // expected-warning{{never executed}}
+  free(b);
+}
+
+void mixed_ne_eq (int a) {
+  char* b = NULL;
+  if (a != 1)
+    b = malloc(1);
+  if (a+1U == 2)
+    return; // no-warning
+  if (a-1U == 0)
+    return; // expected-warning{{never executed}}
+  free(b);
+}
+
+
+// Simple order comparisons with no adjustment
+void baselineGT (unsigned a) {
+  char* b = NULL;
+  if (a > 0)
+    b = malloc(1);
+  if (a == 0)
+    return; // no-warning
+  free(b);
+}
+
+void baselineGE (unsigned a) {
+  char* b = NULL;
+  if (a >= UINT_MAX)
+    b = malloc(1);
+  if (a == UINT_MAX)
+    free(b);
+  return; // no-warning
+}
+
+void baselineLT (unsigned a) {
+  char* b = NULL;
+  if (a < UINT_MAX)
+    b = malloc(1);
+  if (a == UINT_MAX)
+    return; // no-warning
+  free(b);
+}
+
+void baselineLE (unsigned a) {
+  char* b = NULL;
+  if (a <= 0)
+    b = malloc(1);
+  if (a == 0)
+    free(b);
+  return; // no-warning
+}
+
+
+// Adjustment gives each of these an extra solution!
+void adjustedGT (unsigned a) {
+  char* b = NULL;
+  if (a-1 > UINT_MAX-1)
+    b = malloc(1);
+  return; // expected-warning{{leak}}
+}
+
+void adjustedGE (unsigned a) {
+  char* b = NULL;
+  if (a-1 >= UINT_MAX-1)
+    b = malloc(1);
+  if (a == UINT_MAX)
+    free(b);
+  return; // expected-warning{{leak}}
+}
+
+void adjustedLT (unsigned a) {
+  char* b = NULL;
+  if (a+1 < 1)
+    b = malloc(1);
+  return; // expected-warning{{leak}}
+}
+
+void adjustedLE (unsigned a) {
+  char* b = NULL;
+  if (a+1 <= 1)
+    b = malloc(1);
+  if (a == 0)
+    free(b);
+  return; // expected-warning{{leak}}
+}
+
+
+// Tautologies
+void tautologyGT (unsigned a) {
+  char* b = malloc(1);
+  if (a > UINT_MAX)
+    return; // no-warning
+  free(b);
+}
+
+void tautologyGE (unsigned a) {
+  char* b = malloc(1);
+  if (a >= 0)
+    free(b);
+  return; // no-warning
+}
+
+void tautologyLT (unsigned a) {
+  char* b = malloc(1);
+  if (a < 0)
+    return; // expected-warning{{never executed}}
+  free(b);
+}
+
+void tautologyLE (unsigned a) {
+  char* b = malloc(1);
+  if (a <= UINT_MAX)
+    free(b);
+  return; // no-warning
+}
diff --git a/test/Analysis/analyze_display_progress.c b/test/Analysis/analyze_display_progress.c
new file mode 100644
index 0000000..958ed00
--- /dev/null
+++ b/test/Analysis/analyze_display_progress.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -analyze -analyzer-display-progress %s 2>&1 | FileCheck %s
+
+void f() {};
+void g() {};
+void h() {}
+
+// CHECK: analyze_display_progress.c f
+// CHECK: analyze_display_progress.c g
+// CHECK: analyze_display_progress.c h
\ No newline at end of file
diff --git a/test/Analysis/array-struct-region.c b/test/Analysis/array-struct-region.c
new file mode 100644
index 0000000..dabd25b
--- /dev/null
+++ b/test/Analysis/array-struct-region.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-checks -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-checks -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+
+int string_literal_init() {
+  char a[] = "abc";
+  char b[2] = "abc"; // expected-warning{{too long}}
+  char c[5] = "abc";
+
+  if (a[1] != 'b')
+    return 0; // expected-warning{{never executed}}
+  if (b[1] != 'b')
+    return 0; // expected-warning{{never executed}}
+  if (c[1] != 'b')
+    return 0; // expected-warning{{never executed}}
+
+  if (a[3] != 0)
+    return 0; // expected-warning{{never executed}}
+  if (c[3] != 0)
+    return 0; // expected-warning{{never executed}}
+
+  if (c[4] != 0)
+    return 0; // expected-warning{{never executed}}
+
+  return 42;
+}
+
+void nested_compound_literals(int rad) {
+  int vec[6][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169},
+                   {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
+  int a;
+
+  for (a = 0; a < 6; ++a) {
+      vec[a][0] *= rad; // no-warning
+      vec[a][1] *= rad; // no-warning
+  }
+}
+
+void nested_compound_literals_float(float rad) {
+  float vec[6][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169},
+                     {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
+  int a;
+
+  for (a = 0; a < 6; ++a) {
+      vec[a][0] *= rad; // no-warning
+      vec[a][1] *= rad; // no-warning
+  }
+}
diff --git a/test/Analysis/bstring.c b/test/Analysis/bstring.c
new file mode 100644
index 0000000..ffe420f
--- /dev/null
+++ b/test/Analysis/bstring.c
@@ -0,0 +1,292 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
+// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
+// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
+// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
+
+//===----------------------------------------------------------------------===
+// Declarations
+//===----------------------------------------------------------------------===
+
+// Some functions are so similar to each other that they follow the same code
+// path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is
+// defined, make sure to use the variants instead to make sure they are still
+// checked by the analyzer.
+
+// Some functions are implemented as builtins. These should be #defined as
+// BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined.
+
+// Functions that have variants and are also availabe as builtins should be
+// declared carefully! See memcpy() for an example.
+
+#ifdef USE_BUILTINS
+# define BUILTIN(f) __builtin_ ## f
+#else /* USE_BUILTINS */
+# define BUILTIN(f) f
+#endif /* USE_BUILTINS */
+
+typedef typeof(sizeof(int)) size_t;
+
+//===----------------------------------------------------------------------===
+// memcpy()
+//===----------------------------------------------------------------------===
+
+#ifdef VARIANT
+
+#define __memcpy_chk BUILTIN(__memcpy_chk)
+void *__memcpy_chk(void *restrict s1, const void *restrict s2, size_t n,
+                   size_t destlen);
+
+#define memcpy(a,b,c) __memcpy_chk(a,b,c,(size_t)-1)
+
+#else /* VARIANT */
+
+#define memcpy BUILTIN(memcpy)
+void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
+
+#endif /* VARIANT */
+
+
+void memcpy0 () {
+  char src[] = {1, 2, 3, 4};
+  char dst[4] = {0};
+
+  memcpy(dst, src, 4); // no-warning
+
+  if (memcpy(dst, src, 4) != dst) {
+    (void)*(char*)0; // no-warning
+  }
+
+  if (dst[0] != 0)
+    (void)*(char*)0; // expected-warning{{null}}
+}
+
+void memcpy1 () {
+  char src[] = {1, 2, 3, 4};
+  char dst[10];
+
+  memcpy(dst, src, 5); // expected-warning{{Byte string function accesses out-of-bound array element}}
+}
+
+void memcpy2 () {
+  char src[] = {1, 2, 3, 4};
+  char dst[1];
+
+  memcpy(dst, src, 4); // expected-warning{{Byte string function overflows destination buffer}}
+}
+
+void memcpy3 () {
+  char src[] = {1, 2, 3, 4};
+  char dst[3];
+
+  memcpy(dst+1, src+2, 2); // no-warning
+}
+
+void memcpy4 () {
+  char src[] = {1, 2, 3, 4};
+  char dst[10];
+
+  memcpy(dst+2, src+2, 3); // expected-warning{{Byte string function accesses out-of-bound array element}}
+}
+
+void memcpy5() {
+  char src[] = {1, 2, 3, 4};
+  char dst[3];
+
+  memcpy(dst+2, src+2, 2); // expected-warning{{Byte string function overflows destination buffer}}
+}
+
+void memcpy6() {
+  int a[4] = {0};
+  memcpy(a, a, 8); // expected-warning{{overlapping}}  
+}
+
+void memcpy7() {
+  int a[4] = {0};
+  memcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
+}
+
+void memcpy8() {
+  int a[4] = {0};
+  memcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
+}
+
+void memcpy9() {
+  int a[4] = {0};
+  memcpy(a+2, a+1, 4); // no-warning
+  memcpy(a+1, a+2, 4); // no-warning
+}
+
+void memcpy10() {
+  char a[4] = {0};
+  memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to byte string function}}
+}
+
+void memcpy11() {
+  char a[4] = {0};
+  memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to byte string function}}
+}
+
+void memcpy12() {
+  char a[4] = {0};
+  memcpy(0, a, 0); // no-warning
+  memcpy(a, 0, 0); // no-warning
+}
+
+//===----------------------------------------------------------------------===
+// memmove()
+//===----------------------------------------------------------------------===
+
+#ifdef VARIANT
+
+#define __memmove_chk BUILTIN(__memmove_chk)
+void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen);
+
+#define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
+
+#else /* VARIANT */
+
+#define memmove BUILTIN(memmove)
+void *memmove(void *s1, const void *s2, size_t n);
+
+#endif /* VARIANT */
+
+
+void memmove0 () {
+  char src[] = {1, 2, 3, 4};
+  char dst[4] = {0};
+
+  memmove(dst, src, 4); // no-warning
+
+  if (memmove(dst, src, 4) != dst) {
+    (void)*(char*)0; // no-warning
+  }
+
+  if (dst[0] != 0)
+    (void)*(char*)0; // expected-warning{{null}}
+}
+
+void memmove1 () {
+  char src[] = {1, 2, 3, 4};
+  char dst[10];
+
+  memmove(dst, src, 5); // expected-warning{{out-of-bound}}
+}
+
+void memmove2 () {
+  char src[] = {1, 2, 3, 4};
+  char dst[1];
+
+  memmove(dst, src, 4); // expected-warning{{overflow}}
+}
+
+//===----------------------------------------------------------------------===
+// memcmp()
+//===----------------------------------------------------------------------===
+
+#ifdef VARIANT
+
+#define bcmp BUILTIN(bcmp)
+// __builtin_bcmp is not defined with const in Builtins.def.
+int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
+#define memcmp bcmp
+
+#else /* VARIANT */
+
+#define memcmp BUILTIN(memcmp)
+int memcmp(const void *s1, const void *s2, size_t n);
+
+#endif /* VARIANT */
+
+
+void memcmp0 () {
+  char a[] = {1, 2, 3, 4};
+  char b[4] = { 0 };
+
+  memcmp(a, b, 4); // no-warning
+}
+
+void memcmp1 () {
+  char a[] = {1, 2, 3, 4};
+  char b[10] = { 0 };
+
+  memcmp(a, b, 5); // expected-warning{{out-of-bound}}
+}
+
+void memcmp2 () {
+  char a[] = {1, 2, 3, 4};
+  char b[1] = { 0 };
+
+  memcmp(a, b, 4); // expected-warning{{out-of-bound}}
+}
+
+void memcmp3 () {
+  char a[] = {1, 2, 3, 4};
+
+  if (memcmp(a, a, 4))
+    (void)*(char*)0; // no-warning
+}
+
+void memcmp4 (char *input) {
+  char a[] = {1, 2, 3, 4};
+
+  if (memcmp(a, input, 4))
+    (void)*(char*)0; // expected-warning{{null}}
+}
+
+void memcmp5 (char *input) {
+  char a[] = {1, 2, 3, 4};
+
+  if (memcmp(a, 0, 0)) // no-warning
+    (void)*(char*)0;   // no-warning
+  if (memcmp(0, a, 0)) // no-warning
+    (void)*(char*)0;   // no-warning
+  if (memcmp(a, input, 0)) // no-warning
+    (void)*(char*)0;   // no-warning
+}
+
+void memcmp6 (char *a, char *b, size_t n) {
+  int result = memcmp(a, b, n);
+  if (result != 0)
+    return;
+  if (n == 0)
+    (void)*(char*)0; // expected-warning{{null}}
+}
+
+int memcmp7 (char *a, size_t x, size_t y, size_t n) {
+  // We used to crash when either of the arguments was unknown.
+  return memcmp(a, &a[x*y], n) +
+         memcmp(&a[x*y], a, n);
+}
+
+//===----------------------------------------------------------------------===
+// bcopy()
+//===----------------------------------------------------------------------===
+
+#define bcopy BUILTIN(bcopy)
+// __builtin_bcopy is not defined with const in Builtins.def.
+void bcopy(/*const*/ void *s1, void *s2, size_t n);
+
+
+void bcopy0 () {
+  char src[] = {1, 2, 3, 4};
+  char dst[4] = {0};
+
+  bcopy(src, dst, 4); // no-warning
+
+  if (dst[0] != 0)
+    (void)*(char*)0; // expected-warning{{null}}
+}
+
+void bcopy1 () {
+  char src[] = {1, 2, 3, 4};
+  char dst[10];
+
+  bcopy(src, dst, 5); // expected-warning{{out-of-bound}}
+}
+
+void bcopy2 () {
+  char src[] = {1, 2, 3, 4};
+  char dst[1];
+
+  bcopy(src, dst, 4); // expected-warning{{overflow}}
+}
diff --git a/test/Analysis/constant-folding.c b/test/Analysis/constant-folding.c
new file mode 100644
index 0000000..9191a9e0
--- /dev/null
+++ b/test/Analysis/constant-folding.c
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-experimental-checks -verify %s
+
+// Trigger a warning if the analyzer reaches this point in the control flow.
+#define WARN ((void)*(char*)0)
+
+// There should be no warnings unless otherwise indicated.
+
+void testComparisons (int a) {
+  // Sema can already catch the simple comparison a==a,
+  // since that's usually a logic error (and not path-dependent).
+  int b = a;
+  if (!(b==a)) WARN; // expected-warning{{never executed}}
+  if (!(b>=a)) WARN; // expected-warning{{never executed}}
+  if (!(b<=a)) WARN; // expected-warning{{never executed}}
+  if (b!=a) WARN;    // expected-warning{{never executed}}
+  if (b>a) WARN;     // expected-warning{{never executed}}
+  if (b<a) WARN;     // expected-warning{{never executed}}
+}
+
+void testSelfOperations (int a) {
+  if ((a|a) != a) WARN; // expected-warning{{never executed}}
+  if ((a&a) != a) WARN; // expected-warning{{never executed}}
+  if ((a^a) != 0) WARN; // expected-warning{{never executed}}
+  if ((a-a) != 0) WARN; // expected-warning{{never executed}}
+}
+
+void testIdempotent (int a) {
+  if ((a*1) != a) WARN;    // expected-warning{{never executed}}
+  if ((a/1) != a) WARN;    // expected-warning{{never executed}}
+  if ((a+0) != a) WARN;    // expected-warning{{never executed}}
+  if ((a-0) != a) WARN;    // expected-warning{{never executed}}
+  if ((a<<0) != a) WARN;   // expected-warning{{never executed}}
+  if ((a>>0) != a) WARN;   // expected-warning{{never executed}}
+  if ((a^0) != a) WARN;    // expected-warning{{never executed}}
+  if ((a&(~0)) != a) WARN; // expected-warning{{never executed}}
+  if ((a|0) != a) WARN;    // expected-warning{{never executed}}
+}
+
+void testReductionToConstant (int a) {
+  if ((a*0) != 0) WARN; // expected-warning{{never executed}}
+  if ((a&0) != 0) WARN; // expected-warning{{never executed}}
+  if ((a|(~0)) != (~0)) WARN; // expected-warning{{never executed}}
+}
+
+void testSymmetricIntSymOperations (int a) {
+  if ((2+a) != (a+2)) WARN; // expected-warning{{never executed}}
+  if ((2*a) != (a*2)) WARN; // expected-warning{{never executed}}
+  if ((2&a) != (a&2)) WARN; // expected-warning{{never executed}}
+  if ((2^a) != (a^2)) WARN; // expected-warning{{never executed}}
+  if ((2|a) != (a|2)) WARN; // expected-warning{{never executed}}
+}
+
+void testAsymmetricIntSymOperations (int a) {
+  if (((~0) >> a) != (~0)) WARN; // expected-warning{{never executed}}
+  if ((0 >> a) != 0) WARN; // expected-warning{{never executed}}
+  if ((0 << a) != 0) WARN; // expected-warning{{never executed}}
+
+  // Unsigned right shift shifts in zeroes.
+  if ((((unsigned)(~0)) >> ((unsigned) a)) != ((unsigned)(~0)))
+    WARN; // expected-warning{{}}
+}
+
+void testLocations (char *a) {
+  char *b = a;
+  if (!(b==a)) WARN; // expected-warning{{never executed}}
+  if (!(b>=a)) WARN; // expected-warning{{never executed}}
+  if (!(b<=a)) WARN; // expected-warning{{never executed}}
+  if (b!=a) WARN; // expected-warning{{never executed}}
+  if (b>a) WARN; // expected-warning{{never executed}}
+  if (b<a) WARN; // expected-warning{{never executed}}
+  if (b-a) WARN; // expected-warning{{never executed}}
+}
diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
index 209ca65..57d5d11 100644
--- a/test/Analysis/dead-stores.c
+++ b/test/Analysis/dead-stores.c
@@ -1,4 +1,4 @@
-// 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-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
@@ -150,7 +150,7 @@
 
 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}}
+  x = sizeof(int [x = (x || x + 1) * 2]) // expected-warning{{Although the value stored to 'x' is used}} expected-warning{{The left operand to '*' is always 1}}
       ? 5 : 8;
   return x;
 }
@@ -158,7 +158,7 @@
 // Self-assignments should not be flagged as dead stores.
 void f17() {
   int x = 1;
-  x = x; // no-warning
+  x = x;
 }
 
 // <rdar://problem/6506065>
@@ -300,11 +300,11 @@
   case 7:
     (void)(0 && x);
     (void)y7;
-    (void)(0 || (y8, ({ return; }), 1));
+    (void)(0 || (y8, ({ return; }), 1));  // expected-warning {{expression result unused}}
     (void)x;
     break;
   case 8:
-    (void)(1 && (y9, ({ return; }), 1));
+    (void)(1 && (y9, ({ return; }), 1));  // expected-warning {{expression result unused}}
     (void)x;
     break;
   case 9:
@@ -450,3 +450,39 @@
   return y;
 }
 
+// The FOREACH macro in QT uses 'break' statements within statement expressions
+// placed within the increment code of for loops.
+void rdar8014335() {
+  for (int i = 0 ; i != 10 ; ({ break; })) {
+    for ( ; ; ({ ++i; break; })) ;
+    // Note that the next value stored to 'i' is never executed
+    // because the next statement to be executed is the 'break'
+    // in the increment code of the first loop.
+    i = i * 3; // expected-warning{{Value stored to 'i' is never read}} expected-warning{{The left operand to '*' is always 1}}
+  }
+}
+
+// <rdar://problem/8320674> NullStmts followed by do...while() can lead to disconnected CFG
+//
+// This previously caused bogus dead-stores warnings because the body of the first do...while was
+// disconnected from the entry of the function.
+typedef struct { float r; float i; } s_rdar8320674;
+typedef struct { s_rdar8320674 x[1]; } s2_rdar8320674;
+
+void rdar8320674(s_rdar8320674 *z, unsigned y, s2_rdar8320674 *st, int m)
+{
+    s_rdar8320674 * z2;
+    s_rdar8320674 * tw1 = st->x;
+    s_rdar8320674 t;
+    z2 = z + m;
+    do{
+        ; ;
+        do{ (t).r = (*z2).r*(*tw1).r - (*z2).i*(*tw1).i; (t).i = (*z2).r*(*tw1).i + (*z2).i*(*tw1).r; }while(0);
+        tw1 += y;
+        do { (*z2).r=(*z).r-(t).r; (*z2).i=(*z).i-(t).i; }while(0);
+        do { (*z).r += (t).r; (*z).i += (t).i; }while(0);
+        ++z2;
+        ++z;
+    }while (--m);
+}
+
diff --git a/test/Analysis/dead-stores.cpp b/test/Analysis/dead-stores.cpp
index 22d446e..b21ffad 100644
--- a/test/Analysis/dead-stores.cpp
+++ b/test/Analysis/dead-stores.cpp
@@ -92,3 +92,11 @@
   int &y = x;
 }
 
+//===----------------------------------------------------------------------===//
+// Dead stores involving 'new'
+//===----------------------------------------------------------------------===//
+
+static void test_new(unsigned n) {
+  char **p = new char* [n]; // expected-warning{{never read}}
+}
+
diff --git a/test/Analysis/flat-store.c b/test/Analysis/flat-store.c
new file mode 100644
index 0000000..bb274b0
--- /dev/null
+++ b/test/Analysis/flat-store.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=flat -verify %s
+#define FAIL ((void)*(char*)0)
+struct simple { int x; };
+
+void PR7297 () {
+  struct simple a;
+  struct simple *p = &a;
+  p->x = 5;
+  if (!p[0].x) FAIL; // no-warning
+  if (p[0].x) FAIL; // expected-warning {{null}}
+}
diff --git a/test/Analysis/free.c b/test/Analysis/free.c
new file mode 100644
index 0000000..60bb3f2
--- /dev/null
+++ b/test/Analysis/free.c
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -fblocks -verify %s
+void free(void *);
+
+void t1 () {
+  int a[] = { 1 };
+  free(a); // expected-warning {{Argument to free() is the address of the local variable 'a', which is not memory allocated by malloc()}}
+}
+
+void t2 () {
+  int a = 1;
+  free(&a); // expected-warning {{Argument to free() is the address of the local variable 'a', which is not memory allocated by malloc()}}
+}
+
+void t3 () {
+  static int a[] = { 1 };
+  free(a); // expected-warning {{Argument to free() is the address of the static variable 'a', which is not memory allocated by malloc()}}
+}
+
+void t4 (char *x) {
+  free(x); // no-warning
+}
+
+void t5 () {
+  extern char *ptr();
+  free(ptr()); // no-warning
+}
+
+void t6 () {
+  free((void*)1000); // expected-warning {{Argument to free() is a constant address (1000), which is not memory allocated by malloc()}}
+}
+
+void t7 (char **x) {
+  free(*x); // no-warning
+}
+
+void t8 (char **x) {
+  // ugh
+  free((*x)+8); // no-warning
+}
+
+void t9 () {
+label:
+  free(&&label); // expected-warning {{Argument to free() is the address of the label 'label', which is not memory allocated by malloc()}}
+}
+
+void t10 () {
+  free((void*)&t10); // expected-warning {{Argument to free() is the address of the function 't10', which is not memory allocated by malloc()}}
+}
+
+void t11 () {
+  char *p = (char*)__builtin_alloca(2);
+  free(p); // expected-warning {{Argument to free() was allocated by alloca(), not malloc()}}
+}
+
+void t12 () {
+  free(^{return;}); // expected-warning {{Argument to free() is a block, which is not memory allocated by malloc()}}
+}
+
+void t13 (char a) {
+  free(&a); // expected-warning {{Argument to free() is the address of the parameter 'a', which is not memory allocated by malloc()}}
+}
+
+static int someGlobal[2];
+void t14 () {
+  free(someGlobal); // expected-warning {{Argument to free() is the address of the global variable 'someGlobal', which is not memory allocated by malloc()}}
+}
+
+void t15 (char **x, int offset) {
+  // Unknown value
+  free(x[offset]); // no-warning
+}
diff --git a/test/Analysis/func.c b/test/Analysis/func.c
index 53c873d..a7e8461 100644
--- a/test/Analysis/func.c
+++ b/test/Analysis/func.c
@@ -4,7 +4,7 @@
 void f(void) {
   void (*p)(void);
   p = f;
-  p = &f;
+  p = &f; // expected-warning{{Assigned value is always the same as the existing value}}
   p();
   (*p)();
 }
diff --git a/test/Analysis/idempotent-operations.c b/test/Analysis/idempotent-operations.c
new file mode 100644
index 0000000..debff0e
--- /dev/null
+++ b/test/Analysis/idempotent-operations.c
@@ -0,0 +1,174 @@
+// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-check-objc-mem -analyzer-check-idempotent-operations -verify %s
+
+// Basic tests
+
+extern void test(int i);
+extern void test_f(float f);
+
+unsigned basic() {
+  int x = 10, zero = 0, one = 1;
+
+  // x op x
+  x = x;        // expected-warning {{Assigned value is always the same as the existing value}}
+  test(x - x);  // expected-warning {{Both operands to '-' always have the same value}}
+  x -= x;       // expected-warning {{Both operands to '-=' always have the same value}}
+  x = 10;       // no-warning
+  test(x / x);  // expected-warning {{Both operands to '/' always have the same value}}
+  x /= x;       // expected-warning {{Both operands to '/=' always have the same value}}
+  x = 10;       // no-warning
+  test(x & x);  // expected-warning {{Both operands to '&' always have the same value}}
+  x &= x;       // expected-warning {{Both operands to '&=' always have the same value}}
+  test(x | x);  // expected-warning {{Both operands to '|' always have the same value}}
+  x |= x;       // expected-warning {{Both operands to '|=' always have the same value}}
+
+  // x op 1
+  test(x * one);  // expected-warning {{The right operand to '*' is always 1}}
+  x *= one;       // expected-warning {{The right operand to '*=' is always 1}}
+  test(x / one);  // expected-warning {{The right operand to '/' is always 1}}
+  x /= one;       // expected-warning {{The right operand to '/=' is always 1}}
+
+  // 1 op x
+  test(one * x);   // expected-warning {{The left operand to '*' is always 1}}
+
+  // x op 0
+  test(x + zero);  // expected-warning {{The right operand to '+' is always 0}}
+  test(x - zero);  // expected-warning {{The right operand to '-' is always 0}}
+  test(x * zero);  // expected-warning {{The right operand to '*' is always 0}}
+  test(x & zero);  // expected-warning {{The right operand to '&' is always 0}}
+  test(x | zero);  // expected-warning {{The right operand to '|' is always 0}}
+  test(x ^ zero);  // expected-warning {{The right operand to '^' is always 0}}
+  test(x << zero); // expected-warning {{The right operand to '<<' is always 0}}
+  test(x >> zero); // expected-warning {{The right operand to '>>' is always 0}}
+
+  // 0 op x
+  test(zero + x);  // expected-warning {{The left operand to '+' is always 0}}
+  test(zero - x);  // expected-warning {{The left operand to '-' is always 0}}
+  test(zero / x);  // expected-warning {{The left operand to '/' is always 0}}
+  test(zero * x);  // expected-warning {{The left operand to '*' is always 0}}
+  test(zero & x);  // expected-warning {{The left operand to '&' is always 0}}
+  test(zero | x);  // expected-warning {{The left operand to '|' is always 0}}
+  test(zero ^ x);  // expected-warning {{The left operand to '^' is always 0}}
+  test(zero << x); // expected-warning {{The left operand to '<<' is always 0}}
+  test(zero >> x); // expected-warning {{The left operand to '>>' is always 0}}
+
+  // Overwrite the values so these aren't marked as Pseudoconstants
+  x = 1;
+  zero = 2;
+  one = 3;
+
+  return x + zero + one;
+}
+
+void floats(float x) {
+  test_f(x * 1.0);  // no-warning
+  test_f(x * 1.0F); // no-warning
+}
+
+// Ensure that we don't report false poitives in complex loops
+void bailout() {
+  int unused = 0, result = 4;
+  result = result; // expected-warning {{Assigned value is always the same as the existing value}}
+
+  for (unsigned bg = 0; bg < 1024; bg ++) {
+    result = bg * result; // no-warning
+
+    for (int i = 0; i < 256; i++) {
+      unused *= i; // no-warning
+    }
+  }
+}
+
+// Relaxed liveness - check that we don't kill liveness at assignments
+typedef unsigned uintptr_t;
+void kill_at_assign() {
+  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])) { // expected-warning{{Assigned value is always the same as the existing value}}
+    p = 0;
+    *p = 1; // no-warning
+  }
+}
+
+// False positive tests
+
+unsigned false1() {
+  int a = 10;
+  return a * (5 - 2 - 3); // no-warning
+}
+
+enum testenum { enum1 = 0, enum2 };
+unsigned false2() {
+  int a = 1234;
+  return enum1 + a; // no-warning
+}
+
+// Self assignments of unused variables are common false positives
+unsigned false3(int param, int param2) {
+  param = param; // no-warning
+
+  // if a self assigned variable is used later, then it should be reported still
+  param2 = param2; // expected-warning{{Assigned value is always the same as the existing value}}
+
+  unsigned nonparam = 5;
+
+  nonparam = nonparam; // expected-warning{{Assigned value is always the same as the existing value}}
+
+  return param2 + nonparam;
+}
+
+// Pseudo-constants (vars only read) and constants should not be reported
+unsigned false4() {
+  // Trivial constant
+  const int height = 1;
+  int c = 42;
+  test(height * c); // no-warning
+
+  // Pseudo-constant (never changes after decl)
+  int width = height;
+
+  return width * 10; // no-warning
+}
+
+// Block pseudoconstants
+void false4a() {
+  // Pseudo-constant
+  __block int a = 1;
+  int b = 10;
+  __block int c = 0;
+  b *= a; // no-warning
+
+  ^{
+    // Psuedoconstant block var
+    test(b * c); // no-warning
+
+    // Non-pseudoconstant block var
+    int d = 0;
+    test(b * d); // expected-warning{{The right operand to '*' is always 0}}
+    d = 5;
+    test(d);
+  }();
+
+  test(a + b);
+}
+
+// Static vars are common false positives
+int false5() {
+  static int test = 0;
+  int a = 56;
+  a *= test; // no-warning
+  test++;
+  return a;
+}
+
+// Non-local storage vars are considered false positives
+int globalInt = 1;
+int false6() {
+  int localInt = 23;
+
+  localInt /= globalInt;
+
+  return localInt;
+}
diff --git a/test/Analysis/idempotent-operations.cpp b/test/Analysis/idempotent-operations.cpp
new file mode 100644
index 0000000..c5d1ceb
--- /dev/null
+++ b/test/Analysis/idempotent-operations.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-check-objc-mem -analyzer-check-idempotent-operations -verify %s
+
+// C++ specific false positives
+
+extern void test(int i);
+extern void test_ref(int &i);
+
+// Test references affecting pseudoconstants
+void false1() {
+  int a = 0;
+  int five = 5;
+  int &b = a;
+   test(five * a); // expected-warning {{The right operand to '*' is always 0}}
+   b = 4;
+}
diff --git a/test/Analysis/inline.c b/test/Analysis/inline.c
index 952de73..50c1a54 100644
--- a/test/Analysis/inline.c
+++ b/test/Analysis/inline.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-inline-call -analyzer-store region -verify %s
 
 int f1() {
   int y = 1;
diff --git a/test/Analysis/inline2.c b/test/Analysis/inline2.c
index e2758c1..efdb75c 100644
--- a/test/Analysis/inline2.c
+++ b/test/Analysis/inline2.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-inline-call -analyzer-store region -verify %s
 
 // Test parameter 'a' is registered to LiveVariables analysis data although it
 // is not referenced in the function body. 
diff --git a/test/Analysis/inline3.c b/test/Analysis/inline3.c
index 3661263..884b3ed 100644
--- a/test/Analysis/inline3.c
+++ b/test/Analysis/inline3.c
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
-
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-inline-call -analyzer-store region -verify %s
 
 // Test when entering f1(), we set the right AnalysisContext to Environment.
 // Otherwise, block-level expr '1 && a' would not be block-level.
diff --git a/test/Analysis/inline4.c b/test/Analysis/inline4.c
index dd2379f..5a1d193 100644
--- a/test/Analysis/inline4.c
+++ b/test/Analysis/inline4.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-inline-call -analyzer-store region -verify %s
 
 int g(int a) {    
   return a;
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
index 21b6d46..e443150 100644
--- a/test/Analysis/malloc.c
+++ b/test/Analysis/malloc.c
@@ -4,28 +4,142 @@
 void free(void *);
 void *realloc(void *ptr, size_t size);
 void *calloc(size_t nmemb, size_t size);
+void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
+void __attribute((ownership_takes(malloc, 1))) my_free(void *);
+void __attribute((ownership_returns(malloc, 1))) *my_malloc2(size_t);
+void __attribute((ownership_holds(malloc, 1))) my_hold(void *);
+
+// Duplicate attributes are silly, but not an error.
+// Duplicate attribute has no extra effect.
+// If two are of different kinds, that is an error and reported as such. 
+void __attribute((ownership_holds(malloc, 1)))
+__attribute((ownership_holds(malloc, 1)))
+__attribute((ownership_holds(malloc, 3))) my_hold2(void *, void *, void *);
+void *my_malloc3(size_t);
+void *myglobalpointer;
+struct stuff {
+  void *somefield;
+};
+struct stuff myglobalstuff;
 
 void f1() {
-  int *p = malloc(10);
+  int *p = malloc(12);
   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);
+  int *p = malloc(12);
   free(p);
   free(p); // expected-warning{{Try to free a memory block that has been released}}
 }
 
+// ownership attributes tests
+void naf1() {
+  int *p = my_malloc3(12);
+  return; // no-warning
+}
+
+void n2af1() {
+  int *p = my_malloc2(12);
+  return; // expected-warning{{Allocated memory never released. Potential memory leak.}}
+}
+
+void af1() {
+  int *p = my_malloc(12);
+  return; // expected-warning{{Allocated memory never released. Potential memory leak.}}
+}
+
+void af1_b() {
+  int *p = my_malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}}
+}
+
+void af1_c() {
+  myglobalpointer = my_malloc(12); // no-warning
+}
+
+void af1_d() {
+  struct stuff mystuff;
+  mystuff.somefield = my_malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}}
+}
+
+// Test that we can pass out allocated memory via pointer-to-pointer.
+void af1_e(void **pp) {
+  *pp = my_malloc(42); // no-warning
+}
+
+void af1_f(struct stuff *somestuff) {
+  somestuff->somefield = my_malloc(12); // no-warning
+}
+
+// Allocating memory for a field via multiple indirections to our arguments is OK.
+void af1_g(struct stuff **pps) {
+  *pps = my_malloc(sizeof(struct stuff)); // no-warning
+  (*pps)->somefield = my_malloc(42); // no-warning
+}
+
+void af2() {
+  int *p = my_malloc(12);
+  my_free(p);
+  free(p); // expected-warning{{Try to free a memory block that has been released}}
+}
+
+void af2b() {
+  int *p = my_malloc(12);
+  free(p);
+  my_free(p); // expected-warning{{Try to free a memory block that has been released}}
+}
+
+void af2c() {
+  int *p = my_malloc(12);
+  free(p);
+  my_hold(p); // expected-warning{{Try to free a memory block that has been released}}
+}
+
+void af2d() {
+  int *p = my_malloc(12);
+  free(p);
+  my_hold2(0, 0, p); // expected-warning{{Try to free a memory block that has been released}}
+}
+
+// No leak if malloc returns null.
+void af2e() {
+  int *p = my_malloc(12);
+  if (!p)
+    return; // no-warning
+  free(p); // no-warning
+}
+
+// This case would inflict a double-free elsewhere.
+// However, this case is considered an analyzer bug since it causes false-positives.
+void af3() {
+  int *p = my_malloc(12);
+  my_hold(p);
+  free(p); // no-warning
+}
+
+// This case would inflict a double-free elsewhere.
+// However, this case is considered an analyzer bug since it causes false-positives.
+int * af4() {
+  int *p = my_malloc(12);
+  my_free(p);
+  return p; // no-warning
+}
+
+// This case is (possibly) ok, be conservative
+int * af5() {
+  int *p = my_malloc(12);
+  my_hold(p);
+  return p; // no-warning
+}
+
+
+
 // 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); 
+  p = malloc(12); 
   return p; // no-warning
 }
 
@@ -34,18 +148,18 @@
 // functions or inter-procedural analysis, this is a conservative answer.
 static int *p_f4 = 0;
 int *f4() {
-  p_f4 = malloc(10); 
+  p_f4 = malloc(12); 
   return p_f4; // no-warning
 }
 
 int *f5() {
-  int *q = malloc(10);
+  int *q = malloc(12);
   q = realloc(q, 20);
   return q; // no-warning
 }
 
 void f6() {
-  int *p = malloc(10);
+  int *p = malloc(12);
   if (!p)
     return; // no-warning
   else
@@ -67,3 +181,57 @@
   free(x);
   x[0] = 'a'; // expected-warning{{Use dynamically allocated memory after it is freed.}}
 }
+
+void PR6123() {
+  int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}}
+}
+
+void PR7217() {
+  int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}}
+  buf[1] = 'c'; // not crash
+}
+
+void mallocCastToVoid() {
+  void *p = malloc(2);
+  const void *cp = p; // not crash
+  free(p);
+}
+
+void mallocCastToFP() {
+  void *p = malloc(2);
+  void (*fp)() = p; // not crash
+  free(p);
+}
+
+// This tests that malloc() buffers are undefined by default
+char mallocGarbage () {
+	char *buf = malloc(2);
+	char result = buf[1]; // expected-warning{{undefined}}
+	free(buf);
+	return result;
+}
+
+// This tests that calloc() buffers need to be freed
+void callocNoFree () {
+  char *buf = calloc(2,2);
+  return; // expected-warning{{never released}}
+}
+
+// These test that calloc() buffers are zeroed by default
+char callocZeroesGood () {
+	char *buf = calloc(2,2);
+	char result = buf[3]; // no-warning
+	if (buf[1] == 0) {
+	  free(buf);
+	}
+	return result; // no-warning
+}
+
+char callocZeroesBad () {
+	char *buf = calloc(2,2);
+	char result = buf[3]; // no-warning
+	if (buf[1] != 0) {
+	  free(buf); // expected-warning{{never executed}}
+	}
+	return result; // expected-warning{{never released}}
+}
diff --git a/test/Analysis/method-call.cpp b/test/Analysis/method-call.cpp
index dd89159..47f1444 100644
--- a/test/Analysis/method-call.cpp
+++ b/test/Analysis/method-call.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-inline-call -analyzer-store region -verify %s
 struct A {
   int x;
   A(int a) { x = a; }
diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp
index 6794d48..baaa2f6 100644
--- a/test/Analysis/misc-ps-region-store.cpp
+++ b/test/Analysis/misc-ps-region-store.cpp
@@ -132,3 +132,19 @@
   return 0;  
 }
 
+// PR 7675 - passing literals by-reference
+void pr7675(const double &a);
+void pr7675(const int &a);
+void pr7675(const char &a);
+void pr7675_i(const _Complex double &a);
+
+void pr7675_test() {
+  pr7675(10.0);
+  pr7675(10);
+  pr7675('c');
+  pr7675_i(4.0i);
+  // Add null deref to ensure we are analyzing the code up to this point.
+  int *p = 0;
+  *p = 0xDEADBEEF; // expected-warning{{null pointer}}
+}
+
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
index 4255141..d464373 100644
--- a/test/Analysis/misc-ps-region-store.m
+++ b/test/Analysis/misc-ps-region-store.m
@@ -253,7 +253,7 @@
   a = A;
   b = B;
   
-  n = *a++;
+  n = *a++; // expected-warning{{Assigned value is always the same as the existing value}}
   if (n)
     x += *b++; // no-warning
 }
@@ -708,7 +708,7 @@
   long long *z = (long long *) (intptr_t) src;
   long long w = 0;
   int n = 0;
-  for (n = 0; n < y; ++n) {
+  for (n = 0; n < y; ++n) { // expected-warning{{Assigned value is always the same as the existing value}}
     // Previously we crashed analyzing this statement.
     w = *z++;
   }
@@ -1014,3 +1014,55 @@
   float f = *(float*) a;
 }
 
+// <rdar://problem/8032791> False positive due to symbolic store not find
+//  value because of 'const' qualifier
+double rdar_8032791_2();
+double rdar_8032791_1() {
+   struct R8032791 { double x[2]; double y; }
+   data[3] = {
+     {{1.0, 3.0}, 3.0},  //  1   2   3
+     {{1.0, 1.0}, 0.0},  // 1 1 2 2 3 3
+     {{1.0, 3.0}, 1.0}   //    1   2   3
+   };
+
+   double x = 0.0;
+   for (unsigned i = 0 ; i < 3; i++) {
+     const struct R8032791 *p = &data[i];
+     x += p->y + rdar_8032791_2(); // no-warning
+   }
+   return x;
+}
+
+// PR 7450 - Handle pointer arithmetic with __builtin_alloca
+void pr_7450_aux(void *x);
+void pr_7450() {
+  void *p = __builtin_alloca(10);
+  // Don't crash when analyzing the following statement.
+  pr_7450_aux(p + 8);
+}
+
+// <rdar://problem/8243408> - Symbolicate struct values returned by value.
+struct s_rdar_8243408 { int x; };
+extern struct s_rdar_8243408 rdar_8243408_aux(void);
+void rdar_8243408(void) {
+  struct s_rdar_8243408 a = { 1 }, *b = 0;
+  while (a.x && !b)
+    a = rdar_8243408_aux();
+
+  // Previously there was a false error here with 'b' being null.
+  (void) (a.x && b->x); // no-warning
+
+  // Introduce a null deref to ensure we are checking this path.
+  int *p = 0;
+  *p = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}}
+}
+
+// <rdar://problem/8258814>
+int r8258814()
+{
+  int foo;
+  int * a = &foo;
+  a[0] = 10;
+  // Do not warn that the value of 'foo' is uninitialized.
+  return foo; // no-warning
+}
diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m
index fa05f6f..6aac74b 100644
--- a/test/Analysis/misc-ps.m
+++ b/test/Analysis/misc-ps.m
@@ -8,6 +8,10 @@
 // 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
 
+#ifndef __clang_analyzer__
+#error __clang__analyzer__ not defined
+#endif
+
 typedef struct objc_ivar *Ivar;
 typedef struct objc_selector *SEL;
 typedef signed char BOOL;
@@ -82,11 +86,11 @@
 
 void r6268365() {
   unsigned x = 0;
-  x &= r6268365Aux();
+  x &= r6268365Aux(); // expected-warning{{The left operand to '&=' is always 0}}
   unsigned j = 0;
     
   if (x == 0) ++j;
-  if (x == 0) x = x / j; // no-warning
+  if (x == 0) x = x / j; // expected-warning{{Assigned value is always the same as the existing value}} expected-warning{{The right operand to '/' is always 1}}
 }
 
 void divzeroassume(unsigned x, unsigned j) {  
@@ -294,6 +298,7 @@
 typedef void *Opcode;
 Opcode pr_4033_getOpcode();
 void pr_4033(void) {
+  void *lbl = &&next_opcode;
 next_opcode:
   {
     Opcode op = pr_4033_getOpcode();
@@ -318,7 +323,7 @@
 // was the block containing the merge for '?', which would trigger an
 // assertion failure.
 int rdar_7027684_aux();
-int rdar_7027684_aux_2() __attribute__((noreturn));
+int rdar_7027684_aux_2() __attribute__((noreturn)); // expected-warning{{functions declared 'noreturn' should have a 'void' result type}}
 void rdar_7027684(int x, int y) {
   {}; // this empty compound statement is critical.
   (rdar_7027684_aux() ? rdar_7027684_aux_2() : (void) 0);
@@ -402,14 +407,14 @@
   int test_trivial_symbolic_comparison_aux();
   int a = test_trivial_symbolic_comparison_aux();
   int b = a;
-  if (a != b) {
+  if (a != b) { // expected-warning{{Both operands to '!=' always have the same value}}
     int *p = 0;
     *p = 0xDEADBEEF;     // no-warning
   }
   
   a = a == 1;
   b = b == 1;
-  if (a != b) {
+  if (a != b) { // expected-warning{{Both operands to '!=' always have the same value}}
     int *p = 0;
     *p = 0xDEADBEEF;     // no-warning
   }
@@ -453,7 +458,7 @@
 // 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];  
+  for (i = 0; i < 2; i++) p = &p[i]; // expected-warning{{Assigned value is always the same as the existing value}}
   return p[i+1];
 }
 
@@ -578,7 +583,7 @@
 - (id) foo {
   if (self)
     return self;
-  *((int *) 0x0) = 0xDEADBEEF; // no-warning
+  *((volatile int *) 0x0) = 0xDEADBEEF; // no-warning
   return self;
 }
 @end
@@ -933,3 +938,121 @@
   struct s_rev95547 w2 = w;
   w2.z1.x += 20.0; // no-warning
 }
+
+//===----------------------------------------------------------------------===//
+// Test handling statement expressions that don't populate a CFG block that
+// is used to represent the computation of the RHS of a logical operator.
+// This previously triggered a crash.
+//===----------------------------------------------------------------------===//
+
+void pr6938() {
+  if (1 && ({
+    while (0);
+    0;
+  }) == 0) {
+  }
+}
+
+void pr6938_b() {
+  if (1 && *({ // expected-warning{{Dereference of null pointer}}
+    while (0) {}
+    ({
+      (int *) 0;
+    });
+  }) == 0) {
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7979430> - The CFG for code containing an empty
+//  @synchronized block was previously broken (and would crash the analyzer).
+//===----------------------------------------------------------------------===//
+
+void r7979430(id x) {
+  @synchronized(x) {}
+}
+
+//===----------------------------------------------------------------------===
+// PR 7361 - Test that functions wrapped in macro instantiations are analyzed.
+//===----------------------------------------------------------------------===
+#define MAKE_TEST_FN() \
+  void test_pr7361 (char a) {\
+    char* b = 0x0;  *b = a;\
+  }
+
+MAKE_TEST_FN() // expected-warning{{null pointer}}
+
+//===----------------------------------------------------------------------===
+// PR 7491 - Test that symbolic expressions can be used as conditions.
+//===----------------------------------------------------------------------===
+
+void pr7491 () {
+  extern int getint();
+  int a = getint()-1;
+  if (a) {
+    return;
+  }
+  if (!a) {
+    return;
+  } else {
+    // Should be unreachable
+    (void)*(char*)0; // no-warning
+  }
+}
+
+//===----------------------------------------------------------------------===
+// PR 7475 - Test that assumptions about global variables are reset after
+//  calling a global function.
+//===----------------------------------------------------------------------===
+
+int *pr7475_someGlobal;
+void pr7475_setUpGlobal();
+
+void pr7475() {
+  if (pr7475_someGlobal == 0)
+    pr7475_setUpGlobal();
+  *pr7475_someGlobal = 0; // no-warning
+}
+
+void pr7475_warn() {
+  static int *someStatic = 0;
+  if (someStatic == 0)
+    pr7475_setUpGlobal();
+  *someStatic = 0; // expected-warning{{null pointer}}
+}
+
+// <rdar://problem/8202272> - __imag passed non-complex should not crash
+float f0(_Complex float x) {
+  float l0 = __real x;
+  return  __real l0 + __imag l0;
+}
+
+
+//===----------------------------------------------------------------------===
+// Test that we can reduce symbols to constants whether they are on the left
+//  or right side of an expression.
+//===----------------------------------------------------------------------===
+
+void reduce_to_constant(int x, int y) {
+  if (x != 20)
+    return;
+
+  int a = x + y;
+  int b = y + x;
+
+  if (y == -20 && a != 0)
+    (void)*(char*)0; // no-warning
+  if (y == -20 && b != 0)
+    (void)*(char*)0; // no-warning
+}
+
+// <rdar://problem/8360854> - Test that code after a switch statement with no 
+// 'case:' labels is correctly evaluated.
+void r8360854(int n) {
+  switch (n) {
+   default: ;
+  }
+  int *p = 0;
+  *p = 0xDEADBEEF; // expected-warning{{null pointer}}
+}
+
diff --git a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
index 2e9c528..5f51871 100644
--- a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
+++ b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
@@ -72,11 +72,11 @@
 int marker(void) { // control reaches end of non-void function
 }
 
+// CHECK-darwin8: 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-outofbounds.c b/test/Analysis/no-outofbounds.c
index 771323b..a97b68e 100644
--- a/test/Analysis/no-outofbounds.c
+++ b/test/Analysis/no-outofbounds.c
@@ -12,3 +12,20 @@
   short *z = (short*) &x;
   short s = z[0] + z[1]; // no-warning
 }
+
+void g() {
+  int a[2];
+  char *b = (char*)a;
+  b[3] = 'c'; // no-warning
+}
+
+typedef typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void free(void *);
+
+void field() {
+  struct vec { size_t len; int data[0]; };
+  struct vec *a = malloc(sizeof(struct vec) + 10);
+  a->len = 10;
+  a->data[1] = 5; // no-warning
+}
diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c
index 5a1049c..8daa845 100644
--- a/test/Analysis/null-deref-ps.c
+++ b/test/Analysis/null-deref-ps.c
@@ -1,7 +1,7 @@
-// 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
+// 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 -Wreturn-type 
+// 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 -Wreturn-type 
+// 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 -Wreturn-type 
+// 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 -Wreturn-type 
 
 typedef unsigned uintptr_t;
 
@@ -64,13 +64,13 @@
   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])) {
+  if (!(p == &array[0])) { // expected-warning{{Both operands to '==' always have the same value}}
     p = 0;
     *p = 1; // no-warning
   }
-  
+
   if (p) {
     *p = 5; // no-warning
     p = 0;
@@ -81,7 +81,6 @@
   return 0;
 }
 
-
 int f5() {
   
   char *s = "hello world";
@@ -118,6 +117,11 @@
   }  
 }
 
+void f6e(int *p, int offset) {
+  // PR7406 - crash from treating an UnknownVal as defined, to see if it's 0.
+  bar((p+offset)+1, 0); // not crash
+}
+
 int* qux();
 
 int f7(int x) {
@@ -275,7 +279,7 @@
 // Test handling of translating between integer "pointers" and back.
 void f13() {
   int *x = 0;
-  if (((((int) x) << 2) + 1) >> 1) *x = 1; // no-warning
+  if (((((int) x) << 2) + 1) >> 1) *x = 1;
 }
 
 // PR 4759 - Attribute non-null checking by the analyzer was not correctly
diff --git a/test/Analysis/outofbound.c b/test/Analysis/outofbound.c
index e1ff66c..ed51dc6 100644
--- a/test/Analysis/outofbound.c
+++ b/test/Analysis/outofbound.c
@@ -2,6 +2,7 @@
 
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
+void *calloc(size_t, size_t);
 
 char f1() {
   char* s = "abcd";
@@ -36,3 +37,61 @@
   p[1] = a; // no-warning
   p[2] = a; // expected-warning{{Access out-of-bound array element (buffer overflow)}}
 }
+
+void f5() {
+  char *p = calloc(2,2);
+  p[3] = '.'; // no-warning
+  p[4] = '!'; // expected-warning{{out-of-bound}}
+}
+
+void f6() {
+  char a[2];
+  int *b = (int*)a;
+  b[1] = 3; // expected-warning{{out-of-bound}}
+}
+
+void f7() {
+  struct three_words a;
+  a.c[3] = 1; // expected-warning{{out-of-bound}}
+}
+
+void vla(int a) {
+  if (a == 5) {
+    int x[a];
+    x[4] = 4; // no-warning
+    x[5] = 5; // expected-warning{{out-of-bound}}
+  }
+}
+
+void sizeof_vla(int a) {
+  if (a == 5) {
+    char x[a];
+    int y[sizeof(x)];
+    y[4] = 4; // no-warning
+    y[5] = 5; // expected-warning{{out-of-bound}}
+  }
+}
+
+void alloca_region(int a) {
+  if (a == 5) {
+    char *x = __builtin_alloca(a);
+    x[4] = 4; // no-warning
+    x[5] = 5; // expected-warning{{out-of-bound}}
+  }
+}
+
+int symbolic_index(int a) {
+  int x[2] = {1, 2};
+  if (a == 2) {
+    return x[a]; // expected-warning{{out-of-bound}}
+  }
+  return 0;
+}
+
+int symbolic_index2(int a) {
+  int x[2] = {1, 2};
+  if (a < 0) {
+    return x[a]; // expected-warning{{out-of-bound}}
+  }
+  return 0;
+}
diff --git a/test/Analysis/ptr-arith.c b/test/Analysis/ptr-arith.c
index f6bd61c..0c2e221 100644
--- a/test/Analysis/ptr-arith.c
+++ b/test/Analysis/ptr-arith.c
@@ -1,6 +1,9 @@
 // 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
 
+// Used to trigger warnings for unreachable paths.
+#define WARN do { int a, b; int c = &b-&a; } while (0)
+
 void f1() {
   int a[10];
   int *p = a;
@@ -60,3 +63,226 @@
 void f6(int *p, int *q) {
   int d = q - p; // no-warning
 }
+
+void null_operand(int *a) {
+start:
+  // LHS is a label, RHS is NULL
+  if (&&start == 0)
+    WARN; // no-warning
+  if (&&start <  0)
+    WARN; // no-warning
+  if (&&start <= 0)
+    WARN; // no-warning
+  if (!(&&start != 0))
+    WARN; // no-warning
+  if (!(&&start >  0))
+    WARN; // no-warning
+  if (!(&&start >= 0))
+    WARN; // no-warning
+  if (!(&&start - 0))
+    WARN; // no-warning
+
+  // LHS is a non-symbolic value, RHS is NULL
+  if (&a == 0)
+    WARN; // no-warning
+  if (&a <  0)
+    WARN; // no-warning
+  if (&a <= 0)
+    WARN; // no-warning
+  if (!(&a != 0))
+    WARN; // no-warning
+  if (!(&a >  0))
+    WARN; // no-warning
+  if (!(&a >= 0))
+    WARN; // no-warning
+
+  if (!(&a - 0)) // expected-warning{{Pointer arithmetic done on non-array variables}}
+    WARN; // no-warning
+
+  // LHS is NULL, RHS is non-symbolic
+  // The same code is used for labels and non-symbolic values.
+  if (0 == &a)
+    WARN; // no-warning
+  if (0 >  &a)
+    WARN; // no-warning
+  if (0 >= &a)
+    WARN; // no-warning
+  if (!(0 != &a))
+    WARN; // no-warning
+  if (!(0 <  &a))
+    WARN; // no-warning
+  if (!(0 <= &a))
+    WARN; // no-warning
+
+  // LHS is a symbolic value, RHS is NULL
+  if (a == 0)
+    WARN; // expected-warning{{}}
+  if (a <  0)
+    WARN; // no-warning
+  if (a <= 0)
+    WARN; // expected-warning{{}}
+  if (!(a != 0))
+    WARN; // expected-warning{{}}
+  if (!(a >  0))
+    WARN; // expected-warning{{}}
+  if (!(a >= 0))
+    WARN; // no-warning
+  if (!(a - 0))
+    WARN; // expected-warning{{}}
+
+  // LHS is NULL, RHS is a symbolic value
+  if (0 == a)
+    WARN; // expected-warning{{}}
+  if (0 >  a)
+    WARN; // no-warning
+  if (0 >= a)
+    WARN; // expected-warning{{}}
+  if (!(0 != a))
+    WARN; // expected-warning{{}}
+  if (!(0 <  a))
+    WARN; // expected-warning{{}}
+  if (!(0 <= a))
+    WARN; // no-warning
+}
+
+void const_locs() {
+  char *a = (char*)0x1000;
+  char *b = (char*)0x1100;
+start:
+  if (a==b)
+    WARN; // no-warning
+  if (!(a!=b))
+    WARN; // no-warning
+  if (a>b)
+    WARN; // no-warning
+  if (b<a)
+    WARN; // no-warning
+  if (a>=b)
+    WARN; // no-warning
+  if (b<=a)
+    WARN; // no-warning
+  if (b-a != 0x100)
+    WARN; // no-warning
+
+  if (&&start == a)
+    WARN; // expected-warning{{}}
+  if (a == &&start)
+    WARN; // expected-warning{{}}
+  if (&a == (char**)a)
+    WARN; // expected-warning{{}}
+  if ((char**)a == &a)
+    WARN; // expected-warning{{}}
+}
+
+void array_matching_types() {
+  int array[10];
+  int *a = &array[2];
+  int *b = &array[5];
+
+  if (a==b)
+    WARN; // no-warning
+  if (!(a!=b))
+    WARN; // no-warning
+  if (a>b)
+    WARN; // no-warning
+  if (b<a)
+    WARN; // no-warning
+  if (a>=b)
+    WARN; // no-warning
+  if (b<=a)
+    WARN; // no-warning
+  if ((b-a) == 0)
+    WARN; // no-warning
+}
+
+// This takes a different code path than array_matching_types()
+void array_different_types() {
+  int array[10];
+  int *a = &array[2];
+  char *b = (char*)&array[5];
+
+  if (a==b) // expected-warning{{comparison of distinct pointer types}}
+    WARN; // no-warning
+  if (!(a!=b)) // expected-warning{{comparison of distinct pointer types}}
+    WARN; // no-warning
+  if (a>b) // expected-warning{{comparison of distinct pointer types}}
+    WARN; // no-warning
+  if (b<a) // expected-warning{{comparison of distinct pointer types}}
+    WARN; // no-warning
+  if (a>=b) // expected-warning{{comparison of distinct pointer types}}
+    WARN; // no-warning
+  if (b<=a) // expected-warning{{comparison of distinct pointer types}}
+    WARN; // no-warning
+}
+
+struct test { int x; int y; };
+void struct_fields() {
+  struct test a, b;
+
+  if (&a.x == &a.y)
+    WARN; // no-warning
+  if (!(&a.x != &a.y))
+    WARN; // no-warning
+  if (&a.x > &a.y)
+    WARN; // no-warning
+  if (&a.y < &a.x)
+    WARN; // no-warning
+  if (&a.x >= &a.y)
+    WARN; // no-warning
+  if (&a.y <= &a.x)
+    WARN; // no-warning
+
+  if (&a.x == &b.x)
+    WARN; // no-warning
+  if (!(&a.x != &b.x))
+    WARN; // no-warning
+  if (&a.x > &b.x)
+    WARN; // expected-warning{{}}
+  if (&b.x < &a.x)
+    WARN; // expected-warning{{}}
+  if (&a.x >= &b.x)
+    WARN; // expected-warning{{}}
+  if (&b.x <= &a.x)
+    WARN; // expected-warning{{}}
+}
+
+void mixed_region_types() {
+  struct test s;
+  int array[2];
+  void *a = &array, *b = &s;
+
+  if (&a == &b)
+    WARN; // no-warning
+  if (!(&a != &b))
+    WARN; // no-warning
+  if (&a > &b)
+    WARN; // expected-warning{{}}
+  if (&b < &a)
+    WARN; // expected-warning{{}}
+  if (&a >= &b)
+    WARN; // expected-warning{{}}
+  if (&b <= &a)
+    WARN; // expected-warning{{}}
+}
+
+void symbolic_region(int *p) {
+  int a;
+
+  if (&a == p)
+    WARN; // expected-warning{{}}
+  if (&a != p)
+    WARN; // expected-warning{{}}
+  if (&a > p)
+    WARN; // expected-warning{{}}
+  if (&a < p)
+    WARN; // expected-warning{{}}
+  if (&a >= p)
+    WARN; // expected-warning{{}}
+  if (&a <= p)
+    WARN; // expected-warning{{}}
+}
+
+void PR7527 (int *p) {
+  if (((int) p) & 1) // not crash
+    return;
+}
diff --git a/test/Analysis/rdar-6442306-1.m b/test/Analysis/rdar-6442306-1.m
index a2af946..dfe9b72 100644
--- a/test/Analysis/rdar-6442306-1.m
+++ b/test/Analysis/rdar-6442306-1.m
@@ -10,7 +10,7 @@
 typedef struct QuxSize QuxSize;
 typedef struct {
   Foo_record_t Foo;
-  QuxSize size;
+  QuxSize size[0];
 } __Request__SetPortalSize_t;
 
 double __Foo_READSWAP__double(double*);
diff --git a/test/Analysis/rdar-7168531.m b/test/Analysis/rdar-7168531.m
index bb34713..5a7b085 100644
--- a/test/Analysis/rdar-7168531.m
+++ b/test/Analysis/rdar-7168531.m
@@ -1,5 +1,5 @@
-// 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
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -triple i386-apple-darwin10 -analyzer-store=region %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -triple i386-apple-darwin10 -analyzer-store=basic %s
 
 // Note that the target triple is important for this test case.  It specifies that we use the
 // fragile Objective-C ABI.
diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp
index 54d7cf5..f169416 100644
--- a/test/Analysis/reference.cpp
+++ b/test/Analysis/reference.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
+typedef typeof(sizeof(int)) size_t;
+void malloc (size_t);
 
 void f1() {
   int const &i = 3;
@@ -9,3 +11,46 @@
   if (b != 3)
     *p = 1; // no-warning
 }
+
+char* ptr();
+char& ref();
+
+// These next two tests just shouldn't crash.
+char t1 () {
+  ref() = 'c';
+  return '0';
+}
+
+// just a sanity test, the same behavior as t1()
+char t2 () {
+  *ptr() = 'c';
+  return '0';
+}
+
+// Each of the tests below is repeated with pointers as well as references.
+// This is mostly a sanity check, but then again, both should work!
+char t3 () {
+  char& r = ref();
+  r = 'c'; // no-warning
+  if (r) return r;
+  return *(char*)0; // no-warning
+}
+
+char t4 () {
+  char* p = ptr();
+  *p = 'c'; // no-warning
+  if (*p) return *p;
+  return *(char*)0; // no-warning
+}
+
+char t5 (char& r) {
+  r = 'c'; // no-warning
+  if (r) return r;
+  return *(char*)0; // no-warning
+}
+
+char t6 (char* p) {
+  *p = 'c'; // no-warning
+  if (*p) return *p;
+  return *(char*)0; // no-warning
+}
diff --git a/test/Analysis/retain-release-region-store.m b/test/Analysis/retain-release-region-store.m
index db49b91..7b98554 100644
--- a/test/Analysis/retain-release-region-store.m
+++ b/test/Analysis/retain-release-region-store.m
@@ -50,6 +50,7 @@
 @end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
 @end
 @interface NSObject <NSObject> {}
+- (id)init;
 + (id)allocWithZone:(NSZone *)zone;
 + (id)alloc;
 - (void)dealloc;
@@ -223,3 +224,29 @@
   }
 }
 
+// <rdar://problem/8261992> Idempotent operation checker false positive with ObjC ivars
+@interface R8261992 : NSObject {
+  @package int myIvar;
+}
+@end
+
+static void R8261992_ChangeMyIvar(R8261992 *tc) {
+    tc->myIvar = 5;
+}
+
+void R8261992_test(R8261992 *tc) {
+  int temp = tc->myIvar;
+  // The ivar binding for tc->myIvar gets invalidated.
+  R8261992_ChangeMyIvar(tc);
+  tc->myIvar = temp; // no-warning
+  tc = [[R8261992 alloc] init];
+  temp = tc->myIvar; // no-warning
+  // The ivar binding for tc->myIvar gets invalidated.
+  R8261992_ChangeMyIvar(tc);
+  tc->myIvar = temp;
+  [tc release]; // no-warning
+  // did we analyze this?
+  int *p = 0x0;
+  *p = 0xDEADBEEF; // expected-warning{{null}}
+}
+
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index 3f79c0c..064165a 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -468,6 +468,20 @@
   }
 }
 
+// Test that an object is non-null after being CFRetained/CFReleased.
+void f17(int x, CFTypeRef p) {
+  if (x) {
+    CFRelease(p);
+    if (!p)
+      CFRelease(0); // no-warning
+  }
+  else {
+    CFRetain(p);
+    if (!p)
+      CFRetain(0); // no-warning
+  }
+}
+
 // 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.
@@ -1332,3 +1346,24 @@
   ^(NSObject *o){ [o retain]; }(number);
 }
 
+//===--------------------------------------------------------------------===//
+// Test sending message to super that returns an object alias.  Previously
+// this caused a crash in the analyzer.
+//===--------------------------------------------------------------------===//
+
+@interface Rdar8015556 : NSObject {} @end
+@implementation Rdar8015556
+- (id)retain {
+  return [super retain];
+}
+@end
+
+// <rdar://problem/8272168> - Correcly handle Class<...> in Cocoa Conventions
+// detector.
+
+@protocol Prot_R8272168 @end
+Class <Prot_R8272168> GetAClassThatImplementsProt_R8272168();
+void r8272168() {
+  GetAClassThatImplementsProt_R8272168();
+}
+
diff --git a/test/Analysis/stack-addr-ps.c b/test/Analysis/stack-addr-ps.c
index f8cadbe..342b3b1 100644
--- a/test/Analysis/stack-addr-ps.c
+++ b/test/Analysis/stack-addr-ps.c
@@ -3,11 +3,11 @@
 
 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}}
+  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}}
+  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) {
@@ -16,7 +16,7 @@
   if (x)
     y = &w;
     
-  return y; // expected-warning{{Address of stack memory associated with local variable 'w' returned.}}
+  return y; // expected-warning{{Address of stack memory associated with local variable 'w' returned to caller}}
 }
 
 void* compound_literal(int x, int y) {
diff --git a/test/Analysis/stack-addr-ps.cpp b/test/Analysis/stack-addr-ps.cpp
new file mode 100644
index 0000000..593ba1d
--- /dev/null
+++ b/test/Analysis/stack-addr-ps.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
+
+// FIXME: Only the stack-address checking in Sema catches this right now, and
+// the stack analyzer doesn't handle the ImplicitCastExpr (lvalue).
+const int& g() {
+  int s;
+  return s; // expected-warning{{reference to stack memory associated with local variable 's' returned}}
+}
diff --git a/test/Analysis/stackaddrleak.c b/test/Analysis/stackaddrleak.c
new file mode 100644
index 0000000..39808ed
--- /dev/null
+++ b/test/Analysis/stackaddrleak.c
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store region -verify %s
+
+char const *p;
+
+void f0() {
+  char const str[] = "This will change";
+  p = str; // expected-warning{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller.  This will be a dangling reference}}
+}
+
+void f1() {
+  char const str[] = "This will change";
+  p = str; 
+  p = 0; // no-warning
+}
+
+void f2() {
+  p = (const char *) __builtin_alloca(12);  // expected-warning{{Address of stack memory allocated by call to alloca() on line 17 is still referred to by the global variable 'p' upon returning to the caller.  This will be a dangling reference}}
+}
+
+// PR 7383 - previosly the stack address checker would crash on this example
+//  because it would attempt to do a direct load from 'pr7383_list'. 
+static int pr7383(__const char *__)
+{
+  return 0;
+}
+extern __const char *__const pr7383_list[];
+
+// Test that we catch multiple returns via globals when analyzing a function.
+void test_multi_return() {
+  static int *a, *b;
+  int x;
+  a = &x;
+  b = &x; // expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'a' upon returning}} expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'b' upon returning}}
+}
diff --git a/test/Analysis/stream.c b/test/Analysis/stream.c
new file mode 100644
index 0000000..73bbc13
--- /dev/null
+++ b/test/Analysis/stream.c
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-experimental-checks -analyzer-store region -verify %s
+
+typedef __typeof__(sizeof(int)) size_t;
+typedef struct _IO_FILE FILE;
+#define SEEK_SET	0	/* Seek from beginning of file.  */
+#define SEEK_CUR	1	/* Seek from current position.  */
+#define SEEK_END	2	/* Seek from end of file.  */
+extern FILE *fopen(const char *path, const char *mode);
+extern FILE *tmpfile(void);
+extern int fclose(FILE *fp);
+extern size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+extern int fseek (FILE *__stream, long int __off, int __whence);
+extern long int ftell (FILE *__stream);
+extern void rewind (FILE *__stream);
+
+void f1(void) {
+  FILE *p = fopen("foo", "r");
+  char buf[1024];
+  fread(buf, 1, 1, p); // expected-warning {{Stream pointer might be NULL.}}
+  fclose(p);
+}
+
+void f2(void) {
+  FILE *p = fopen("foo", "r");
+  fseek(p, 1, SEEK_SET); // expected-warning {{Stream pointer might be NULL.}}
+  fclose(p);
+}
+
+void f3(void) {
+  FILE *p = fopen("foo", "r");
+  ftell(p); // expected-warning {{Stream pointer might be NULL.}}
+  fclose(p);
+}
+
+void f4(void) {
+  FILE *p = fopen("foo", "r");
+  rewind(p); // expected-warning {{Stream pointer might be NULL.}}
+  fclose(p);
+}
+
+void f5(void) {
+  FILE *p = fopen("foo", "r");
+  if (!p)
+    return;
+  fseek(p, 1, SEEK_SET); // no-warning
+  fseek(p, 1, 3); // expected-warning {{The whence argument to fseek() should be SEEK_SET, SEEK_END, or SEEK_CUR.}}
+  fclose(p);
+}
+
+void f6(void) {
+  FILE *p = fopen("foo", "r");
+  fclose(p); 
+  fclose(p); // expected-warning {{Try to close a file Descriptor already closed. Cause undefined behaviour.}}
+}
+
+void f7(void) {
+  FILE *p = tmpfile();
+  ftell(p); // expected-warning {{Stream pointer might be NULL.}}
+  fclose(p);
+}
+
+void f8(int c) {
+  FILE *p = fopen("foo.c", "r");
+  if(c)
+    return; // expected-warning {{Opened File never closed. Potential Resource leak.}}
+  fclose(p);
+}
+
+FILE *f9(void) {
+  FILE *p = fopen("foo.c", "r");
+  if (p)
+    return p; // no-warning
+  else
+    return 0;
+}
+
+void pr7831(FILE *fp) {
+  fclose(fp); // no-warning
+}
diff --git a/test/Analysis/string.c b/test/Analysis/string.c
new file mode 100644
index 0000000..35ed710
--- /dev/null
+++ b/test/Analysis/string.c
@@ -0,0 +1,240 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
+// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
+// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
+// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
+
+//===----------------------------------------------------------------------===
+// Declarations
+//===----------------------------------------------------------------------===
+
+// Some functions are so similar to each other that they follow the same code
+// path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is
+// defined, make sure to use the variants instead to make sure they are still
+// checked by the analyzer.
+
+// Some functions are implemented as builtins. These should be #defined as
+// BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined.
+
+// Functions that have variants and are also availabe as builtins should be
+// declared carefully! See memcpy() for an example.
+
+#ifdef USE_BUILTINS
+# define BUILTIN(f) __builtin_ ## f
+#else /* USE_BUILTINS */
+# define BUILTIN(f) f
+#endif /* USE_BUILTINS */
+
+#define NULL 0
+typedef typeof(sizeof(int)) size_t;
+
+//===----------------------------------------------------------------------===
+// strlen()
+//===----------------------------------------------------------------------===
+
+#define strlen BUILTIN(strlen)
+size_t strlen(const char *s);
+
+void strlen_constant0() {
+  if (strlen("123") != 3)
+    (void)*(char*)0; // no-warning
+}
+
+void strlen_constant1() {
+  const char *a = "123";
+  if (strlen(a) != 3)
+    (void)*(char*)0; // no-warning
+}
+
+void strlen_constant2(char x) {
+  char a[] = "123";
+  if (strlen(a) != 3)
+    (void)*(char*)0; // no-warning
+  a[0] = x;
+  if (strlen(a) != 3)
+    (void)*(char*)0; // expected-warning{{null}}
+}
+
+size_t strlen_null() {
+  return strlen(0); // expected-warning{{Null pointer argument in call to byte string function}}
+}
+
+size_t strlen_fn() {
+  return strlen((char*)&strlen_fn); // expected-warning{{Argument to byte string function is the address of the function 'strlen_fn', which is not a null-terminated string}}
+}
+
+size_t strlen_nonloc() {
+label:
+  return strlen((char*)&&label); // expected-warning{{Argument to byte string function is the address of the label 'label', which is not a null-terminated string}}
+}
+
+void strlen_subregion() {
+  struct two_strings { char a[2], b[2] };
+  extern void use_two_strings(struct two_strings *);
+
+  struct two_strings z;
+  use_two_strings(&z);
+
+  size_t a = strlen(z.a);
+  z.b[0] = 5;
+  size_t b = strlen(z.a);
+  if (a == 0 && b != 0)
+    (void)*(char*)0; // expected-warning{{never executed}}
+
+  use_two_strings(&z);
+
+  size_t c = strlen(z.a);
+  if (a == 0 && c != 0)
+    (void)*(char*)0; // expected-warning{{null}}
+}
+
+extern void use_string(char *);
+void strlen_argument(char *x) {
+  size_t a = strlen(x);
+  size_t b = strlen(x);
+  if (a == 0 && b != 0)
+    (void)*(char*)0; // expected-warning{{never executed}}
+
+  use_string(x);
+
+  size_t c = strlen(x);
+  if (a == 0 && c != 0)
+    (void)*(char*)0; // expected-warning{{null}}  
+}
+
+extern char global_str[];
+void strlen_global() {
+  size_t a = strlen(global_str);
+  size_t b = strlen(global_str);
+  if (a == 0 && b != 0)
+    (void)*(char*)0; // expected-warning{{never executed}}
+
+  // Call a function with unknown effects, which should invalidate globals.
+  use_string(0);
+
+  size_t c = strlen(global_str);
+  if (a == 0 && c != 0)
+    (void)*(char*)0; // expected-warning{{null}}  
+}
+
+void strlen_indirect(char *x) {
+  size_t a = strlen(x);
+  char *p = x;
+  char **p2 = &p;
+  size_t b = strlen(x);
+  if (a == 0 && b != 0)
+    (void)*(char*)0; // expected-warning{{never executed}}
+
+  extern void use_string_ptr(char*const*);
+  use_string_ptr(p2);
+
+  size_t c = strlen(x);
+  if (a == 0 && c != 0)
+    (void)*(char*)0; // expected-warning{{null}}
+}
+
+void strlen_liveness(const char *x) {
+  if (strlen(x) < 5)
+    return;
+  if (strlen(x) < 5)
+    (void)*(char*)0; // no-warning
+}
+
+//===----------------------------------------------------------------------===
+// strcpy()
+//===----------------------------------------------------------------------===
+
+#ifdef VARIANT
+
+#define __strcpy_chk BUILTIN(__strcpy_chk)
+char *__strcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
+
+#define strcpy(a,b) __strcpy_chk(a,b,(size_t)-1)
+
+#else /* VARIANT */
+
+#define strcpy BUILTIN(strcpy)
+char *strcpy(char *restrict s1, const char *restrict s2);
+
+#endif /* VARIANT */
+
+
+void strcpy_null_dst(char *x) {
+  strcpy(NULL, x); // expected-warning{{Null pointer argument in call to byte string function}}
+}
+
+void strcpy_null_src(char *x) {
+  strcpy(x, NULL); // expected-warning{{Null pointer argument in call to byte string function}}
+}
+
+void strcpy_fn(char *x) {
+  strcpy(x, (char*)&strcpy_fn); // expected-warning{{Argument to byte string function is the address of the function 'strcpy_fn', which is not a null-terminated string}}
+}
+
+void strcpy_effects(char *x, char *y) {
+  char a = x[0];
+
+  if (strcpy(x, y) != x)
+    (void)*(char*)0; // no-warning
+
+  if (strlen(x) != strlen(y))
+    (void)*(char*)0; // no-warning
+
+  if (a != x[0])
+    (void)*(char*)0; // expected-warning{{null}}
+}
+
+void strcpy_overflow(char *y) {
+  char x[4];
+  if (strlen(y) == 4)
+    strcpy(x, y); // expected-warning{{Byte string function overflows destination buffer}}
+}
+
+void strcpy_no_overflow(char *y) {
+  char x[4];
+  if (strlen(y) == 3)
+    strcpy(x, y); // no-warning
+}
+
+//===----------------------------------------------------------------------===
+// stpcpy()
+//===----------------------------------------------------------------------===
+
+#ifdef VARIANT
+
+#define __stpcpy_chk BUILTIN(__stpcpy_chk)
+char *__stpcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
+
+#define stpcpy(a,b) __stpcpy_chk(a,b,(size_t)-1)
+
+#else /* VARIANT */
+
+#define stpcpy BUILTIN(stpcpy)
+char *stpcpy(char *restrict s1, const char *restrict s2);
+
+#endif /* VARIANT */
+
+
+void stpcpy_effect(char *x, char *y) {
+  char a = x[0];
+
+  if (stpcpy(x, y) != &x[strlen(y)])
+    (void)*(char*)0; // no-warning
+
+  if (strlen(x) != strlen(y))
+    (void)*(char*)0; // no-warning
+
+  if (a != x[0])
+    (void)*(char*)0; // expected-warning{{null}}
+}
+
+void stpcpy_overflow(char *y) {
+  char x[4];
+  if (strlen(y) == 4)
+    stpcpy(x, y); // expected-warning{{Byte string function overflows destination buffer}}
+}
+
+void stpcpy_no_overflow(char *y) {
+  char x[4];
+  if (strlen(y) == 3)
+    stpcpy(x, y); // no-warning
+}
diff --git a/test/Analysis/undef-buffers.c b/test/Analysis/undef-buffers.c
new file mode 100644
index 0000000..4c5beb3
--- /dev/null
+++ b/test/Analysis/undef-buffers.c
@@ -0,0 +1,32 @@
+// 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 *);
+
+char stackBased1 () {
+  char buf[2];
+  buf[0] = 'a';
+  return buf[1]; // expected-warning{{Undefined}}
+}
+
+char stackBased2 () {
+  char buf[2];
+  buf[1] = 'a';
+  return buf[0]; // expected-warning{{Undefined}}
+}
+
+char heapBased1 () {
+  char *buf = malloc(2);
+  buf[0] = 'a';
+  char result = buf[1]; // expected-warning{{undefined}}
+  free(buf);
+  return result;
+}
+
+char heapBased2 () {
+  char *buf = malloc(2);
+  buf[1] = 'a';
+  char result = buf[0]; // expected-warning{{undefined}}
+  free(buf);
+  return result;
+}
diff --git a/test/Analysis/uninit-vals-ps-region.m b/test/Analysis/uninit-vals-ps-region.m
index 69c1ecd..751e91b 100644
--- a/test/Analysis/uninit-vals-ps-region.m
+++ b/test/Analysis/uninit-vals-ps-region.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -analyzer-check-idempotent-operations -verify %s
 
 struct s {
   int data;
@@ -42,7 +42,7 @@
 void test_uninit_neg() {
   struct TestUninit v1 = { 0, 0 };
   struct TestUninit v2 = test_uninit_aux();
-  test_unit_aux2(v2.x + v1.y); // no-warning
+  test_unit_aux2(v2.x + v1.y); // expected-warning{{The right operand to '+' is always 0}}
 }
 
 extern void test_uninit_struct_arg_aux(struct TestUninit arg);
diff --git a/test/Analysis/unreachable-code-path.c b/test/Analysis/unreachable-code-path.c
new file mode 100644
index 0000000..0715327
--- /dev/null
+++ b/test/Analysis/unreachable-code-path.c
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-checks -analyzer-check-objc-mem -analyzer-check-dead-stores -verify -analyzer-opt-analyze-nested-blocks %s
+
+extern void foo(int a);
+
+// The first few tests are non-path specific - we should be able to find them
+
+void test(unsigned a) {
+  switch (a) {
+    a += 5; // expected-warning{{never executed}}
+  case 2:
+    a *= 10;
+  case 3:
+    a %= 2;
+  }
+  foo(a);
+}
+
+void test2(unsigned a) {
+ help:
+  if (a > 0)
+    return;
+  if (a == 0)
+    return;
+  foo(a); // expected-warning{{never executed}}
+  goto help;
+}
+
+void test3(unsigned a) {
+  while(1);
+  if (a > 5) { // expected-warning{{never executed}}
+    return;
+  }
+}
+
+// These next tests are path-sensitive
+
+void test4() {
+  int a = 5;
+
+  while (a > 1)
+    a -= 2;
+
+  if (a > 1) {
+    a = a + 56; // expected-warning{{never executed}}
+  }
+
+  foo(a);
+}
+
+extern void bar(char c);
+
+void test5(const char *c) {
+  foo(c[0]);
+
+  if (!c) {
+    bar(1); // expected-warning{{never executed}}
+  }
+}
+
+// These next tests are false positives and should not generate warnings
+
+void test6(const char *c) {
+  if (c) return;
+  if (!c) return;
+  __builtin_unreachable(); // no-warning
+}
+
+// Compile-time constant false positives
+#define CONSTANT 0
+enum test_enum { Off, On };
+void test7() {
+  if (CONSTANT)
+    return; // no-warning
+
+  if (sizeof(int))
+    return; // no-warning
+
+  if (Off)
+    return; // no-warning
+}
+
+void test8() {
+  static unsigned a = 0;
+
+  if (a)
+    a = 123; // no-warning
+
+  a = 5;
+}
+
+// Check for bugs where multiple statements are reported
+void test9(unsigned a) {
+  switch (a) {
+    if (a) // expected-warning{{never executed}}
+      foo(a + 5); // no-warning
+    else // no-warning
+      foo(a); // no-warning
+    case 1:
+    case 2:
+      break;
+    default:
+      break;
+  }
+}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 6bb5b6c..611867f 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -54,7 +54,7 @@
                   --param build_config=${CMAKE_CFG_INTDIR}
                   -sv ${CLANG_TEST_EXTRA_ARGS}
                   ${CMAKE_CURRENT_BINARY_DIR}/${testdir}
-                  DEPENDS clang c-index-test
+                  DEPENDS clang c-index-test FileCheck not count
                   COMMENT "Running Clang regression tests in ${testdir}")
   endforeach()
 
@@ -65,7 +65,7 @@
                 --param build_config=${CMAKE_CFG_INTDIR}
                 -sv ${CLANG_TEST_EXTRA_ARGS}
                 ${CMAKE_CURRENT_BINARY_DIR}
-                DEPENDS clang c-index-test
+                DEPENDS clang c-index-test FileCheck not count
                 COMMENT "Running Clang regression tests")
 
   add_custom_target(clang-c++tests
@@ -75,6 +75,6 @@
                 --param build_config=${CMAKE_CFG_INTDIR}
                 -sv ${CLANG_TEST_EXTRA_ARGS}
                 ${CMAKE_CURRENT_SOURCE_DIR}/../utils/C++Tests
-                DEPENDS clang c-index-test
+                DEPENDS clang c-index-test FileCheck not count
                 COMMENT "Running Clang regression tests")
 endif()
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
index ee01416..0c905fb 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
@@ -71,3 +71,40 @@
   }
 }
 
+extern "C" {
+  struct L { };
+}
+
+void h(L); // expected-note{{candidate function}}
+
+namespace P {
+  void h(L); // expected-note{{candidate function}}
+  void test_transparent_context_adl(L l) {
+    {
+      h(l); // expected-error {{call to 'h' is ambiguous}}
+    }
+  }
+}
+
+namespace test5 {
+  namespace NS {
+    struct A;
+    void foo(void (*)(A&));
+  }
+  void bar(NS::A& a);
+
+  void test() {
+    foo(&bar);
+  }
+}
+
+// PR6762: __builtin_va_list should be invisible to ADL on all platforms.
+void test6_function(__builtin_va_list &argv);
+namespace test6 {
+  void test6_function(__builtin_va_list &argv);
+
+  void test() {
+    __builtin_va_list args;
+    test6_function(args);
+  }
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp b/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
new file mode 100644
index 0000000..3fde0da
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify %s
+
+// C++98 [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. 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
+//    -- if the name is not found, the name found in the class of the object
+//       expression is used, otherwise
+//    -- 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
+//    -- 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.
+
+// From PR 7247
+template<typename T>
+struct set{};  // expected-note{{lookup from the current scope refers here}}
+struct Value {
+  template<typename T>
+  void set(T value) {}  // expected-note{{lookup in the object type 'Value' refers here}}
+
+  void resolves_to_same() {
+    Value v;
+    v.set<double>(3.2);
+  }
+};
+void resolves_to_different() {
+  {
+    Value v;
+    // The fact that the next line is a warning rather than an error is an
+    // extension.
+    v.set<double>(3.2);  // expected-warning{{lookup of 'set' in member access expression is ambiguous; using member of 'Value' [-Wambiguous-member-template]}}
+  }
+  {
+    int set;  // Non-template.
+    Value v;
+    v.set<double>(3.2);
+  }
+}
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
index 35efba5..355ac4a 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp
@@ -1,4 +1,7 @@
 // RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// XFAIL: *
+// Our C++0x doesn't currently have specialized destructor name handling,
+// since the specification is still in flux.
 struct C { 
   typedef int I;
 }; 
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp
index 633d5cd..0956de3 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp
@@ -20,5 +20,5 @@
 typedef A AB; 
 int main() {
   AB *p; 
-  p->AB::~AB(); // expected-error{{identifier 'AB' in pseudo-destructor expression does not name a type}}
+  p->AB::~AB(); // expected-error{{expected the class name after '~' to name a destructor}}
 }
diff --git a/test/CXX/basic/basic.scope/basic.scope.pdecl/p9.cpp b/test/CXX/basic/basic.scope/basic.scope.pdecl/p9.cpp
new file mode 100644
index 0000000..e64b675
--- /dev/null
+++ b/test/CXX/basic/basic.scope/basic.scope.pdecl/p9.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Template type parameters.
+typedef unsigned char T;
+template<typename T = T> struct X0 { };
+template<> struct X0<unsigned char> { static const bool value = true; };
+int array0[X0<>::value? 1 : -1];
+
+// Non-type template parameters.
+const int N = 17;
+template<int N = N> struct X1 { };
+template<> struct X1<17> { static const bool value = true; };
+int array1[X1<>::value? 1 : -1];
+
+// Template template parameters.
+template<template<class> class X0 = X0> struct X2 { };
+template<> struct X2<X0> { static const bool value = true; };
+int array2[X2<>::value? 1 : -1];
diff --git a/test/CXX/class.access/class.access.base/p1.cpp b/test/CXX/class.access/class.access.base/p1.cpp
index 0988431..43cc99e 100644
--- a/test/CXX/class.access/class.access.base/p1.cpp
+++ b/test/CXX/class.access/class.access.base/p1.cpp
@@ -54,8 +54,10 @@
 //   of the base class are accessible as protected members of the
 //   derived class.
 namespace test1 {
-  class Base {
-  public: int pub; static int spub;
+  class Base { // expected-note 6{{member is declared here}}
+  public: 
+    int pub; // expected-note{{member is declared here}}
+    static int spub; // expected-note{{member is declared here}}
   protected: int prot; static int sprot; // expected-note 4 {{declared protected here}}
   private: int priv; static int spriv; // expected-note 8 {{declared private here}}
   };
@@ -102,13 +104,15 @@
 //   the base class are accessible as private members of the derived
 //   class.
 namespace test2 {
-  class Base {
+  class Base { // expected-note 6{{member is declared here}}
   public:
-    int pub;
-    static int spub;
+    int pub; // expected-note{{member is declared here}}
+    static int spub; // expected-note{{member is declared here}}
   protected:
-    int prot; // expected-note {{declared protected here}}
-    static int sprot; // expected-note {{declared protected here}}
+    int prot; // expected-note {{declared protected here}} \
+    // expected-note{{member is declared here}}
+    static int sprot; // expected-note {{declared protected here}} \
+    // expected-note{{member is declared here}}
   private:
     int priv; // expected-note 4 {{declared private here}}
     static int spriv; // expected-note 4 {{declared private here}}
diff --git a/test/CXX/class.access/class.access.base/p5.cpp b/test/CXX/class.access/class.access.base/p5.cpp
index 938d9fb..255fbfc 100644
--- a/test/CXX/class.access/class.access.base/p5.cpp
+++ b/test/CXX/class.access/class.access.base/p5.cpp
@@ -27,7 +27,7 @@
   };
 
   struct D {
-    public: static int x;
+    public: static int x; // expected-note{{member is declared here}}
     static int test() { return x; }
   };
   struct E : private D { // expected-note{{constrained by private inheritance}}
@@ -45,7 +45,7 @@
 
 namespace test2 {
   class A {
-  protected: static int x;
+  protected: static int x; // expected-note{{member is declared here}}
   };
 
   class B : private A {}; // expected-note {{private inheritance}}
diff --git a/test/CXX/class.access/class.access.dcl/p1.cpp b/test/CXX/class.access/class.access.dcl/p1.cpp
index 5d7905f..aab5fff 100644
--- a/test/CXX/class.access/class.access.dcl/p1.cpp
+++ b/test/CXX/class.access/class.access.dcl/p1.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 // This is just the test for [namespace.udecl]p4 with 'using'
 // uniformly stripped out.
diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp
index 991698d..277b70b 100644
--- a/test/CXX/class.access/class.friend/p1.cpp
+++ b/test/CXX/class.access/class.friend/p1.cpp
@@ -6,9 +6,6 @@
 //   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; }
@@ -124,7 +121,7 @@
     friend struct ilist_walker_bad;
     X *Prev;
   protected:
-    X *getPrev() { return Prev; }
+    X *getPrev() { return Prev; } // expected-note{{member is declared here}}
   };
 
   class ilist_node : private ilist_half_node { // expected-note {{declared private here}} expected-note {{constrained by private inheritance here}}
@@ -189,7 +186,7 @@
   struct Inequal {};
   bool test() {
     Holder<Inequal> a, b;
-    return a == b; // expected-note {{requested here}}
+    return a == b;  // expected-note {{requested here}}
   }
 }
 
@@ -287,3 +284,25 @@
     friend class test9;
   };
 }
+
+// PR7230
+namespace test10 {
+  extern "C" void f(void);
+  extern "C" void g(void);
+
+  namespace NS {
+    class C {
+      void foo(void); // expected-note {{declared private here}}
+      friend void test10::f(void);
+    };
+    static C* bar;
+  }
+
+  void f(void) {
+    NS::bar->foo();
+  }
+
+  void g(void) {
+    NS::bar->foo(); // expected-error {{private member}}
+  }
+}
diff --git a/test/CXX/class.access/class.protected/p1.cpp b/test/CXX/class.access/class.protected/p1.cpp
index 6ff630c..ab7a7dc 100644
--- a/test/CXX/class.access/class.protected/p1.cpp
+++ b/test/CXX/class.access/class.protected/p1.cpp
@@ -2,8 +2,10 @@
 
 namespace test0 {
   class A {
-    protected: int x; // expected-note 3 {{declared}}
-    static int sx; // expected-note 3 {{declared}}
+    protected: int x; // expected-note 3 {{declared}} \
+    // expected-note {{member is declared here}}
+    static int sx; // expected-note 3 {{declared}} \
+    // expected-note {{member is declared here}}
   };
   class B : public A {
   };
@@ -136,8 +138,8 @@
 namespace test4 {
   class C;
   class A {
-    protected: int x; // expected-note 2 {{declared}}
-    static int sx;
+    protected: int x; // expected-note 3 {{declared}}
+    static int sx;    // expected-note 3{{member is declared here}}
     static void test(C&);
   };
   class B : public A {
@@ -174,8 +176,8 @@
 namespace test5 {
   class D;
   class A {
-    protected: int x;
-    static int sx;
+    protected: int x; // expected-note 3{{member is declared here}}
+    static int sx; // expected-note 3{{member is declared here}}
     static void test(D&);
   };
   class B : public A {
@@ -326,16 +328,16 @@
 }
 
 namespace test9 {
-  class A {
-  protected: int foo(); // expected-note 8 {{declared}}
+  class A { // expected-note {{member is declared here}}
+  protected: int foo(); // expected-note 7 {{declared}}
   };
 
-  class B : public A {
+  class B : public A { // expected-note {{member is declared here}}
     friend class D;
   };
 
   class C : protected B { // expected-note {{declared}} \
-                          // expected-note 6 {{constrained}}
+                          // expected-note 9 {{constrained}}
   };
 
   class D : public A {
@@ -348,7 +350,7 @@
 
     static void test(B &b) {
       b.foo();
-      b.A::foo(); // expected-error {{'foo' is a protected member}}
+      b.A::foo();
       b.B::foo();
       b.C::foo(); // expected-error {{'foo' is a protected member}}
     }
@@ -356,8 +358,7 @@
     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}} \
+      c.A::foo(); // 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}}
@@ -385,3 +386,50 @@
 
   template class A<int>;
 }
+
+// rdar://problem/8360285: class.protected friendship
+namespace test11 {
+  class A {
+  protected:
+    int foo();
+  };
+
+  class B : public A {
+    friend class C;
+  };
+
+  class C {
+    void test() {
+      B b;
+      b.A::foo();
+    }
+  };
+}
+
+// This friendship is considered because a public member of A would be
+// a private member of C.
+namespace test12 {
+  class A { protected: int foo(); };
+  class B : public virtual A {};
+  class C : private B { friend void test(); };
+  class D : private C, public virtual A {};
+
+  void test() {
+    D d;
+    d.A::foo();
+  }
+}
+
+// This friendship is not considered because a public member of A is
+// inaccessible in C.
+namespace test13 {
+  class A { protected: int foo(); }; // expected-note {{declared protected here}}
+  class B : private virtual A {};
+  class C : private B { friend void test(); };
+  class D : public virtual A {};
+
+  void test() {
+    D d;
+    d.A::foo(); // expected-error {{protected member}}
+  }
+}
diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp
index 2786aef..fa6e183 100644
--- a/test/CXX/class.access/p4.cpp
+++ b/test/CXX/class.access/p4.cpp
@@ -97,7 +97,7 @@
   A A::foo; // okay
   
   class B : A { }; // expected-error {{base class 'test2::A' has private constructor}}
-  B b;
+  B b; // expected-note{{implicit default constructor}}
   
   class C : virtual A { 
   public:
@@ -105,7 +105,7 @@
   };
 
   class D : C { }; // expected-error {{inherited virtual base class 'test2::A' has private constructor}}
-  D d;
+  D d; // expected-note{{implicit default constructor}}
 }
 
 // Implicit destructor calls.
@@ -143,13 +143,15 @@
   };
 
   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}}
+                   // expected-error 2 {{inherited virtual base class 'Base<3>' has private destructor}} \
+    // expected-note 2{{implicit default constructor}}
     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;
+  {}; 
+  Derived3 d3; // expected-note {{implicit default constructor}}\
+               // expected-note{{implicit default destructor}}}
 }
 
 // Conversion functions.
@@ -158,7 +160,7 @@
   private:
     operator Private(); // expected-note 4 {{declared private here}}
   public:
-    operator Public();
+    operator Public(); // expected-note 2{{member is declared here}}
   };
 
   class Derived1 : private Base { // expected-note 2 {{declared private here}} \
@@ -202,16 +204,16 @@
     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}}
+  class Test1 { A a; }; // expected-error {{private member}}
   void test1() {
     Test1 a;
-    a = Test1();
+    a = Test1(); // expected-note{{implicit default copy}}
   }
 
-  class Test2 : A {}; // expected-error {{base class 'test5::A' has private copy assignment operator}}
+  class Test2 : A {}; // expected-error {{private member}}
   void test2() {
     Test2 a;
-    a = Test2();
+    a = Test2(); // expected-note{{implicit default copy}}
   }
 }
 
@@ -224,12 +226,12 @@
 
   class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}}
   void test1(const Test1 &t) {
-    Test1 a = t;
+    Test1 a = t; // expected-note{{implicit default copy}}
   }
 
   class Test2 : A {}; // expected-error {{base class 'test6::A' has private copy constructor}}
   void test2(const Test2 &t) {
-    Test2 a = t;
+    Test2 a = t; // expected-note{{implicit default copy}}
   }
 }
 
@@ -265,7 +267,7 @@
 // Don't silently upgrade forbidden-access paths to private.
 namespace test9 {
   class A {
-    public: static int x;
+  public: static int x; // expected-note {{member is declared here}}
   };
   class B : private A { // expected-note {{constrained by private inheritance here}}
   };
@@ -363,3 +365,88 @@
   }
 }
 
+// PR 7024
+namespace test15 {
+  template <class T> class A {
+  private:
+    int private_foo; // expected-note {{declared private here}}
+    static int private_sfoo; // expected-note {{declared private here}}
+  protected:
+    int protected_foo; // expected-note 4 {{declared protected here}}
+    static int protected_sfoo; // expected-note 3 {{declared protected here}}
+
+    int test1(A<int> &a) {
+      return a.private_foo; // expected-error {{private member}}
+    }
+
+    int test2(A<int> &a) {
+      return a.private_sfoo; // expected-error {{private member}}
+    }
+
+    int test3(A<int> &a) {
+      return a.protected_foo; // expected-error {{protected member}}
+    }
+
+    int test4(A<int> &a) {
+      return a.protected_sfoo; // expected-error {{protected member}}
+    }
+  };
+
+  template class A<int>;
+  template class A<long>; // expected-note 4 {{in instantiation}} 
+
+  template <class T> class B : public A<T> {
+    // TODO: These first two accesses can be detected as ill-formed at
+    // definition time because they're member accesses and A<int> can't
+    // be a subclass of B<T> for any T.
+
+    int test1(A<int> &a) {
+      return a.protected_foo; // expected-error 2 {{protected member}}
+    }
+
+    int test2(A<int> &a) {
+      return a.protected_sfoo; // expected-error {{protected member}}
+    }
+
+    int test3(B<int> &b) {
+      return b.protected_foo; // expected-error {{protected member}}
+    }
+
+    int test4(B<int> &b) {
+      return b.protected_sfoo; // expected-error {{protected member}}
+    }
+  };
+
+  template class B<int>;  // expected-note {{in instantiation}}
+  template class B<long>; // expected-note 4 {{in instantiation}}
+}
+
+// PR7281
+namespace test16 {
+  class A { ~A(); }; // expected-note 2{{declared private here}}
+  void b() { throw A(); } // expected-error{{temporary of type 'test16::A' has private destructor}} \
+  // expected-error{{exception object of type 'test16::A' has private destructor}}
+}
+
+// rdar://problem/8146294
+namespace test17 {
+  class A {
+    template <typename T> class Inner { }; // expected-note {{declared private here}}
+  };
+
+  A::Inner<int> s; // expected-error {{'Inner' is a private member of 'test17::A'}}
+}
+
+namespace test18 {
+  template <class T> class A {};
+  class B : A<int> {
+    A<int> member;
+  };
+
+  // FIXME: this access to A should be forbidden (because C++ is dumb),
+  // but LookupResult can't express the necessary information to do
+  // the check, so we aggressively suppress access control.
+  class C : B {
+    A<int> member;
+  };
+}
diff --git a/test/CXX/class.access/p6.cpp b/test/CXX/class.access/p6.cpp
index d51d75d..8795708 100644
--- a/test/CXX/class.access/p6.cpp
+++ b/test/CXX/class.access/p6.cpp
@@ -52,3 +52,90 @@
     A apriv = priv; // expected-error {{private constructor}}
   }
 }
+
+// PR6967
+namespace test2 {
+  class A {
+  public:
+    template <class T> static void set(T &t, typename T::type v) {
+      t.value = v;
+    }
+    template <class T> static typename T::type get(const T &t) {
+      return t.value;
+    }
+  };
+
+  class B {
+    friend class A;
+
+  private:
+    typedef int type;
+    type value;
+  };
+
+  int test() {
+    B b;
+    A::set(b, 0);
+    return A::get(b);
+  }
+}
+
+namespace test3 {
+  class Green {}; class Blue {};
+
+  // We have to wrap this in a class because a partial specialization
+  // isn't actually in the context of the template.
+  struct Outer {
+    template <class T, class Nat> class A {
+    };
+  };
+
+  template <class T> class Outer::A<T, typename T::nature> {
+  public:
+    static void foo();
+  };
+
+  class B {
+  private: typedef Green nature;
+    friend class Outer;
+  };
+
+  void test() {
+    Outer::A<B, Green>::foo();
+    Outer::A<B, Blue>::foo(); // expected-error {{no member named 'foo'}}
+  }
+}
+
+namespace test4 {
+  template <class T> class A {
+  private: typedef int type;
+    template <class U> friend void foo(U &, typename U::type);
+  };
+
+  template <class U> void foo(U &, typename U::type) {}
+  
+  void test() {
+    A<int> a;
+    foo(a, 0);
+  }
+}
+
+// PR7644
+namespace test5 {
+  class A {
+    enum Enum { E0, E1, E2 }; // expected-note 4 {{declared private here}}
+    template <Enum> void foo();
+    template <Enum> class bar;
+  };
+
+  template <A::Enum en> void A::foo() {}
+  template <A::Enum en> class A::bar {};
+
+  template <A::Enum en> void foo() {} // expected-error {{'Enum' is a private member of 'test5::A'}}
+  template <A::Enum en> class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}}
+
+  class B {
+    template <A::Enum en> void foo() {} // expected-error {{'Enum' is a private member of 'test5::A'}}
+    template <A::Enum en> class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}}
+  };
+}
diff --git a/test/CXX/class/class.static/class.static.data/p4.cpp b/test/CXX/class/class.static/class.static.data/p4.cpp
new file mode 100644
index 0000000..2b1eca7
--- /dev/null
+++ b/test/CXX/class/class.static/class.static.data/p4.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+struct InClassInitializerOnly {
+  static const int i = 0;
+};
+int const InClassInitializerOnly::i;
+
+struct OutOfClassInitializerOnly {
+  static const int i;
+};
+int const OutOfClassInitializerOnly::i = 0;
+
+struct InClassInitializerAndOutOfClassCopyInitializer {
+  static const int i = 0; // expected-note{{previous definition is here}}
+};
+int const InClassInitializerAndOutOfClassCopyInitializer::i = 0; // expected-error{{redefinition of 'i'}}
+
+struct InClassInitializerAndOutOfClassDirectInitializer {
+  static const int i = 0; // expected-note{{previous definition is here}}
+};
+int const InClassInitializerAndOutOfClassDirectInitializer::i(0); // expected-error{{redefinition of 'i'}}
+
+
+
+int main() { }
+
diff --git a/test/CXX/conv/conv.ptr/p2.cpp b/test/CXX/conv/conv.ptr/p2.cpp
new file mode 100644
index 0000000..8808d20
--- /dev/null
+++ b/test/CXX/conv/conv.ptr/p2.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace pr7801 {
+  extern void* x[];
+  void* dummy[] = { &x };
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.def/p1.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.def/p1.cpp
new file mode 100644
index 0000000..04584da
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.def/p1.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+namespace a {} // original
+namespace a {} // ext
+inline namespace b {} // inline original
+inline namespace b {} // inline ext
+inline namespace {} // inline unnamed
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp
index 1aa163a..546c4a4 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 namespace test0 {
   namespace ns0 {
@@ -31,3 +31,4 @@
     using test1::foo;
   }
 }
+
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
index 25371c7..cc28bf6 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
@@ -111,34 +111,53 @@
 
   struct Derived1 : Base {
     using Base::foo;
-    template <int n> Opaque<2> foo() { return Opaque<2>(); }
+    template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}}
   };
 
   struct Derived2 : Base {
-    template <int n> Opaque<2> foo() { return Opaque<2>(); }
+    template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}}
     using Base::foo;
   };
 
   struct Derived3 : Base {
     using Base::foo;
-    template <class T> Opaque<3> foo() { return Opaque<3>(); }
+    template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}}
   };
 
   struct Derived4 : Base {
-    template <class T> Opaque<3> foo() { return Opaque<3>(); }
+    template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}}
     using Base::foo;
   };
 
   void test() {
     expect<0>(Base().foo<int>());
     expect<1>(Base().foo<0>());
-    expect<0>(Derived1().foo<int>());
+    expect<0>(Derived1().foo<int>()); // expected-error {{no matching member function for call to 'foo'}}
     expect<2>(Derived1().foo<0>());
-    expect<0>(Derived2().foo<int>());
+    expect<0>(Derived2().foo<int>()); // expected-error {{no matching member function for call to 'foo'}}
     expect<2>(Derived2().foo<0>());
     expect<3>(Derived3().foo<int>());
-    expect<1>(Derived3().foo<0>());
+    expect<1>(Derived3().foo<0>()); // expected-error {{no matching member function for call to 'foo'}}
     expect<3>(Derived4().foo<int>());
-    expect<1>(Derived4().foo<0>());
+    expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}}
+  }
+}
+
+// PR7384: access control for member templates.
+namespace test4 {
+  class Base {
+  protected:
+    template<typename T> void foo(T);
+    template<typename T> void bar(T); // expected-note {{declared protected here}}
+  };
+
+  struct Derived : Base {
+    using Base::foo;
+  };
+
+  void test() {
+    Derived d;
+    d.foo<int>(3);
+    d.bar<int>(3); // expected-error {{'bar' is a protected member}}
   }
 }
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp
index ec814b1..dd44bfc 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp
@@ -55,6 +55,19 @@
   }
 }
 
+// Typedef redeclaration.
+namespace rdar8018262 {
+  typedef void (*fp)();
+
+  namespace N {
+    typedef void (*fp)();
+  }
+
+  using N::fp;
+
+  fp fp_1;
+}
+
 // Things to test:
 //   member operators
 //   conversion operators
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp
index fd2df01..4660971 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp
@@ -81,3 +81,18 @@
 
   template struct Derived<int>; // expected-note {{in instantiation of template class}}
 }
+
+// Redeclarations are okay in a function.
+namespace test3 {
+  namespace N {
+    int f(int);
+    typedef int type;
+  }
+
+  void g() {
+    using N::f;
+    using N::f;
+    using N::type;
+    using N::type;
+  }
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p6.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p6.cpp
new file mode 100644
index 0000000..4cb91cd
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p6.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// <rdar://problem/8296180>
+typedef int pid_t;
+namespace ns {
+  typedef int pid_t;
+}
+using namespace ns;
+pid_t x;
+
+struct A { };
+namespace ns {
+  typedef ::A A;
+}
+A a;
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
new file mode 100644
index 0000000..cd71d55
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// XFAIL: *
+
+struct notlit {
+  notlit() {}
+};
+struct notlit2 {
+  notlit2() {}
+};
+
+// valid declarations
+constexpr int i1 = 0;
+constexpr int f1() { return 0; }
+struct s1 {
+  constexpr static int mi = 0;
+};
+
+// invalid declarations
+// not a definition of an object
+constexpr extern int i2; // x
+// not a literal type
+constexpr notlit nl1; // x
+// function parameters
+void f2(constexpr int i) {} // x
+// non-static member
+struct s2 {
+  constexpr int mi; // x
+};
+// redeclaration mismatch
+constexpr int f3(); // n
+int f3(); // x
+int f4(); // n
+constexpr int f4(); // x
+
+// template stuff
+template <typename T>
+constexpr T ft(T t) { return t; }
+
+// specialization can differ in constepxr
+template <>
+notlit ft(notlit nl) { return nl; }
+
+constexpr int i3 = ft(1);
+
+void test() {
+  // ignore constexpr when instantiating with non-literal
+  notlit2 nl2;
+  (void)ft(nl2);
+}
+
+// Examples from the standard:
+constexpr int square(int x);
+constexpr int bufsz = 1024;
+
+constexpr struct pixel { // x
+  int x;
+  int y;
+  constexpr pixel(int);
+};
+
+constexpr pixel::pixel(int a)
+  : x(square(a)), y(square(a))
+  { }
+
+constexpr pixel small(2); // x (no definition of square(int) yet, so can't
+                          // constexpr-eval pixel(int))
+
+constexpr int square(int x) {
+  return x * x;
+}
+
+constexpr pixel large(4); // now valid
+
+int next(constexpr int x) { // x
+      return x + 1;
+}
+
+extern constexpr int memsz; // x
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
index 99a4f7a..d7b9eff 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p3.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p3.cpp
@@ -1,11 +1,13 @@
 // RUN: %clang_cc1 -verify %s
-// XFAIL: *
 
-void f0(void) {
-  inline void f1(); // expected-error {{'inline' is not allowed on block scope function declaration}}
+void f0a(void) {
+   inline void f1(); // expected-error {{inline declaration of 'f1' not allowed in block scope}}
+}
+
+void f0b(void) {
+   void f1();
 }
 
 // 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.stc/p9.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp
index f507eec..491ab17 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp
@@ -1,12 +1,11 @@
 // RUN: %clang_cc1 -verify %s
 
-struct S; // expected-note {{forward declaration of 'S'}}
+struct S; // expected-note 2{{forward declaration of 'S'}}
 extern S a;
 extern S f(); // expected-note {{'f' declared here}}
-extern void g(S a); // expected-note {{candidate function}}
+extern void g(S a);
 
 void h() {
-  // FIXME: This diagnostic could be better.
-  g(a); // expected-error {{no matching function for call to 'g'}}
+  g(a); // expected-error {{argument type 'S' is incomplete}}
   f(); // expected-error {{calling 'f' with incomplete return type 'S'}}
 }
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
deleted file mode 100644
index 5a342d4..0000000
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p16-cxx0x-no-extra-copy.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-// 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/p5-cxx03-extra-copy.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
index 1639411..ae59598 100644
--- 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
@@ -1,9 +1,10 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -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.
+// cases where that copy constructor is somehow unavailable.  As an
+// extension, this is only a warning.
 
 struct X1 {
   X1();
@@ -28,6 +29,7 @@
 template<typename T>
 T get_value_badly() {
   double *dp = 0;
+  // The extension doesn't extend far enough to turn this error into a warning.
   T *tp = dp; // expected-error{{ cannot initialize a variable of type 'int *' with an lvalue of type 'double *'}}
   return T();
 }
@@ -41,7 +43,7 @@
 // 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'}}
+  X5(const X5&, const X5& = X5()); // expected-warning{{no viable constructor copying parameter of type 'X5'}}
 };
 
 void g1(const X1&);
@@ -51,11 +53,25 @@
 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'}}
+  g1(X1()); // expected-warning{{no viable constructor copying parameter of type 'X1'; C++98 requires a copy constructor when binding a reference to a temporary [-Wbind-to-temporary-copy]}}
+  g2(X2()); // expected-warning{{C++98 requires an accessible copy constructor for class 'X2' when binding a reference to a temporary; was private [-Wbind-to-temporary-copy]}}
+  g3(X3()); // expected-warning{{no viable constructor copying parameter of type 'X3'}}
   g4(X4<int>());
-  g5(X5()); // expected-error{{no viable constructor copying parameter of type 'X5'}}
+  g5(X5());  // Generates a warning in the default argument.
 }
 
-// Check for dangerous recursion in default arguments.
+// Check that unavailable copy constructors still cause SFINAE failures.
+template<int> struct int_c { };
+
+template<typename T> T f(const T&);
+
+// Would be ambiguous with the next g(), except the instantiation failure in
+// sizeof() prevents that.
+template<typename T>
+int &g(int_c<sizeof(f(T()))> * = 0);
+
+template<typename T> float &g();
+
+void h() {
+  float &fp2 = g<X3>();  // Not ambiguous.
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp
new file mode 100644
index 0000000..5cfb11a
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp
@@ -0,0 +1,64 @@
+// 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>());
+}
+
+// Check that unavailable copy constructors do not cause SFINAE failures.
+template<int> struct int_c { };
+
+template<typename T> T f(const T&);
+
+template<typename T>
+int &g(int_c<sizeof(f(T()))> * = 0);  // expected-note{{candidate function [with T = X3]}}
+
+template<typename T> float &g();  // expected-note{{candidate function [with T = X3]}}
+
+void h() {
+  float &fp = g<X3>();  // expected-error{{call to 'g' is ambiguous}}
+}
diff --git a/test/CXX/except/except.spec/p14-ir.cpp b/test/CXX/except/except.spec/p14-ir.cpp
new file mode 100644
index 0000000..4d8d1f7
--- /dev/null
+++ b/test/CXX/except/except.spec/p14-ir.cpp
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -o - %s | FileCheck %s
+
+// Copy constructor
+struct X0 {
+  X0();
+  X0(const X0 &) throw();
+  X0(X0 &);
+};
+
+struct X1 {
+  X1();
+  X1(const X1 &) throw();
+};
+
+struct X2 : X1 { 
+  X2();
+};
+struct X3 : X0, X1 { 
+  X3();
+};
+
+struct X4 {
+  X4(X4 &) throw();
+};
+
+struct X5 : X0, X4 { };
+
+void test(X2 x2, X3 x3, X5 x5) {
+  // CHECK: define linkonce_odr void @_ZN2X2C1ERKS_
+  // CHECK:      call void @_ZN2X2C2ERKS_({{.*}}) nounwind
+  // CHECK-NEXT: ret void
+  // CHECK-NEXT: }
+  X2 x2a(x2);
+  // CHECK: define linkonce_odr void @_ZN2X3C1ERKS_
+  // CHECK:      call void @_ZN2X3C2ERKS_({{.*}}) nounwind
+  // CHECK-NEXT: ret void
+  // CHECK-NEXT: }
+  X3 x3a(x3);
+  // CHECK: define linkonce_odr void @_ZN2X5C1ERS_
+  // CHECK-NOT: call void @__cxa_call_unexpected
+  // CHECK: ret void
+  X5 x5a(x5);
+}
+
+// Default constructor
+struct X6 {
+  X6() throw();
+};
+
+struct X7 { 
+  X7();
+};
+
+struct X8 : X6 { };
+struct X9 : X6, X7 { };
+
+void test() {
+  // CHECK: define linkonce_odr void @_ZN2X8C1Ev
+  // CHECK:      call void @_ZN2X8C2Ev({{.*}}) nounwind
+  // CHECK-NEXT: ret void
+  X8();
+
+  // CHECK: define linkonce_odr void @_ZN2X9C1Ev
+  //   FIXME: check that this is the end of the line here:
+  // CHECK:      call void @_ZN2X9C2Ev({{.*}})
+  // CHECK-NEXT: ret void
+  X9();
+
+  // CHECK: define linkonce_odr void @_ZN2X9C2Ev
+  // CHECK:      call void @_ZN2X6C2Ev({{.*}}) nounwind
+  //   FIXME: and here:
+  // CHECK-NEXT: call void @_ZN2X7C2Ev({{.*}})
+  // CHECK: ret void
+
+  // CHECK: define linkonce_odr void @_ZN2X8C2Ev
+  // CHECK:      call void @_ZN2X6C2Ev({{.*}}) nounwind
+  // CHECK-NEXT: ret void
+}
diff --git a/test/CXX/except/except.spec/p14.cpp b/test/CXX/except/except.spec/p14.cpp
new file mode 100644
index 0000000..9450b1c
--- /dev/null
+++ b/test/CXX/except/except.spec/p14.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fexceptions -verify %s
+struct A { };
+struct B { };
+struct C { };
+
+// Destructor
+struct X0 { 
+  virtual ~X0() throw(A); // expected-note{{overridden virtual function is here}} 
+};
+struct X1 { 
+  virtual ~X1() throw(B); // expected-note{{overridden virtual function is here}} 
+};
+struct X2 : public X0, public X1 { }; // expected-error 2{{exception specification of overriding function is more lax than base version}}
+ 
+// Copy-assignment operator.
+struct CA0 {
+  CA0 &operator=(const CA0&) throw(A);
+};
+struct CA1 {
+  CA1 &operator=(const CA1&) throw(B);
+};
+struct CA2 : CA0, CA1 { };
+
+void test_CA() {
+  CA2 &(CA2::*captr1)(const CA2&) throw(A, B) = &CA2::operator=;
+  CA2 &(CA2::*captr2)(const CA2&) throw(A, B, C) = &CA2::operator=;
+  CA2 &(CA2::*captr3)(const CA2&) throw(A) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}}
+  CA2 &(CA2::*captr4)(const CA2&) throw(B) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}}
+}
diff --git a/test/CXX/expr/expr.post/expr.ref/p3.cpp b/test/CXX/expr/expr.post/expr.ref/p3.cpp
new file mode 100644
index 0000000..98771d3
--- /dev/null
+++ b/test/CXX/expr/expr.post/expr.ref/p3.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+template<typename T> struct Node {
+	int lhs;
+	void splay( )                
+	{
+		Node<T> n[1];
+		(void)n->lhs;
+	}
+};
+
+void f() {
+	Node<int> n;
+	return n.splay();
+}
diff --git a/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp b/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp
new file mode 100644
index 0000000..170c734
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// rdar://problem/8347416
+namespace test0 {
+  struct A {
+    void foo(void (A::*)(int)); // expected-note {{passing argument to parameter here}}
+    template<typename T> void g(T);
+
+    void test() {
+      // FIXME: this diagnostic is terrible
+      foo(&g<int>); // expected-error {{cannot initialize a parameter of type 'void (test0::A::*)(int)' with an rvalue of type '<overloaded function type>'}}
+    }
+  };
+}
+
+// This should succeed.
+namespace test1 {
+  struct A {
+    static void f(void (A::*)());
+    static void f(void (*)(int));
+    void g();
+    static void g(int);
+
+    void test() {
+      f(&g);
+    }
+  };
+}
+
+// Also rdar://problem/8347416
+namespace test2 {
+  struct A {
+    static int foo(short);
+    static int foo(float);
+    int foo(int);
+    int foo(double);
+
+    void test();
+  };
+
+  void A::test() {
+    // FIXME: This diagnostic is terrible.
+    int (A::*ptr)(int) = &(A::foo); // expected-error {{cannot initialize a variable of type 'int (test2::A::*)(int)' with an rvalue of type '<overloaded function type>'}}
+  }
+}
diff --git a/test/CXX/special/class.copy/p20.cpp b/test/CXX/special/class.copy/p20.cpp
new file mode 100644
index 0000000..8dfb7ca
--- /dev/null
+++ b/test/CXX/special/class.copy/p20.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct ConstCopy {
+  ConstCopy();
+  ConstCopy &operator=(const ConstCopy&);
+};
+
+struct NonConstCopy {
+  NonConstCopy();
+  NonConstCopy &operator=(NonConstCopy&);
+};
+
+struct VirtualInheritsNonConstCopy : virtual NonConstCopy { 
+  VirtualInheritsNonConstCopy();
+  VirtualInheritsNonConstCopy &operator=(const VirtualInheritsNonConstCopy&);
+};
+
+struct ImplicitNonConstCopy1 : NonConstCopy {  // expected-note{{the implicit copy assignment operator}}
+  ImplicitNonConstCopy1();
+};
+
+struct ImplicitNonConstCopy2 { // expected-note{{the implicit copy assignment operator}}
+  ImplicitNonConstCopy2();
+  NonConstCopy ncc;
+};
+
+struct ImplicitNonConstCopy3 { // expected-note{{the implicit copy assignment operator}}
+  ImplicitNonConstCopy3();
+  NonConstCopy ncc_array[2][3];
+};
+
+struct ImplicitNonConstCopy4 : VirtualInheritsNonConstCopy { 
+  ImplicitNonConstCopy4();
+};
+
+void test_non_const_copy(const ImplicitNonConstCopy1 &cincc1,
+                         const ImplicitNonConstCopy2 &cincc2,
+                         const ImplicitNonConstCopy3 &cincc3,
+                         const ImplicitNonConstCopy4 &cincc4,
+                         const VirtualInheritsNonConstCopy &vincc) {
+  (void)sizeof(ImplicitNonConstCopy1() = cincc1); // expected-error{{no viable overloaded '='}}
+  (void)sizeof(ImplicitNonConstCopy2() = cincc2); // expected-error{{no viable overloaded '='}}
+  (void)sizeof(ImplicitNonConstCopy3() = cincc3); // expected-error{{no viable overloaded '='}}
+  (void)sizeof(ImplicitNonConstCopy4() = cincc4); // okay
+  (void)sizeof(VirtualInheritsNonConstCopy() = vincc);
+}
diff --git a/test/CXX/special/class.copy/p9.cpp b/test/CXX/special/class.copy/p9.cpp
new file mode 100644
index 0000000..d037944
--- /dev/null
+++ b/test/CXX/special/class.copy/p9.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct ConstCopy {
+  ConstCopy();
+  ConstCopy(const ConstCopy&);
+};
+
+struct NonConstCopy {
+  NonConstCopy();
+  NonConstCopy(NonConstCopy&);
+};
+
+struct VirtualInheritsNonConstCopy : virtual NonConstCopy { 
+  VirtualInheritsNonConstCopy();
+  VirtualInheritsNonConstCopy(const VirtualInheritsNonConstCopy&);
+};
+
+struct ImplicitNonConstCopy1 : NonConstCopy { 
+  ImplicitNonConstCopy1();
+};
+
+struct ImplicitNonConstCopy2 {
+  ImplicitNonConstCopy2();
+  NonConstCopy ncc;
+};
+
+struct ImplicitNonConstCopy3 { 
+  ImplicitNonConstCopy3();
+  NonConstCopy ncc_array[2][3];
+};
+
+struct ImplicitNonConstCopy4 : VirtualInheritsNonConstCopy { 
+  ImplicitNonConstCopy4();
+};
+
+void test_non_const_copy(const ImplicitNonConstCopy1 &cincc1,
+                         const ImplicitNonConstCopy2 &cincc2,
+                         const ImplicitNonConstCopy3 &cincc3,
+                         const ImplicitNonConstCopy4 &cincc4) {
+  (void)sizeof(ImplicitNonConstCopy1(cincc1)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy1 const' to 'ImplicitNonConstCopy1' is not allowed}}
+  (void)sizeof(ImplicitNonConstCopy2(cincc2)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy2 const' to 'ImplicitNonConstCopy2' is not allowed}}
+  (void)sizeof(ImplicitNonConstCopy3(cincc3)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy3 const' to 'ImplicitNonConstCopy3' is not allowed}}
+  (void)sizeof(ImplicitNonConstCopy4(cincc4)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy4 const' to 'ImplicitNonConstCopy4' is not allowed}}
+}
diff --git a/test/CXX/special/class.dtor/p9.cpp b/test/CXX/special/class.dtor/p9.cpp
new file mode 100644
index 0000000..8b76a15
--- /dev/null
+++ b/test/CXX/special/class.dtor/p9.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef typeof(sizeof(int)) size_t;
+
+// PR7803
+namespace test0 {
+  class A {
+  public:
+    static void operator delete(void *p) {};
+    virtual ~A();
+  };
+
+  class B : protected A {
+  public:
+    ~B();
+  };
+
+  class C : protected B {
+  public:
+    using B::operator delete;
+    ~C();
+  };
+
+  // Shouldn't have an error.
+  C::~C() {}
+}
+
+namespace test1 {
+  class A {
+  public:
+    static void operator delete(void *p) {}; // expected-note {{member 'operator delete' declared here}}
+    virtual ~A();
+  };
+
+  class B : protected A {
+  public:
+    static void operator delete(void *, size_t) {}; // expected-note {{member 'operator delete' declared here}}
+    ~B();
+  };
+
+  class C : protected B {
+  public:
+    using A::operator delete;
+    using B::operator delete;
+
+    ~C();
+  };
+
+  C::~C() {} // expected-error {{multiple suitable 'operator delete' functions in 'C'}}
+}
+
+// ...at the point of definition of a virtual destructor...
+namespace test2 {
+  struct A {
+    virtual ~A();
+    static void operator delete(void*, const int &);
+  };
+
+  struct B {
+    virtual ~B();
+    static void operator delete(void*, const int &); // expected-note {{declared here}}
+  };
+  B::~B() {} // expected-error {{no suitable member 'operator delete' in 'B'}}
+
+  struct CBase { virtual ~CBase(); };
+  struct C : CBase { // expected-error {{no suitable member 'operator delete' in 'C'}}
+    static void operator delete(void*, const int &); // expected-note {{declared here}}
+  };
+  void test() {
+    C c; // expected-note {{first required here}}
+  }
+}
+
+// PR7346
+namespace test3 {
+  struct A {
+    virtual ~A();
+    static void operator delete(void*, const int &);
+  };
+
+  struct B : A {
+    virtual ~B() {}
+    static void operator delete(void*);
+  };
+}
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
index e344eed..97457ea 100644
--- 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
@@ -14,3 +14,35 @@
 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];
+
+namespace DependentSubstPartialOrdering {
+  template<typename T, typename U = void, typename V = void>
+  struct X { 
+    static const unsigned value = 1;
+  };
+
+  template<typename T, typename U>
+  struct X<T, U, typename T::is_b> {
+    static const unsigned value = 2;
+  };
+
+  template<typename T>
+  struct X<T, typename T::is_a, typename T::is_b> {
+    static const unsigned value = 3;
+  };
+
+  struct X1 { };
+
+  struct X2 { 
+    typedef void is_b;
+  };
+
+  struct X3 {
+    typedef void is_a;
+    typedef void is_b;
+  };
+
+  int check_X1[X<X1, void, void>::value == 1? 1 : -1];
+  int check_X2[X<X2, void, void>::value == 2? 1 : -1];
+  int check_X3[X<X3, void, void>::value == 3? 1 : -1];
+}
diff --git a/test/CXX/temp/temp.decls/temp.friend/p4.cpp b/test/CXX/temp/temp.decls/temp.friend/p4.cpp
new file mode 100644
index 0000000..226ac0f
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.friend/p4.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X1 {
+  friend void f6(int) { } // expected-error{{redefinition of}} \
+                          // expected-note{{previous definition}}
+};
+
+X1<int> x1a; 
+X1<float> x1b; // expected-note {{in instantiation of}}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp b/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp
new file mode 100644
index 0000000..7352be2
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Check for template type parameter pack (mis-)matches with template
+// type parameters.
+template<typename ...T> struct X0t;
+template<typename ...T> struct X0t;
+
+template<typename ...T> struct X1t; // expected-note{{previous template type parameter pack declared here}}
+template<typename T> struct X1t; // expected-error{{template type parameter conflicts with previous template type parameter pack}}
+
+template<typename T> struct X2t; // expected-note{{previous template type parameter declared here}}
+template<typename ...T> struct X2t; // expected-error{{template type parameter pack conflicts with previous template type parameter}}
+
+template<template<typename ...T> class> struct X0tt; 
+template<template<typename ...T> class> struct X0tt; 
+
+template<template<typename ...T> class> struct X1tt; // expected-note{{previous template type parameter pack declared here}}
+template<template<typename T> class> struct X1tt; // expected-error{{template type parameter conflicts with previous template type parameter pack}}
+
+template<template<typename T> class> struct X2tt; // expected-note{{previous template type parameter declared here}}
+template<template<typename ...T> class> struct X2tt; // expected-error{{template type parameter pack conflicts with previous template type parameter}}
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
index dc79300..5556f35 100644
--- a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp
@@ -43,3 +43,23 @@
     return Foo<T>(b, quuz);
   }
 }
+
+// PR7641
+namespace PR7641 {
+  namespace N2
+  {
+    template<class>
+    int f0(int);
+  }
+  namespace N
+  {
+    using N2::f0;
+  }
+
+  template<class R,class B1>
+  int
+  f1(R(a)(B1));
+
+  void f2()
+  { f1(N::f0<int>); }
+}
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
index 1b7310f..90d2949 100644
--- 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
@@ -16,7 +16,8 @@
 }
 
 // TODO: this diagnostic can and should improve
-template<typename T> void f2(T*, T*); // expected-note 2 {{candidate template ignored: failed template argument deduction}}
+template<typename T> void f2(T*, T*); // expected-note {{candidate template ignored: failed template argument deduction}} \
+// expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'float')}}
 
 struct ConvToIntPtr {
   operator int*() const;
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
index 6edf079..1b240cc 100644
--- 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
@@ -1,7 +1,7 @@
 // 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}}\
+  template<class T> void apply(T x, void (*f)(T)) { f(x); } // expected-note 2 {{candidate template ignored: deduced conflicting types for parameter 'T'}}\
   // expected-note {{no overload of 'temp2' matching 'void (*)(int)'}}
 
   template<class A> void temp(A);
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
index 2a7f16d..bf5f962 100644
--- 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
@@ -1,7 +1,7 @@
 // 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}}
+template<short s> void f(A<s>); // expected-note{{candidate template ignored: substitution failure}}
 
 void k1() { 
   A<1> a;
@@ -15,14 +15,14 @@
   g(b); // OK: cv-qualifiers are ignored on template parameter types
 }
 
-template<short s> void h(int (&)[s]); // expected-note{{failed template argument deduction}}
+template<short s> void h(int (&)[s]); // expected-note{{candidate function template not viable: requires 1 argument, but 2 were provided}}
 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}}
+template<short s> void h(int (&)[s], A<s>);  // expected-note{{candidate template ignored: substitution failure}}
 void k4() {
   A<5> a;
   int array[5];
diff --git a/test/CXX/temp/temp.names/p2.cpp b/test/CXX/temp/temp.names/p2.cpp
new file mode 100644
index 0000000..93e45dd
--- /dev/null
+++ b/test/CXX/temp/temp.names/p2.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Ensure that when enforcing access control an unqualified template name with
+// explicit template arguments, we don't lose the context of the name lookup
+// because of the required early lookup to determine if it names a template.
+namespace PR7163 {
+  template <typename R, typename P> void h(R (*func)(P)) {}
+  class C {
+    template <typename T> static void g(T*) {};
+   public:
+    void f() { h(g<int>); }
+  };
+}
diff --git a/test/CXX/temp/temp.param/p2.cpp b/test/CXX/temp/temp.param/p2.cpp
index 41868c5..fed6e9c 100644
--- a/test/CXX/temp/temp.param/p2.cpp
+++ b/test/CXX/temp/temp.param/p2.cpp
@@ -14,4 +14,9 @@
 // A storage class shall not be specified in a template-parameter declaration.
 template<static int Value> struct Z; // FIXME: expect an error
 
+// Make sure that we properly disambiguate non-type template parameters that
+// start with 'class'.
+class X1 { };
+template<class X1 *xptr> struct Y2 { };
+
 // FIXME: add the example from p2
diff --git a/test/CXX/temp/temp.param/p4.cpp b/test/CXX/temp/temp.param/p4.cpp
index 5ec402a..809fb20 100644
--- a/test/CXX/temp/temp.param/p4.cpp
+++ b/test/CXX/temp/temp.param/p4.cpp
@@ -17,4 +17,5 @@
 
 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 *'}}
+template<void *Ptr> struct A12;
+template<int (*IncompleteArrayPtr)[]> struct A13;
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p11.cpp b/test/CXX/temp/temp.spec/temp.explicit/p11.cpp
new file mode 100644
index 0000000..4ca5428
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.explicit/p11.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class X {
+  template <typename T> class Y {};
+};
+
+class A {
+  class B {};
+  class C {};
+};
+
+// C++0x [temp.explicit] 14.7.2/11:
+//   The usual access checking rules do not apply to names used to specify
+//   explicit instantiations.
+template class X::Y<A::B>;
+
+// As an extension, this rule is applied to explicit specializations as well.
+template <> class X::Y<A::C> {};
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p2.cpp b/test/CXX/temp/temp.spec/temp.explicit/p2.cpp
index 8538d27..70d338b 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p2.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p2.cpp
@@ -25,9 +25,9 @@
 
 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}}
+template struct XInt::Inner; // expected-warning{{template-id}}
+template void XInt::f(); // expected-warning{{template-id}}
+template int XInt::value; // expected-warning{{template-id}}
 
 namespace N {
   template<typename T>
@@ -39,5 +39,5 @@
 }
 using namespace N;
 
-template struct X1<int>; // expected-error{{must occur in}}
-template void f1(int); // expected-error{{must occur in}}
+template struct X1<int>; // expected-warning{{must occur in}}
+template void f1(int); // expected-warning{{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
index e9758bc..48c42c3 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p3.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p3.cpp
@@ -2,8 +2,9 @@
 
 // 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<typename T> void f0(T);
 template void f0(int); // okay
+template<typename T> void f0(T) { }
 
 // 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 
@@ -47,3 +48,27 @@
 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}}
+
+
+// A definition of a class template is sufficient to explicitly
+// instantiate a member of the class template which itself is not yet defined.
+namespace PR7979 {
+  template <typename T> struct S {
+    void f();
+    static void g();
+    static int i;
+    struct S2 {
+      void h();
+    };
+  };
+
+  template void S<int>::f();
+  template void S<int>::g();
+  template int S<int>::i;
+  template void S<int>::S2::h();
+
+  template <typename T> void S<T>::f() {}
+  template <typename T> void S<T>::g() {}
+  template <typename T> int S<T>::i;
+  template <typename T> void S<T>::S2::h() {}
+}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p5.cpp b/test/CXX/temp/temp.spec/temp.explicit/p5.cpp
index 13fb049..7522d02 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p5.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p5.cpp
@@ -11,7 +11,7 @@
 // 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 Y<int>; // expected-warning{{must occur in}}
 
 template class N::Y<char*>; 
 template void N::Y<double>::mf();
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
index e67233c..57b012f 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -std=c++0x -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -emit-llvm -std=c++0x -o - %s | FileCheck %s
 
 template<typename T>
 struct X0 {
diff --git a/test/CodeCompletion/Inputs/reserved.h b/test/CodeCompletion/Inputs/reserved.h
new file mode 100644
index 0000000..fafe4ac
--- /dev/null
+++ b/test/CodeCompletion/Inputs/reserved.h
@@ -0,0 +1,2 @@
+typedef int _INTEGER_TYPE;
+typedef float FLOATING_TYPE;
diff --git a/test/CodeCompletion/call.c b/test/CodeCompletion/call.c
index 8210389..8581414 100644
--- a/test/CodeCompletion/call.c
+++ b/test/CodeCompletion/call.c
@@ -6,7 +6,7 @@
   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
+  // 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#>)
diff --git a/test/CodeCompletion/call.cpp b/test/CodeCompletion/call.cpp
index 1df958e..f06470f 100644
--- a/test/CodeCompletion/call.cpp
+++ b/test/CodeCompletion/call.cpp
@@ -17,8 +17,8 @@
 
 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#>)
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:19:9 %s -o - | FileCheck -check-prefix=CC1 %s
+  // CHECK-CC1: COMPLETION: Pattern : dynamic_cast<<#type#>>(<#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#>)
diff --git a/test/CodeCompletion/enum-switch-case.c b/test/CodeCompletion/enum-switch-case.c
index 0820726..d5df371 100644
--- a/test/CodeCompletion/enum-switch-case.c
+++ b/test/CodeCompletion/enum-switch-case.c
@@ -18,11 +18,28 @@
 
     case Green:
       break;
-      
+  }
+
+  unsigned c2;
+  switch (c2) {
+    case 
+  }
+
     // 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
-      
+
+    // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:25:10 %s -o - | FileCheck -check-prefix=CC2 %s      
+  // CHECK-CC2: COMPLETION: Blue : [#enum Color#]Blue
+  // CHECK-CC2-NEXT: COMPLETION: c2 : [#unsigned int#]c2
+  // CHECK-CC2-NEXT: COMPLETION: color : [#enum Color#]color
+  // CHECK-CC2-NEXT: COMPLETION: Green : [#enum Color#]Green
+  // CHECK-CC2-NEXT: COMPLETION: Indigo : [#enum Color#]Indigo
+  // CHECK-CC2-NEXT: COMPLETION: Orange : [#enum Color#]Orange
+  // CHECK-CC2-NEXT: COMPLETION: Red : [#enum Color#]Red
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : sizeof(<#expression-or-type#>)
+  // CHECK-CC2-NEXT: COMPLETION: Violet : [#enum Color#]Violet
+  // CHECK-CC2-NEXT: COMPLETION: Yellow : [#enum Color#]Yellow
diff --git a/test/CodeCompletion/ordinary-name.c b/test/CodeCompletion/ordinary-name.c
index 1580d01..0807b74 100644
--- a/test/CodeCompletion/ordinary-name.c
+++ b/test/CodeCompletion/ordinary-name.c
@@ -1,10 +1,14 @@
+#include <reserved.h>
 struct X { int x; };
-
 typedef struct t TYPEDEF;
-
+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
+  // RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only -code-completion-at=%s:6:9 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+  // CHECK-CC1: _Imaginary
+  // CHECK-CC1-NOT: _INTEGER_TYPE;
+  // CHECK-CC1: _TYPEDEF
+  // CHECK-CC1: FLOATING_TYPE
   // CHECK-CC1: foo
-  // CHECK-CC1: y
   // CHECK-CC1: TYPEDEF
+  // CHECK-CC1: y
diff --git a/test/CodeCompletion/ordinary-name.cpp b/test/CodeCompletion/ordinary-name.cpp
index 699b01d..7e08c72 100644
--- a/test/CodeCompletion/ordinary-name.cpp
+++ b/test/CodeCompletion/ordinary-name.cpp
@@ -4,37 +4,37 @@
 
 void foo() {
   int y = 17;
-  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:6:14 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -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-NEXT: COMPLETION: Pattern : const_cast<<#type#>>(<#expression#>)
   // CHECK-CC1: COMPLETION: Pattern : delete <#expression#>
-  // CHECK-CC1-NEXT: 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: Pattern : dynamic_cast<<#type#>>(<#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: COMPLETION: Pattern : goto <#label#>
   // 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: Pattern : new <#type#>(<#expressions#>)
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : new <#type#>[<#size#>](<#expressions#>)
   // CHECK-CC1-NEXT: COMPLETION: operator
-  // CHECK-CC1-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type#>>(<#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: Pattern : static_cast<<#type#>>(<#expression#>)
   // CHECK-CC1-NEXT: COMPLETION: struct
   // CHECK-CC1-NEXT: COMPLETION: Pattern : switch(<#condition#>){
   // CHECK-CC1: COMPLETION: t : t
@@ -42,10 +42,11 @@
   // 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 : typedef <#type#> <#name#>
   // 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: Pattern : typename <#qualifier#>::<#name#>
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : typeof <#expression#>
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : typeof(<#type#>)
   // CHECK-CC1-NEXT: COMPLETION: union
   // CHECK-CC1-NEXT: COMPLETION: unsigned
   // CHECK-CC1-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
@@ -57,7 +58,7 @@
   // 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
+  // RUN: %clang_cc1 -fsyntax-only  -code-completion-patterns -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
@@ -71,7 +72,7 @@
   // 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: COMPLETION: Pattern : namespace <#name#> = <#namespace#>
   // CHECK-CC2-NEXT: COMPLETION: operator
   // CHECK-CC2-NEXT: COMPLETION: short
   // CHECK-CC2-NEXT: COMPLETION: signed
@@ -81,19 +82,20 @@
   // 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: Pattern : typedef <#type#> <#name#>
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#>
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : typeof <#expression#>
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : typeof(<#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: Pattern : using <#qualifier#>::<#name#>
   // 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
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -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
@@ -117,50 +119,52 @@
   // 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: Pattern : typedef <#type#> <#name#>
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#>
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : typeof <#expression#>
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : typeof(<#type#>)
   // CHECK-CC3-NEXT: COMPLETION: union
   // CHECK-CC3-NEXT: COMPLETION: unsigned
-  // CHECK-CC3-NEXT: COMPLETION: Pattern : using <#qualified-id#>
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>
   // 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
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -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 : const_cast<<#type#>>(<#expression#>)
   // CHECK-CC4-NEXT: COMPLETION: Pattern : delete <#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: Pattern : dynamic_cast<<#type#>>(<#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: Pattern : new <#type#>(<#expressions#>)
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : new <#type#>[<#size#>](<#expressions#>)
   // CHECK-CC4-NEXT: COMPLETION: operator
-  // CHECK-CC4-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type-id#>>(<#expression#>)
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type#>>(<#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: Pattern : static_cast<<#type#>>(<#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: Pattern : typename <#qualifier#>::<#name#>
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : typeof <#expression#>
+  // CHECK-CC4-NEXT: COMPLETION: Pattern : typeof(<#type#>)
   // CHECK-CC4-NEXT: COMPLETION: union
   // CHECK-CC4-NEXT: COMPLETION: unsigned
   // CHECK-CC4-NEXT: COMPLETION: void
diff --git a/test/CodeCompletion/truncation.c b/test/CodeCompletion/truncation.c
index 134139d..1b446b7 100644
--- a/test/CodeCompletion/truncation.c
+++ b/test/CodeCompletion/truncation.c
@@ -2,6 +2,8 @@
 
 struct 
 
+/* foo */
+
 // 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
@@ -9,3 +11,8 @@
 // CHECK-CC2: X
 // CHECK-CC2: Xa
 // CHECK-CC2: Y
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:5:3 -o - %s | FileCheck -check-prefix=CC3 %s
+// CHECK-CC3: X
+// CHECK-CC3: Xa
+// CHECK-CC3: Y
diff --git a/test/CodeGen/2008-07-29-override-alias-decl.c b/test/CodeGen/2008-07-29-override-alias-decl.c
index a4bea0e..dbe10b3 100644
--- a/test/CodeGen/2008-07-29-override-alias-decl.c
+++ b/test/CodeGen/2008-07-29-override-alias-decl.c
@@ -2,10 +2,7 @@
 
 int x() { return 1; }
 
-// CHECK:  [[retval:%.*]] = alloca i32
-// CHECK:  store i32 1, i32* [[retval]]
-// CHECK:  [[load:%.*]] = load i32* [[retval]]
-// CHECK:  ret i32 [[load]]
+// CHECK:  ret i32 1
 
 
 int f() __attribute__((weak, alias("x")));
@@ -17,9 +14,6 @@
   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]]
+// CHECK:  ret i32 [[call]]
 
diff --git a/test/CodeGen/2008-12-02-logical-or-fold.c b/test/CodeGen/2008-12-02-logical-or-fold.c
deleted file mode 100644
index 167ad29..0000000
--- a/test/CodeGen/2008-12-02-logical-or-fold.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | grep "store i32 1"
-// PR3150
-
-int a() {return 1||1;}
diff --git a/test/CodeGen/2009-04-23-dbg.c b/test/CodeGen/2009-04-23-dbg.c
index 6a8bf01..704aba2 100644
--- a/test/CodeGen/2009-04-23-dbg.c
+++ b/test/CodeGen/2009-04-23-dbg.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -g -o %t  %s -emit-llvm-bc && llc %t -o %t.s
+// RUN: %clang_cc1 -S -g -o %t %s
 # 1 "a.c"
 # 1 "a.c" 1
 # 1 "<built-in>" 1
diff --git a/test/CodeGen/2009-10-20-GlobalDebug.c b/test/CodeGen/2009-10-20-GlobalDebug.c
index 99be469..3c46bea 100644
--- a/test/CodeGen/2009-10-20-GlobalDebug.c
+++ b/test/CodeGen/2009-10-20-GlobalDebug.c
@@ -1,4 +1,8 @@
 // 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;}
+// CHECK: ascii   "localstatic"          ## DW_AT_name
+// CHECK: asciz   "global" ## External Name
+int main() { 
+  static int localstatic;
+  return 0;
+}
diff --git a/test/CodeGen/2010-08-10-DbgConstant.c b/test/CodeGen/2010-08-10-DbgConstant.c
new file mode 100644
index 0000000..5b8f064
--- /dev/null
+++ b/test/CodeGen/2010-08-10-DbgConstant.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -S -emit-llvm -g  %s -o - | grep DW_TAG_variable
+
+static const unsigned int ro = 201;
+void bar(int);
+void foo() { bar(ro); }
diff --git a/test/CodeGen/_Bool-conversion.c b/test/CodeGen/_Bool-conversion.c
new file mode 100644
index 0000000..fce7ada
--- /dev/null
+++ b/test/CodeGen/_Bool-conversion.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple i386 -emit-llvm -O2 -o - %s | FileCheck %s
+
+// CHECK: define i32 @f0()
+// CHECK:  ret i32 1
+// CHECK: }
+
+static _Bool f0_0(void *a0) { return (_Bool) a0; }
+int f0() { return f0_0((void*) 0x2); }
diff --git a/test/CodeGen/address-space-field1.c b/test/CodeGen/address-space-field1.c
index a81e08e..73c4da1 100644
--- a/test/CodeGen/address-space-field1.c
+++ b/test/CodeGen/address-space-field1.c
@@ -1,22 +1,22 @@
-// RUN: %clang_cc1 -emit-llvm < %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 < %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:  [[t0:%.*]] = load %struct.S addrspace(2)** [[p2addr]], align 8   ; <%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:  [[t2:%.*]] = load i32 addrspace(2)* [[t1]], align 4            ; <i32> [#uses=1]
+// CHECK:  [[t3:%.*]] = load %struct.S addrspace(1)** [[p1addr]], align 8  ; <%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:  store i32 [[t2]], i32 addrspace(1)* [[t4]], align 4
+// CHECK:  [[t5:%.*]] = load %struct.S addrspace(2)** [[p2addr]], align 8  ; <%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:  [[t7:%.*]] = load i32 addrspace(2)* [[t6]], align 4            ; <i32> [#uses=1]
+// CHECK:  [[t8:%.*]] = load %struct.S addrspace(1)** [[p1addr]], align 8  ; <%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:  store i32 [[t7]], i32 addrspace(1)* [[t9]], align 4
 // CHECK:  ret void
 // CHECK:}
 
diff --git a/test/CodeGen/address-space-field2.c b/test/CodeGen/address-space-field2.c
index 198fd22..9c21cab 100644
--- a/test/CodeGen/address-space-field2.c
+++ b/test/CodeGen/address-space-field2.c
@@ -16,10 +16,6 @@
 // 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)
diff --git a/test/CodeGen/address-space-field3.c b/test/CodeGen/address-space-field3.c
index 090f4a1..c17085c 100644
--- a/test/CodeGen/address-space-field3.c
+++ b/test/CodeGen/address-space-field3.c
@@ -16,10 +16,6 @@
 // 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)
diff --git a/test/CodeGen/address-space-field4.c b/test/CodeGen/address-space-field4.c
index a1906c0..a896ab6 100644
--- a/test/CodeGen/address-space-field4.c
+++ b/test/CodeGen/address-space-field4.c
@@ -23,8 +23,6 @@
 // CHECK: addrspace(3)
 // CHECK: addrspace(3)
 // CHECK: addrspace(1)
-// CHECK: addrspace(3)
-// CHECK: addrspace(3)
 // CHECK: addrspace(1)
 // CHECK: addrspace(1)
 // CHECK: addrspace(1)
@@ -33,10 +31,6 @@
 // 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)
 
diff --git a/test/CodeGen/address-space.c b/test/CodeGen/address-space.c
index 5b58919..04f88dc 100644
--- a/test/CodeGen/address-space.c
+++ b/test/CodeGen/address-space.c
@@ -1,20 +1,44 @@
-// 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 | FileCheck %s
 // RUN: %clang_cc1 -emit-llvm < %s | grep 'load.*addrspace(2).. @A'
 // RUN: %clang_cc1 -emit-llvm < %s | grep 'load.*addrspace(2).. @B'
 
+
+// CHECK: @foo = common addrspace(1) global
 int foo __attribute__((address_space(1)));
+
+// CHECK: @ban = common addrspace(1) global
 int ban[10] __attribute__((address_space(1)));
 
-int bar() { return foo; }
+// CHECK: define i32 @test1() 
+// CHECK: load i32 addrspace(1)* @foo
+int test1() { return foo; }
 
-int baz(int i) { return ban[i]; }
+// CHECK: define i32 @test2(i32 %i) 
+// CHECK: load i32 addrspace(1)*
+// CHECK-NEXT: ret i32
+int test2(int i) { return ban[i]; }
 
 // Both A and B point into addrspace(2).
 __attribute__((address_space(2))) int *A, *B;
 
+// CHECK: define void @test3()
+// CHECK: load i32 addrspace(2)** @B
+// CHECK: load i32 addrspace(2)* 
+// CHECK: load i32 addrspace(2)** @A
+// CHECK: store i32 {{.*}}, i32 addrspace(2)*
 void test3() {
   *A = *B;
 }
 
+// PR7437
+typedef struct {
+  float aData[1];
+} MyStruct;
+
+// CHECK: define void @test4(
+// CHECK: call void @llvm.memcpy.p0i8.p2i8
+// CHECK: call void @llvm.memcpy.p2i8.p0i8
+void test4(MyStruct __attribute__((address_space(2))) *pPtr) {
+  MyStruct s = pPtr[0];
+  pPtr[0] = s;
+}
diff --git a/test/CodeGen/altivec.c b/test/CodeGen/altivec.c
new file mode 100644
index 0000000..9e38df5
--- /dev/null
+++ b/test/CodeGen/altivec.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -faltivec -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: @test0 = global <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+vector int test0 = (vector int)(1);
diff --git a/test/CodeGen/arm-arguments.c b/test/CodeGen/arm-arguments.c
index 72fd7c3..73bc03d 100644
--- a/test/CodeGen/arm-arguments.c
+++ b/test/CodeGen/arm-arguments.c
@@ -1,131 +1,131 @@
 // 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()
+// APCS-GNU: define signext i8 @f0()
 // AAPCS: define arm_aapcscc signext i8 @f0()
 char f0(void) {
   return 0;
 }
 
-// APCS-GNU: define arm_apcscc i8 @f1()
+// APCS-GNU: define i8 @f1()
 // AAPCS: define arm_aapcscc i8 @f1()
 struct s1 { char f0; };
 struct s1 f1(void) {}
 
-// APCS-GNU: define arm_apcscc i16 @f2()
+// APCS-GNU: define i16 @f2()
 // AAPCS: define arm_aapcscc i16 @f2()
 struct s2 { short f0; };
 struct s2 f2(void) {}
 
-// APCS-GNU: define arm_apcscc i32 @f3()
+// APCS-GNU: define i32 @f3()
 // AAPCS: define arm_aapcscc i32 @f3()
 struct s3 { int f0; };
 struct s3 f3(void) {}
 
-// APCS-GNU: define arm_apcscc i32 @f4()
+// APCS-GNU: define 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: define 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: define 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()
+// APCS-GNU: define 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: define 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()
+// APCS-GNU: define 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()
+// APCS-GNU: define 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: define 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()
+// APCS-GNU: define 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: define void @f13(
 // APCS-GNU: struct.s13* sret
 
 // FIXME: This should return a float.
-// AAPCS-FIXME: define arm_aapcscc float @f13()
+// AAPCS-FIXME: darm_aapcscc efine float @f13()
 struct s13 { float f0; };
 struct s13 f13(void) {}
 
-// APCS-GNU: define arm_apcscc void @f14(
+// APCS-GNU: define 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()
+// APCS-GNU: define void @f15()
 // AAPCS: define arm_aapcscc void @f15()
 void f15(struct s7 a0) {}
 
-// APCS-GNU: define arm_apcscc void @f16()
+// APCS-GNU: define void @f16()
 // AAPCS: define arm_aapcscc void @f16()
 void f16(struct s8 a0) {}
 
-// APCS-GNU: define arm_apcscc i32 @f17()
+// APCS-GNU: define 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()
+// APCS-GNU: define 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: define 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: define 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()
+// APCS-GNU: define 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()
+// APCS-GNU: define i16 @f22()
+// APCS-GNU: define i32 @f23()
+// APCS-GNU: define i64 @f24()
+// APCS-GNU: define i128 @f25()
+// APCS-GNU: define i64 @f26()
+// APCS-GNU: define i128 @f27()
 // AAPCS: define arm_aapcscc i16 @f22()
 // AAPCS: define arm_aapcscc i32 @f23()
 // AAPCS: define arm_aapcscc void @f24({{.*}} sret
@@ -139,17 +139,17 @@
 _Complex float      f26(void) {}
 _Complex double     f27(void) {}
 
-// APCS-GNU: define arm_apcscc i16 @f28()
+// APCS-GNU: define i16 @f28()
 // AAPCS: define arm_aapcscc i16 @f28()
 struct s28 { _Complex char f0; };
 struct s28 f28() {}
 
-// APCS-GNU: define arm_apcscc i32 @f29()
+// APCS-GNU: define i32 @f29()
 // AAPCS: define arm_aapcscc i32 @f29()
 struct s29 { _Complex short f0; };
 struct s29 f29() {}
 
-// APCS-GNU: define arm_apcscc void @f30({{.*}} sret
+// APCS-GNU: define void @f30({{.*}} sret
 // AAPCS: define arm_aapcscc void @f30({{.*}} sret
 struct s30 { _Complex int f0; };
 struct s30 f30() {}
diff --git a/test/CodeGen/arm-cc.c b/test/CodeGen/arm-cc.c
new file mode 100644
index 0000000..74eecc7
--- /dev/null
+++ b/test/CodeGen/arm-cc.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -target-abi apcs-gnu -emit-llvm -w -o - %s | FileCheck -check-prefix=DARWIN-APCS %s
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -target-abi aapcs  -emit-llvm -w -o - %s | FileCheck -check-prefix=DARWIN-AAPCS %s
+// RUN: %clang_cc1 -triple arm-none-linux-gnueabi -target-abi apcs-gnu -emit-llvm -w -o - %s | FileCheck -check-prefix=LINUX-APCS %s
+// RUN: %clang_cc1 -triple arm-none-linux-gnueabi -target-abi aapcs  -emit-llvm -w -o - %s | FileCheck -check-prefix=LINUX-AAPCS %s
+
+
+// DARWIN-APCS: define void @f()
+// DARWIN-APCS: call void @g
+// DARWIN-AAPCS: define arm_aapcscc void @f()
+// DARWIN-AAPCS: call arm_aapcscc void @g
+// LINUX-APCS: define arm_apcscc void @f()
+// LINUX-APCS: call arm_apcscc void @g
+// LINUX-AAPCS: define void @f()
+// LINUX-AAPCS: call void @g
+void g(void);
+void f(void) {
+  g();
+}
diff --git a/test/CodeGen/asm-errors.c b/test/CodeGen/asm-errors.c
index 7323e61..aea5cb2 100644
--- a/test/CodeGen/asm-errors.c
+++ b/test/CodeGen/asm-errors.c
@@ -1,4 +1,4 @@
-// RUN: not %clang_cc1 -triple i386-apple-darwin10 -emit-obj %s  > %t 2>&1
+// RUN: not %clang_cc1 -triple i386-apple-darwin10 -emit-obj %s -o /dev/null > %t 2>&1
 // RUN: FileCheck %s < %t
 
 int test1(int X) {
diff --git a/test/CodeGen/asm-inout.c b/test/CodeGen/asm-inout.c
new file mode 100644
index 0000000..f042766
--- /dev/null
+++ b/test/CodeGen/asm-inout.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+// PR3800
+int *foo(void);
+
+// CHECK: @test1
+void test1() {
+  // CHECK: [[REGCALLRESULT:%[a-zA-Z0-9\.]+]] = call i32* @foo()
+  // CHECK: call void asm "foobar", "=*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* [[REGCALLRESULT]], i32* [[REGCALLRESULT]])
+  asm ("foobar" : "+m"(*foo()));
+}
+
+// CHECK: @test2
+void test2() {
+  // CHECK: [[REGCALLRESULT:%[a-zA-Z0-9\.]+]] = call i32* @foo()
+  // CHECK: load i32* [[REGCALLRESULT]]
+  // CHECK: call i32 asm
+  // CHECK: store i32 {{%[a-zA-Z0-9\.]+}}, i32* [[REGCALLRESULT]]
+  asm ("foobar" : "+r"(*foo()));
+}
diff --git a/test/CodeGen/asm.c b/test/CodeGen/asm.c
index 5077028..eb11285 100644
--- a/test/CodeGen/asm.c
+++ b/test/CodeGen/asm.c
@@ -168,3 +168,25 @@
   // CHECK: call x86_fp80 asm sideeffect "frndint"
   // CHECK-NEXT: fptrunc x86_fp80 {{.*}} to float
 }
+
+// <rdar://problem/8348447> - accept 'l' constraint
+unsigned char t22(unsigned char a, unsigned char b) {
+  unsigned int la = a;
+  unsigned int lb = b;
+  unsigned int bigres;
+  unsigned char res;
+  __asm__ ("0:\n1:\n" : [bigres] "=la"(bigres) : [la] "0"(la), [lb] "c"(lb) :
+                        "edx", "cc");
+  res = bigres;
+  return res;
+}
+
+// <rdar://problem/8348447> - accept 'l' constraint
+unsigned char t23(unsigned char a, unsigned char b) {
+  unsigned int la = a;
+  unsigned int lb = b;
+  unsigned char res;
+  __asm__ ("0:\n1:\n" : [res] "=la"(res) : [la] "0"(la), [lb] "c"(lb) :
+                        "edx", "cc");
+  return res;
+}
diff --git a/test/CodeGen/asm_arm.c b/test/CodeGen/asm_arm.c
index aac47d5..633bf55 100644
--- a/test/CodeGen/asm_arm.c
+++ b/test/CodeGen/asm_arm.c
@@ -30,3 +30,25 @@
                     "vst1.32 {q4},        [%0,:128] \n\t"
                     :: "r"(a), "r"(b));
 }
+
+// {sp, lr, pc} are the canonical names for {r13, r14, r15}.
+//
+// CHECK: @test5
+// CHECK: call void asm sideeffect "", "~{sp},~{lr},~{pc},~{sp},~{lr},~{pc}"()
+void test5() {
+  __asm__("" : : : "r13", "r14", "r15", "sp", "lr", "pc");
+}
+
+// CHECK: @test6
+// CHECK: call void asm sideeffect "", "
+// CHECK: ~{s0},~{s1},~{s2},~{s3},~{s4},~{s5},~{s6},~{s7},
+// CHECK: ~{s8},~{s9},~{s10},~{s11},~{s12},~{s13},~{s14},~{s15},
+// CHECK: ~{s16},~{s17},~{s18},~{s19},~{s20},~{s21},~{s22},~{s23},
+// CHECK: ~{s24},~{s25},~{s26},~{s27},~{s28},~{s29},~{s30},~{s31}"()
+void test6() {
+  __asm__("" : : :
+          "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+          "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
+          "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
+          "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31");
+}
diff --git a/test/CodeGen/assign.c b/test/CodeGen/assign.c
new file mode 100644
index 0000000..eab3d35
--- /dev/null
+++ b/test/CodeGen/assign.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple x86_64 -emit-llvm -o - %s | FileCheck %s
+
+// Check that we don't generate unnecessary reloads.
+//
+// CHECK: define void @f0()
+// CHECK:      [[x_0:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[y_0:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 1, i32* [[x_0]]
+// CHECK-NEXT: store i32 1, i32* [[x_0]]
+// CHECK-NEXT: store i32 1, i32* [[y_0]]
+// CHECK: }
+void f0() {
+  int x, y;
+  x = 1;
+  y = (x = 1);
+}
+
+// Check that we do generate reloads for volatile access.
+//
+// CHECK: define void @f1()
+// CHECK:      [[x_1:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[y_1:%.*]] = alloca i32, align 4
+// CHECK-NEXT: volatile store i32 1, i32* [[x_1]]
+// CHECK-NEXT: volatile store i32 1, i32* [[x_1]]
+// CHECK-NEXT: [[tmp_1:%.*]] = volatile load i32* [[x_1]]
+// CHECK-NEXT: volatile store i32 [[tmp_1]], i32* [[y_1]]
+// CHECK: }
+void f1() {
+  volatile int x, y;
+  x = 1;
+  y = (x = 1);
+}
diff --git a/test/CodeGen/atomic.c b/test/CodeGen/atomic.c
index aa5aa15..d0a7e04 100644
--- a/test/CodeGen/atomic.c
+++ b/test/CodeGen/atomic.c
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 > %t1
-// RUN: grep @llvm.memory.barrier %t1 | count 38
+// RUN: grep @llvm.memory.barrier %t1 | count 42
 // 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
@@ -7,7 +7,7 @@
 // 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.cmp.swap.i32 %t1 | count 5
 // RUN: grep @llvm.atomic.load.and.i32 %t1
 // RUN: grep @llvm.atomic.load.or.i8 %t1
 // RUN: grep @llvm.atomic.load.xor.i8 %t1
@@ -19,6 +19,7 @@
   int old;
   int val = 1;
   char valc = 1;
+  _Bool valb = 0;
   unsigned int uval = 1;
   int cmp = 0;
 
@@ -43,10 +44,18 @@
 
   
   __sync_val_compare_and_swap((void **)0, (void *)0, (void *)0);
-
+  if ( __sync_val_compare_and_swap(&valb, 0, 1)) {
+    old = 42;
+  }
+  __sync_bool_compare_and_swap((void **)0, (void *)0, (void *)0);
   
   __sync_lock_release(&val);
   __sync_synchronize ();
 
   return old;
 }
+
+void release_return(int *lock) {
+  // Ensure this is actually returning void all the way through.
+  return __sync_lock_release(lock);
+}
diff --git a/test/CodeGen/available-externally-suppress.c b/test/CodeGen/available-externally-suppress.c
new file mode 100644
index 0000000..747d3cd
--- /dev/null
+++ b/test/CodeGen/available-externally-suppress.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -emit-llvm -o - -O0 -triple x86_64-apple-darwin10 %s | FileCheck %s
+
+// Ensure that we don't emit available_externally functions at -O0.
+int x;
+
+inline void f0(int y) { x = y; }
+
+// CHECK: define void @test()
+// CHECK: declare void @f0(i32)
+void test() {
+  f0(17);
+}
+
+inline int __attribute__((always_inline)) f1(int x) { 
+  int blarg = 0;
+  for (int i = 0; i < x; ++i)
+    blarg = blarg + x * i;
+  return blarg; 
+}
+
+// CHECK: @test1
+int test1(int x) { 
+  // CHECK: br i1
+  // CHECK-NOT: call
+  // CHECK: ret i32
+  return f1(x); 
+}
diff --git a/test/CodeGen/bitfield-2.c b/test/CodeGen/bitfield-2.c
index e91859f..8de432f 100644
--- a/test/CodeGen/bitfield-2.c
+++ b/test/CodeGen/bitfield-2.c
@@ -12,7 +12,7 @@
 // CHECK-RECORD: Record: struct s0
 // CHECK-RECORD: Layout: <CGRecordLayout
 // CHECK-RECORD:   LLVMType:<{ [3 x i8] }>
-// CHECK-RECORD:   ContainsPointerToDataMember:0
+// CHECK-RECORD:   IsZeroInitializable:1
 // CHECK-RECORD:   BitFields:[
 // CHECK-RECORD:     <CGBitFieldInfo Size:24 IsSigned:1
 // CHECK-RECORD:                     NumComponents:2 Components: [
@@ -57,7 +57,7 @@
 // CHECK-RECORD: Record: struct s1
 // CHECK-RECORD: Layout: <CGRecordLayout
 // CHECK-RECORD:   LLVMType:<{ [2 x i8], i8 }>
-// CHECK-RECORD:   ContainsPointerToDataMember:0
+// CHECK-RECORD:   IsZeroInitializable:1
 // CHECK-RECORD:   BitFields:[
 // CHECK-RECORD:     <CGBitFieldInfo Size:10 IsSigned:1
 // CHECK-RECORD:                     NumComponents:1 Components: [
@@ -114,7 +114,7 @@
 // CHECK-RECORD: Record: union u2
 // CHECK-RECORD: Layout: <CGRecordLayout
 // CHECK-RECORD:   LLVMType:<{ i8 }>
-// CHECK-RECORD:   ContainsPointerToDataMember:0
+// CHECK-RECORD:   IsZeroInitializable:1
 // CHECK-RECORD:   BitFields:[
 // CHECK-RECORD:     <CGBitFieldInfo Size:3 IsSigned:0
 // CHECK-RECORD:                     NumComponents:1 Components: [
@@ -289,7 +289,7 @@
 // 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:   IsZeroInitializable:1
 // CHECK-RECORD:   BitFields:[
 // CHECK-RECORD:     <CGBitFieldInfo Size:5 IsSigned:1
 // CHECK-RECORD:                     NumComponents:1 Components: [
diff --git a/test/CodeGen/block-decl-merging.c b/test/CodeGen/block-decl-merging.c
new file mode 100644
index 0000000..1e7a9f4
--- /dev/null
+++ b/test/CodeGen/block-decl-merging.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -emit-llvm -o - %s | \
+// RUN:   FileCheck %s
+
+// CHECK: @_NSConcreteGlobalBlock = extern_weak global
+extern void * _NSConcreteStackBlock[32] __attribute__((weak_import));
+// CHECK: @_NSConcreteStackBlock = extern_weak global
+extern void * _NSConcreteGlobalBlock[32] __attribute__((weak_import));
+extern void _Block_object_dispose(const void *, const int) __attribute__((weak_import));
+// CHECK: declare extern_weak void @_Block_object_assign
+extern void _Block_object_assign(void *, const void *, const int) __attribute__((weak_import));
+// CHECK: declare extern_weak void @_Block_object_dispose
+
+void *x = ^(){};
+
+void f1(void (^a0)(void));
+
+void f0() {
+  __block int x;
+  f1(^(void){ x = 1; });
+}
diff --git a/test/CodeGen/blocks-aligned-byref-variable.c b/test/CodeGen/blocks-aligned-byref-variable.c
index 79ac41d..07d683c 100644
--- a/test/CodeGen/blocks-aligned-byref-variable.c
+++ b/test/CodeGen/blocks-aligned-byref-variable.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-apple-darwin10
-// RUN: %clang_cc1 -emit-llvm -o - -triple i386-apple-darwin10 
+// RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-apple-darwin10 -fblocks %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple i386-apple-darwin10 -fblocks %s
 typedef int __attribute__((aligned(32)))  ai;
 
 void f() {
diff --git a/test/CodeGen/blocks.c b/test/CodeGen/blocks.c
index e7625b1..6888356 100644
--- a/test/CodeGen/blocks.c
+++ b/test/CodeGen/blocks.c
@@ -12,7 +12,7 @@
   int a[64];
 };
 
-// RUN: grep 'internal void @__f2_block_invoke_(.struct.s0\* sret .*, .*, .* byval .*)' %t
+// RUN: grep 'internal void @__f2_block_invoke_0(.struct.s0\* sret .*, .*, .* byval .*)' %t
 struct s0 f2(struct s0 a0) {
   return ^(struct s0 a1){ return a1; }(a0);
 }
@@ -27,3 +27,9 @@
   ^ { i = 1; }();
 };
 
+typedef double ftype(double);
+// It's not clear that we *should* support this syntax, but until that decision
+// is made, we should support it properly and not crash.
+ftype ^test2 = ^ftype {
+  return 0;
+};
diff --git a/test/CodeGen/blockstret.c b/test/CodeGen/blockstret.c
index 09292b8..f630f22 100644
--- a/test/CodeGen/blockstret.c
+++ b/test/CodeGen/blockstret.c
@@ -98,8 +98,8 @@
 /*
 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 non-zero: 1
 should be non-zero: 1
 should be zero: 0
 
diff --git a/test/CodeGen/builtin-attributes.c b/test/CodeGen/builtin-attributes.c
index 944aac3..afde3fa 100644
--- a/test/CodeGen/builtin-attributes.c
+++ b/test/CodeGen/builtin-attributes.c
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -triple arm-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm-unknown-linux-gnueabi -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: declare arm_aapcscc i32 @printf(i8*, ...)
+// CHECK: declare i32 @printf(i8*, ...)
 void f0() {
   printf("a\n");
 }
 
-// CHECK: call arm_aapcscc void @exit
+// CHECK: call void @exit
 // CHECK: unreachable
 void f1() {
   exit(1);
diff --git a/test/CodeGen/builtin-expect.c b/test/CodeGen/builtin-expect.c
new file mode 100644
index 0000000..8f02c4d
--- /dev/null
+++ b/test/CodeGen/builtin-expect.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+int x;
+int y(void);
+void foo();
+void FUNC() {
+// CHECK: [[call:%.*]] = call i32 @y
+  if (__builtin_expect (x, y()))
+    foo ();
+}
+
diff --git a/test/CodeGen/builtins-arm.c b/test/CodeGen/builtins-arm.c
index 5553757..09df1ef 100644
--- a/test/CodeGen/builtins-arm.c
+++ b/test/CodeGen/builtins-arm.c
@@ -1,6 +1,12 @@
-// RUN: %clang_cc1 -triple thumbv7-eabi -target-cpu cortex-a8 -O3 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -Wall -Werror -triple thumbv7-eabi -target-cpu cortex-a8 -O3 -emit-llvm -o - %s | FileCheck %s
 
 void *f0()
 {
   return __builtin_thread_pointer();
 }
+
+void f1(char *a, char *b) {
+	__clear_cache(a,b);
+}
+
+// CHECK: call {{.*}} @__clear_cache
diff --git a/test/CodeGen/builtins-ppc-altivec.c b/test/CodeGen/builtins-ppc-altivec.c
index 04249cc..8627499 100644
--- a/test/CodeGen/builtins-ppc-altivec.c
+++ b/test/CodeGen/builtins-ppc-altivec.c
@@ -1,217 +1,1839 @@
 // RUN: %clang_cc1 -faltivec -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
 
-#include "altivec.h"
+vector bool char vbc = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 };
+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 bool short vbs = { 1, 0, 1, 0, 1, 0, 1, 0 };
+vector short vs = { -1, 2, -3, 4, -5, 6, -7, 8 };
+vector unsigned short vus = { 1, 2, 3, 4, 5, 6, 7, 8 };
+vector pixel vp = { 1, 2, 3, 4, 5, 6, 7, 8 };
+vector bool int vbi = { 1, 0, 1, 0 };
+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 };
 
-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 bool char res_vbc;
+vector signed char res_vsc;
+vector unsigned char res_vuc;
+vector bool short res_vbs;
+vector short res_vs;
+vector unsigned short res_vus;
+vector pixel res_vp;
+vector bool int res_vbi;
+vector int res_vi;
+vector unsigned int res_vui;
+vector float res_vf;
 
-  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;
+signed char param_sc;
+unsigned char param_uc;
+short param_s;
+unsigned short param_us;
+int param_i;
+unsigned int param_ui;
+float param_f;
 
-  int param_i;
-  int res_i;
+int res_i;
+
+// CHECK: define void @test1
+void test1() {
 
   /* vec_abs */
-  vsc = vec_abs(vsc);              // CHECK: sub <16 x i8> zeroinitializer
-                                   // CHECK: @llvm.ppc.altivec.vmaxsb
+  vsc = vec_abs(vsc);                           // CHECK: sub nsw <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
+  vs = vec_abs(vs);                             // CHECK: sub nsw <8 x i16> zeroinitializer
+                                                // CHECK: @llvm.ppc.altivec.vmaxsh
 
-  vi = vec_abs(vi);                // CHECK: sub <4 x i32> zeroinitializer
-                                   // CHECK: @llvm.ppc.altivec.vmaxsw
+  vi = vec_abs(vi);                             // CHECK: sub nsw <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>
+  vf = vec_abs(vf);                             // CHECK: and <4 x i32>
 
   /* vec_abs */
-  vsc = vec_abss(vsc);             // CHECK: @llvm.ppc.altivec.vsubsbs
-                                   // CHECK: @llvm.ppc.altivec.vmaxsb
+  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
+  vs = 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
+  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_vsc = vec_add(vsc, vsc);                  // CHECK: add nsw <16 x i8>
+  res_vsc = vec_add(vbc, vsc);                  // CHECK: add nsw <16 x i8>
+  res_vsc = vec_add(vsc, vbc);                  // CHECK: add nsw <16 x i8>
+  res_vuc = vec_add(vuc, vuc);                  // CHECK: add <16 x i8>
+  res_vuc = vec_add(vbc, vuc);                  // CHECK: add <16 x i8>
+  res_vuc = vec_add(vuc, vbc);                  // CHECK: add <16 x i8>
+  res_vs  = vec_add(vs, vs);                    // CHECK: add nsw <8 x i16>
+  res_vs  = vec_add(vbs, vs);                   // CHECK: add nsw <8 x i16>
+  res_vs  = vec_add(vs, vbs);                   // CHECK: add nsw <8 x i16>
+  res_vus = vec_add(vus, vus);                  // CHECK: add <8 x i16>
+  res_vus = vec_add(vbs, vus);                  // CHECK: add <8 x i16>
+  res_vus = vec_add(vus, vbs);                  // CHECK: add <8 x i16>
+  res_vi  = vec_add(vi, vi);                    // CHECK: add nsw <4 x i32>
+  res_vi  = vec_add(vbi, vi);                   // CHECK: add nsw <4 x i32>
+  res_vi  = vec_add(vi, vbi);                   // CHECK: add nsw <4 x i32>
+  res_vui = vec_add(vui, vui);                  // CHECK: add <4 x i32>
+  res_vui = vec_add(vbi, vui);                  // CHECK: add <4 x i32>
+  res_vui = vec_add(vui, vbi);                  // CHECK: add <4 x i32>
+  res_vf  = vec_add(vf, vf);                    // CHECK: fadd <4 x float>
+  res_vsc = vec_vaddubm(vsc, vsc);              // CHECK: add nsw <16 x i8>
+  res_vsc = vec_vaddubm(vbc, vsc);              // CHECK: add nsw <16 x i8>
+  res_vsc = vec_vaddubm(vsc, vbc);              // 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_vuc = vec_vaddubm(vbc, vuc);              // CHECK: add <16 x i8>
+  res_vuc = vec_vaddubm(vuc, vbc);              // CHECK: add <16 x i8>
+  res_vs  = vec_vadduhm(vs, vs);                // CHECK: add nsw <8 x i16>
+  res_vs  = vec_vadduhm(vbs, vs);               // CHECK: add nsw <8 x i16>
+  res_vs  = vec_vadduhm(vs, vbs);               // 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_vus = vec_vadduhm(vbs, vus);              // CHECK: add <8 x i16>
+  res_vus = vec_vadduhm(vus, vbs);              // CHECK: add <8 x i16>
+  res_vi  = vec_vadduwm(vi, vi);                // CHECK: add nsw <4 x i32>
+  res_vi  = vec_vadduwm(vbi, vi);               // CHECK: add nsw <4 x i32>
+  res_vi  = vec_vadduwm(vi, vbi);               // 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>
+  res_vui = vec_vadduwm(vbi, vui);              // CHECK: add <4 x i32>
+  res_vui = vec_vadduwm(vui, vbi);              // CHECK: add <4 x i32>
+  res_vf  = vec_vaddfp(vf, vf);                 // CHECK: fadd <4 x float>
 
   /* vec_addc */
+  res_vui = vec_addc(vui, vui);                 // HECK: @llvm.ppc.altivec.vaddcuw
   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_vsc = vec_adds(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vaddsbs
+  res_vsc = vec_adds(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vaddsbs
+  res_vsc = vec_adds(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vaddsbs
+  res_vuc = vec_adds(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vaddubs
+  res_vuc = vec_adds(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vaddubs
+  res_vuc = vec_adds(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vaddubs
+  res_vs  = vec_adds(vs, vs);                   // CHECK: @llvm.ppc.altivec.vaddshs
+  res_vs  = vec_adds(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vaddshs
+  res_vs  = vec_adds(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vaddshs
+  res_vus = vec_adds(vus, vus);                 // CHECK: @llvm.ppc.altivec.vadduhs
+  res_vus = vec_adds(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vadduhs
+  res_vus = vec_adds(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vadduhs
+  res_vi  = vec_adds(vi, vi);                   // CHECK: @llvm.ppc.altivec.vaddsws
+  res_vi  = vec_adds(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vaddsws
+  res_vi  = vec_adds(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vaddsws
+  res_vui = vec_adds(vui, vui);                 // CHECK: @llvm.ppc.altivec.vadduws
+  res_vui = vec_adds(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vadduws
+  res_vui = vec_adds(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vadduws
+  res_vsc = vec_vaddsbs(vsc, vsc);              // CHECK: @llvm.ppc.altivec.vaddsbs
+  res_vsc = vec_vaddsbs(vbc, vsc);              // CHECK: @llvm.ppc.altivec.vaddsbs
+  res_vsc = vec_vaddsbs(vsc, vbc);              // 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_vuc = vec_vaddubs(vbc, vuc);              // CHECK: @llvm.ppc.altivec.vaddubs
+  res_vuc = vec_vaddubs(vuc, vbc);              // CHECK: @llvm.ppc.altivec.vaddubs
+  res_vs  = vec_vaddshs(vs, vs);                // CHECK: @llvm.ppc.altivec.vaddshs
+  res_vs  = vec_vaddshs(vbs, vs);               // CHECK: @llvm.ppc.altivec.vaddshs
+  res_vs  = vec_vaddshs(vs, vbs);               // 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_vus = vec_vadduhs(vbs, vus);              // CHECK: @llvm.ppc.altivec.vadduhs
+  res_vus = vec_vadduhs(vus, vbs);              // CHECK: @llvm.ppc.altivec.vadduhs
+  res_vi  = vec_vaddsws(vi, vi);                // CHECK: @llvm.ppc.altivec.vaddsws
+  res_vi  = vec_vaddsws(vbi, vi);               // CHECK: @llvm.ppc.altivec.vaddsws
+  res_vi  = vec_vaddsws(vi, vbi);               // CHECK: @llvm.ppc.altivec.vaddsws
   res_vui = vec_vadduws(vui, vui);              // CHECK: @llvm.ppc.altivec.vadduws
+  res_vui = vec_vadduws(vbi, vui);              // CHECK: @llvm.ppc.altivec.vadduws
+  res_vui = vec_vadduws(vui, vbi);              // 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_and */
+  res_vsc = vec_and(vsc, vsc);                  // CHECK: and <16 x i8>
+  res_vsc = vec_and(vbc, vsc);                  // CHECK: and <16 x i8>
+  res_vsc = vec_and(vsc, vbc);                  // CHECK: and <16 x i8>
+  res_vuc = vec_and(vuc, vuc);                  // CHECK: and <16 x i8>
+  res_vuc = vec_and(vbc, vuc);                  // CHECK: and <16 x i8>
+  res_vuc = vec_and(vuc, vbc);                  // CHECK: and <16 x i8>
+  res_vbc = vec_and(vbc, vbc);                  // CHECK: and <16 x i8>
+  res_vs  = vec_and(vs, vs);                    // CHECK: and <8 x i16>
+  res_vs  = vec_and(vbs, vs);                   // CHECK: and <8 x i16>
+  res_vs  = vec_and(vs, vbs);                   // CHECK: and <8 x i16>
+  res_vus = vec_and(vus, vus);                  // CHECK: and <8 x i16>
+  res_vus = vec_and(vbs, vus);                  // CHECK: and <8 x i16>
+  res_vus = vec_and(vus, vbs);                  // CHECK: and <8 x i16>
+  res_vbs = vec_and(vbs, vbs);                  // CHECK: and <8 x i16>
+  res_vi  = vec_and(vi, vi);                    // CHECK: and <4 x i32>
+  res_vi  = vec_and(vbi, vi);                   // CHECK: and <4 x i32>
+  res_vi  = vec_and(vi, vbi);                   // CHECK: and <4 x i32>
+  res_vui = vec_and(vui, vui);                  // CHECK: and <4 x i32>
+  res_vui = vec_and(vbi, vui);                  // CHECK: and <4 x i32>
+  res_vui = vec_and(vui, vbi);                  // CHECK: and <4 x i32>
+  res_vbi = vec_and(vbi, vbi);                  // CHECK: and <4 x i32>
+  res_vsc = vec_vand(vsc, vsc);                 // CHECK: and <16 x i8>
+  res_vsc = vec_vand(vbc, vsc);                 // CHECK: and <16 x i8>
+  res_vsc = vec_vand(vsc, vbc);                 // CHECK: and <16 x i8>
+  res_vuc = vec_vand(vuc, vuc);                 // CHECK: and <16 x i8>
+  res_vuc = vec_vand(vbc, vuc);                 // CHECK: and <16 x i8>
+  res_vuc = vec_vand(vuc, vbc);                 // CHECK: and <16 x i8>
+  res_vbc = vec_vand(vbc, vbc);                 // CHECK: and <16 x i8>
+  res_vs  = vec_vand(vs, vs);                   // CHECK: and <8 x i16>
+  res_vs  = vec_vand(vbs, vs);                  // CHECK: and <8 x i16>
+  res_vs  = vec_vand(vs, vbs);                  // CHECK: and <8 x i16>
+  res_vus = vec_vand(vus, vus);                 // CHECK: and <8 x i16>
+  res_vus = vec_vand(vbs, vus);                 // CHECK: and <8 x i16>
+  res_vus = vec_vand(vus, vbs);                 // CHECK: and <8 x i16>
+  res_vbs = vec_vand(vbs, vbs);                 // CHECK: and <8 x i16>
+  res_vi  = vec_vand(vi, vi);                   // CHECK: and <4 x i32>
+  res_vi  = vec_vand(vbi, vi);                  // CHECK: and <4 x i32>
+  res_vi  = vec_vand(vi, vbi);                  // CHECK: and <4 x i32>
+  res_vui = vec_vand(vui, vui);                 // CHECK: and <4 x i32>
+  res_vui = vec_vand(vbi, vui);                 // CHECK: and <4 x i32>
+  res_vui = vec_vand(vui, vbi);                 // CHECK: and <4 x i32>
+  res_vbi = vec_vand(vbi, vbi);                 // CHECK: and <4 x i32>
 
-  /* 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_andc */
+  res_vsc = vec_andc(vsc, vsc);                 // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
 
+  res_vsc = vec_andc(vbc, vsc);                 // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+
+  res_vsc = vec_andc(vsc, vbc);                 // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+
+  res_vuc = vec_andc(vuc, vuc);                 // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+
+  res_vuc = vec_andc(vbc, vuc);                 // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+
+  res_vuc = vec_andc(vuc, vbc);                 // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+
+  res_vbc = vec_andc(vbc, vbc);                 // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+
+  res_vs  = vec_andc(vs, vs);                   // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+
+  res_vs  = vec_andc(vbs, vs);                  // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+
+  res_vs  = vec_andc(vs, vbs);                  // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+
+  res_vus = vec_andc(vus, vus);                 // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+
+  res_vus = vec_andc(vbs, vus);                 // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+
+  res_vus = vec_andc(vus, vbs);                 // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+
+  res_vbs = vec_andc(vbs, vbs);                 // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+
+  res_vi  = vec_andc(vi, vi);                   // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vi  = vec_andc(vbi, vi);                  // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vi  = vec_andc(vi, vbi);                  // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vui = vec_andc(vui, vui);                 // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vui = vec_andc(vbi, vui);                 // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vui = vec_andc(vui, vbi);                 // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vf = vec_andc(vf, vf);                    // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vf = vec_andc(vbi, vf);                   // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vf = vec_andc(vf, vbi);                   // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vsc = vec_vandc(vsc, vsc);                // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+
+  res_vsc = vec_vandc(vbc, vsc);                // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+
+  res_vsc = vec_vandc(vsc, vbc);                // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+
+  res_vuc = vec_vandc(vuc, vuc);                // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+
+  res_vuc = vec_vandc(vbc, vuc);                // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+
+  res_vuc = vec_vandc(vuc, vbc);                // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+
+  res_vbc = vec_vandc(vbc, vbc);                // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+
+  res_vs  = vec_vandc(vs, vs);                  // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+
+  res_vs  = vec_vandc(vbs, vs);                 // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+
+  res_vs  = vec_vandc(vs, vbs);                 // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+
+  res_vus = vec_vandc(vus, vus);                // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+
+  res_vus = vec_vandc(vbs, vus);                // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+
+  res_vus = vec_vandc(vus, vbs);                // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+
+  res_vbs = vec_vandc(vbs, vbs);                // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+
+  res_vi  = vec_vandc(vi, vi);                  // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vi  = vec_vandc(vbi, vi);                 // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vi  = vec_vandc(vi, vbi);                 // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vui = vec_vandc(vui, vui);                // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vui = vec_vandc(vbi, vui);                // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vui = vec_vandc(vui, vbi);                // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vf = vec_vandc(vf, vf);                   // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vf = vec_vandc(vbi, vf);                  // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+  res_vf = vec_vandc(vf, vbi);                  // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+
+}
+
+// CHECK: define void @test2
+void test2() {
   /* 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_vsc = vec_avg(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vavgsb
+  res_vuc = vec_avg(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vavgub
+  res_vs  = vec_avg(vs, vs);                    // CHECK: @llvm.ppc.altivec.vavgsh
+  res_vus = vec_avg(vus, vus);                  // CHECK: @llvm.ppc.altivec.vavguh
+  res_vi  = vec_avg(vi, vi);                    // CHECK: @llvm.ppc.altivec.vavgsw
+  res_vui = vec_avg(vui, vui);                  // CHECK: @llvm.ppc.altivec.vavguw
+  res_vsc = vec_vavgsb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vavgsb
+  res_vuc = 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_vus = 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
+  res_vui = 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_ceil */
+  res_vf = vec_ceil(vf);                        // CHECK: @llvm.ppc.altivec.vrfip
+  res_vf = vec_vrfip(vf);                       // CHECK: @llvm.ppc.altivec.vrfip
 
   /* vec_cmpb */
+  res_vi = vec_cmpb(vf, vf);                    // CHECK: @llvm.ppc.altivec.vcmpbfp
   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
+  res_vbc = vec_cmpeq(vsc, vsc);                // CHECK: @llvm.ppc.altivec.vcmpequb
+  res_vbc = vec_cmpeq(vuc, vuc);                // CHECK: @llvm.ppc.altivec.vcmpequb
+  res_vbs = vec_cmpeq(vs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh
+  res_vbs = vec_cmpeq(vus, vus);                // CHECK: @llvm.ppc.altivec.vcmpequh
+  res_vbi = vec_cmpeq(vi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw
+  res_vbi = vec_cmpeq(vui, vui);                // CHECK: @llvm.ppc.altivec.vcmpequw
+  res_vbi = vec_cmpeq(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpeqfp
 
   /* vec_cmpge */
-  res_vi = __builtin_vec_cmpge(vf, vf);         // CHECK: @llvm.ppc.altivec.vcmpgefp
+  res_vbi = vec_cmpge(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp
+  res_vbi = vec_vcmpgefp(vf, vf);               // CHECK: @llvm.ppc.altivec.vcmpgefp
+}
 
+// CHECK: define void @test5
+void test5() {
+  
   /* 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
+  res_vbc = vec_cmpgt(vsc, vsc);                // CHECK: @llvm.ppc.altivec.vcmpgtsb
+  res_vbc = vec_cmpgt(vuc, vuc);                // CHECK: @llvm.ppc.altivec.vcmpgtub
+  res_vbs = vec_cmpgt(vs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh
+  res_vbs = vec_cmpgt(vus, vus);                // CHECK: @llvm.ppc.altivec.vcmpgtuh
+  res_vbi = vec_cmpgt(vi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw
+  res_vbi = vec_cmpgt(vui, vui);                // CHECK: @llvm.ppc.altivec.vcmpgtuw
+  res_vbi = vec_cmpgt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp
+  res_vbc = vec_vcmpgtsb(vsc, vsc);             // CHECK: @llvm.ppc.altivec.vcmpgtsb
+  res_vbc = vec_vcmpgtub(vuc, vuc);             // CHECK: @llvm.ppc.altivec.vcmpgtub
+  res_vbs = vec_vcmpgtsh(vs, vs);               // CHECK: @llvm.ppc.altivec.vcmpgtsh
+  res_vbs = vec_vcmpgtuh(vus, vus);             // CHECK: @llvm.ppc.altivec.vcmpgtuh
+  res_vbi = vec_vcmpgtsw(vi, vi);               // CHECK: @llvm.ppc.altivec.vcmpgtsw
+  res_vbi = vec_vcmpgtuw(vui, vui);             // CHECK: @llvm.ppc.altivec.vcmpgtuw
+  res_vbi = vec_vcmpgtfp(vf, vf);               // CHECK: @llvm.ppc.altivec.vcmpgtfp
 
   /* vec_cmple */
-  res_vi = __builtin_vec_cmple(vf, vf);         // CHECK: @llvm.ppc.altivec.vcmpgefp
+  res_vbi = vec_cmple(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp
+}
 
+// CHECK: define void @test6
+void test6() {
   /* 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
+  res_vbc = vec_cmplt(vsc, vsc);                // CHECK: @llvm.ppc.altivec.vcmpgtsb
+  res_vbc = vec_cmplt(vuc, vuc);                // CHECK: @llvm.ppc.altivec.vcmpgtub
+  res_vbs = vec_cmplt(vs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh
+  res_vbs = vec_cmplt(vus, vus);                // CHECK: @llvm.ppc.altivec.vcmpgtuh
+  res_vbi = vec_cmplt(vi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw
+  res_vbi = vec_cmplt(vui, vui);                // CHECK: @llvm.ppc.altivec.vcmpgtuw
+  res_vbi = vec_cmplt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp
+
+  /* vec_ctf */
+  res_vf  = vec_ctf(vi, param_i);               // CHECK: @llvm.ppc.altivec.vcfsx
+  res_vf  = vec_ctf(vui, 0);                    // CHECK: @llvm.ppc.altivec.vcfux
+  res_vf  = vec_vcfsx(vi, 0);                   // CHECK: @llvm.ppc.altivec.vcfsx
+  res_vf  = vec_vcfux(vui, 0);                  // CHECK: @llvm.ppc.altivec.vcfux
+
+  /* vec_cts */
+  res_vi = vec_cts(vf, 0);                      // CHECK: @llvm.ppc.altivec.vctsxs
+  res_vi = vec_vctsxs(vf, 0);                   // CHECK: @llvm.ppc.altivec.vctsxs
+
+  /* vec_ctu */
+  res_vui = vec_ctu(vf, 0);                     // CHECK: @llvm.ppc.altivec.vctuxs
+  res_vui = vec_vctuxs(vf, 0);                  // CHECK: @llvm.ppc.altivec.vctuxs
+
+  /* vec_dss */
+  vec_dss(param_i);                             // CHECK: @llvm.ppc.altivec.dss
+
+  /* vec_dssall */
+  vec_dssall();                                 // CHECK: @llvm.ppc.altivec.dssall
+
+  /* vec_dst */
+  vec_dst(&vsc, 0, 0);                          // CHECK: @llvm.ppc.altivec.dst
+
+  /* vec_dstst */
+  vec_dstst(&vs, 0, 0);                         // CHECK: @llvm.ppc.altivec.dstst
+
+  /* vec_dststt */
+  vec_dststt(&param_i, 0, 0);                   // CHECK: @llvm.ppc.altivec.dststt
+
+  /* vec_dstt */
+  vec_dstt(&vf, 0, 0);                          // CHECK: @llvm.ppc.altivec.dstt
+
+  /* vec_expte */
+  res_vf = vec_expte(vf);                       // CHECK: @llvm.ppc.altivec.vexptefp
+  res_vf = vec_vexptefp(vf);                    // CHECK: @llvm.ppc.altivec.vexptefp
+
+  /* vec_floor */
+  res_vf = vec_floor(vf);                       // CHECK: @llvm.ppc.altivec.vrfim
+  res_vf = vec_vrfim(vf);                       // CHECK: @llvm.ppc.altivec.vrfim
+
+  /* vec_ld */
+  res_vsc = vec_ld(0, &vsc);                    // CHECK: @llvm.ppc.altivec.lvx
+  res_vsc = vec_ld(0, &param_sc);               // CHECK: @llvm.ppc.altivec.lvx
+  res_vuc = vec_ld(0, &vuc);                    // CHECK: @llvm.ppc.altivec.lvx
+  res_vuc = vec_ld(0, &param_uc);               // CHECK: @llvm.ppc.altivec.lvx
+  res_vbc = vec_ld(0, &vbc);                    // CHECK: @llvm.ppc.altivec.lvx
+  res_vs  = vec_ld(0, &vs);                     // CHECK: @llvm.ppc.altivec.lvx
+  res_vs  = vec_ld(0, &param_s);                // CHECK: @llvm.ppc.altivec.lvx
+  res_vus = vec_ld(0, &vus);                    // CHECK: @llvm.ppc.altivec.lvx
+  res_vus = vec_ld(0, &param_us);               // CHECK: @llvm.ppc.altivec.lvx
+  res_vbs = vec_ld(0, &vbs);                    // CHECK: @llvm.ppc.altivec.lvx
+  res_vp  = vec_ld(0, &vp);                     // CHECK: @llvm.ppc.altivec.lvx
+  res_vi  = vec_ld(0, &vi);                     // CHECK: @llvm.ppc.altivec.lvx
+  res_vi  = vec_ld(0, &param_i);                // CHECK: @llvm.ppc.altivec.lvx
+  res_vui = vec_ld(0, &vui);                    // CHECK: @llvm.ppc.altivec.lvx
+  res_vui = vec_ld(0, &param_ui);               // CHECK: @llvm.ppc.altivec.lvx
+  res_vbi = vec_ld(0, &vbi);                    // CHECK: @llvm.ppc.altivec.lvx
+  res_vf  = vec_ld(0, &vf);                     // CHECK: @llvm.ppc.altivec.lvx
+  res_vf  = vec_ld(0, &param_f);                // CHECK: @llvm.ppc.altivec.lvx
+  res_vsc = vec_lvx(0, &vsc);                   // CHECK: @llvm.ppc.altivec.lvx
+  res_vsc = vec_lvx(0, &param_sc);              // CHECK: @llvm.ppc.altivec.lvx
+  res_vuc = vec_lvx(0, &vuc);                   // CHECK: @llvm.ppc.altivec.lvx
+  res_vuc = vec_lvx(0, &param_uc);              // CHECK: @llvm.ppc.altivec.lvx
+  res_vbc = vec_lvx(0, &vbc);                   // CHECK: @llvm.ppc.altivec.lvx
+  res_vs  = vec_lvx(0, &vs);                    // CHECK: @llvm.ppc.altivec.lvx
+  res_vs  = vec_lvx(0, &param_s);               // CHECK: @llvm.ppc.altivec.lvx
+  res_vus = vec_lvx(0, &vus);                   // CHECK: @llvm.ppc.altivec.lvx
+  res_vus = vec_lvx(0, &param_us);              // CHECK: @llvm.ppc.altivec.lvx
+  res_vbs = vec_lvx(0, &vbs);                   // CHECK: @llvm.ppc.altivec.lvx
+  res_vp  = vec_lvx(0, &vp);                    // CHECK: @llvm.ppc.altivec.lvx
+  res_vi  = vec_lvx(0, &vi);                    // CHECK: @llvm.ppc.altivec.lvx
+  res_vi  = vec_lvx(0, &param_i);               // CHECK: @llvm.ppc.altivec.lvx
+  res_vui = vec_lvx(0, &vui);                   // CHECK: @llvm.ppc.altivec.lvx
+  res_vui = vec_lvx(0, &param_ui);              // CHECK: @llvm.ppc.altivec.lvx
+  res_vbi = vec_lvx(0, &vbi);                   // CHECK: @llvm.ppc.altivec.lvx
+  res_vf  = vec_lvx(0, &vf);                    // CHECK: @llvm.ppc.altivec.lvx
+  res_vf  = vec_lvx(0, &param_f);               // CHECK: @llvm.ppc.altivec.lvx
+
+  /* vec_lde */
+  res_vsc = vec_lde(0, &vsc);                   // CHECK: @llvm.ppc.altivec.lvebx
+  res_vuc = vec_lde(0, &vuc);                   // CHECK: @llvm.ppc.altivec.lvebx
+  res_vs  = vec_lde(0, &vs);                    // CHECK: @llvm.ppc.altivec.lvehx
+  res_vus = vec_lde(0, &vus);                   // CHECK: @llvm.ppc.altivec.lvehx
+  res_vi  = vec_lde(0, &vi);                    // CHECK: @llvm.ppc.altivec.lvewx
+  res_vui = vec_lde(0, &vui);                   // CHECK: @llvm.ppc.altivec.lvewx
+  res_vf  = vec_lde(0, &vf);                    // CHECK: @llvm.ppc.altivec.lvewx
+  res_vsc = vec_lvebx(0, &vsc);                 // CHECK: @llvm.ppc.altivec.lvebx
+  res_vuc = vec_lvebx(0, &vuc);                 // CHECK: @llvm.ppc.altivec.lvebx
+  res_vs  = vec_lvehx(0, &vs);                  // CHECK: @llvm.ppc.altivec.lvehx
+  res_vus = vec_lvehx(0, &vus);                 // CHECK: @llvm.ppc.altivec.lvehx
+  res_vi  = vec_lvewx(0, &vi);                  // CHECK: @llvm.ppc.altivec.lvewx
+  res_vui = vec_lvewx(0, &vui);                 // CHECK: @llvm.ppc.altivec.lvewx
+  res_vf  = vec_lvewx(0, &vf);                  // CHECK: @llvm.ppc.altivec.lvewx
+
+  /* vec_ldl */
+  res_vsc = vec_ldl(0, &vsc);                   // CHECK: @llvm.ppc.altivec.lvxl
+  res_vsc = vec_ldl(0, &param_sc);              // CHECK: @llvm.ppc.altivec.lvxl
+  res_vuc = vec_ldl(0, &vuc);                   // CHECK: @llvm.ppc.altivec.lvxl
+  res_vuc = vec_ldl(0, &param_uc);              // CHECK: @llvm.ppc.altivec.lvxl
+  res_vbc = vec_ldl(0, &vbc);                   // CHECK: @llvm.ppc.altivec.lvxl
+  res_vs  = vec_ldl(0, &vs);                    // CHECK: @llvm.ppc.altivec.lvxl
+  res_vs  = vec_ldl(0, &param_s);               // CHECK: @llvm.ppc.altivec.lvxl
+  res_vus = vec_ldl(0, &vus);                   // CHECK: @llvm.ppc.altivec.lvxl
+  res_vus = vec_ldl(0, &param_us);              // CHECK: @llvm.ppc.altivec.lvxl
+  res_vbs = vec_ldl(0, &vbs);                   // CHECK: @llvm.ppc.altivec.lvxl
+  res_vp  = vec_ldl(0, &vp);                    // CHECK: @llvm.ppc.altivec.lvxl
+  res_vi  = vec_ldl(0, &vi);                    // CHECK: @llvm.ppc.altivec.lvxl
+  res_vi  = vec_ldl(0, &param_i);               // CHECK: @llvm.ppc.altivec.lvxl
+  res_vui = vec_ldl(0, &vui);                   // CHECK: @llvm.ppc.altivec.lvxl
+  res_vui = vec_ldl(0, &param_ui);              // CHECK: @llvm.ppc.altivec.lvxl
+  res_vbi = vec_ldl(0, &vbi);                   // CHECK: @llvm.ppc.altivec.lvxl
+  res_vf  = vec_ldl(0, &vf);                    // CHECK: @llvm.ppc.altivec.lvxl
+  res_vf  = vec_ldl(0, &param_f);               // CHECK: @llvm.ppc.altivec.lvxl
+  res_vsc = vec_lvxl(0, &vsc);                  // CHECK: @llvm.ppc.altivec.lvxl
+  res_vsc = vec_lvxl(0, &param_sc);             // CHECK: @llvm.ppc.altivec.lvxl
+  res_vuc = vec_lvxl(0, &vuc);                  // CHECK: @llvm.ppc.altivec.lvxl
+  res_vbc = vec_lvxl(0, &vbc);                  // CHECK: @llvm.ppc.altivec.lvxl
+  res_vuc = vec_lvxl(0, &param_uc);             // CHECK: @llvm.ppc.altivec.lvxl
+  res_vs  = vec_lvxl(0, &vs);                   // CHECK: @llvm.ppc.altivec.lvxl
+  res_vs  = vec_lvxl(0, &param_s);              // CHECK: @llvm.ppc.altivec.lvxl
+  res_vus = vec_lvxl(0, &vus);                  // CHECK: @llvm.ppc.altivec.lvxl
+  res_vus = vec_lvxl(0, &param_us);             // CHECK: @llvm.ppc.altivec.lvxl
+  res_vbs = vec_lvxl(0, &vbs);                  // CHECK: @llvm.ppc.altivec.lvxl
+  res_vp  = vec_lvxl(0, &vp);                   // CHECK: @llvm.ppc.altivec.lvxl
+  res_vi  = vec_lvxl(0, &vi);                   // CHECK: @llvm.ppc.altivec.lvxl
+  res_vi  = vec_lvxl(0, &param_i);              // CHECK: @llvm.ppc.altivec.lvxl
+  res_vui = vec_lvxl(0, &vui);                  // CHECK: @llvm.ppc.altivec.lvxl
+  res_vui = vec_lvxl(0, &param_ui);             // CHECK: @llvm.ppc.altivec.lvxl
+  res_vbi = vec_lvxl(0, &vbi);                  // CHECK: @llvm.ppc.altivec.lvxl
+  res_vf  = vec_lvxl(0, &vf);                   // CHECK: @llvm.ppc.altivec.lvxl
+  res_vf  = vec_lvxl(0, &param_f);              // CHECK: @llvm.ppc.altivec.lvxl
+
+  /* vec_loge */
+  res_vf = vec_loge(vf);                        // CHECK: @llvm.ppc.altivec.vlogefp
+  res_vf = vec_vlogefp(vf);                     // CHECK: @llvm.ppc.altivec.vlogefp
+
+  /* vec_lvsl */
+  res_vuc = vec_lvsl(0, &param_i);              // CHECK: @llvm.ppc.altivec.lvsl
+
+  /* vec_lvsr */
+  res_vuc = vec_lvsr(0, &param_i);              // CHECK: @llvm.ppc.altivec.lvsr
+
+  /* vec_madd */
+  res_vf =vec_madd(vf, vf, vf);                 // CHECK: @llvm.ppc.altivec.vmaddfp
+  res_vf = vec_vmaddfp(vf, vf, vf);             // CHECK: @llvm.ppc.altivec.vmaddfp
+
+  /* vec_madds */
+  res_vs = vec_madds(vs, vs, vs);               // CHECK: @llvm.ppc.altivec.vmhaddshs
+  res_vs = vec_vmhaddshs(vs, vs, vs);           // CHECK: @llvm.ppc.altivec.vmhaddshs
 
   /* 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_vsc = vec_max(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vmaxsb
+  res_vsc = vec_max(vbc, vsc);                  // CHECK: @llvm.ppc.altivec.vmaxsb
+  res_vsc = vec_max(vsc, vbc);                  // CHECK: @llvm.ppc.altivec.vmaxsb
+  res_vuc = vec_max(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vmaxub
+  res_vuc = vec_max(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vmaxub
+  res_vuc = vec_max(vuc, vbc);                  // CHECK: @llvm.ppc.altivec.vmaxub
+  res_vs  = vec_max(vs, vs);                    // CHECK: @llvm.ppc.altivec.vmaxsh
+  res_vs  = vec_max(vbs, vs);                   // CHECK: @llvm.ppc.altivec.vmaxsh
+  res_vs  = vec_max(vs, vbs);                   // 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_vus = vec_max(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vmaxuh
+  res_vus = vec_max(vus, vbs);                  // CHECK: @llvm.ppc.altivec.vmaxuh
+  res_vi  = vec_max(vi, vi);                    // CHECK: @llvm.ppc.altivec.vmaxsw
+  res_vi  = vec_max(vbi, vi);                   // CHECK: @llvm.ppc.altivec.vmaxsw
+  res_vi  = vec_max(vi, vbi);                   // CHECK: @llvm.ppc.altivec.vmaxsw
+  res_vui = vec_max(vui, vui);                  // CHECK: @llvm.ppc.altivec.vmaxuw
+  res_vui = vec_max(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vmaxuw
+  res_vui = vec_max(vui, vbi);                  // CHECK: @llvm.ppc.altivec.vmaxuw
+  res_vf  = vec_max(vf, vf);                    // CHECK: @llvm.ppc.altivec.vmaxfp
+  res_vsc = vec_vmaxsb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vmaxsb
+  res_vsc = vec_vmaxsb(vbc, vsc);               // CHECK: @llvm.ppc.altivec.vmaxsb
+  res_vsc = vec_vmaxsb(vsc, vbc);               // CHECK: @llvm.ppc.altivec.vmaxsb
+  res_vuc = vec_vmaxub(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vmaxub
+  res_vuc = vec_vmaxub(vbc, vuc);               // CHECK: @llvm.ppc.altivec.vmaxub
+  res_vuc = vec_vmaxub(vuc, vbc);               // CHECK: @llvm.ppc.altivec.vmaxub
+  res_vs  = vec_vmaxsh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vmaxsh
+  res_vs  = vec_vmaxsh(vbs, vs);                // CHECK: @llvm.ppc.altivec.vmaxsh
+  res_vs  = vec_vmaxsh(vs, vbs);                // CHECK: @llvm.ppc.altivec.vmaxsh
+  res_vus = vec_vmaxuh(vus, vus);               // CHECK: @llvm.ppc.altivec.vmaxuh
+  res_vus = vec_vmaxuh(vbs, vus);               // CHECK: @llvm.ppc.altivec.vmaxuh
+  res_vus = vec_vmaxuh(vus, vbs);               // CHECK: @llvm.ppc.altivec.vmaxuh
+  res_vi  = vec_vmaxsw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vmaxsw
+  res_vi  = vec_vmaxsw(vbi, vi);                // CHECK: @llvm.ppc.altivec.vmaxsw
+  res_vi  = vec_vmaxsw(vi, vbi);                // 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
+  res_vui = vec_vmaxuw(vbi, vui);               // CHECK: @llvm.ppc.altivec.vmaxuw
+  res_vui = vec_vmaxuw(vui, vbi);               // CHECK: @llvm.ppc.altivec.vmaxuw
+  res_vf  = vec_vmaxfp(vf, vf);                 // CHECK: @llvm.ppc.altivec.vmaxfp
+
+  /* vec_mergeh */
+  res_vsc = vec_mergeh(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_mergeh(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_mergeh(vbc, vbc);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_mergeh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_mergeh(vp, vp);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_mergeh(vus, vus);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_mergeh(vbs, vbs);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_mergeh(vi, vi);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_mergeh(vui, vui);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_mergeh(vbi, vbi);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_mergeh(vf, vf);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_vmrghb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_vmrghb(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_vmrghb(vbc, vbc);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_vmrghh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_vmrghh(vp, vp);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_vmrghh(vus, vus);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_vmrghh(vbs, vbs);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_vmrghw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_vmrghw(vui, vui);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_vmrghw(vbi, vbi);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_vmrghw(vf, vf);                 // CHECK: @llvm.ppc.altivec.vperm
+
+  /* vec_mergel */
+  res_vsc = vec_mergel(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_mergel(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_mergel(vbc, vbc);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_mergel(vs, vs);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_mergeh(vp, vp);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_mergel(vus, vus);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_mergel(vbs, vbs);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_mergel(vi, vi);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_mergel(vui, vui);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_mergel(vbi, vbi);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_mergel(vf, vf);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_vmrglb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_vmrglb(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_vmrglb(vbc, vbc);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_vmrglh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_vmrglh(vp, vp);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_vmrglh(vus, vus);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_vmrglh(vbs, vbs);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_vmrglw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_vmrglw(vui, vui);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_vmrglw(vbi, vbi);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_vmrglw(vf, vf);                 // CHECK: @llvm.ppc.altivec.vperm
 
   /* vec_mfvscr */
-  vf = vec_mfvscr();                            // CHECK: @llvm.ppc.altivec.mfvscr
+  vus = 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_vsc = vec_min(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vminsb
+  res_vsc = vec_min(vbc, vsc);                  // CHECK: @llvm.ppc.altivec.vminsb
+  res_vsc = vec_min(vsc, vbc);                  // CHECK: @llvm.ppc.altivec.vminsb
+  res_vuc = vec_min(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vminub
+  res_vuc = vec_min(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vminub
+  res_vuc = vec_min(vuc, vbc);                  // CHECK: @llvm.ppc.altivec.vminub
+  res_vs  = vec_min(vs, vs);                    // CHECK: @llvm.ppc.altivec.vminsh
+  res_vs  = vec_min(vbs, vs);                   // CHECK: @llvm.ppc.altivec.vminsh
+  res_vs  = vec_min(vs, vbs);                   // 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_vus = vec_min(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vminuh
+  res_vus = vec_min(vus, vbs);                  // CHECK: @llvm.ppc.altivec.vminuh
+  res_vi  = vec_min(vi, vi);                    // CHECK: @llvm.ppc.altivec.vminsw
+  res_vi  = vec_min(vbi, vi);                   // CHECK: @llvm.ppc.altivec.vminsw
+  res_vi  = vec_min(vi, vbi);                   // CHECK: @llvm.ppc.altivec.vminsw
+  res_vui = vec_min(vui, vui);                  // CHECK: @llvm.ppc.altivec.vminuw
+  res_vui = vec_min(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vminuw
+  res_vui = vec_min(vui, vbi);                  // CHECK: @llvm.ppc.altivec.vminuw
+  res_vf  = vec_min(vf, vf);                    // CHECK: @llvm.ppc.altivec.vminfp
+  res_vsc = vec_vminsb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vminsb
+  res_vsc = vec_vminsb(vbc, vsc);               // CHECK: @llvm.ppc.altivec.vminsb
+  res_vsc = vec_vminsb(vsc, vbc);               // CHECK: @llvm.ppc.altivec.vminsb
+  res_vuc = vec_vminub(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vminub
+  res_vuc = vec_vminub(vbc, vuc);               // CHECK: @llvm.ppc.altivec.vminub
+  res_vuc = vec_vminub(vuc, vbc);               // CHECK: @llvm.ppc.altivec.vminub
+  res_vs  = vec_vminsh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vminsh
+  res_vs  = vec_vminsh(vbs, vs);                // CHECK: @llvm.ppc.altivec.vminsh
+  res_vs  = vec_vminsh(vs, vbs);                // CHECK: @llvm.ppc.altivec.vminsh
+  res_vus = vec_vminuh(vus, vus);               // CHECK: @llvm.ppc.altivec.vminuh
+  res_vus = vec_vminuh(vbs, vus);               // CHECK: @llvm.ppc.altivec.vminuh
+  res_vus = vec_vminuh(vus, vbs);               // CHECK: @llvm.ppc.altivec.vminuh
+  res_vi  = vec_vminsw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vminsw
+  res_vi  = vec_vminsw(vbi, vi);                // CHECK: @llvm.ppc.altivec.vminsw
+  res_vi  = vec_vminsw(vi, vbi);                // 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
+  res_vui = vec_vminuw(vbi, vui);               // CHECK: @llvm.ppc.altivec.vminuw
+  res_vui = vec_vminuw(vui, vbi);               // CHECK: @llvm.ppc.altivec.vminuw
+  res_vf  = vec_vminfp(vf, vf);                 // CHECK: @llvm.ppc.altivec.vminfp
+
+  /* vec_mladd */
+  res_vus = vec_mladd(vus, vus, vus);           // CHECK: mul <8 x i16>
+                                                // CHECK: add <8 x i16>
+
+  res_vs = vec_mladd(vus, vs, vs);              // CHECK: mul nsw <8 x i16>
+                                                // CHECK: add nsw <8 x i16>
+
+  res_vs = vec_mladd(vs, vus, vus);             // CHECK: mul nsw <8 x i16>
+                                                // CHECK: add nsw <8 x i16>
+
+  res_vs = vec_mladd(vs, vs, vs);               // CHECK: mul nsw <8 x i16>
+                                                // CHECK: add nsw <8 x i16>
+
+  /* vec_mradds */
+  res_vs = vec_mradds(vs, vs, vs);              // CHECK: @llvm.ppc.altivec.vmhraddshs
+  res_vs = vec_vmhraddshs(vs, vs, vs);          // CHECK: @llvm.ppc.altivec.vmhraddshs
+ 
+  /* vec_msum */
+  res_vi  = vec_msum(vsc, vuc, vi);             // CHECK: @llvm.ppc.altivec.vmsummbm
+  res_vui = vec_msum(vuc, vuc, vui);            // CHECK: @llvm.ppc.altivec.vmsumubm
+  res_vi  = vec_msum(vs, vs, vi);               // CHECK: @llvm.ppc.altivec.vmsumshm
+  res_vui = vec_msum(vus, vus, vui);            // CHECK: @llvm.ppc.altivec.vmsumuhm
+  res_vi  = vec_vmsummbm(vsc, vuc, vi);         // CHECK: @llvm.ppc.altivec.vmsummbm
+  res_vui = vec_vmsumubm(vuc, vuc, vui);        // CHECK: @llvm.ppc.altivec.vmsumubm
+  res_vi  = vec_vmsumshm(vs, vs, vi);           // CHECK: @llvm.ppc.altivec.vmsumshm
+  res_vui = vec_vmsumuhm(vus, vus, vui);        // CHECK: @llvm.ppc.altivec.vmsumuhm
+
+  /* vec_msums */
+  res_vi  = vec_msums(vs, vs, vi);              // CHECK: @llvm.ppc.altivec.vmsumshs
+  res_vui = vec_msums(vus, vus, vui);           // CHECK: @llvm.ppc.altivec.vmsumuhs
+  res_vi  = vec_vmsumshs(vs, vs, vi);           // CHECK: @llvm.ppc.altivec.vmsumshs
+  res_vui = vec_vmsumuhs(vus, vus, vui);        // CHECK: @llvm.ppc.altivec.vmsumuhs
 
   /* vec_mtvscr */
   vec_mtvscr(vsc);                              // CHECK: @llvm.ppc.altivec.mtvscr
+  vec_mtvscr(vuc);                              // CHECK: @llvm.ppc.altivec.mtvscr
+  vec_mtvscr(vbc);                              // CHECK: @llvm.ppc.altivec.mtvscr
+  vec_mtvscr(vs);                               // CHECK: @llvm.ppc.altivec.mtvscr
+  vec_mtvscr(vus);                              // CHECK: @llvm.ppc.altivec.mtvscr
+  vec_mtvscr(vbs);                              // CHECK: @llvm.ppc.altivec.mtvscr
+  vec_mtvscr(vp);                               // CHECK: @llvm.ppc.altivec.mtvscr
+  vec_mtvscr(vi);                               // CHECK: @llvm.ppc.altivec.mtvscr
+  vec_mtvscr(vui);                              // CHECK: @llvm.ppc.altivec.mtvscr
+  vec_mtvscr(vbi);                              // CHECK: @llvm.ppc.altivec.mtvscr
+
+  /* vec_mule */
+  res_vs  = vec_mule(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vmulesb
+  res_vus = vec_mule(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vmuleub
+  res_vi  = vec_mule(vs, vs);                   // CHECK: @llvm.ppc.altivec.vmulesh
+  res_vui = vec_mule(vus, vus);                 // CHECK: @llvm.ppc.altivec.vmuleuh
+  res_vs  = vec_vmulesb(vsc, vsc);              // CHECK: @llvm.ppc.altivec.vmulesb
+  res_vus = vec_vmuleub(vuc, vuc);              // CHECK: @llvm.ppc.altivec.vmuleub
+  res_vi  = vec_vmulesh(vs, vs);                // CHECK: @llvm.ppc.altivec.vmulesh
+  res_vui = vec_vmuleuh(vus, vus);              // CHECK: @llvm.ppc.altivec.vmuleuh
+
+  /* vec_mulo */
+  res_vs  = vec_mulo(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vmulosb
+  res_vus = vec_mulo(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vmuloub
+  res_vi  = vec_mulo(vs, vs);                   // CHECK: @llvm.ppc.altivec.vmulosh
+  res_vui = vec_mulo(vus, vus);                 // CHECK: @llvm.ppc.altivec.vmulouh
+  res_vs  = vec_vmulosb(vsc, vsc);              // CHECK: @llvm.ppc.altivec.vmulosb
+  res_vus = vec_vmuloub(vuc, vuc);              // CHECK: @llvm.ppc.altivec.vmuloub
+  res_vi  = vec_vmulosh(vs, vs);                // CHECK: @llvm.ppc.altivec.vmulosh
+  res_vui = vec_vmulouh(vus, vus);              // CHECK: @llvm.ppc.altivec.vmulouh
+
+  /* vec_nmsub */
+  res_vf = vec_nmsub(vf, vf, vf);               // CHECK: @llvm.ppc.altivec.vnmsubfp
+  res_vf = vec_vnmsubfp(vf, vf, vf);            // CHECK: @llvm.ppc.altivec.vnmsubfp
+
+  /* vec_nor */
+  res_vsc = vec_nor(vsc, vsc);                  // CHECK: or <16 x i8>
+                                                // CHECK: xor <16 x i8>
+
+  res_vuc = vec_nor(vuc, vuc);                  // CHECK: or <16 x i8>
+                                                // CHECK: xor <16 x i8>
+
+  res_vuc = vec_nor(vbc, vbc);                  // CHECK: or <16 x i8>
+                                                // CHECK: xor <16 x i8>
+
+  res_vs  = vec_nor(vs, vs);                    // CHECK: or <8 x i16>
+                                                // CHECK: xor <8 x i16>
+
+  res_vus = vec_nor(vus, vus);                  // CHECK: or <8 x i16>
+                                                // CHECK: xor <8 x i16>
+
+  res_vus = vec_nor(vbs, vbs);                  // CHECK: or <8 x i16>
+                                                // CHECK: xor <8 x i16>
+
+  res_vi  = vec_nor(vi, vi);                    // CHECK: or <4 x i32>
+                                                // CHECK: xor <4 x i32>
+
+  res_vui = vec_nor(vui, vui);                  // CHECK: or <4 x i32>
+                                                // CHECK: xor <4 x i32>
+
+  res_vui = vec_nor(vbi, vbi);                  // CHECK: or <4 x i32>
+                                                // CHECK: xor <4 x i32>
+
+  res_vf  = vec_nor(vf, vf);                    // CHECK: or <4 x i32>
+                                                // CHECK: xor <4 x i32>
+
+  res_vsc = vec_vnor(vsc, vsc);                 // CHECK: or <16 x i8>
+                                                // CHECK: xor <16 x i8>
+
+  res_vuc = vec_vnor(vuc, vuc);                 // CHECK: or <16 x i8>
+                                                // CHECK: xor <16 x i8>
+
+  res_vuc = vec_vnor(vbc, vbc);                 // CHECK: or <16 x i8>
+                                                // CHECK: xor <16 x i8>
+
+  res_vs  = vec_vnor(vs, vs);                   // CHECK: or <8 x i16>
+                                                // CHECK: xor <8 x i16>
+
+  res_vus = vec_vnor(vus, vus);                 // CHECK: or <8 x i16>
+                                                // CHECK: xor <8 x i16>
+
+  res_vus = vec_vnor(vbs, vbs);                 // CHECK: or <8 x i16>
+                                                // CHECK: xor <8 x i16>
+
+  res_vi  = vec_vnor(vi, vi);                   // CHECK: or <4 x i32>
+                                                // CHECK: xor <4 x i32>
+
+  res_vui = vec_vnor(vui, vui);                 // CHECK: or <4 x i32>
+                                                // CHECK: xor <4 x i32>
+
+  res_vui = vec_vnor(vbi, vbi);                 // CHECK: or <4 x i32>
+                                                // CHECK: xor <4 x i32>
+
+  res_vf  = vec_vnor(vf, vf);                   // CHECK: or <4 x i32>
+                                                // CHECK: xor <4 x i32>
+
+  /* vec_or */
+  res_vsc = vec_or(vsc, vsc);                   // CHECK: or <16 x i8>
+  res_vsc = vec_or(vbc, vsc);                   // CHECK: or <16 x i8>
+  res_vsc = vec_or(vsc, vbc);                   // CHECK: or <16 x i8>
+  res_vuc = vec_or(vuc, vuc);                   // CHECK: or <16 x i8>
+  res_vuc = vec_or(vbc, vuc);                   // CHECK: or <16 x i8>
+  res_vuc = vec_or(vuc, vbc);                   // CHECK: or <16 x i8>
+  res_vbc = vec_or(vbc, vbc);                   // CHECK: or <16 x i8>
+  res_vs  = vec_or(vs, vs);                     // CHECK: or <8 x i16>
+  res_vs  = vec_or(vbs, vs);                    // CHECK: or <8 x i16>
+  res_vs  = vec_or(vs, vbs);                    // CHECK: or <8 x i16>
+  res_vus = vec_or(vus, vus);                   // CHECK: or <8 x i16>
+  res_vus = vec_or(vbs, vus);                   // CHECK: or <8 x i16>
+  res_vus = vec_or(vus, vbs);                   // CHECK: or <8 x i16>
+  res_vbs = vec_or(vbs, vbs);                   // CHECK: or <8 x i16>
+  res_vi  = vec_or(vi, vi);                     // CHECK: or <4 x i32>
+  res_vi  = vec_or(vbi, vi);                    // CHECK: or <4 x i32>
+  res_vi  = vec_or(vi, vbi);                    // CHECK: or <4 x i32>
+  res_vui = vec_or(vui, vui);                   // CHECK: or <4 x i32>
+  res_vui = vec_or(vbi, vui);                   // CHECK: or <4 x i32>
+  res_vui = vec_or(vui, vbi);                   // CHECK: or <4 x i32>
+  res_vbi = vec_or(vbi, vbi);                   // CHECK: or <4 x i32>
+  res_vf  = vec_or(vf, vf);                     // CHECK: or <4 x i32>
+  res_vf  = vec_or(vbi, vf);                    // CHECK: or <4 x i32>
+  res_vf  = vec_or(vf, vbi);                    // CHECK: or <4 x i32>
+  res_vsc = vec_vor(vsc, vsc);                  // CHECK: or <16 x i8>
+  res_vsc = vec_vor(vbc, vsc);                  // CHECK: or <16 x i8>
+  res_vsc = vec_vor(vsc, vbc);                  // CHECK: or <16 x i8>
+  res_vuc = vec_vor(vuc, vuc);                  // CHECK: or <16 x i8>
+  res_vuc = vec_vor(vbc, vuc);                  // CHECK: or <16 x i8>
+  res_vuc = vec_vor(vuc, vbc);                  // CHECK: or <16 x i8>
+  res_vbc = vec_vor(vbc, vbc);                  // CHECK: or <16 x i8>
+  res_vs  = vec_vor(vs, vs);                    // CHECK: or <8 x i16>
+  res_vs  = vec_vor(vbs, vs);                   // CHECK: or <8 x i16>
+  res_vs  = vec_vor(vs, vbs);                   // CHECK: or <8 x i16>
+  res_vus = vec_vor(vus, vus);                  // CHECK: or <8 x i16>
+  res_vus = vec_vor(vbs, vus);                  // CHECK: or <8 x i16>
+  res_vus = vec_vor(vus, vbs);                  // CHECK: or <8 x i16>
+  res_vbs = vec_vor(vbs, vbs);                  // CHECK: or <8 x i16>
+  res_vi  = vec_vor(vi, vi);                    // CHECK: or <4 x i32>
+  res_vi  = vec_vor(vbi, vi);                   // CHECK: or <4 x i32>
+  res_vi  = vec_vor(vi, vbi);                   // CHECK: or <4 x i32>
+  res_vui = vec_vor(vui, vui);                  // CHECK: or <4 x i32>
+  res_vui = vec_vor(vbi, vui);                  // CHECK: or <4 x i32>
+  res_vui = vec_vor(vui, vbi);                  // CHECK: or <4 x i32>
+  res_vbi = vec_vor(vbi, vbi);                  // CHECK: or <4 x i32>
+  res_vf  = vec_vor(vf, vf);                    // CHECK: or <4 x i32>
+  res_vf  = vec_vor(vbi, vf);                   // CHECK: or <4 x i32>
+  res_vf  = vec_vor(vf, vbi);                   // CHECK: or <4 x i32>
+
+  /* vec_pack */
+  res_vsc = vec_pack(vs, vs);                   // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_pack(vus, vus);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_pack(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_pack(vi, vi);                   // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_pack(vui, vui);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_pack(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_vpkuhum(vs, vs);                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_vpkuhum(vus, vus);              // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_vpkuhum(vbs, vbs);              // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_vpkuwum(vi, vi);                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_vpkuwum(vui, vui);              // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_vpkuwum(vbi, vbi);              // CHECK: @llvm.ppc.altivec.vperm
+
+  /* vec_packpx */
+  res_vp = vec_packpx(vui, vui);                // CHECK: @llvm.ppc.altivec.vpkpx
+  res_vp = vec_vpkpx(vui, vui);                 // CHECK: @llvm.ppc.altivec.vpkpx
+
+  /* vec_packs */
+  res_vsc = vec_packs(vs, vs);                  // CHECK: @llvm.ppc.altivec.vpkshss
+  res_vuc = vec_packs(vus, vus);                // CHECK: @llvm.ppc.altivec.vpkuhus
+  res_vs  = vec_packs(vi, vi);                  // CHECK: @llvm.ppc.altivec.vpkswss
+  res_vus = vec_packs(vui, vui);                // CHECK: @llvm.ppc.altivec.vpkuwus
+  res_vsc = vec_vpkshss(vs, vs);                // CHECK: @llvm.ppc.altivec.vpkshss
+  res_vuc = vec_vpkuhus(vus, vus);              // CHECK: @llvm.ppc.altivec.vpkuhus
+  res_vs  = vec_vpkswss(vi, vi);                // CHECK: @llvm.ppc.altivec.vpkswss
+  res_vus = vec_vpkuwus(vui, vui);              // CHECK: @llvm.ppc.altivec.vpkuwus
+
+  /* vec_packsu */
+  res_vuc = vec_packsu(vs, vs);                 // CHECK: @llvm.ppc.altivec.vpkshus
+  res_vuc = vec_packsu(vus, vus);               // CHECK: @llvm.ppc.altivec.vpkuhus
+  res_vus = vec_packsu(vi, vi);                 // CHECK: @llvm.ppc.altivec.vpkswus
+  res_vus = vec_packsu(vui, vui);               // CHECK: @llvm.ppc.altivec.vpkuwus
+  res_vuc = vec_vpkshus(vs, vs);                // CHECK: @llvm.ppc.altivec.vpkshus
+  res_vuc = vec_vpkshus(vus, vus);              // CHECK: @llvm.ppc.altivec.vpkuhus
+  res_vus = vec_vpkswus(vi, vi);                // CHECK: @llvm.ppc.altivec.vpkswus
+  res_vus = vec_vpkswus(vui, vui);              // CHECK: @llvm.ppc.altivec.vpkuwus
+
+  /* vec_perm */
+  res_vsc = vec_perm(vsc, vsc, vuc);            // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_perm(vuc, vuc, vuc);            // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_perm(vbc, vbc, vuc);            // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_perm(vs, vs, vuc);              // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_perm(vus, vus, vuc);            // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_perm(vbs, vbs, vuc);            // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_perm(vp, vp, vuc);              // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_perm(vi, vi, vuc);              // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_perm(vui, vui, vuc);            // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_perm(vbi, vbi, vuc);            // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_perm(vf, vf, vuc);              // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_vperm(vsc, vsc, vuc);           // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_vperm(vuc, vuc, vuc);           // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_vperm(vbc, vbc, vuc);           // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_vperm(vs, vs, vuc);             // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_vperm(vus, vus, vuc);           // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_vperm(vbs, vbs, vuc);           // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_vperm(vp, vp, vuc);             // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_vperm(vi, vi, vuc);             // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_vperm(vui, vui, vuc);           // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_vperm(vbi, vbi, vuc);           // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_vperm(vf, vf, vuc);             // CHECK: @llvm.ppc.altivec.vperm
+
+  /* vec_re */
+  res_vf = vec_re(vf);                          // CHECK: @llvm.ppc.altivec.vrefp
+  res_vf = vec_vrefp(vf);                       // CHECK: @llvm.ppc.altivec.vrefp
+
+  /* vec_rl */
+  res_vsc = vec_rl(vsc, vuc);                   // CHECK: @llvm.ppc.altivec.vrlb
+  res_vuc = vec_rl(vuc, vuc);                   // CHECK: @llvm.ppc.altivec.vrlb
+  res_vs  = vec_rl(vs, vus);                    // CHECK: @llvm.ppc.altivec.vrlh
+  res_vus = vec_rl(vus, vus);                   // CHECK: @llvm.ppc.altivec.vrlh
+  res_vi  = vec_rl(vi, vui);                    // CHECK: @llvm.ppc.altivec.vrlw
+  res_vui = vec_rl(vui, vui);                   // CHECK: @llvm.ppc.altivec.vrlw
+  res_vsc = vec_vrlb(vsc, vuc);                 // CHECK: @llvm.ppc.altivec.vrlb
+  res_vuc = vec_vrlb(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vrlb
+  res_vs  = vec_vrlh(vs, vus);                  // CHECK: @llvm.ppc.altivec.vrlh
+  res_vus = vec_vrlh(vus, vus);                 // CHECK: @llvm.ppc.altivec.vrlh
+  res_vi  = vec_vrlw(vi, vui);                  // CHECK: @llvm.ppc.altivec.vrlw
+  res_vui = vec_vrlw(vui, vui);                 // CHECK: @llvm.ppc.altivec.vrlw
+
+  /* vec_round */
+  res_vf = vec_round(vf);                       // CHECK: @llvm.ppc.altivec.vrfin
+  res_vf = vec_vrfin(vf);                       // CHECK: @llvm.ppc.altivec.vrfin
+
+  /* vec_rsqrte */
+  res_vf = vec_rsqrte(vf);                      // CHECK: @llvm.ppc.altivec.vrsqrtefp
+  res_vf = vec_vrsqrtefp(vf);                   // CHECK: @llvm.ppc.altivec.vrsqrtefp
+
+  /* vec_sel */
+  res_vsc = vec_sel(vsc, vsc, vuc);             // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: or <16 x i8>
+
+  res_vsc = vec_sel(vsc, vsc, vbc);             // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: or <16 x i8>
+
+  res_vuc = vec_sel(vuc, vuc, vuc);             // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: or <16 x i8>
+
+  res_vuc = vec_sel(vuc, vuc, vbc);             // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: or <16 x i8>
+
+  res_vbc = vec_sel(vbc, vbc, vuc);             // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: or <16 x i8>
+
+  res_vbc = vec_sel(vbc, vbc, vbc);             // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: or <16 x i8>
+
+  res_vs  = vec_sel(vs, vs, vus);               // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: or <8 x i16>
+
+  res_vs  = vec_sel(vs, vs, vbs);               // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: or <8 x i16>
+
+  res_vus = vec_sel(vus, vus, vus);             // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: or <8 x i16>
+
+  res_vus = vec_sel(vus, vus, vbs);             // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: or <8 x i16>
+
+  res_vbs = vec_sel(vbs, vbs, vus);             // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: or <8 x i16>
+
+  res_vbs = vec_sel(vbs, vbs, vbs);             // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: or <8 x i16>
+
+  res_vi  = vec_sel(vi, vi, vui);               // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vi  = vec_sel(vi, vi, vbi);               // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vui = vec_sel(vui, vui, vui);             // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vui = vec_sel(vui, vui, vbi);             // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vbi = vec_sel(vbi, vbi, vui);             // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vbi = vec_sel(vbi, vbi, vbi);             // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vf  = vec_sel(vf, vf, vui);               // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vf  = vec_sel(vf, vf, vbi);               // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vsc = vec_vsel(vsc, vsc, vuc);            // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: or <16 x i8>
+
+  res_vsc = vec_vsel(vsc, vsc, vbc);            // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: or <16 x i8>
+
+  res_vuc = vec_vsel(vuc, vuc, vuc);            // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: or <16 x i8>
+
+  res_vuc = vec_vsel(vuc, vuc, vbc);            // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: or <16 x i8>
+
+  res_vbc = vec_vsel(vbc, vbc, vuc);            // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: or <16 x i8>
+
+  res_vbc = vec_vsel(vbc, vbc, vbc);            // CHECK: xor <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: and <16 x i8>
+                                                // CHECK: or <16 x i8>
+
+  res_vs  = vec_vsel(vs, vs, vus);              // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: or <8 x i16>
+
+  res_vs  = vec_vsel(vs, vs, vbs);              // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: or <8 x i16>
+
+  res_vus = vec_vsel(vus, vus, vus);            // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: or <8 x i16>
+
+  res_vus = vec_vsel(vus, vus, vbs);            // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: or <8 x i16>
+
+  res_vbs = vec_vsel(vbs, vbs, vus);            // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: or <8 x i16>
+
+  res_vbs = vec_vsel(vbs, vbs, vbs);            // CHECK: xor <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: and <8 x i16>
+                                                // CHECK: or <8 x i16>
+
+  res_vi  = vec_vsel(vi, vi, vui);              // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vi  = vec_vsel(vi, vi, vbi);              // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vui = vec_vsel(vui, vui, vui);            // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vui = vec_vsel(vui, vui, vbi);            // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vbi = vec_vsel(vbi, vbi, vui);            // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vbi = vec_vsel(vbi, vbi, vbi);            // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vf  = vec_vsel(vf, vf, vui);              // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  res_vf  = vec_vsel(vf, vf, vbi);              // CHECK: xor <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: and <4 x i32>
+                                                // CHECK: or <4 x i32>
+
+  /* vec_sl */
+  res_vsc = vec_sl(vsc, vuc);                   // CHECK: shl <16 x i8>
+  res_vuc = vec_sl(vuc, vuc);                   // CHECK: shl <16 x i8>
+  res_vs  = vec_sl(vs, vus);                    // CHECK: shl <8 x i16>
+  res_vus = vec_sl(vus, vus);                   // CHECK: shl <8 x i16>
+  res_vi  = vec_sl(vi, vui);                    // CHECK: shl <4 x i32>
+  res_vui = vec_sl(vui, vui);                   // CHECK: shl <4 x i32>
+  res_vsc = vec_vslb(vsc, vuc);                 // CHECK: shl <16 x i8>
+  res_vuc = vec_vslb(vuc, vuc);                 // CHECK: shl <16 x i8>
+  res_vs  = vec_vslh(vs, vus);                  // CHECK: shl <8 x i16>
+  res_vus = vec_vslh(vus, vus);                 // CHECK: shl <8 x i16>
+  res_vi  = vec_vslw(vi, vui);                  // CHECK: shl <4 x i32>
+  res_vui = vec_vslw(vui, vui);                 // CHECK: shl <4 x i32>
+
+  /* vec_sld */
+  res_vsc = vec_sld(vsc, vsc, 0);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_sld(vuc, vuc, 0);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_sld(vs, vs, 0);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_sld(vus, vus, 0);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_sld(vp, vp, 0);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_sld(vi, vi, 0);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_sld(vui, vui, 0);               // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_sld(vf, vf, 0);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_vsldoi(vsc, vsc, 0);            // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_vsldoi(vuc, vuc, 0);            // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_vsldoi(vs, vs, 0);              // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_vsldoi(vus, vus, 0);            // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_vsldoi(vp, vp, 0);              // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_vsldoi(vi, vi, 0);              // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_vsldoi(vui, vui, 0);            // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_vsldoi(vf, vf, 0);              // CHECK: @llvm.ppc.altivec.vperm
+
+  /* vec_sll */
+  res_vsc = vec_sll(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vsc = vec_sll(vsc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vsc = vec_sll(vsc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vuc = vec_sll(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vuc = vec_sll(vuc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vuc = vec_sll(vuc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbc = vec_sll(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbc = vec_sll(vbc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbc = vec_sll(vbc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vs  = vec_sll(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vs  = vec_sll(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vs  = vec_sll(vs, vui);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vus = vec_sll(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vus = vec_sll(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vus = vec_sll(vus, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbs = vec_sll(vbs, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbs = vec_sll(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbs = vec_sll(vbs, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vp  = vec_sll(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vp  = vec_sll(vp, vus);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vp  = vec_sll(vp, vui);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vi  = vec_sll(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vi  = vec_sll(vi, vus);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vi  = vec_sll(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vui = vec_sll(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vui = vec_sll(vui, vus);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vui = vec_sll(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbi = vec_sll(vbi, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbi = vec_sll(vbi, vus);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbi = vec_sll(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vsc = vec_vsl(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vsc = vec_vsl(vsc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vsc = vec_vsl(vsc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vuc = vec_vsl(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vuc = vec_vsl(vuc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vuc = vec_vsl(vuc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbc = vec_vsl(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbc = vec_vsl(vbc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbc = vec_vsl(vbc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vs  = vec_vsl(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vs  = vec_vsl(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vs  = vec_vsl(vs, vui);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vus = vec_vsl(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vus = vec_vsl(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vus = vec_vsl(vus, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbs = vec_vsl(vbs, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbs = vec_vsl(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbs = vec_vsl(vbs, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vp  = vec_vsl(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vp  = vec_vsl(vp, vus);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vp  = vec_vsl(vp, vui);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vi  = vec_vsl(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vi  = vec_vsl(vi, vus);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vi  = vec_vsl(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsl
+  res_vui = vec_vsl(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vui = vec_vsl(vui, vus);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vui = vec_vsl(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbi = vec_vsl(vbi, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbi = vec_vsl(vbi, vus);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vbi = vec_vsl(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+
+  /* vec_slo */
+  res_vsc = vec_slo(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vsc = vec_slo(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vuc = vec_slo(vuc, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vuc = vec_slo(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vs  = vec_slo(vs, vsc);                   // CHECK: @llvm.ppc.altivec.vslo
+  res_vs  = vec_slo(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vslo
+  res_vus = vec_slo(vus, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vus = vec_slo(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vp  = vec_slo(vp, vsc);                   // CHECK: @llvm.ppc.altivec.vslo
+  res_vp  = vec_slo(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vslo
+  res_vi  = vec_slo(vi, vsc);                   // CHECK: @llvm.ppc.altivec.vslo
+  res_vi  = vec_slo(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vslo
+  res_vui = vec_slo(vui, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vui = vec_slo(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vf  = vec_slo(vf, vsc);                   // CHECK: @llvm.ppc.altivec.vslo
+  res_vf  = vec_slo(vf, vuc);                   // CHECK: @llvm.ppc.altivec.vslo
+  res_vsc = vec_vslo(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vslo
+  res_vsc = vec_vslo(vsc, vuc);                 // CHECK: @llvm.ppc.altivec.vslo
+  res_vuc = vec_vslo(vuc, vsc);                 // CHECK: @llvm.ppc.altivec.vslo
+  res_vuc = vec_vslo(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vslo
+  res_vs  = vec_vslo(vs, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vs  = vec_vslo(vs, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vus = vec_vslo(vus, vsc);                 // CHECK: @llvm.ppc.altivec.vslo
+  res_vus = vec_vslo(vus, vuc);                 // CHECK: @llvm.ppc.altivec.vslo
+  res_vp  = vec_vslo(vp, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vp  = vec_vslo(vp, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vi  = vec_vslo(vi, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vi  = vec_vslo(vi, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vui = vec_vslo(vui, vsc);                 // CHECK: @llvm.ppc.altivec.vslo
+  res_vui = vec_vslo(vui, vuc);                 // CHECK: @llvm.ppc.altivec.vslo
+  res_vf  = vec_vslo(vf, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vf  = vec_vslo(vf, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
+
+  /* vec_splat */
+  res_vsc = vec_splat(vsc, 0);                  // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_splat(vuc, 0);                  // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_splat(vbc, 0);                  // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_splat(vs, 0);                   // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_splat(vus, 0);                  // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_splat(vbs, 0);                  // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_splat(vp, 0);                   // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_splat(vi, 0);                   // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_splat(vui, 0);                  // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_splat(vbi, 0);                  // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_splat(vf, 0);                   // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_vspltb(vsc, 0);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_vspltb(vuc, 0);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_vspltb(vbc, 0);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_vsplth(vs, 0);                  // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_vsplth(vus, 0);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_vsplth(vbs, 0);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_vsplth(vp, 0);                  // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_vspltw(vi, 0);                  // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_vspltw(vui, 0);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_vspltw(vbi, 0);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_vspltw(vf, 0);                  // CHECK: @llvm.ppc.altivec.vperm
+
+  /* vec_splat_s8 */
+  res_vsc = vec_splat_s8(0x09);                 // TODO: add check
+  res_vsc = vec_vspltisb(0x09);                 // TODO: add check
+
+  /* vec_splat_s16 */
+  res_vs = vec_splat_s16(0x09);                 // TODO: add check
+  res_vs = vec_vspltish(0x09);                  // TODO: add check
+
+  /* vec_splat_s32 */
+  res_vi = vec_splat_s32(0x09);                 // TODO: add check
+  res_vi = vec_vspltisw(0x09);                  // TODO: add check
+
+  /* vec_splat_u8 */
+  res_vuc = vec_splat_u8(0x09);                 // TODO: add check
+
+  /* vec_splat_u16 */
+  res_vus = vec_splat_u16(0x09);                // TODO: add check
+
+  /* vec_splat_u32 */
+  res_vui = vec_splat_u32(0x09);                // TODO: add check
+
+  /* vec_sr */
+  res_vsc = vec_sr(vsc, vuc);                   // CHECK: shr <16 x i8>
+  res_vuc = vec_sr(vuc, vuc);                   // CHECK: shr <16 x i8>
+  res_vs  = vec_sr(vs, vus);                    // CHECK: shr <8 x i16>
+  res_vus = vec_sr(vus, vus);                   // CHECK: shr <8 x i16>
+  res_vi  = vec_sr(vi, vui);                    // CHECK: shr <4 x i32>
+  res_vui = vec_sr(vui, vui);                   // CHECK: shr <4 x i32>
+  res_vsc = vec_vsrb(vsc, vuc);                 // CHECK: shr <16 x i8>
+  res_vuc = vec_vsrb(vuc, vuc);                 // CHECK: shr <16 x i8>
+  res_vs  = vec_vsrh(vs, vus);                  // CHECK: shr <8 x i16>
+  res_vus = vec_vsrh(vus, vus);                 // CHECK: shr <8 x i16>
+  res_vi  = vec_vsrw(vi, vui);                  // CHECK: shr <4 x i32>
+  res_vui = vec_vsrw(vui, vui);                 // CHECK: shr <4 x i32>
+
+  /* vec_sra */
+  res_vsc = vec_sra(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsrab
+  res_vuc = vec_sra(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsrab
+  res_vs  = vec_sra(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsrah
+  res_vus = vec_sra(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsrah
+  res_vi  = vec_sra(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsraw
+  res_vui = vec_sra(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsraw
+  res_vsc = vec_vsrab(vsc, vuc);                // CHECK: @llvm.ppc.altivec.vsrab
+  res_vuc = vec_vsrab(vuc, vuc);                // CHECK: @llvm.ppc.altivec.vsrab
+  res_vs  = vec_vsrah(vs, vus);                 // CHECK: @llvm.ppc.altivec.vsrah
+  res_vus = vec_vsrah(vus, vus);                // CHECK: @llvm.ppc.altivec.vsrah
+  res_vi  = vec_vsraw(vi, vui);                 // CHECK: @llvm.ppc.altivec.vsraw
+  res_vui = vec_vsraw(vui, vui);                // CHECK: @llvm.ppc.altivec.vsraw
+
+  /* vec_srl */
+  res_vsc = vec_srl(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vsc = vec_srl(vsc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vsc = vec_srl(vsc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vuc = vec_srl(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vuc = vec_srl(vuc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vuc = vec_srl(vuc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbc = vec_srl(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbc = vec_srl(vbc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbc = vec_srl(vbc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vs  = vec_srl(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vs  = vec_srl(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vs  = vec_srl(vs, vui);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vus = vec_srl(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vus = vec_srl(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vus = vec_srl(vus, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbs = vec_srl(vbs, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbs = vec_srl(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbs = vec_srl(vbs, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vp  = vec_srl(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vp  = vec_srl(vp, vus);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vp  = vec_srl(vp, vui);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vi  = vec_srl(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vi  = vec_srl(vi, vus);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vi  = vec_srl(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vui = vec_srl(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vui = vec_srl(vui, vus);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vui = vec_srl(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbi = vec_srl(vbi, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbi = vec_srl(vbi, vus);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbi = vec_srl(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vsc = vec_vsr(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vsc = vec_vsr(vsc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vsc = vec_vsr(vsc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vuc = vec_vsr(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vuc = vec_vsr(vuc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vuc = vec_vsr(vuc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbc = vec_vsr(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbc = vec_vsr(vbc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbc = vec_vsr(vbc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vs  = vec_vsr(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vs  = vec_vsr(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vs  = vec_vsr(vs, vui);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vus = vec_vsr(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vus = vec_vsr(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vus = vec_vsr(vus, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbs = vec_vsr(vbs, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbs = vec_vsr(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbs = vec_vsr(vbs, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vp  = vec_vsr(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vp  = vec_vsr(vp, vus);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vp  = vec_vsr(vp, vui);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vi  = vec_vsr(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vi  = vec_vsr(vi, vus);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vi  = vec_vsr(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsr
+  res_vui = vec_vsr(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vui = vec_vsr(vui, vus);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vui = vec_vsr(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbi = vec_vsr(vbi, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbi = vec_vsr(vbi, vus);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vbi = vec_vsr(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+
+  /* vec_sro */
+  res_vsc = vec_sro(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vsc = vec_sro(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vuc = vec_sro(vuc, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vuc = vec_sro(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vs  = vec_sro(vs, vsc);                   // CHECK: @llvm.ppc.altivec.vsro
+  res_vs  = vec_sro(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsro
+  res_vus = vec_sro(vus, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vus = vec_sro(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vp  = vec_sro(vp, vsc);                   // CHECK: @llvm.ppc.altivec.vsro
+  res_vp  = vec_sro(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsro
+  res_vi  = vec_sro(vi, vsc);                   // CHECK: @llvm.ppc.altivec.vsro
+  res_vi  = vec_sro(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsro
+  res_vui = vec_sro(vui, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vui = vec_sro(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vf  = vec_sro(vf, vsc);                   // CHECK: @llvm.ppc.altivec.vsro
+  res_vf  = vec_sro(vf, vuc);                   // CHECK: @llvm.ppc.altivec.vsro
+  res_vsc = vec_vsro(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vsro
+  res_vsc = vec_vsro(vsc, vuc);                 // CHECK: @llvm.ppc.altivec.vsro
+  res_vuc = vec_vsro(vuc, vsc);                 // CHECK: @llvm.ppc.altivec.vsro
+  res_vuc = vec_vsro(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vsro
+  res_vs  = vec_vsro(vs, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vs  = vec_vsro(vs, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vus = vec_vsro(vus, vsc);                 // CHECK: @llvm.ppc.altivec.vsro
+  res_vus = vec_vsro(vus, vuc);                 // CHECK: @llvm.ppc.altivec.vsro
+  res_vp  = vec_vsro(vp, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vp  = vec_vsro(vp, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vi  = vec_vsro(vi, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vi  = vec_vsro(vi, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vui = vec_vsro(vui, vsc);                 // CHECK: @llvm.ppc.altivec.vsro
+  res_vui = vec_vsro(vui, vuc);                 // CHECK: @llvm.ppc.altivec.vsro
+  res_vf  = vec_vsro(vf, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vf  = vec_vsro(vf, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
+
+  /* vec_st */
+  vec_st(vsc, 0, &vsc);                        // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vsc, 0, &param_sc);                   // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vuc, 0, &vuc);                        // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vuc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vbc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vbc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vbc, 0, &vbc);                        // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vs, 0, &vs);                          // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vs, 0, &param_s);                     // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vus, 0, &vus);                        // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vus, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vbs, 0, &param_s);                    // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vbs, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vbs, 0, &vbs);                        // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vp, 0, &param_s);                     // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vp, 0, &param_us);                    // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vp, 0, &vp);                          // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vi, 0, &vi);                          // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vi, 0, &param_i);                     // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vui, 0, &vui);                        // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vui, 0, &param_ui);                   // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vbi, 0, &param_i);                    // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vbi, 0, &param_ui);                   // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vbi, 0, &vbi);                        // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vf, 0, &vf);                          // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vf, 0, &param_f);                     // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vsc, 0, &vsc);                      // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vsc, 0, &param_sc);                 // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vuc, 0, &vuc);                      // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vuc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vbc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vbc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vbc, 0, &vbc);                      // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vs, 0, &vs);                        // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vs, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vus, 0, &vus);                      // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vus, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vbs, 0, &param_s);                  // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vbs, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vbs, 0, &vbs);                      // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vp, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vp, 0, &param_us);                  // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vp, 0, &vp);                        // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vi, 0, &vi);                        // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vi, 0, &param_i);                   // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vui, 0, &vui);                      // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vui, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vbi, 0, &param_i);                  // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vbi, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vbi, 0, &vbi);                      // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vf, 0, &vf);                        // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvx(vf, 0, &param_f);                   // CHECK: @llvm.ppc.altivec.stvx
+
+  /* vec_ste */
+  vec_ste(vsc, 0, &param_sc);                  // CHECK: @llvm.ppc.altivec.stvebx
+  vec_ste(vuc, 0, &param_uc);                  // CHECK: @llvm.ppc.altivec.stvebx
+  vec_ste(vbc, 0, &param_sc);                  // CHECK: @llvm.ppc.altivec.stvebx
+  vec_ste(vbc, 0, &param_uc);                  // CHECK: @llvm.ppc.altivec.stvebx
+  vec_ste(vs, 0, &param_s);                    // CHECK: @llvm.ppc.altivec.stvehx
+  vec_ste(vus, 0, &param_us);                  // CHECK: @llvm.ppc.altivec.stvehx
+  vec_ste(vbs, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.stvehx
+  vec_ste(vbs, 0, &param_us);                  // CHECK: @llvm.ppc.altivec.stvehx
+  vec_ste(vp, 0, &param_s);                    // CHECK: @llvm.ppc.altivec.stvehx
+  vec_ste(vp, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvehx
+  vec_ste(vi, 0, &param_i);                    // CHECK: @llvm.ppc.altivec.stvewx
+  vec_ste(vui, 0, &param_ui);                  // CHECK: @llvm.ppc.altivec.stvewx
+  vec_ste(vbi, 0, &param_i);                   // CHECK: @llvm.ppc.altivec.stvewx
+  vec_ste(vbi, 0, &param_ui);                  // CHECK: @llvm.ppc.altivec.stvewx
+  vec_ste(vf, 0, &param_f);                    // CHECK: @llvm.ppc.altivec.stvewx
+  vec_stvebx(vsc, 0, &param_sc);               // CHECK: @llvm.ppc.altivec.stvebx
+  vec_stvebx(vuc, 0, &param_uc);               // CHECK: @llvm.ppc.altivec.stvebx
+  vec_stvebx(vbc, 0, &param_sc);               // CHECK: @llvm.ppc.altivec.stvebx
+  vec_stvebx(vbc, 0, &param_uc);               // CHECK: @llvm.ppc.altivec.stvebx
+  vec_stvehx(vs, 0, &param_s);                 // CHECK: @llvm.ppc.altivec.stvehx
+  vec_stvehx(vus, 0, &param_us);               // CHECK: @llvm.ppc.altivec.stvehx
+  vec_stvehx(vbs, 0, &param_s);                // CHECK: @llvm.ppc.altivec.stvehx
+  vec_stvehx(vbs, 0, &param_us);               // CHECK: @llvm.ppc.altivec.stvehx
+  vec_stvehx(vp, 0, &param_s);                 // CHECK: @llvm.ppc.altivec.stvehx
+  vec_stvehx(vp, 0, &param_us);                // CHECK: @llvm.ppc.altivec.stvehx
+  vec_stvewx(vi, 0, &param_i);                 // CHECK: @llvm.ppc.altivec.stvewx
+  vec_stvewx(vui, 0, &param_ui);               // CHECK: @llvm.ppc.altivec.stvewx
+  vec_stvewx(vbi, 0, &param_i);                // CHECK: @llvm.ppc.altivec.stvewx
+  vec_stvewx(vbi, 0, &param_ui);               // CHECK: @llvm.ppc.altivec.stvewx
+  vec_stvewx(vf, 0, &param_f);                 // CHECK: @llvm.ppc.altivec.stvewx
+
+  /* vec_stl */
+  vec_stl(vsc, 0, &vsc);                        // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vsc, 0, &param_sc);                   // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vuc, 0, &vuc);                        // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vuc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vbc, 0, &param_sc);                   // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vbc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vbc, 0, &vbc);                        // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vs, 0, &vs);                          // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vs, 0, &param_s);                     // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vus, 0, &vus);                        // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vus, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vbs, 0, &param_s);                    // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vbs, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vbs, 0, &vbs);                        // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vp, 0, &param_s);                     // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vp, 0, &param_us);                    // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vp, 0, &vp);                          // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vi, 0, &vi);                          // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vi, 0, &param_i);                     // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vui, 0, &vui);                        // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vui, 0, &param_ui);                   // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vbi, 0, &param_i);                    // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vbi, 0, &param_ui);                   // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vbi, 0, &vbi);                        // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vf, 0, &vf);                          // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vf, 0, &param_f);                     // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vsc, 0, &vsc);                      // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vsc, 0, &param_sc);                 // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vuc, 0, &vuc);                      // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vuc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vbc, 0, &param_sc);                 // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vbc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vbc, 0, &vbc);                      // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vs, 0, &vs);                        // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vs, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vus, 0, &vus);                      // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vus, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vbs, 0, &param_s);                  // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vbs, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vbs, 0, &vbs);                      // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vp, 0, &param_s);                  // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vp, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vp, 0, &vp);                      // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vi, 0, &vi);                        // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vi, 0, &param_i);                   // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vui, 0, &vui);                      // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vui, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vbi, 0, &param_i);                  // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vbi, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vbi, 0, &vbi);                      // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vf, 0, &vf);                        // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvxl(vf, 0, &param_f);                   // CHECK: @llvm.ppc.altivec.stvxl
+
+  /* vec_sub */
+  res_vsc = vec_sub(vsc, vsc);                  // CHECK: sub nsw <16 x i8>
+  res_vsc = vec_sub(vbc, vsc);                  // CHECK: sub nsw <16 x i8>
+  res_vsc = vec_sub(vsc, vbc);                  // CHECK: sub nsw <16 x i8>
+  res_vuc = vec_sub(vuc, vuc);                  // CHECK: sub <16 x i8>
+  res_vuc = vec_sub(vbc, vuc);                  // CHECK: sub <16 x i8>
+  res_vuc = vec_sub(vuc, vbc);                  // CHECK: sub <16 x i8>
+  res_vs  = vec_sub(vs, vs);                    // CHECK: sub nsw <8 x i16>
+  res_vs  = vec_sub(vbs, vs);                   // CHECK: sub nsw <8 x i16>
+  res_vs  = vec_sub(vs, vbs);                   // CHECK: sub nsw <8 x i16>
+  res_vus = vec_sub(vus, vus);                  // CHECK: sub <8 x i16>
+  res_vus = vec_sub(vbs, vus);                  // CHECK: sub <8 x i16>
+  res_vus = vec_sub(vus, vbs);                  // CHECK: sub <8 x i16>
+  res_vi  = vec_sub(vi, vi);                    // CHECK: sub nsw <4 x i32>
+  res_vi  = vec_sub(vbi, vi);                   // CHECK: sub nsw <4 x i32>
+  res_vi  = vec_sub(vi, vbi);                   // CHECK: sub nsw <4 x i32>
+  res_vui = vec_sub(vui, vui);                  // CHECK: sub <4 x i32>
+  res_vui = vec_sub(vbi, vui);                  // CHECK: sub <4 x i32>
+  res_vui = vec_sub(vui, vbi);                  // CHECK: sub <4 x i32>
+  res_vf  = vec_sub(vf, vf);                    // CHECK: fsub <4 x float>
+  res_vsc = vec_vsububm(vsc, vsc);              // CHECK: sub nsw <16 x i8>
+  res_vsc = vec_vsububm(vbc, vsc);              // CHECK: sub nsw <16 x i8>
+  res_vsc = vec_vsububm(vsc, vbc);              // CHECK: sub nsw <16 x i8>
+  res_vuc = vec_vsububm(vuc, vuc);              // CHECK: sub <16 x i8>
+  res_vuc = vec_vsububm(vbc, vuc);              // CHECK: sub <16 x i8>
+  res_vuc = vec_vsububm(vuc, vbc);              // CHECK: sub <16 x i8>
+  res_vs  = vec_vsubuhm(vs, vs);                // CHECK: sub nsw <8 x i16>
+  res_vs  = vec_vsubuhm(vbs, vus);              // CHECK: sub <8 x i16>
+  res_vs  = vec_vsubuhm(vus, vbs);              // CHECK: sub <8 x i16>
+  res_vus = vec_vsubuhm(vus, vus);              // CHECK: sub <8 x i16>
+  res_vus = vec_vsubuhm(vbs, vus);              // CHECK: sub <8 x i16>
+  res_vus = vec_vsubuhm(vus, vbs);              // CHECK: sub <8 x i16>
+  res_vi  = vec_vsubuwm(vi, vi);                // CHECK: sub nsw <4 x i32>
+  res_vi  = vec_vsubuwm(vbi, vi);               // CHECK: sub nsw <4 x i32>
+  res_vi  = vec_vsubuwm(vi, vbi);               // CHECK: sub nsw <4 x i32>
+  res_vui = vec_vsubuwm(vui, vui);              // CHECK: sub <4 x i32>
+  res_vui = vec_vsubuwm(vbi, vui);              // CHECK: sub <4 x i32>
+  res_vui = vec_vsubuwm(vui, vbi);              // CHECK: sub <4 x i32>
+  res_vf  = vec_vsubfp(vf, vf);                 // CHECK: fsub <4 x float>
+
+  /* vec_subc */
+  res_vui = vec_subc(vui, vui);                 // CHECK: @llvm.ppc.altivec.vsubcuw
+  res_vui = vec_vsubcuw(vui, vui);              // CHECK: @llvm.ppc.altivec.vsubcuw
+
+  /* vec_subs */
+  res_vsc = vec_subs(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vsubsbs
+  res_vsc = vec_subs(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vsubsbs
+  res_vsc = vec_subs(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vsubsbs
+  res_vuc = vec_subs(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vsububs
+  res_vuc = vec_subs(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vsububs
+  res_vuc = vec_subs(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vsububs
+  res_vs  = vec_subs(vs, vs);                   // CHECK: @llvm.ppc.altivec.vsubshs
+  res_vs  = vec_subs(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vsubshs
+  res_vs  = vec_subs(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vsubshs
+  res_vus = vec_subs(vus, vus);                 // CHECK: @llvm.ppc.altivec.vsubuhs
+  res_vus = vec_subs(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vsubuhs
+  res_vus = vec_subs(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vsubuhs
+  res_vi  = vec_subs(vi, vi);                   // CHECK: @llvm.ppc.altivec.vsubsws
+  res_vi  = vec_subs(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vsubsws
+  res_vi  = vec_subs(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vsubsws
+  res_vui = vec_subs(vui, vui);                 // CHECK: @llvm.ppc.altivec.vsubuws
+  res_vui = vec_subs(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vsubuws
+  res_vui = vec_subs(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vsubuws
+  res_vsc = vec_vsubsbs(vsc, vsc);              // CHECK: @llvm.ppc.altivec.vsubsbs
+  res_vsc = vec_vsubsbs(vbc, vsc);              // CHECK: @llvm.ppc.altivec.vsubsbs
+  res_vsc = vec_vsubsbs(vsc, vbc);              // CHECK: @llvm.ppc.altivec.vsubsbs
+  res_vuc = vec_vsububs(vuc, vuc);              // CHECK: @llvm.ppc.altivec.vsububs
+  res_vuc = vec_vsububs(vbc, vuc);              // CHECK: @llvm.ppc.altivec.vsububs
+  res_vuc = vec_vsububs(vuc, vbc);              // CHECK: @llvm.ppc.altivec.vsububs
+  res_vs  = vec_vsubshs(vs, vs);                // CHECK: @llvm.ppc.altivec.vsubshs
+  res_vs  = vec_vsubshs(vbs, vs);               // CHECK: @llvm.ppc.altivec.vsubshs
+  res_vs  = vec_vsubshs(vs, vbs);               // CHECK: @llvm.ppc.altivec.vsubshs
+  res_vus = vec_vsubuhs(vus, vus);              // CHECK: @llvm.ppc.altivec.vsubuhs
+  res_vus = vec_vsubuhs(vbs, vus);              // CHECK: @llvm.ppc.altivec.vsubuhs
+  res_vus = vec_vsubuhs(vus, vbs);              // CHECK: @llvm.ppc.altivec.vsubuhs
+  res_vi  = vec_vsubsws(vi, vi);                // CHECK: @llvm.ppc.altivec.vsubsws
+  res_vi  = vec_vsubsws(vbi, vi);               // CHECK: @llvm.ppc.altivec.vsubsws
+  res_vi  = vec_vsubsws(vi, vbi);               // CHECK: @llvm.ppc.altivec.vsubsws
+  res_vui = vec_vsubuws(vui, vui);              // CHECK: @llvm.ppc.altivec.vsubuws
+  res_vui = vec_vsubuws(vbi, vui);              // CHECK: @llvm.ppc.altivec.vsubuws
+  res_vui = vec_vsubuws(vui, vbi);              // CHECK: @llvm.ppc.altivec.vsubuws
+
+  /* vec_sum4s */
+  res_vi  = vec_sum4s(vsc, vi);                 // CHECK: @llvm.ppc.altivec.vsum4sbs
+  res_vui = vec_sum4s(vuc, vui);                // CHECK: @llvm.ppc.altivec.vsum4ubs
+  res_vi  = vec_sum4s(vs, vi);                  // CHECK: @llvm.ppc.altivec.vsum4shs
+  res_vi  = vec_vsum4sbs(vsc, vi);              // CHECK: @llvm.ppc.altivec.vsum4sbs
+  res_vui = vec_vsum4ubs(vuc, vui);             // CHECK: @llvm.ppc.altivec.vsum4ubs
+  res_vi  = vec_vsum4shs(vs, vi);               // CHECK: @llvm.ppc.altivec.vsum4shs
+
+  /* vec_sum2s */
+  res_vi = vec_sum2s(vi, vi);                   // CHECK: @llvm.ppc.altivec.vsum2sws
+  res_vi = vec_vsum2sws(vi, vi);                // CHECK: @llvm.ppc.altivec.vsum2sws
+
+  /* vec_sums */
+  res_vi = vec_sums(vi, vi);                    // CHECK: @llvm.ppc.altivec.vsumsws
+  res_vi = vec_vsumsws(vi, vi);                 // CHECK: @llvm.ppc.altivec.vsumsws
+
+  /* vec_trunc */
+  res_vf = vec_trunc(vf);                       // CHECK: @llvm.ppc.altivec.vrfiz
+  res_vf = vec_vrfiz(vf);                       // CHECK: @llvm.ppc.altivec.vrfiz
+
+  /* vec_unpackh */
+  res_vs  = vec_unpackh(vsc);                   // CHECK: @llvm.ppc.altivec.vupkhsb
+  res_vbs = vec_unpackh(vbc);                   // CHECK: @llvm.ppc.altivec.vupkhsb
+  res_vi  = vec_unpackh(vs);                    // CHECK: @llvm.ppc.altivec.vupkhsh
+  res_vbi = vec_unpackh(vbs);                   // CHECK: @llvm.ppc.altivec.vupkhsh
+  res_vui = vec_unpackh(vp);                    // CHECK: @llvm.ppc.altivec.vupkhsh
+  res_vs  = vec_vupkhsb(vsc);                   // CHECK: @llvm.ppc.altivec.vupkhsb
+  res_vbs = vec_vupkhsb(vbc);                   // CHECK: @llvm.ppc.altivec.vupkhsb
+  res_vi  = vec_vupkhsh(vs);                    // CHECK: @llvm.ppc.altivec.vupkhsh
+  res_vbi = vec_vupkhsh(vbs);                   // CHECK: @llvm.ppc.altivec.vupkhsh
+  res_vui = vec_vupkhsh(vp);                    // CHECK: @llvm.ppc.altivec.vupkhsh
+
+  /* vec_unpackl */
+  res_vs  = vec_unpackl(vsc);                   // CHECK: @llvm.ppc.altivec.vupklsb
+  res_vbs = vec_unpackl(vbc);                   // CHECK: @llvm.ppc.altivec.vupklsb
+  res_vi  = vec_unpackl(vs);                    // CHECK: @llvm.ppc.altivec.vupklsh
+  res_vbi = vec_unpackl(vbs);                   // CHECK: @llvm.ppc.altivec.vupklsh
+  res_vui = vec_unpackl(vp);                    // CHECK: @llvm.ppc.altivec.vupklsh
+  res_vs  = vec_vupklsb(vsc);                   // CHECK: @llvm.ppc.altivec.vupklsb
+  res_vbs = vec_vupklsb(vbc);                   // CHECK: @llvm.ppc.altivec.vupklsb
+  res_vi  = vec_vupklsh(vs);                    // CHECK: @llvm.ppc.altivec.vupklsh
+  res_vbi = vec_vupklsh(vbs);                   // CHECK: @llvm.ppc.altivec.vupklsh
+  res_vui = vec_vupklsh(vp);                    // CHECK: @llvm.ppc.altivec.vupklsh
+
+  /* vec_xor */
+  res_vsc = vec_xor(vsc, vsc);                  // CHECK: xor <16 x i8>
+  res_vsc = vec_xor(vbc, vsc);                  // CHECK: xor <16 x i8>
+  res_vsc = vec_xor(vsc, vbc);                  // CHECK: xor <16 x i8>
+  res_vuc = vec_xor(vuc, vuc);                  // CHECK: xor <16 x i8>
+  res_vuc = vec_xor(vbc, vuc);                  // CHECK: xor <16 x i8>
+  res_vuc = vec_xor(vuc, vbc);                  // CHECK: xor <16 x i8>
+  res_vbc = vec_xor(vbc, vbc);                  // CHECK: xor <16 x i8>
+  res_vs  = vec_xor(vs, vs);                    // CHECK: xor <8 x i16>
+  res_vs  = vec_xor(vbs, vs);                   // CHECK: xor <8 x i16>
+  res_vs  = vec_xor(vs, vbs);                   // CHECK: xor <8 x i16>
+  res_vus = vec_xor(vus, vus);                  // CHECK: xor <8 x i16>
+  res_vus = vec_xor(vbs, vus);                  // CHECK: xor <8 x i16>
+  res_vus = vec_xor(vus, vbs);                  // CHECK: xor <8 x i16>
+  res_vbs = vec_xor(vbs, vbs);                  // CHECK: xor <8 x i16>
+  res_vi  = vec_xor(vi, vi);                    // CHECK: xor <4 x i32>
+  res_vi  = vec_xor(vbi, vi);                   // CHECK: xor <4 x i32>
+  res_vi  = vec_xor(vi, vbi);                   // CHECK: xor <4 x i32>
+  res_vui = vec_xor(vui, vui);                  // CHECK: xor <4 x i32>
+  res_vui = vec_xor(vbi, vui);                  // CHECK: xor <4 x i32>
+  res_vui = vec_xor(vui, vbi);                  // CHECK: xor <4 x i32>
+  res_vbi = vec_xor(vbi, vbi);                  // CHECK: xor <4 x i32>
+  res_vf  = vec_xor(vf, vf);                    // CHECK: xor <4 x i32>
+  res_vf  = vec_xor(vbi, vf);                   // CHECK: xor <4 x i32>
+  res_vf  = vec_xor(vf, vbi);                   // CHECK: xor <4 x i32>
+  res_vsc = vec_vxor(vsc, vsc);                 // CHECK: xor <16 x i8>
+  res_vsc = vec_vxor(vbc, vsc);                 // CHECK: xor <16 x i8>
+  res_vsc = vec_vxor(vsc, vbc);                 // CHECK: xor <16 x i8>
+  res_vuc = vec_vxor(vuc, vuc);                 // CHECK: xor <16 x i8>
+  res_vuc = vec_vxor(vbc, vuc);                 // CHECK: xor <16 x i8>
+  res_vuc = vec_vxor(vuc, vbc);                 // CHECK: xor <16 x i8>
+  res_vbc = vec_vxor(vbc, vbc);                 // CHECK: xor <16 x i8>
+  res_vs  = vec_vxor(vs, vs);                   // CHECK: xor <8 x i16>
+  res_vs  = vec_vxor(vbs, vs);                  // CHECK: xor <8 x i16>
+  res_vs  = vec_vxor(vs, vbs);                  // CHECK: xor <8 x i16>
+  res_vus = vec_vxor(vus, vus);                 // CHECK: xor <8 x i16>
+  res_vus = vec_vxor(vbs, vus);                 // CHECK: xor <8 x i16>
+  res_vus = vec_vxor(vus, vbs);                 // CHECK: xor <8 x i16>
+  res_vbs = vec_vxor(vbs, vbs);                 // CHECK: xor <8 x i16>
+  res_vi  = vec_vxor(vi, vi);                   // CHECK: xor <4 x i32>
+  res_vi  = vec_vxor(vbi, vi);                  // CHECK: xor <4 x i32>
+  res_vi  = vec_vxor(vi, vbi);                  // CHECK: xor <4 x i32>
+  res_vui = vec_vxor(vui, vui);                 // CHECK: xor <4 x i32>
+  res_vui = vec_vxor(vbi, vui);                 // CHECK: xor <4 x i32>
+  res_vui = vec_vxor(vui, vbi);                 // CHECK: xor <4 x i32>
+  res_vbi = vec_vxor(vbi, vbi);                 // CHECK: xor <4 x i32>
+  res_vf  = vec_vxor(vf, vf);                   // CHECK: xor <4 x i32>
+  res_vf  = vec_vxor(vbi, vf);                  // CHECK: xor <4 x i32>
+  res_vf  = vec_vxor(vf, vbi);                  // CHECK: xor <4 x i32>
 
   /* ------------------------------ 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(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
   res_i = vec_all_eq(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_all_eq(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_all_eq(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_all_eq(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_all_eq(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
   res_i = vec_all_eq(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_eq(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
   res_i = vec_all_eq(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_eq(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_eq(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_eq(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_eq(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_eq(vp, vp);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
   res_i = vec_all_eq(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_all_eq(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
   res_i = vec_all_eq(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_all_eq(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_all_eq(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_all_eq(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_all_eq(vbi, vbi);                 // 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(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
   res_i = vec_all_ge(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_ge(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_ge(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_ge(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_ge(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
   res_i = vec_all_ge(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_all_ge(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
   res_i = vec_all_ge(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_ge(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_ge(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_ge(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_ge(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
   res_i = vec_all_ge(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_all_ge(vi, vbi);                  // 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
+  res_i = vec_all_ge(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_ge(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_ge(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_ge(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_ge(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_all_gt */
   res_i = vec_all_gt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+  res_i = vec_all_gt(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
   res_i = vec_all_gt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_gt(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_gt(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_gt(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_gt(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
   res_i = vec_all_gt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_all_gt(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
   res_i = vec_all_gt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_gt(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_gt(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_gt(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_gt(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
   res_i = vec_all_gt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_all_gt(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
   res_i = vec_all_gt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_gt(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_gt(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_gt(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_gt(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
   res_i = vec_all_gt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_all_in */
@@ -219,23 +1841,78 @@
 
   /* vec_all_le */
   res_i = vec_all_le(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+  res_i = vec_all_le(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
   res_i = vec_all_le(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_le(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_le(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_le(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_le(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
   res_i = vec_all_le(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_all_le(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
   res_i = vec_all_le(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_le(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_le(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_le(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_le(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
   res_i = vec_all_le(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_all_le(vi, vbi);                  // 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
+  res_i = vec_all_le(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_le(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_le(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_le(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_le(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+
+  /* vec_all_lt */
+  res_i = vec_all_lt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+  res_i = vec_all_lt(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+  res_i = vec_all_lt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_lt(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_lt(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_lt(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_lt(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_all_lt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_all_lt(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_all_lt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_lt(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_lt(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_lt(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_lt(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_all_lt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_all_lt(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_all_lt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_lt(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_lt(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_lt(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_lt(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_all_lt(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(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
   res_i = vec_all_ne(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_all_ne(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_all_ne(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_all_ne(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_all_ne(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
   res_i = vec_all_ne(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_ne(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
   res_i = vec_all_ne(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_ne(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_ne(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_ne(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_ne(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_all_ne(vp, vp);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
   res_i = vec_all_ne(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_all_ne(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
   res_i = vec_all_ne(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_all_ne(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_all_ne(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_all_ne(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_all_ne(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
   res_i = vec_all_ne(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
 
   /* vec_all_nge */
@@ -255,47 +1932,123 @@
 
   /*  vec_any_eq */
   res_i = vec_any_eq(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_any_eq(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
   res_i = vec_any_eq(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_any_eq(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_any_eq(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_any_eq(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_any_eq(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
   res_i = vec_any_eq(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_eq(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
   res_i = vec_any_eq(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_eq(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_eq(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_eq(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_eq(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_eq(vp, vp);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
   res_i = vec_any_eq(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_any_eq(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
   res_i = vec_any_eq(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_any_eq(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_any_eq(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_any_eq(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_any_eq(vbi, vbi);                 // 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(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
   res_i = vec_any_ge(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_ge(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_ge(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_ge(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_ge(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
   res_i = vec_any_ge(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_any_ge(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
   res_i = vec_any_ge(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_ge(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_ge(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_ge(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_ge(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
   res_i = vec_any_ge(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_any_ge(vi, vbi);                  // 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
+  res_i = vec_any_ge(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_ge(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_ge(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_ge(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_ge(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_any_gt */
   res_i = vec_any_gt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+  res_i = vec_any_gt(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
   res_i = vec_any_gt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_gt(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_gt(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_gt(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_gt(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
   res_i = vec_any_gt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_any_gt(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
   res_i = vec_any_gt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_gt(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_gt(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_gt(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_gt(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
   res_i = vec_any_gt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_any_gt(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
   res_i = vec_any_gt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_gt(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_gt(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_gt(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_gt(vbi, vbi);                 // 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(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
   res_i = vec_any_le(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_le(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_le(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_le(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_le(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
   res_i = vec_any_le(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_any_le(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
   res_i = vec_any_le(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_le(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_le(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_le(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_le(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
   res_i = vec_any_le(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_any_le(vi, vbi);                  // 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
+  res_i = vec_any_le(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_le(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_le(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_le(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_le(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_any_lt */
   res_i = vec_any_lt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+  res_i = vec_any_lt(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
   res_i = vec_any_lt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_lt(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_lt(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_lt(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
+  res_i = vec_any_lt(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
   res_i = vec_any_lt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+  res_i = vec_any_lt(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
   res_i = vec_any_lt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_lt(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_lt(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_lt(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+  res_i = vec_any_lt(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
   res_i = vec_any_lt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+  res_i = vec_any_lt(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
   res_i = vec_any_lt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_lt(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_lt(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_lt(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+  res_i = vec_any_lt(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
   res_i = vec_any_lt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_any_nan */
@@ -303,11 +2056,27 @@
 
   /* vec_any_ne */
   res_i = vec_any_ne(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_any_ne(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
   res_i = vec_any_ne(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_any_ne(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_any_ne(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_any_ne(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
+  res_i = vec_any_ne(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
   res_i = vec_any_ne(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_ne(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
   res_i = vec_any_ne(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_ne(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_ne(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_ne(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_ne(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
+  res_i = vec_any_ne(vp, vp);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
   res_i = vec_any_ne(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_any_ne(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
   res_i = vec_any_ne(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_any_ne(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_any_ne(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_any_ne(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
+  res_i = vec_any_ne(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
   res_i = vec_any_ne(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
 
   /* vec_any_nge */
@@ -327,6 +2096,4 @@
 
   /* 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
index b587814..1b4e68b 100644
--- a/test/CodeGen/builtins-x86.c
+++ b/test/CodeGen/builtins-x86.c
@@ -24,6 +24,14 @@
 typedef float V4f __attribute__((vector_size(16)));
 typedef double V2d __attribute__((vector_size(16)));
 
+// 256-bit
+typedef char V32c __attribute__((vector_size(32)));
+typedef signed int V8i __attribute__((vector_size(32)));
+typedef signed long long V4LLi __attribute__((vector_size(32)));
+
+typedef double V4d __attribute__((vector_size(32)));
+typedef float  V8f __attribute__((vector_size(32)));
+
 void f0() {
   signed char         tmp_c;
 //  unsigned char       tmp_Uc;
@@ -76,6 +84,22 @@
   V2LLi  tmp_V2LLi;
   V4f    tmp_V4f;
   V2d    tmp_V2d;
+  V2d*   tmp_V2dp;
+  V4f*   tmp_V4fp;
+  const V2d* tmp_V2dCp;
+  const V4f* tmp_V4fCp;
+
+  // 256-bit
+  V32c   tmp_V32c;
+  V4d    tmp_V4d;
+  V8f    tmp_V8f;
+  V4LLi  tmp_V4LLi;
+  V8i    tmp_V8i;
+  V4LLi* tmp_V4LLip;
+  V4d*   tmp_V4dp;
+  V8f*   tmp_V8fp;
+  const V4d* tmp_V4dCp;
+  const V8f* tmp_V8fCp;
 
   tmp_i = __builtin_ia32_comieq(tmp_V4f, tmp_V4f);
   tmp_i = __builtin_ia32_comilt(tmp_V4f, tmp_V4f);
@@ -365,6 +389,95 @@
   tmp_V2d = __builtin_ia32_roundpd(tmp_V2d, imm_i_0_16);
   tmp_V4f = __builtin_ia32_insertps128(tmp_V4f, tmp_V4f, tmp_i);
 #endif
+
+  tmp_V4d = __builtin_ia32_addsubpd256(tmp_V4d, tmp_V4d);
+  tmp_V8f = __builtin_ia32_addsubps256(tmp_V8f, tmp_V8f);
+  tmp_V4d = __builtin_ia32_haddpd256(tmp_V4d, tmp_V4d);
+  tmp_V8f = __builtin_ia32_hsubps256(tmp_V8f, tmp_V8f);
+  tmp_V4d = __builtin_ia32_hsubpd256(tmp_V4d, tmp_V4d);
+  tmp_V8f = __builtin_ia32_haddps256(tmp_V8f, tmp_V8f);
+  tmp_V4d = __builtin_ia32_maxpd256(tmp_V4d, tmp_V4d);
+  tmp_V8f = __builtin_ia32_maxps256(tmp_V8f, tmp_V8f);
+  tmp_V4d = __builtin_ia32_minpd256(tmp_V4d, tmp_V4d);
+  tmp_V8f = __builtin_ia32_minps256(tmp_V8f, tmp_V8f);
+  tmp_V2d = __builtin_ia32_vpermilvarpd(tmp_V2d, tmp_V2LLi);
+  tmp_V4f = __builtin_ia32_vpermilvarps(tmp_V4f, tmp_V4i);
+  tmp_V4d = __builtin_ia32_vpermilvarpd256(tmp_V4d, tmp_V4LLi);
+  tmp_V8f = __builtin_ia32_vpermilvarps256(tmp_V8f, tmp_V8i);
+  tmp_V4d = __builtin_ia32_blendpd256(tmp_V4d, tmp_V4d, 0x7);
+  tmp_V8f = __builtin_ia32_blendps256(tmp_V8f, tmp_V8f, 0x7);
+  tmp_V4d = __builtin_ia32_blendvpd256(tmp_V4d, tmp_V4d, tmp_V4d);
+  tmp_V8f = __builtin_ia32_blendvps256(tmp_V8f, tmp_V8f, tmp_V8f);
+  tmp_V8f = __builtin_ia32_dpps256(tmp_V8f, tmp_V8f, 0x7);
+  tmp_V4d = __builtin_ia32_cmppd256(tmp_V4d, tmp_V4d, 0);
+  tmp_V8f = __builtin_ia32_cmpps256(tmp_V8f, tmp_V8f, 0);
+  tmp_V2d = __builtin_ia32_vextractf128_pd256(tmp_V4d, 0x7);
+  tmp_V4f = __builtin_ia32_vextractf128_ps256(tmp_V8f, 0x7);
+  tmp_V4i = __builtin_ia32_vextractf128_si256(tmp_V8i, 0x7);
+  tmp_V4d = __builtin_ia32_cvtdq2pd256(tmp_V4i);
+  tmp_V8f = __builtin_ia32_cvtdq2ps256(tmp_V8i);
+  tmp_V4f = __builtin_ia32_cvtpd2ps256(tmp_V4d);
+  tmp_V8i = __builtin_ia32_cvtps2dq256(tmp_V8f);
+  tmp_V4d = __builtin_ia32_cvtps2pd256(tmp_V4f);
+  tmp_V4i = __builtin_ia32_cvttpd2dq256(tmp_V4d);
+  tmp_V4i = __builtin_ia32_cvtpd2dq256(tmp_V4d);
+  tmp_V8i = __builtin_ia32_cvttps2dq256(tmp_V8f);
+  tmp_V4d = __builtin_ia32_vperm2f128_pd256(tmp_V4d, tmp_V4d, 0x7);
+  tmp_V8f = __builtin_ia32_vperm2f128_ps256(tmp_V8f, tmp_V8f, 0x7);
+  tmp_V8i = __builtin_ia32_vperm2f128_si256(tmp_V8i, tmp_V8i, 0x7);
+  tmp_V2d = __builtin_ia32_vpermilpd(tmp_V2d, 0x7);
+  tmp_V4f = __builtin_ia32_vpermilps(tmp_V4f, 0x7);
+  tmp_V4d = __builtin_ia32_vpermilpd256(tmp_V4d, 0x7);
+  tmp_V8f = __builtin_ia32_vpermilps256(tmp_V8f, 0x7);
+  tmp_V4d = __builtin_ia32_vinsertf128_pd256(tmp_V4d, tmp_V2d, 0x7);
+  tmp_V8f = __builtin_ia32_vinsertf128_ps256(tmp_V8f, tmp_V4f, 0x7);
+  tmp_V8i = __builtin_ia32_vinsertf128_si256(tmp_V8i, tmp_V4i, 0x7);
+  tmp_V4d = __builtin_ia32_sqrtpd256(tmp_V4d);
+  tmp_V8f = __builtin_ia32_sqrtps256(tmp_V8f);
+  tmp_V8f = __builtin_ia32_rsqrtps256(tmp_V8f);
+  tmp_V8f = __builtin_ia32_rcpps256(tmp_V8f);
+  tmp_V4d = __builtin_ia32_roundpd256(tmp_V4d, tmp_i);
+  tmp_V8f = __builtin_ia32_roundps256(tmp_V8f, tmp_i);
+  tmp_i = __builtin_ia32_vtestzpd(tmp_V2d, tmp_V2d);
+  tmp_i = __builtin_ia32_vtestcpd(tmp_V2d, tmp_V2d);
+  tmp_i = __builtin_ia32_vtestnzcpd(tmp_V2d, tmp_V2d);
+  tmp_i = __builtin_ia32_vtestzps(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_vtestcps(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_vtestnzcps(tmp_V4f, tmp_V4f);
+  tmp_i = __builtin_ia32_vtestzpd256(tmp_V4d, tmp_V4d);
+  tmp_i = __builtin_ia32_vtestcpd256(tmp_V4d, tmp_V4d);
+  tmp_i = __builtin_ia32_vtestnzcpd256(tmp_V4d, tmp_V4d);
+  tmp_i = __builtin_ia32_vtestzps256(tmp_V8f, tmp_V8f);
+  tmp_i = __builtin_ia32_vtestcps256(tmp_V8f, tmp_V8f);
+  tmp_i = __builtin_ia32_vtestnzcps256(tmp_V8f, tmp_V8f);
+  tmp_i = __builtin_ia32_ptestz256(tmp_V4LLi, tmp_V4LLi);
+  tmp_i = __builtin_ia32_ptestc256(tmp_V4LLi, tmp_V4LLi);
+  tmp_i = __builtin_ia32_ptestnzc256(tmp_V4LLi, tmp_V4LLi);
+  tmp_i = __builtin_ia32_movmskpd256(tmp_V4d);
+  tmp_i = __builtin_ia32_movmskps256(tmp_V8f);
+  __builtin_ia32_vzeroall();
+  __builtin_ia32_vzeroupper();
+  tmp_V4f = __builtin_ia32_vbroadcastss(tmp_fCp);
+  tmp_V4d = __builtin_ia32_vbroadcastsd256(tmp_dCp);
+  tmp_V8f = __builtin_ia32_vbroadcastss256(tmp_fCp);
+  tmp_V4d = __builtin_ia32_vbroadcastf128_pd256(tmp_V2dCp);
+  tmp_V8f = __builtin_ia32_vbroadcastf128_ps256(tmp_V4fCp);
+  tmp_V4d = __builtin_ia32_loadupd256(tmp_dCp);
+  tmp_V8f = __builtin_ia32_loadups256(tmp_fCp);
+  __builtin_ia32_storeupd256(tmp_dp, tmp_V4d);
+  __builtin_ia32_storeups256(tmp_fp, tmp_V8f);
+  tmp_V32c = __builtin_ia32_loaddqu256(tmp_cCp);
+  __builtin_ia32_storedqu256(tmp_cp, tmp_V32c);
+  tmp_V32c = __builtin_ia32_lddqu256(tmp_cCp);
+  __builtin_ia32_movntdq256(tmp_V4LLip, tmp_V4LLi);
+  __builtin_ia32_movntpd256(tmp_dp, tmp_V4d);
+  __builtin_ia32_movntps256(tmp_fp, tmp_V8f);
+  tmp_V2d = __builtin_ia32_maskloadpd(tmp_V2dCp, tmp_V2d);
+  tmp_V4f = __builtin_ia32_maskloadps(tmp_V4fCp, tmp_V4f);
+  tmp_V4d = __builtin_ia32_maskloadpd256(tmp_V4dCp, tmp_V4d);
+  tmp_V8f = __builtin_ia32_maskloadps256(tmp_V8fCp, tmp_V8f);
+  __builtin_ia32_maskstorepd(tmp_V2dp, tmp_V2d, tmp_V2d);
+  __builtin_ia32_maskstoreps(tmp_V4fp, tmp_V4f, tmp_V4f);
+  __builtin_ia32_maskstorepd256(tmp_V4dp, tmp_V4d, tmp_V4d);
+  __builtin_ia32_maskstoreps256(tmp_V8fp, tmp_V8f, tmp_V8f);
 }
-
-
diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c
index a4424d7..40f7724 100644
--- a/test/CodeGen/builtins.c
+++ b/test/CodeGen/builtins.c
@@ -39,9 +39,10 @@
   Q(inff, ());
   Q(infl, ());
 
+  P(fpclassify, (0, 1, 2, 3, 4, 1.0));
+  P(fpclassify, (0, 1, 2, 3, 4, 1.0f));
+  P(fpclassify, (0, 1, 2, 3, 4, 1.0l));
   // 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, (""));
@@ -163,3 +164,42 @@
 
 }
 // CHECK: }
+
+
+// CHECK: define void @test_float_builtins
+void test_float_builtins(float F, double D, long double LD) {
+  volatile int res;
+  res = __builtin_isinf(F);
+  // CHECK:  call float @fabsf(float
+  // CHECK:  fcmp oeq float {{.*}}, 0x7FF0000000000000
+
+  res = __builtin_isinf(D);
+  // CHECK:  call double @fabs(double
+  // CHECK:  fcmp oeq double {{.*}}, 0x7FF0000000000000
+  
+  res = __builtin_isinf(LD);
+  // CHECK:  call x86_fp80 @fabsl(x86_fp80
+  // CHECK:  fcmp oeq x86_fp80 {{.*}}, 0xK7FFF8000000000000000
+  
+  res = __builtin_isfinite(F);
+  // CHECK: fcmp oeq float 
+  // CHECK: call float @fabsf
+  // CHECK: fcmp une float {{.*}}, 0x7FF0000000000000
+  // CHECK: and i1 
+
+  res = __builtin_isnormal(F);
+  // CHECK: fcmp oeq float
+  // CHECK: call float @fabsf
+  // CHECK: fcmp ult float {{.*}}, 0x7FF0000000000000
+  // CHECK: fcmp uge float {{.*}}, 0x3810000000000000
+  // CHECK: and i1
+  // CHECK: and i1
+}
+
+// CHECK: define void @test_builtin_longjmp
+void test_builtin_longjmp(void **buffer) {
+  // CHECK: [[BITCAST:%.*]] = bitcast
+  // CHECK-NEXT: call void @llvm.eh.sjlj.longjmp(i8* [[BITCAST]])
+  __builtin_longjmp(buffer, 1);
+  // CHECK-NEXT: unreachable
+}
diff --git a/test/CodeGen/complex.c b/test/CodeGen/complex.c
index ca60610..055383e 100644
--- a/test/CodeGen/complex.c
+++ b/test/CodeGen/complex.c
@@ -89,3 +89,7 @@
   --ci1;
 }
 
+// <rdar://problem/7958272>
+double t7(double _Complex c) {
+  return __builtin_fabs(__real__(c));
+}
diff --git a/test/CodeGen/const-arithmetic.c b/test/CodeGen/const-arithmetic.c
index e12b4f6..92c02f0 100644
--- a/test/CodeGen/const-arithmetic.c
+++ b/test/CodeGen/const-arithmetic.c
@@ -1,7 +1,7 @@
 // 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]
+// 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 16 ; <[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 16 ; <[2 x i8*]*> [#uses=0]
 
 extern struct { unsigned char a, b; } g0[];
 void *g1[] = {g0 + -1, g0 + -23 };
diff --git a/test/CodeGen/const-unordered-compare.c b/test/CodeGen/const-unordered-compare.c
new file mode 100644
index 0000000..ffd04db
--- /dev/null
+++ b/test/CodeGen/const-unordered-compare.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+// Checks folding of an unordered comparison
+int nan_ne_check() {
+  // CHECK: ret i32 1
+  return (__builtin_nanf("") != __builtin_nanf("")) ? 1 : 0;
+}
diff --git a/test/CodeGen/debug-info-enum.c b/test/CodeGen/debug-info-enum.c
new file mode 100644
index 0000000..b4a1ce0
--- /dev/null
+++ b/test/CodeGen/debug-info-enum.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1  -emit-llvm -g %s -o %t
+// RUN: grep DW_TAG_enumeration_type %t
+// Radar 8195980
+
+enum vtag {
+  VT_ONE
+};
+
+int foo(int i) {
+  return i == VT_ONE;
+}
diff --git a/test/CodeGen/debug-info-scope.c b/test/CodeGen/debug-info-scope.c
new file mode 100644
index 0000000..6051e6e
--- /dev/null
+++ b/test/CodeGen/debug-info-scope.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -g -emit-llvm < %s | FileCheck %s
+// Two variables with same name in separate scope.
+// Radar 8330217.
+int main() {
+	int j = 0;
+	int k = 0;
+// CHECK: DW_TAG_auto_variable
+// CHECK-NEXT: DW_TAG_lexical_block
+	for (int i = 0; i < 10; i++)
+		j++;
+	for (int i = 0; i < 10; i++)
+		k++;
+	return 0;
+}
diff --git a/test/CodeGen/decl.c b/test/CodeGen/decl.c
index 7ffb700..7a9971e 100644
--- a/test/CodeGen/decl.c
+++ b/test/CodeGen/decl.c
@@ -89,3 +89,31 @@
 struct test8s { int f0; char f1; } test8g = {};
 
 
+// PR7519
+
+struct S {
+  void (*x) (struct S *);
+};
+
+extern struct S *global_dc;
+void cp_diagnostic_starter(struct S *);
+
+void init_error(void) {
+  global_dc->x = cp_diagnostic_starter;
+}
+
+
+
+// rdar://8147692 - ABI crash in recursive struct-through-function-pointer.
+typedef struct {
+  int x5a;
+} x5;
+
+typedef struct x2 *x0;
+typedef long (*x1)(x0 x0a, x5 x6);
+struct x2 {
+  x1 x4;
+};
+long x3(x0 x0a, x5 a) {
+  return x0a->x4(x0a, a);
+}
diff --git a/test/CodeGen/enum2.c b/test/CodeGen/enum2.c
new file mode 100644
index 0000000..3203627
--- /dev/null
+++ b/test/CodeGen/enum2.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -g -emit-llvm -o /dev/null
+int v;
+enum e { MAX };
+
+void foo (void)
+{
+  v = MAX;
+}
diff --git a/test/CodeGen/exprs.c b/test/CodeGen/exprs.c
index d82cbf4..c9978b8 100644
--- a/test/CodeGen/exprs.c
+++ b/test/CodeGen/exprs.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o -
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s
 
 // PR1895
 // sizeof function
@@ -119,3 +119,36 @@
 void f10() {
   __builtin_sin(0);
 }
+
+// rdar://7530813
+// CHECK: define i32 @f11
+int f11(long X) {
+  int A[100];
+  return A[X];
+
+// CHECK: [[Xaddr:%[^ ]+]] = alloca i64, align 8
+// CHECK: load {{.*}}* [[Xaddr]]
+// CHECK-NEXT: getelementptr inbounds [100 x i32]* %A, i32 0, 
+// CHECK-NEXT: load i32*
+}
+
+int f12() {
+  // PR3150
+  // CHECK: define i32 @f12
+  // CHECK: ret i32 1
+  return 1||1;
+}
+
+// Make sure negate of fp uses -0.0 for proper -0 handling.
+double f13(double X) {
+  // CHECK: define double @f13
+  // CHECK: fsub double -0.0
+  return -X;
+}
+
+// Check operations on incomplete types.
+struct s14;
+void f14(struct s13 *a) {
+  (void) &*a;
+}
+
diff --git a/test/CodeGen/extern-inline.c b/test/CodeGen/extern-inline.c
index 5dd9bfd..60f6d03 100644
--- a/test/CodeGen/extern-inline.c
+++ b/test/CodeGen/extern-inline.c
@@ -19,7 +19,7 @@
 static int f2(int a, int b) {return a*b;}
 // CHECK: load i32* %{{.*}}
 // CHECK: load i32* %{{.*}}
-// CHECK: mul i32 %{{.*}}, %{{.*}}
+// CHECK: mul nsw i32 %{{.*}}, %{{.*}}
 int h2(void) {return f2(1,2);}
 // CHECK: call i32 @f2
 
diff --git a/test/CodeGen/frame-pointer-elim.c b/test/CodeGen/frame-pointer-elim.c
new file mode 100644
index 0000000..79c0599
--- /dev/null
+++ b/test/CodeGen/frame-pointer-elim.c
@@ -0,0 +1,29 @@
+// RUN: %clang -ccc-host-triple i386 -S -o - %s | \
+// RUN:   FileCheck --check-prefix=DEFAULT %s
+// DEFAULT: f0:
+// DEFAULT: pushl %ebp
+// DEFAULT: ret
+// DEFAULT: f1:
+// DEFAULT: pushl %ebp
+// DEFAULT: ret
+
+// RUN: %clang -ccc-host-triple i386 -S -o - -fomit-frame-pointer %s | \
+// RUN:   FileCheck --check-prefix=OMIT_ALL %s
+// OMIT_ALL: f0:
+// OMIT_ALL-NOT: pushl %ebp
+// OMIT_ALL: ret
+// OMIT_ALL: f1:
+// OMIT_ALL-NOT: pushl %ebp
+// OMIT_ALL: ret
+
+// RUN: %clang -ccc-host-triple i386 -S -o - -momit-leaf-frame-pointer %s | \
+// RUN:   FileCheck --check-prefix=OMIT_LEAF %s
+// OMIT_LEAF: f0:
+// OMIT_LEAF-NOT: pushl %ebp
+// OMIT_LEAF: ret
+// OMIT_LEAF: f1:
+// OMIT_LEAF: pushl %ebp
+// OMIT_LEAF: ret
+
+void f0() {}
+void f1() { f0(); }
diff --git a/test/CodeGen/func-in-block.c b/test/CodeGen/func-in-block.c
new file mode 100644
index 0000000..7e65ff9
--- /dev/null
+++ b/test/CodeGen/func-in-block.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -emit-llvm -o - %s | FileCheck %s
+// rdar: // 7860965
+
+extern void PRINTF(const char *);
+extern void B(void (^)(void));
+
+int main()
+{
+    PRINTF(__func__);
+    B(
+       ^{
+            PRINTF(__func__);
+        }
+    );
+    return 0; // not reached
+}
+
+// CHECK: @__func__.__main_block_invoke_0 = private constant [22 x i8] c"__main_block_invoke_0\00"
+// CHECK: call void @PRINTF({{.*}}@__func__.__main_block_invoke_ 
diff --git a/test/CodeGen/functions.c b/test/CodeGen/functions.c
index 5629ef5..a2c692d 100644
--- a/test/CodeGen/functions.c
+++ b/test/CodeGen/functions.c
@@ -47,3 +47,15 @@
 // CHECK: define void @f7(float{{.*}}, float{{.*}})
 // CHECK: call void @f6(float{{.*}}, float{{.*}})
 }
+
+// PR6911 - incomplete function types
+struct Incomplete;
+void f8_callback(struct Incomplete);
+void f8_user(void (*callback)(struct Incomplete));
+void f8_test() {
+  f8_user(&f8_callback);
+// CHECK: define void @f8_test()
+// CHECK: call void @f8_user({{.*}}* bitcast (void ()* @f8_callback to {{.*}}*))
+// CHECK: declare void @f8_user({{.*}}*)
+// CHECK: declare void @f8_callback()
+}
diff --git a/test/CodeGen/init.c b/test/CodeGen/init.c
index d48e723..c8de99d 100644
--- a/test/CodeGen/init.c
+++ b/test/CodeGen/init.c
@@ -40,3 +40,9 @@
     .x = value.x
   }};
 }
+
+// rdar://problem/8154689
+void f6() {
+  int x;
+  long ids[] = { (long) &x };  
+}
diff --git a/test/CodeGen/inline.c b/test/CodeGen/inline.c
index a17b069..a6b4b3e 100644
--- a/test/CodeGen/inline.c
+++ b/test/CodeGen/inline.c
@@ -1,5 +1,5 @@
 // RUN: echo "GNU89 tests:"
-// RUN: %clang %s -emit-llvm -S -o %t -std=gnu89
+// RUN: %clang %s -O1 -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
@@ -14,7 +14,7 @@
 // RUN: grep "define available_externally i32 @test5" %t
 
 // RUN: echo "\nC99 tests:"
-// RUN: %clang %s -emit-llvm -S -o %t -std=c99
+// RUN: %clang %s -O1 -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
@@ -29,7 +29,7 @@
 // RUN: grep "define available_externally i32 @test5" %t
 
 // RUN: echo "\nC++ tests:"
-// RUN: %clang %s -emit-llvm -S -o %t -std=c++98
+// RUN: %clang %s -O1 -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
diff --git a/test/CodeGen/inline2.c b/test/CodeGen/inline2.c
index 737b58f..fca4fff 100644
--- a/test/CodeGen/inline2.c
+++ b/test/CodeGen/inline2.c
@@ -1,5 +1,5 @@
-// 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
+// RUN: %clang_cc1 -O1 -std=gnu89 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix GNU89 %s
+// RUN: %clang_cc1 -O1 -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()
diff --git a/test/CodeGen/instrument-functions.c b/test/CodeGen/instrument-functions.c
new file mode 100644
index 0000000..d80385e
--- /dev/null
+++ b/test/CodeGen/instrument-functions.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -S -emit-llvm -o - %s -finstrument-functions | FileCheck %s
+
+// CHECK: @test1
+int test1(int x) {
+// CHECK: __cyg_profile_func_enter
+// CHECK: __cyg_profile_func_exit
+// CHECK: ret
+  return x;
+}
+
+// CHECK: @test2
+int test2(int) __attribute__((no_instrument_function));
+int test2(int x) {
+// CHECK-NOT: __cyg_profile_func_enter
+// CHECK-NOT: __cyg_profile_func_exit
+// CHECK: ret
+  return x;
+}
diff --git a/test/CodeGen/integer-overflow.c b/test/CodeGen/integer-overflow.c
new file mode 100644
index 0000000..9bed741
--- /dev/null
+++ b/test/CodeGen/integer-overflow.c
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s --check-prefix=DEFAULT
+// RUN: %clang_cc1 %s -emit-llvm -o - -fwrapv | FileCheck %s --check-prefix=WRAPV
+// RUN: %clang_cc1 %s -emit-llvm -o - -ftrapv | FileCheck %s --check-prefix=TRAPV
+
+
+// Tests for signed integer overflow stuff.
+// rdar://7432000 rdar://7221421
+void test1() {
+  // DEFAULT: define void @test1
+  // WRAPV: define void @test1
+  // TRAPV: define void @test1
+  extern volatile int f11G, a, b;
+  
+  // DEFAULT: add nsw i32
+  // WRAPV: add i32
+  // TRAPV: llvm.sadd.with.overflow.i32
+  f11G = a + b;
+  
+  // DEFAULT: sub nsw i32
+  // WRAPV: sub i32
+  // TRAPV: llvm.ssub.with.overflow.i32
+  f11G = a - b;
+  
+  // DEFAULT: mul nsw i32
+  // WRAPV: mul i32
+  // TRAPV: llvm.smul.with.overflow.i32
+  f11G = a * b;
+
+  // DEFAULT: sub nsw i32 0, 
+  // WRAPV: sub i32 0, 
+  // TRAPV: llvm.ssub.with.overflow.i32(i32 0
+  f11G = -a;
+  
+  // PR7426 - Overflow checking for increments.
+  
+  // DEFAULT: add nsw i32 {{.*}}, 1
+  // WRAPV: add i32 {{.*}}, 1
+  // TRAPV: llvm.sadd.with.overflow.i32({{.*}}, i32 1)
+  ++a;
+  
+  // DEFAULT: add nsw i32 {{.*}}, -1
+  // WRAPV: add i32 {{.*}}, -1
+  // TRAPV: llvm.sadd.with.overflow.i32({{.*}}, i32 -1)
+  --a;
+}
diff --git a/test/CodeGen/lineno-dbginfo.c b/test/CodeGen/lineno-dbginfo.c
index c5c350f..176d415 100644
--- a/test/CodeGen/lineno-dbginfo.c
+++ b/test/CodeGen/lineno-dbginfo.c
@@ -1,6 +1,5 @@
 // RUN: echo "#include <stdio.h>" > %t.h
-// RUN: %clang -S -save-temps -g -include %t.h %s -emit-llvm -o %t.ll
+// RUN: %clang -S -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/microsoft-call-conv.c b/test/CodeGen/microsoft-call-conv.c
new file mode 100644
index 0000000..95f5fa3
--- /dev/null
+++ b/test/CodeGen/microsoft-call-conv.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s
+
+void __fastcall f1(void);
+void __stdcall f2(void);
+void __thiscall f3(void);
+void __fastcall f4(void) {
+// CHECK: define x86_fastcallcc void @f4()
+  f1();
+// CHECK: call x86_fastcallcc void @f1()
+}
+void __stdcall f5(void) {
+// CHECK: define x86_stdcallcc void @f5()
+  f2();
+// CHECK: call x86_stdcallcc void @f2()
+}
+void __thiscall f6(void) {
+// CHECK: define x86_thiscallcc void @f6()
+  f3();
+// CHECK: call x86_thiscallcc void @f3()
+}
+
+// PR5280
+void (__fastcall *pf1)(void) = f1;
+void (__stdcall *pf2)(void) = f2;
+void (__thiscall *pf3)(void) = f3;
+void (__fastcall *pf4)(void) = f4;
+void (__stdcall *pf5)(void) = f5;
+void (__thiscall *pf6)(void) = f6;
+
+int main(void) {
+    f4(); f5(); f6();
+    // CHECK: call x86_fastcallcc void @f4()
+    // CHECK: call x86_stdcallcc void @f5()
+    // CHECK: call x86_thiscallcc void @f6()
+    pf1(); pf2(); pf3(); pf4(); pf5(); pf6();
+    // CHECK: call x86_fastcallcc void %{{.*}}()
+    // CHECK: call x86_stdcallcc void %{{.*}}()
+    // CHECK: call x86_thiscallcc void %{{.*}}()
+    // CHECK: call x86_fastcallcc void %{{.*}}()
+    // CHECK: call x86_stdcallcc void %{{.*}}()
+    // CHECK: call x86_thiscallcc void %{{.*}}()
+    return 0;
+}
+
+// PR7117
+void __stdcall f7(foo) int foo; {}
+void f8(void) {
+  f7(0);
+  // CHECK: call x86_stdcallcc void (...)* bitcast
+}
diff --git a/test/CodeGen/object-size.c b/test/CodeGen/object-size.c
index 3920ec5..287d742 100644
--- a/test/CodeGen/object-size.c
+++ b/test/CodeGen/object-size.c
@@ -13,32 +13,38 @@
 char *gp;
 int gi, gj;
 
+// CHECK: define void @test1
 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");
 }
 
+// CHECK: define void @test2
 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");
 }
 
+// CHECK: define void @test3
 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");
 }
 
+// CHECK: define void @test4
 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");
 }
 
+// CHECK: define void @test5
 void test5() {
   // CHECK:     = load i8** @gp
   // CHECK-NEXT:= call i64 @llvm.objectsize.i64(i8* %{{.*}}, i1 false)
   strcpy(gp, "Hi there");
 }
 
+// CHECK: define void @test6
 void test6() {
   char buf[57];
 
@@ -46,6 +52,7 @@
   strcpy(&buf[4], "Hi there");
 }
 
+// CHECK: define void @test7
 void test7() {
   int i;
   // CHECK-NOT:   __strcpy_chk
@@ -53,6 +60,7 @@
   strcpy((++i, gbuf), "Hi there");
 }
 
+// CHECK: define void @test8
 void test8() {
   char *buf[50];
   // CHECK-NOT:   __strcpy_chk
@@ -60,12 +68,14 @@
   strcpy(buf[++gi], "Hi there");
 }
 
+// CHECK: define void @test9
 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");
 }
 
+// CHECK: define void @test10
 char **p;
 void test10() {
   // CHECK-NOT:   __strcpy_chk
@@ -73,36 +83,42 @@
   strcpy(*(++p), "Hi there");
 }
 
+// CHECK: define void @test11
 void test11() {
   // CHECK-NOT:   __strcpy_chk
-  // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
+  // 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(gp = gbuf, "Hi there");
 }
 
+// CHECK: define void @test12
 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");
 }
 
+// CHECK: define void @test13
 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");
 }
 
+// CHECK: define void @test14
 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");
 }
 
+// CHECK: define void @test15
 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");
 }
 
+// CHECK: define void @test16
 void test16() {
   // CHECK-NOT:   __strcpy_chk
   // CHECK:       = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0))
diff --git a/test/CodeGen/packed-structure.c b/test/CodeGen/packed-structure.c
new file mode 100644
index 0000000..2934d01
--- /dev/null
+++ b/test/CodeGen/packed-structure.c
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -triple x86_64 -emit-llvm -o - %s | opt -S -strip -o %t
+// RUX: llvm-gcc -flto -S -O3 -o %t %s
+// RUN: FileCheck --check-prefix=CHECK-GLOBAL < %t %s
+// RUN: FileCheck --check-prefix=CHECK-FUNCTIONS < %t %s
+
+struct s0 {
+  int x;
+  int y __attribute__((packed));
+};
+
+// CHECK-GLOBAL: @s0_align_x = global i32 4
+
+// FIXME: This should be 1 to match gcc. PR7951.
+// CHECK-GLOBAL: @s0_align_y = global i32 4
+
+// CHECK-GLOBAL: @s0_align = global i32 4
+int s0_align_x = __alignof(((struct s0*)0)->x);
+int s0_align_y = __alignof(((struct s0*)0)->y);
+int s0_align   = __alignof(struct s0);
+
+// CHECK-FUNCTIONS: define i32 @s0_load_x
+// CHECK-FUNCTIONS: [[s0_load_x:%.*]] = load i32* {{.*}}, align 4
+// CHECK-FUNCTIONS: ret i32 [[s0_load_x]]
+int s0_load_x(struct s0 *a) { return a->x; }
+// FIXME: This seems like it should be align 1. This is actually something which
+// has changed in llvm-gcc recently, previously both x and y would be loaded
+// with align 1 (in 2363.1 at least).
+//
+// CHECK-FUNCTIONS: define i32 @s0_load_y
+// CHECK-FUNCTIONS: [[s0_load_y:%.*]] = load i32* {{.*}}, align 4
+// CHECK-FUNCTIONS: ret i32 [[s0_load_y]]
+int s0_load_y(struct s0 *a) { return a->y; }
+// CHECK-FUNCTIONS: define void @s0_copy
+// CHECK-FUNCTIONS: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 8, i32 4, i1 false)
+void s0_copy(struct s0 *a, struct s0 *b) { *b = *a; }
+
+//
+
+struct s1 {
+  int x;
+  int y;
+} __attribute__((packed));
+
+// CHECK-GLOBAL: @s1_align_x = global i32 1
+// CHECK-GLOBAL: @s1_align_y = global i32 1
+// CHECK-GLOBAL: @s1_align = global i32 1
+int s1_align_x = __alignof(((struct s1*)0)->x);
+int s1_align_y = __alignof(((struct s1*)0)->y);
+int s1_align   = __alignof(struct s1);
+
+// CHECK-FUNCTIONS: define i32 @s1_load_x
+// CHECK-FUNCTIONS: [[s1_load_x:%.*]] = load i32* {{.*}}, align 1
+// CHECK-FUNCTIONS: ret i32 [[s1_load_x]]
+int s1_load_x(struct s1 *a) { return a->x; }
+// CHECK-FUNCTIONS: define i32 @s1_load_y
+// CHECK-FUNCTIONS: [[s1_load_y:%.*]] = load i32* {{.*}}, align 1
+// CHECK-FUNCTIONS: ret i32 [[s1_load_y]]
+int s1_load_y(struct s1 *a) { return a->y; }
+// CHECK-FUNCTIONS: define void @s1_copy
+// CHECK-FUNCTIONS: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 8, i32 1, i1 false)
+void s1_copy(struct s1 *a, struct s1 *b) { *b = *a; }
+
+//
+
+#pragma pack(push,2)
+struct s2 {
+  int x;
+  int y;
+};
+#pragma pack(pop)
+
+// CHECK-GLOBAL: @s2_align_x = global i32 2
+// CHECK-GLOBAL: @s2_align_y = global i32 2
+// CHECK-GLOBAL: @s2_align = global i32 2
+int s2_align_x = __alignof(((struct s2*)0)->x);
+int s2_align_y = __alignof(((struct s2*)0)->y);
+int s2_align   = __alignof(struct s2);
+
+// CHECK-FUNCTIONS: define i32 @s2_load_x
+// CHECK-FUNCTIONS: [[s2_load_y:%.*]] = load i32* {{.*}}, align 2
+// CHECK-FUNCTIONS: ret i32 [[s2_load_y]]
+int s2_load_x(struct s2 *a) { return a->x; }
+// CHECK-FUNCTIONS: define i32 @s2_load_y
+// CHECK-FUNCTIONS: [[s2_load_y:%.*]] = load i32* {{.*}}, align 2
+// CHECK-FUNCTIONS: ret i32 [[s2_load_y]]
+int s2_load_y(struct s2 *a) { return a->y; }
+// CHECK-FUNCTIONS: define void @s2_copy
+// CHECK-FUNCTIONS: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 8, i32 2, i1 false)
+void s2_copy(struct s2 *a, struct s2 *b) { *b = *a; }
diff --git a/test/CodeGen/pascal-wchar-string.c b/test/CodeGen/pascal-wchar-string.c
new file mode 100644
index 0000000..89e4de4
--- /dev/null
+++ b/test/CodeGen/pascal-wchar-string.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -emit-llvm -o -  %s -fpascal-strings -fshort-wchar  | FileCheck %s
+// rdar: // 8020384
+
+extern void abort (void);
+
+typedef unsigned short UInt16;
+
+typedef UInt16 UniChar;
+
+int main(int argc, char* argv[])
+{
+
+        char st[] = "\pfoo";            // pascal string
+        UniChar wt[] = L"\pbar";        // pascal Unicode string
+	UniChar wt1[] = L"\p";
+	UniChar wt2[] = L"\pgorf";
+
+        if (st[0] != 3)
+          abort ();
+        if (wt[0] != 3)
+          abort ();
+        if (wt1[0] != 0)
+          abort ();
+        if (wt2[0] != 4)
+          abort ();
+        
+        return 0;
+}
+
+// CHECK: c"\03\00b\00a\00r\00\00\00"
+// CHECK: c"\04\00g\00o\00r\00f\00\00\00"
diff --git a/test/CodeGen/pragma-pack-1.c b/test/CodeGen/pragma-pack-1.c
index f5d3016..c30a62a 100644
--- a/test/CodeGen/pragma-pack-1.c
+++ b/test/CodeGen/pragma-pack-1.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - 
+// RUN: %clang_cc1 -emit-llvm -o - %s
 
 // PR4610
 #pragma pack(4)
diff --git a/test/CodeGen/pragma-visibility.c b/test/CodeGen/pragma-visibility.c
new file mode 100644
index 0000000..16460a2
--- /dev/null
+++ b/test/CodeGen/pragma-visibility.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+#pragma GCC visibility push(hidden)
+int x = 2;
+// CHECK: @x = hidden global
+
+extern int y;
+#pragma GCC visibility pop
+int y = 4;
+// CHECK: @y = hidden global
+
+#pragma GCC visibility push(hidden)
+extern __attribute((visibility("default"))) int z;
+int z = 0;
+// CHECK: @z = global
+#pragma GCC visibility pop
+
+#pragma GCC visibility push(hidden)
+void f() {}
+// CHECK: define hidden void @f
+
+__attribute((visibility("default"))) void g();
+void g() {}
+// CHECK: define void @g
diff --git a/test/CodeGen/regparm.c b/test/CodeGen/regparm.c
index b60f8c7..ec5cbab 100644
--- a/test/CodeGen/regparm.c
+++ b/test/CodeGen/regparm.c
@@ -14,6 +14,11 @@
 static void FASTCALL
 reduced(char b, double c, foo* d, double e, int f);
 
+// PR7025
+void FASTCALL f1(int i, int j, int k);
+// CHECK: define void @f1(i32 inreg %i, i32 inreg %j, i32 %k)
+void f1(int i, int j, int k) { }
+
 int
 main(void) {
   // CHECK: call void @reduced(i8 signext inreg 0, {{.*}} %struct.anon* inreg null
diff --git a/test/CodeGen/statements.c b/test/CodeGen/statements.c
index e3835f0..0ea0597 100644
--- a/test/CodeGen/statements.c
+++ b/test/CodeGen/statements.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 < %s -emit-llvm
+// RUN: %clang_cc1 -Wreturn-type %s -emit-llvm -o /dev/null
 
 void test1(int x) {
 switch (x) {
@@ -31,5 +31,10 @@
 }
 
 // PR3869
-int test5(long long b) { goto *b; }
+int test5(long long b) {
+  static void *lbls[] = { &&lbl };
+  goto *b;
+ lbl:
+  return 0;
+}
 
diff --git a/test/CodeGen/staticinit.c b/test/CodeGen/staticinit.c
index cd1f059..8c5cdd0 100644
--- a/test/CodeGen/staticinit.c
+++ b/test/CodeGen/staticinit.c
@@ -29,3 +29,13 @@
 // RUN: grep "f1.l0 = internal global i32 ptrtoint (i32 ()\* @f1 to i32)" %t
 int f1(void) { static int l0 = (unsigned) f1; }
 
+// PR7044
+char *f2(char key) {
+  switch (key) {
+    static char _msg[40];
+  case '\014':
+    return _msg;
+  }
+
+  return 0;
+}
diff --git a/test/CodeGen/stdcall-fastcall.c b/test/CodeGen/stdcall-fastcall.c
index bea6df3..6f3b003 100644
--- a/test/CodeGen/stdcall-fastcall.c
+++ b/test/CodeGen/stdcall-fastcall.c
@@ -2,32 +2,49 @@
 
 void __attribute__((fastcall)) f1(void);
 void __attribute__((stdcall)) f2(void);
-void __attribute__((fastcall)) f3(void) {
-// CHECK: define x86_fastcallcc void @f3()
+void __attribute__((thiscall)) f3(void);
+void __attribute__((fastcall)) f4(void) {
+// CHECK: define x86_fastcallcc void @f4()
   f1();
 // CHECK: call x86_fastcallcc void @f1()
 }
-void __attribute__((stdcall)) f4(void) {
-// CHECK: define x86_stdcallcc void @f4()
+void __attribute__((stdcall)) f5(void) {
+// CHECK: define x86_stdcallcc void @f5()
   f2();
 // CHECK: call x86_stdcallcc void @f2()
 }
+void __attribute__((thiscall)) f6(void) {
+// CHECK: define x86_thiscallcc void @f6()
+  f3();
+// CHECK: call x86_thiscallcc void @f3()
+}
 
 // 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;
+void (__attribute__((thiscall)) *pf3)(void) = f3;
+void (__attribute__((fastcall)) *pf4)(void) = f4;
+void (__attribute__((stdcall)) *pf5)(void) = f5;
+void (__attribute__((thiscall)) *pf6)(void) = f6;
 
 int main(void) {
-    f3(); f4();
-    // CHECK: call x86_fastcallcc void @f3()
-    // CHECK: call x86_stdcallcc void @f4()
-    pf1(); pf2(); pf3(); pf4();
+    f4(); f5(); f6();
+    // CHECK: call x86_fastcallcc void @f4()
+    // CHECK: call x86_stdcallcc void @f5()
+    // CHECK: call x86_thiscallcc void @f6()
+    pf1(); pf2(); pf3(); pf4(); pf5(); pf6();
     // CHECK: call x86_fastcallcc void %{{.*}}()
     // CHECK: call x86_stdcallcc void %{{.*}}()
+    // CHECK: call x86_thiscallcc void %{{.*}}()
     // CHECK: call x86_fastcallcc void %{{.*}}()
     // CHECK: call x86_stdcallcc void %{{.*}}()
+    // CHECK: call x86_thiscallcc void %{{.*}}()
     return 0;
 }
 
+// PR7117
+void __attribute((stdcall)) f7(foo) int foo; {}
+void f8(void) {
+  f7(0);
+  // CHECK: call x86_stdcallcc void (...)* bitcast
+}
diff --git a/test/CodeGen/struct-init.c b/test/CodeGen/struct-init.c
index 88b57a2..926e5a7 100644
--- a/test/CodeGen/struct-init.c
+++ b/test/CodeGen/struct-init.c
@@ -10,3 +10,11 @@
 const zend_ini_entry ini_entries[] = {
   {  ((char*)&((zend_ini_entry*)0)->mh_arg1 - (char*)(void*)0)},
 };
+
+// PR7564
+struct GLGENH {
+  int : 27;
+  int EMHJAA : 1;
+};
+
+struct GLGENH ABHFBF = {1};
diff --git a/test/CodeGen/thread-specifier.c b/test/CodeGen/thread-specifier.c
index b1e1ed8..a16103f 100644
--- a/test/CodeGen/thread-specifier.c
+++ b/test/CodeGen/thread-specifier.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -o - %s | grep thread_local | count 4
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -o - %s | not grep common
 
 __thread int a;
 extern __thread int b;
diff --git a/test/CodeGen/trapv.c b/test/CodeGen/trapv.c
index d10d617..7f192c6 100644
--- a/test/CodeGen/trapv.c
+++ b/test/CodeGen/trapv.c
@@ -1,10 +1,51 @@
-// RUN: %clang_cc1 -ftrapv %s -emit-llvm -o %t
-// RUN: grep "__overflow_handler" %t | count 2
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -ftrapv %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: [[I32O:%.*]] = type { i32, i1 }
 
 unsigned int ui, uj, uk;
 int i, j, k;
 
-void foo() {
+// CHECK: define void @test0()
+void test0() {
+  // -ftrapv doesn't affect unsigned arithmetic.
+  // CHECK:      [[T1:%.*]] = load i32* @uj
+  // CHECK-NEXT: [[T2:%.*]] = load i32* @uk
+  // CHECK-NEXT: [[T3:%.*]] = add i32 [[T1]], [[T2]]
+  // CHECK-NEXT: store i32 [[T3]], i32* @ui
   ui = uj + uk;
+
+  // CHECK:      [[T1:%.*]] = load i32* @j
+  // CHECK-NEXT: [[T2:%.*]] = load i32* @k
+  // CHECK-NEXT: [[T3:%.*]] = call [[I32O]] @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 [[T2]])
+  // CHECK-NEXT: [[T4:%.*]] = extractvalue [[I32O]] [[T3]], 0
+  // CHECK-NEXT: [[T5:%.*]] = extractvalue [[I32O]] [[T3]], 1
+  // CHECK-NEXT: br i1 [[T5]]
+  // CHECK:      call void @llvm.trap()
   i = j + k;
 }
+
+// CHECK: define void @test1()
+void test1() {
+  extern void opaque(int);
+  opaque(i++);
+
+  // CHECK:      [[T1:%.*]] = load i32* @i
+  // CHECK-NEXT: [[T2:%.*]] = call [[I32O]] @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 1)
+  // CHECK-NEXT: [[T3:%.*]] = extractvalue [[I32O]] [[T2]], 0
+  // CHECK-NEXT: [[T4:%.*]] = extractvalue [[I32O]] [[T2]], 1
+  // CHECK-NEXT: br i1 [[T4]]
+  // CHECK:      call void @llvm.trap()
+}
+
+// CHECK: define void @test2()
+void test2() {
+  extern void opaque(int);
+  opaque(++i);
+
+  // CHECK:      [[T1:%.*]] = load i32* @i
+  // CHECK-NEXT: [[T2:%.*]] = call [[I32O]] @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 1)
+  // CHECK-NEXT: [[T3:%.*]] = extractvalue [[I32O]] [[T2]], 0
+  // CHECK-NEXT: [[T4:%.*]] = extractvalue [[I32O]] [[T2]], 1
+  // CHECK-NEXT: br i1 [[T4]]
+  // CHECK:      call void @llvm.trap()
+}
diff --git a/test/CodeGen/typedef-func.c b/test/CodeGen/typedef-func.c
index bc08b35..1467e8b 100644
--- a/test/CodeGen/typedef-func.c
+++ b/test/CodeGen/typedef-func.c
@@ -2,7 +2,7 @@
 
 // PR2414
 struct mad_frame{};
-enum mad_flow {};
+enum mad_flow {ont};
 
 typedef enum mad_flow filter_func_t(void *, struct mad_frame *);
 
diff --git a/test/CodeGen/unwind-attr.c b/test/CodeGen/unwind-attr.c
index ee3199d..c588ca8 100644
--- a/test/CodeGen/unwind-attr.c
+++ b/test/CodeGen/unwind-attr.c
@@ -1,6 +1,24 @@
-// RUN: %clang_cc1 -fexceptions -emit-llvm -o - %s | grep "@foo()" | not grep nounwind
-// RUN: %clang_cc1 -emit-llvm -o - %s | grep "@foo()" | grep nounwind 
+// RUN: %clang_cc1 -fexceptions -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck -check-prefix NOEXC %s
 
-int foo(void) {
+int opaque();
+
+// CHECK:       define [[INT:i.*]] @test0() {
+// CHECK-NOEXC: define [[INT:i.*]] @test0() nounwind {
+int test0(void) {
+  return opaque();
+}
+
+// <rdar://problem/8087431>: locally infer nounwind at -O0
+// CHECK:       define [[INT:i.*]] @test1() nounwind {
+// CHECK-NOEXC: define [[INT:i.*]] @test1() nounwind {
+int test1(void) {
+  return 0;
+}
+
+// <rdar://problem/8283071>: not for weak functions
+// CHECK:       define weak [[INT:i.*]] @test2() {
+// CHECK-NOEXC: define weak [[INT:i.*]] @test2() nounwind {
+__attribute__((weak)) int test2(void) {
   return 0;
 }
diff --git a/test/CodeGen/vector.c b/test/CodeGen/vector.c
index c16d65b..3fa5f14 100644
--- a/test/CodeGen/vector.c
+++ b/test/CodeGen/vector.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -target-cpu pentium4 -g -emit-llvm %s -o -
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -O1 -target-cpu pentium4 -target-feature +sse4.1 -g -emit-llvm %s -o - | FileCheck %s
 typedef short __v4hi __attribute__ ((__vector_size__ (8)));
 
 void test1() {
@@ -20,6 +20,8 @@
 
 
 
+// Don't include mm_malloc.h, it's system specific.
+#define __MM_MALLOC_H
 
 #include <mmintrin.h>
 
@@ -40,3 +42,16 @@
 
   return result;
 }
+
+#include <smmintrin.h>
+
+unsigned long test_epi8(__m128i x) { return _mm_extract_epi8(x, 4); }
+// CHECK: @test_epi8
+// CHECK: extractelement <16 x i8> {{.*}}, i32 4
+// CHECK: zext i8 {{.*}} to i32
+
+unsigned long test_epi16(__m128i x) { return _mm_extract_epi16(x, 3); }
+
+// CHECK: @test_epi16
+// CHECK: extractelement <8 x i16> {{.*}}, i32 3
+// CHECK: zext i16 {{.*}} to i32
diff --git a/test/CodeGen/volatile.c b/test/CodeGen/volatile.c
index db87a37..1a996de 100644
--- a/test/CodeGen/volatile.c
+++ b/test/CodeGen/volatile.c
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -emit-llvm < %s -o %t
-// RUN: grep volatile %t | count 29
+// RUN: grep volatile %t | count 28
 // RUN: grep memcpy %t | count 7
 
-// The number 29 comes from the current codegen for volatile loads;
+// The number 28 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
 
@@ -64,7 +64,7 @@
   i=vV[3];
   i=VE.yx[1];
   i=vVE.zy[1];
-  i = aggFct().x;
+  i = aggFct().x; // Note: not volatile
   i=vtS;
 
 
diff --git a/test/CodeGen/x86_32-arguments.c b/test/CodeGen/x86_32-arguments.c
index 01c3e23..19a0f52 100644
--- a/test/CodeGen/x86_32-arguments.c
+++ b/test/CodeGen/x86_32-arguments.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -triple i386-apple-darwin9 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -w -fblocks -triple i386-apple-darwin9 -emit-llvm -o %t %s
 // RUN: FileCheck < %t %s
 
 // CHECK: define signext i8 @f0()
@@ -214,3 +214,10 @@
   int y;
 };
 void f53(struct s53 x) {}
+
+typedef unsigned short v2i16 __attribute__((__vector_size__(4)));
+
+// CHECK: define i32 @f54(i32 %arg.coerce)
+// rdar://8359483
+v2i16 f54(v2i16 arg) { return arg+arg; }
+
diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c
index 47b2eb1..51a234d 100644
--- a/test/CodeGen/x86_64-arguments.c
+++ b/test/CodeGen/x86_64-arguments.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o %t %s
-// RUN: FileCheck < %t %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s| FileCheck %s
+#include <stdarg.h>
 
 // CHECK: %0 = type { i64, double }
 
@@ -45,7 +45,7 @@
 // Test merging/passing of upper eightbyte with X87 class.
 //
 // CHECK: define %0 @f8_1()
-// CHECK: define void @f8_2(%0)
+// CHECK: define void @f8_2(i64 %a0.coerce0, double %a0.coerce1)
 union u8 {
   long double a;
   int b;
@@ -56,22 +56,22 @@
 // CHECK: define i64 @f9()
 struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} }
 
-// CHECK: define void @f10(i64)
+// CHECK: define void @f10(i64 %a0.coerce)
 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)
+// CHECK: define i32 @f12_0()
+// CHECK: define void @f12_1(i32 %a0.coerce)
 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)
+// CHECK: define void @f13(%struct.s13_0* sret %agg.result, i32 %a, i32 %b, i32 %c, i32 %d, {{.*}}* byval %e, i32 %f)
 
 struct s13_0 { long long f0[3]; };
 struct s13_1 { long long f0[2]; };
@@ -92,10 +92,10 @@
 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
+// Check for valid coercion.  The struct should be passed/returned as i32, not
+// as i64 for better code quality.
+// rdar://8135035
+// CHECK: define void @f18(i32 %a, i32 %f18_arg1.coerce) 
 struct f18_s0 { int f0; };
 void f18(int a, struct f18_s0 f18_arg1) { while (1) {} }
 
@@ -113,3 +113,135 @@
   int y;
 };
 void f20(struct s20 x) {}
+
+struct StringRef {
+  long x;
+  const char *Ptr;
+};
+
+// rdar://7375902
+// CHECK: define i8* @f21(i64 %S.coerce0, i8* %S.coerce1) 
+const char *f21(struct StringRef S) { return S.x+S.Ptr; }
+
+// PR7567
+typedef __attribute__ ((aligned(16))) struct f22s { unsigned long long x[2]; } L;
+void f22(L x, L y) { }
+// CHECK: @f22
+// CHECK: %x = alloca{{.*}}, align 16
+// CHECK: %y = alloca{{.*}}, align 16
+
+
+
+// PR7714
+struct f23S {
+  short f0;
+  unsigned f1;
+  int f2;
+};
+
+
+void f23(int A, struct f23S B) {
+  // CHECK: define void @f23(i32 %A, i64 %B.coerce0, i32 %B.coerce1)
+}
+
+struct f24s { long a; int b; };
+
+struct f23S f24(struct f23S *X, struct f24s *P2) {
+  return *X;
+  
+  // CHECK: define %struct.f24s @f24(%struct.f23S* %X, %struct.f24s* %P2)
+}
+
+// rdar://8248065
+typedef float v4f32 __attribute__((__vector_size__(16)));
+v4f32 f25(v4f32 X) {
+  // CHECK: define <4 x float> @f25(<4 x float> %X)
+  // CHECK-NOT: alloca
+  // CHECK: alloca <4 x float>
+  // CHECK-NOT: alloca
+  // CHECK: store <4 x float> %X, <4 x float>*
+  // CHECK-NOT: store
+  // CHECK: ret <4 x float>
+  return X+X;
+}
+
+struct foo26 {
+  int *X;
+  float *Y;
+};
+
+struct foo26 f26(struct foo26 *P) {
+  // CHECK: define %struct.foo26 @f26(%struct.foo26* %P)
+  return *P;
+}
+
+
+struct v4f32wrapper {
+  v4f32 v;
+};
+
+struct v4f32wrapper f27(struct v4f32wrapper X) {
+  // CHECK: define <4 x float> @f27(<4 x float> %X.coerce)
+  return X;
+}
+
+// rdar://5711709
+struct f28c {
+  double x;
+  int y;
+};
+void f28(struct f28c C) {
+  // CHECK: define void @f28(double %C.coerce0, i32 %C.coerce1)
+}
+
+struct f29a {
+  struct c {
+    double x;
+    int y;
+  } x[1];
+};
+
+void f29a(struct f29a A) {
+  // CHECK: define void @f29a(double %A.coerce0, i32 %A.coerce1)
+}
+
+// rdar://8249586
+struct S0 { char f0[8]; char f2; char f3; char f4; };
+void f30(struct S0 p_4) {
+  // CHECK: define void @f30(i64 %p_4.coerce0, i24 %p_4.coerce1)
+}
+
+// Pass the third element as a float when followed by tail padding.
+// rdar://8251384
+struct f31foo { float a, b, c; };
+float f31(struct f31foo X) {
+  // CHECK: define float @f31(<2 x float> %X.coerce0, float %X.coerce1)
+  return X.c;
+}
+
+_Complex float f32(_Complex float A, _Complex float B) {
+  // rdar://6379669
+  // CHECK: define <2 x float> @f32(<2 x float> %A.coerce, <2 x float> %B.coerce)
+  return A+B;
+}
+
+
+// rdar://8357396
+struct f33s { long x; float c,d; };
+
+void f33(va_list X) {
+  va_arg(X, struct f33s);
+}
+
+typedef unsigned long long v1i64 __attribute__((__vector_size__(8)));
+
+// rdar://8359248
+// CHECK: define i64 @f34(i64 %arg.coerce)
+v1i64 f34(v1i64 arg) { return arg; }
+
+
+// rdar://8358475
+// CHECK: define i64 @f35(i64 %arg.coerce)
+typedef unsigned long v1i64_2 __attribute__((__vector_size__(8)));
+v1i64_2 f35(v1i64_2 arg) { return arg+arg; }
+
diff --git a/test/CodeGenCXX/DynArrayInit.cpp b/test/CodeGenCXX/DynArrayInit.cpp
new file mode 100644
index 0000000..4b4c2ec
--- /dev/null
+++ b/test/CodeGenCXX/DynArrayInit.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -O3 -emit-llvm -o - %s | FileCheck %s
+// PR7490
+
+// CHECK: define signext i8 @_Z2f0v
+// CHECK: ret i8 0
+// CHECK: }
+inline void* operator new[](unsigned long, void* __p)  { return __p; }
+static void f0_a(char *a) {
+  new (a) char[4]();
+}
+char f0() {
+  char a[4];
+  f0_a(a);
+  return a[0] + a[1] + a[2] + a[3];
+}
diff --git a/test/CodeGenCXX/PR5863-unreachable-block.cpp b/test/CodeGenCXX/PR5863-unreachable-block.cpp
new file mode 100644
index 0000000..7709615
--- /dev/null
+++ b/test/CodeGenCXX/PR5863-unreachable-block.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+
+// PR5863
+class E { };
+
+void P1() {
+ try {
+  int a=0, b=0;
+  if (a > b) // simply filling in 0 or 1 doesn't trigger the assertion
+    throw E(); // commenting out 'if' or 'throw' 'fixes' the assertion failure
+  try { } catch (...) { } // empty try/catch block needed for failure
+ } catch (...) { } // this try/catch block needed for failure
+}
diff --git a/test/CodeGenCXX/PR6747.cpp b/test/CodeGenCXX/PR6747.cpp
deleted file mode 100644
index 5a07ce6..0000000
--- a/test/CodeGenCXX/PR6747.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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/address-of-fntemplate.cpp b/test/CodeGenCXX/address-of-fntemplate.cpp
index c5fa89d..162c6e5 100644
--- a/test/CodeGenCXX/address-of-fntemplate.cpp
+++ b/test/CodeGenCXX/address-of-fntemplate.cpp
@@ -11,3 +11,17 @@
 }
 // CHECK: define linkonce_odr void @_Z1fIiEvT_
 // CHECK: define linkonce_odr void @_Z1fIiEvv
+
+namespace PR6973 {
+  template<typename T>
+  struct X {
+    void f(const T&);
+  };
+
+  template<typename T>
+  int g();
+
+  void h(X<int (*)()> xf) {
+    xf.f(&g<int>);
+  }
+}
diff --git a/test/CodeGenCXX/alloca-align.cpp b/test/CodeGenCXX/alloca-align.cpp
index b70e366..99d6ab5 100644
--- a/test/CodeGenCXX/alloca-align.cpp
+++ b/test/CodeGenCXX/alloca-align.cpp
@@ -18,7 +18,7 @@
   (void) (struct s0) { 0, 0, 0, 0 };
 }
 
-// CHECK: define i64 @f2
+// CHECK: define i32 @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) {
diff --git a/test/CodeGenCXX/anonymous-namespaces.cpp b/test/CodeGenCXX/anonymous-namespaces.cpp
index 695f8f5..3ec7032 100644
--- a/test/CodeGenCXX/anonymous-namespaces.cpp
+++ b/test/CodeGenCXX/anonymous-namespaces.cpp
@@ -1,13 +1,14 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
-
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o - > %t
+// RUN: FileCheck %s -check-prefix=1 < %t
+// RUN: FileCheck %s -check-prefix=2 < %t
 
 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
+  // CHECK-1: @_ZN12_GLOBAL__N_11bE = internal global i32 0
+  // CHECK-1: @_ZN12_GLOBAL__N_1L1cE = internal global i32 0
+  // CHECK-1: @_ZN12_GLOBAL__N_11D1dE = internal global i32 0
+  // CHECK-1: @_ZN12_GLOBAL__N_11aE = internal global i32 0
   int a = 0;
 
   int b = f();
@@ -20,12 +21,19 @@
   
   int D::d = f();
 
-  // CHECK: define internal i32 @_ZN12_GLOBAL__N_13fooEv()
+  // Check for generation of a VTT with internal linkage
+  // CHECK-1: @_ZTSN12_GLOBAL__N_11X1EE = internal constant
+  struct X { 
+    struct EBase { };
+    struct E : public virtual EBase { virtual ~E() {} };
+  };
+
+  // CHECK-1: define internal i32 @_ZN12_GLOBAL__N_13fooEv()
   int foo() {
     return 32;
   }
 
-  // CHECK: define internal i32 @_ZN12_GLOBAL__N_11A3fooEv()
+  // CHECK-1: define internal i32 @_ZN12_GLOBAL__N_11A3fooEv()
   namespace A {
     int foo() {
       return 45;
@@ -36,3 +44,25 @@
 int concrete() {
   return a + foo() + A::foo();
 }
+
+void test_XE() { throw X::E(); }
+
+// Miscompile on llvmc plugins.
+namespace test2 {
+  struct A {
+    template <class T> struct B {
+      static void foo() {}
+    };
+  };
+  namespace {
+    struct C;
+  }
+
+  // CHECK-2: define void @_ZN5test24testEv()
+  // CHECK-2:   call void @_ZN5test21A1BINS_12_GLOBAL__N_11CEE3fooEv()
+  void test() {
+    A::B<C>::foo();
+  }
+
+  // CHECK-2: define internal void @_ZN5test21A1BINS_12_GLOBAL__N_11CEE3fooEv()
+}
diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
index ea3eafc..9ba3805 100644
--- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp
+++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s
 
 struct A {
   union {
@@ -10,3 +10,83 @@
 };
 
 A a;
+
+namespace PR7021 {
+  struct X
+  {
+    union { long l; };
+  };
+
+  // CHECK: define void @_ZN6PR70211fENS_1XES0_
+  void f(X x, X z) {
+    X x1;
+
+    // CHECK: store i64 1, i64
+    x1.l = 1;
+
+    // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+    X x2(x1);
+
+    X x3;
+    // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+    x3 = x1;
+
+    // CHECK: ret void
+  }
+}
+
+namespace test2 {
+  struct A {
+    struct {
+      union {
+        int b;
+      };
+    };
+
+    A();
+  };
+
+  A::A() : b(10) { }
+  // CHECK: define void @_ZN5test21AC2Ev(
+  // CHECK-NOT: }
+  // CHECK: store i32 10
+  // CHECK: }
+}
+
+namespace test3 {
+  struct A {
+    union {
+      mutable char fibers[100];
+      struct {
+        void (*callback)(void*);
+        void *callback_value;
+      };
+    };
+
+    A();
+  };
+
+  A::A() : callback(0), callback_value(0) {}
+  // CHECK: define void @ZN5test31AC2Ev(
+  // CHECK: [[THIS:%.*]] = load
+  // CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
+  // CHECK-NEXT: [[STRUCT:%.*]] = getelementptr inbounds {{.*}} [[UNION]], i32 0, i32 0
+  // CHECK-NEXT: [[CALLBACK:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 0
+  // CHECK-NEXT: store void (i8*)* null, void (i8*)** [[CALLBACK]]
+  // CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
+  // CHECK-NEXT: [[STRUCT:%.*]] = getelementptr inbounds {{.*}} [[UNION]], i32 0, i32 0
+  // CHECK-NEXT: [[CVALUE:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 0
+  // CHECK-NEXT: store i8* null, void i8** [[CVALUE]]
+}
+
+struct S {
+  // CHECK: store i32 42
+  // CHECK: store i32 55
+  S() : x(42), y(55) {}
+  union {
+    struct {
+      int x;
+      union { int y; };
+    };
+  };
+} s;
diff --git a/test/CodeGenCXX/arm-cc.cpp b/test/CodeGenCXX/arm-cc.cpp
new file mode 100644
index 0000000..6027746
--- /dev/null
+++ b/test/CodeGenCXX/arm-cc.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -triple=arm-unknown-linux-gnueabi -target-abi aapcs -emit-llvm -o - | FileCheck %s
+
+class SMLoc {
+ const char *Ptr;
+public:
+ SMLoc();
+ SMLoc(const SMLoc &RHS);
+};
+SMLoc foo(void *p);
+void bar(void *x) {
+ foo(x);
+}
+void zed(SMLoc x);
+void baz() {
+  SMLoc a;
+  zed(a);
+}
+
+// CHECK: declare void @_Z3fooPv(%class.SMLoc* sret, i8*)
+// CHECK: declare void @_Z3zed5SMLoc(%class.SMLoc*)
diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp
index 5cca788..1d4085c 100644
--- a/test/CodeGenCXX/arm.cpp
+++ b/test/CodeGenCXX/arm.cpp
@@ -16,5 +16,4 @@
 bar baz;
 
 // CHECK: @_GLOBAL__D_a()
-// CHECK: call arm_apcscc  void @_ZN3barD1Ev(%class.bar* @baz)
-
+// CHECK: call void @_ZN3barD1Ev(%class.bar* @baz)
diff --git a/test/CodeGenCXX/array-value-initialize.cpp b/test/CodeGenCXX/array-value-initialize.cpp
index 5fe6c20..8a3d5ff 100644
--- a/test/CodeGenCXX/array-value-initialize.cpp
+++ b/test/CodeGenCXX/array-value-initialize.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -emit-llvm -o - %s
 
 // PR5463
 extern "C" int printf(...);
@@ -21,8 +22,31 @@
         S sbar_[5];
 };
 
-int main(void)
-{
+int test1(void) {
         Foo a;
 }
 
+// PR7063
+
+
+struct Unit
+{
+  Unit() {}
+  Unit(const Unit& v)  {}
+};
+
+
+struct Stuff
+{
+  Unit leafPos[1];
+};
+
+
+int main()
+{
+  
+  Stuff a;
+  Stuff b = a;
+  
+  return 0;
+}
\ No newline at end of file
diff --git a/test/CodeGenCXX/block-destruct.cpp b/test/CodeGenCXX/block-destruct.cpp
new file mode 100644
index 0000000..f809ca2
--- /dev/null
+++ b/test/CodeGenCXX/block-destruct.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+
+struct A { ~A(); };
+
+void f() {
+  __block A a;
+}
+
+// CHECK: call void @_ZN1AD1Ev
diff --git a/test/CodeGenCXX/block-in-ctor-dtor.cpp b/test/CodeGenCXX/block-in-ctor-dtor.cpp
new file mode 100644
index 0000000..e4389a4
--- /dev/null
+++ b/test/CodeGenCXX/block-in-ctor-dtor.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+
+typedef void (^dispatch_block_t)(void);
+
+void dispatch_once(dispatch_block_t);
+
+class Zone {
+public:
+  Zone();
+  ~Zone();
+};
+
+Zone::Zone() {
+    dispatch_once(^{});
+    dispatch_once(^{});
+}
+
+Zone::~Zone() {
+    dispatch_once(^{});
+    dispatch_once(^{});
+}
+
+class X : public virtual Zone {
+  X();
+  ~X();
+};
+
+X::X() {
+    dispatch_once(^{});
+    dispatch_once(^{});
+};
+
+X::~X() {
+    dispatch_once(^{});
+    dispatch_once(^{});
+};
+
+
+// CHECK: define internal void @___ZN4ZoneC2Ev_block_invoke_
+// CHECK: define internal void @___ZN4ZoneC2Ev_block_invoke_
+// CHECK: define internal void @___ZN4ZoneD2Ev_block_invoke_
+// CHECK: define internal void @___ZN4ZoneD2Ev_block_invoke_
+// CHECK: define internal void @___ZN1XC1Ev_block_invoke_
+// CHECK: define internal void @___ZN1XC1Ev_block_invoke_
+// CHECK: define internal void @___ZN1XC2Ev_block_invoke_
+// CHECK: define internal void @___ZN1XC2Ev_block_invoke_
+// CHECK: define internal void @___ZN1XD2Ev_block_invoke_
+// CHECK: define internal void @___ZN1XD2Ev_block_invoke_
diff --git a/test/CodeGenCXX/c99-variable-length-array.cpp b/test/CodeGenCXX/c99-variable-length-array.cpp
new file mode 100644
index 0000000..66c14ff
--- /dev/null
+++ b/test/CodeGenCXX/c99-variable-length-array.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+struct X {
+  X();
+  ~X();
+};
+
+struct Y {
+  Y();
+  ~Y();
+};
+
+// CHECK: define void @_Z1fiPPKc(
+void f(int argc, const char* argv[]) {
+  // CHECK: call void @_ZN1XC1Ev
+  X x;
+  // CHECK: call i8* @llvm.stacksave(
+  const char *argv2[argc];
+  // CHECK: call void @_ZN1YC1Ev
+  Y y;
+  for (int i = 0; i != argc; ++i)
+    argv2[i] = argv[i];
+
+  // CHECK: call void @_ZN1YD1Ev
+  // CHECK: call void @llvm.stackrestore
+  // CHECK: call void @_ZN1XD1Ev
+  // CHECK: ret void
+}
diff --git a/test/CodeGenCXX/class-layout.cpp b/test/CodeGenCXX/class-layout.cpp
index 31091c5..9303bda 100644
--- a/test/CodeGenCXX/class-layout.cpp
+++ b/test/CodeGenCXX/class-layout.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
 
-// An extra byte shoudl be allocated for an empty class.
+// An extra byte should be allocated for an empty class.
 // CHECK: %struct.A = type { i8 }
 struct A { } a;
 
@@ -9,5 +9,5 @@
 struct B { void *a; int b; } b;
 
 // C should have a vtable pointer.
-// CHECK: %struct.C = type { i8**, i32 }
+// CHECK: %struct.C = type { i32 (...)**, i32 }
 struct C { virtual void f(); int a; } *c;
diff --git a/test/CodeGenCXX/condition.cpp b/test/CodeGenCXX/condition.cpp
index e435408..cc2eaf5 100644
--- a/test/CodeGenCXX/condition.cpp
+++ b/test/CodeGenCXX/condition.cpp
@@ -14,6 +14,7 @@
 
 struct X {
   X();
+  X(const X&);
   ~X();
   operator bool();
 };
@@ -23,6 +24,9 @@
   ~Y();
 };
 
+X getX();
+
+// CHECK: define void @_Z11if_destructi(
 void if_destruct(int z) {
   // Verify that the condition variable is destroyed at the end of the
   // "if" statement.
@@ -44,6 +48,14 @@
   // CHECK: call  void @_ZN1YD1Ev
   // CHECK: br
   // CHECK: call  void @_ZN1XD1Ev
+
+  // CHECK: call void @_Z4getXv
+  // CHECK: call zeroext i1 @_ZN1XcvbEv
+  // CHECK: call void @_ZN1XD1Ev
+  // CHECK: br
+  if (getX()) { }
+
+  // CHECK: ret
 }
 
 struct ConvertibleToInt {
@@ -52,6 +64,8 @@
   operator int();
 };
 
+ConvertibleToInt getConvToInt();
+
 void switch_destruct(int z) {
   // CHECK: call void @_ZN16ConvertibleToIntC1Ev
   switch (ConvertibleToInt conv = ConvertibleToInt()) {
@@ -59,52 +73,245 @@
     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;
+
+  // CHECK: call void @_Z12getConvToIntv
+  // CHECK: call i32 @_ZN16ConvertibleToIntcviEv
+  // CHECK: call void @_ZN16ConvertibleToIntD1Ev
+  switch(getConvToInt()) {
+  case 0:
+    break;
+  }
+  // CHECK: store i32 27
+  z = 27;
+  // CHECK: ret
 }
 
 int foo();
 
+// CHECK: define void @_Z14while_destructi
 void while_destruct(int z) {
-  // CHECK: define void @_Z14while_destructi
-  // CHECK: {{while.cond:|:2}}
+  // CHECK: [[Z:%.*]] = alloca i32
+  // CHECK: [[CLEANUPDEST:%.*]] = alloca i32
   while (X x = X()) {
     // CHECK: call void @_ZN1XC1Ev
+    // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv
+    // CHECK-NEXT: br i1 [[COND]]
 
-    // CHECK: {{while.body:|:4}}
-    // CHECK: store i32 21
+    // Loop-exit staging block.
+    // CHECK: store i32 3, i32* [[CLEANUPDEST]]
+    // CHECK-NEXT: br
+
+    // While body.
+    // CHECK: store i32 21, i32* [[Z]]
+    // CHECK: store i32 0, i32* [[CLEANUPDEST]]
+    // CHECK-NEXT: br
     z = 21;
 
-    // CHECK: {{while.cleanup:|:5}}
+    // Cleanup.
     // CHECK: call void @_ZN1XD1Ev
+    // CHECK-NEXT: [[DEST:%.*]] = load i32* [[CLEANUPDEST]]
+    // CHECK-NEXT: switch i32 [[DEST]]
   }
-  // CHECK: {{while.end|:7}}
-  // CHECK: store i32 22
+
+  // CHECK: store i32 22, i32* [[Z]]
   z = 22;
+
+  // CHECK: call void @_Z4getXv
+  // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv
+  // CHECK-NEXT: call void @_ZN1XD1Ev
+  // CHECK-NEXT: br
+  while(getX()) { }
+
+  // CHECK: store i32 25, i32* [[Z]]
+  z = 25;
+
+  // CHECK: ret
 }
 
+// CHECK: define void @_Z12for_destructi(
 void for_destruct(int z) {
-  // CHECK: define void @_Z12for_destruct
+  // CHECK: [[Z:%.*]] = alloca i32
+  // CHECK: [[CLEANUPDEST:%.*]] = alloca i32
+  // CHECK: [[I:%.*]] = alloca i32
   // CHECK: call void @_ZN1YC1Ev
-  for(Y y = Y(); X x = X(); ++z)
-    // CHECK: {{for.cond:|:2}}
+  // CHECK-NEXT: br
+  // -> %for.cond
+
+  for(Y y = Y(); X x = X(); ++z) {
+    // %for.cond: The loop condition.
     // CHECK: call void @_ZN1XC1Ev
-    // CHECK: {{for.body:|:4}}
-    // CHECK: store i32 23
+    // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv(
+    // CHECK-NEXT: br i1 [[COND]]
+    // -> %for.body, %for.cond.cleanup
+
+    // %for.cond.cleanup: Exit cleanup staging.
+    // CHECK: store i32 2, i32* [[CLEANUPDEST]]
+    // CHECK-NEXT: br
+    // -> %cleanup
+
+    // %for.body:
+    // CHECK: store i32 23, i32* [[Z]]
+    // CHECK-NEXT: br
+    // -> %for.inc
     z = 23;
-    // CHECK: {{for.inc:|:5}}
-    // CHECK: br label %{{for.cond.cleanup|8}}
-    // CHECK: {{for.cond.cleanup:|:8}}
+
+    // %for.inc:
+    // CHECK: [[TMP:%.*]] = load i32* [[Z]]
+    // CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1
+    // CHECK-NEXT: store i32 [[INC]], i32* [[Z]]
+    // CHECK-NEXT: store i32 0, i32* [[CLEANUPDEST]]
+    // CHECK-NEXT: br
+    // -> %cleanup
+
+    // %cleanup:  Destroys X.
     // CHECK: call void @_ZN1XD1Ev
-  // CHECK: {{for.end:|:10}}
-  // CHECK: call void @_ZN1YD1Ev
+    // CHECK-NEXT: [[YDESTTMP:%.*]] = load i32* [[CLEANUPDEST]]
+    // CHECK-NEXT: switch i32 [[YDESTTMP]]
+    // 0 -> %cleanup.cont, default -> %cleanup1
+
+    // %cleanup.cont:  (eliminable)
+    // CHECK: br
+    // -> %for.cond
+
+    // %cleanup1: Destroys Y.
+    // CHECK: call void @_ZN1YD1Ev(
+    // CHECK-NEXT: br
+    // -> %for.end
+  }
+
+  // %for.end:
   // CHECK: store i32 24
   z = 24;
+
+  // CHECK-NEXT: store i32 0, i32* [[I]]
+  // CHECK-NEXT: br
+  // -> %for.cond6
+
+  // %for.cond6:
+  // CHECK: call void @_Z4getXv
+  // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv
+  // CHECK-NEXT: call void @_ZN1XD1Ev
+  // CHECK-NEXT: br
+  // -> %for.body10, %for.end16
+
+  // %for.body10:
+  // CHECK: br
+  // -> %for.inc11
+
+  // %for.inc11:
+  // CHECK: call void @_Z4getXv
+  // CHECK-NEXT: load i32* [[I]]
+  // CHECK-NEXT: add
+  // CHECK-NEXT: store
+  // CHECK-NEXT: call void @_ZN1XD1Ev
+  // CHECK-NEXT: br
+  // -> %for.cond6
+  int i = 0;
+  for(; getX(); getX(), ++i) { }
+
+  // %for.end16
+  // CHECK: store i32 26
+  z = 26;
+
+  // CHECK-NEXT: ret void
 }
+
+void do_destruct(int z) {
+  // CHECK: define void @_Z11do_destruct
+  do {
+    // CHECK: store i32 77
+    z = 77;
+    // CHECK: call void @_Z4getXv
+    // CHECK: call zeroext i1 @_ZN1XcvbEv
+    // CHECK: call void @_ZN1XD1Ev
+    // CHECK: br
+  } while (getX());
+  // CHECK: store i32 99
+  z = 99;
+  // CHECK: ret
+}
+
+int f(X); 
+
+template<typename T>
+int instantiated(T x) { 
+  int result;
+
+  // CHECK: call void @_ZN1XC1ERKS_
+  // CHECK: call i32 @_Z1f1X
+  // CHECK: call void @_ZN1XD1Ev
+  // CHECK: br
+  // CHECK: store i32 2
+  // CHECK: br
+  // CHECK: store i32 3
+  if (f(x)) { result = 2; } else { result = 3; }
+
+  // CHECK: call void @_ZN1XC1ERKS_
+  // CHECK: call i32 @_Z1f1X
+  // CHECK: call void @_ZN1XD1Ev
+  // CHECK: br
+  // CHECK: store i32 4
+  // CHECK: br
+  while (f(x)) { result = 4; }
+
+  // CHECK: call void @_ZN1XC1ERKS_
+  // CHECK: call i32 @_Z1f1X
+  // CHECK: call void @_ZN1XD1Ev
+  // CHECK: br
+  // CHECK: store i32 6
+  // CHECK: br
+  // CHECK: call void @_ZN1XC1ERKS_
+  // CHECK: call i32 @_Z1f1X
+  // CHECK: store i32 5
+  // CHECK: call void @_ZN1XD1Ev
+  // CHECK: br
+  for (; f(x); f(x), result = 5) {
+    result = 6;
+  }
+
+  // CHECK: call void @_ZN1XC1ERKS_
+  // CHECK: call i32 @_Z1f1X
+  // CHECK: call void @_ZN1XD1Ev
+  // CHECK: switch i32
+  // CHECK: store i32 7
+  // CHECK: store i32 8
+  switch (f(x)) {
+  case 0: 
+    result = 7;
+    break;
+
+  case 1:
+    result = 8;
+  }
+
+  // CHECK: store i32 9
+  // CHECK: br
+  // CHECK: call void @_ZN1XC1ERKS_
+  // CHECK: call i32 @_Z1f1X
+  // CHECK: call void @_ZN1XD1Ev
+  // CHECK: br
+  do {
+    result = 9;
+  } while (f(x));
+
+  // CHECK: store i32 10
+  // CHECK: call void @_ZN1XC1ERKS_
+  // CHECK: call zeroext i1 @_ZN1XcvbEv
+  // CHECK: call void @_ZN1XD1Ev
+  // CHECK: br
+  do {
+    result = 10;
+  } while (X(x));
+
+  // CHECK: ret i32
+  return result;
+}
+
+template int instantiated(X);
diff --git a/test/CodeGenCXX/constructor-convert.cpp b/test/CodeGenCXX/constructor-convert.cpp
index 7de0772..338febb 100644
--- a/test/CodeGenCXX/constructor-convert.cpp
+++ b/test/CodeGenCXX/constructor-convert.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -emit-llvm -S -o - %s
+// RUN: %clang_cc1 -emit-llvm -o - %s
 
 // PR5775
 class Twine {
diff --git a/test/CodeGenCXX/constructors.cpp b/test/CodeGenCXX/constructors.cpp
index e070905..a8dc7fc 100644
--- a/test/CodeGenCXX/constructors.cpp
+++ b/test/CodeGenCXX/constructors.cpp
@@ -92,3 +92,15 @@
 // CHECK: call void @_ZN10ValueClassC1Eii(
 // CHECK: call void @_ZN1AC2E10ValueClass(
 // CHECK: call void @_ZN6MemberC1Ei(
+
+
+// PR6622:  this shouldn't crash
+namespace test0 {
+  struct A {};
+  struct B : virtual A { int x; };
+  struct C : B {};
+  
+  void test(C &in) {
+    C tmp = in;
+  }
+}
diff --git a/test/CodeGenCXX/copy-constructor-elim-2.cpp b/test/CodeGenCXX/copy-constructor-elim-2.cpp
index 3a06c10..73e9b94 100644
--- a/test/CodeGenCXX/copy-constructor-elim-2.cpp
+++ b/test/CodeGenCXX/copy-constructor-elim-2.cpp
@@ -5,3 +5,29 @@
 // CHECK: define void @_Z1fv
 // CHECK: call void @_ZN1AC1Ei
 // CHECK-NEXT: ret void
+
+// Verify that we do not elide copies when constructing a base class.
+namespace no_elide_base {
+  struct Base { 
+    Base(const Base&);
+    ~Base();
+  };
+
+  struct Other {
+    operator Base() const;
+  };
+
+  struct Derived : public virtual Base { 
+    Derived(const Other &O);
+  };
+
+  // CHECK: define void @_ZN13no_elide_base7DerivedC1ERKNS_5OtherE
+  Derived::Derived(const Other &O) 
+    // CHECK: call void @_ZNK13no_elide_base5OthercvNS_4BaseEEv
+    // CHECK: call void @_ZN13no_elide_base4BaseC2ERKS0_
+    // CHECK: call void @_ZN13no_elide_base4BaseD1Ev
+    : Base(O)
+  {
+    // CHECK: ret void
+  }
+}
diff --git a/test/CodeGenCXX/copy-in-cplus-object.cpp b/test/CodeGenCXX/copy-in-cplus-object.cpp
new file mode 100644
index 0000000..bdfca5e
--- /dev/null
+++ b/test/CodeGenCXX/copy-in-cplus-object.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+
+struct S {
+  S(const char *);
+  ~S();
+};
+
+struct TestObject
+{
+	TestObject(const TestObject& inObj, int def = 100,  const S &Silly = "silly");
+	TestObject();
+	~TestObject();
+	TestObject& operator=(const TestObject& inObj);
+	int version() const;
+
+};
+
+void testRoutine() {
+    TestObject one;
+    int (^V)() = ^{ return one.version(); };
+}
+
+// CHECK: call void @_ZN10TestObjectC1Ev
+// CHECK: call void @_ZN1SC1EPKc
+// CHECK: call void @_ZN10TestObjectC1ERKS_iRK1S
+// CHECK: call void @_ZN1SD1Ev
+// CHECK: call void @_ZN10TestObjectD1Ev
+// CHECK: call void @_ZN10TestObjectD1Ev
diff --git a/test/CodeGenCXX/cxx-apple-kext.cpp b/test/CodeGenCXX/cxx-apple-kext.cpp
index 8d67b53..e9a1727 100644
--- a/test/CodeGenCXX/cxx-apple-kext.cpp
+++ b/test/CodeGenCXX/cxx-apple-kext.cpp
@@ -1,11 +1,11 @@
-// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 %s -flto -S -o - |\
+// RUN: %clangxx -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: %clangxx -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: @_ZTI3foo = {{.*}} @_ZTVN10__cxxabiv117
 // CHECK-NO-KEXT: call i32 @__cxa_atexit({{.*}} @_ZN3fooD1Ev
 // CHECK-NO-KEXT: declare i32 @__cxa_atexit
 
diff --git a/test/CodeGenCXX/debug-info-byval.cpp b/test/CodeGenCXX/debug-info-byval.cpp
new file mode 100644
index 0000000..c99518e
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-byval.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang -g -S %s -o - | FileCheck %s
+// Test to check presense of debug info for byval parameter.
+// Radar 8350436.
+class DAG {
+public:
+  int i;
+  int j;
+};
+
+class EVT {
+public:
+  int a;
+  int b;
+  int c;
+};
+
+class VAL {
+public:
+  int x;
+  int y;
+};
+void foo(EVT e);
+EVT bar();
+
+void get(int *i, unsigned dl, VAL v, VAL *p, unsigned n, EVT missing_arg) {
+//CHECK: .ascii "missing_arg"
+  EVT e = bar();
+  if (dl == n)
+    foo(missing_arg);
+}
+
diff --git a/test/CodeGenCXX/debug-info-class.cpp b/test/CodeGenCXX/debug-info-class.cpp
new file mode 100644
index 0000000..151c5f9
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-class.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang  -emit-llvm -g -S %s -o - | grep HdrSize
+struct A {
+  int one;
+  static const int HdrSize = 52;
+  int two;
+  A() {
+    int x = 1;
+  }
+};
+int main() {
+  A a;
+}
diff --git a/test/CodeGenCXX/debug-info-ctor.cpp b/test/CodeGenCXX/debug-info-ctor.cpp
new file mode 100644
index 0000000..c31eebe
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-ctor.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s
+
+struct X {
+  X(int v);
+
+  int value;
+};
+
+X::X(int v) {
+  // CHECK_TEMPORARILY_DISABLED: call void @_ZN1XC2Ei(%struct.X* %this1, i32 %tmp), !dbg
+  // TEMPORARY CHECK: X
+  value = v;
+}
+
diff --git a/test/CodeGenCXX/debug-info-enum.cpp b/test/CodeGenCXX/debug-info-enum.cpp
new file mode 100644
index 0000000..c08fc35
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-enum.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang -fverbose-asm -S -g %s -o - | grep DW_TAG_enumeration_type
+
+int v;
+enum index  { MAX };
+void foo(void)
+{
+  v = MAX;
+}
diff --git a/test/CodeGenCXX/debug-info-friend.cpp b/test/CodeGenCXX/debug-info-friend.cpp
new file mode 100644
index 0000000..c50f281
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-friend.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang -fverbose-asm -S -g %s -o - | grep DW_TAG_friend
+
+class MyFriend;
+
+class SomeClass
+{
+ friend class MyFriend;
+};
+
+SomeClass sc;
+
diff --git a/test/CodeGenCXX/debug-info-template.cpp b/test/CodeGenCXX/debug-info-template.cpp
new file mode 100644
index 0000000..233090c
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-template.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm-only -g -S %s -o - | grep "TC<int>"
+template<typename T>
+class TC {
+public:
+  TC(const TC &) {}
+  TC() {}
+};
+
+TC<int> tci;
diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp
index 6bb9533..71c8603 100644
--- a/test/CodeGenCXX/debug-info.cpp
+++ b/test/CodeGenCXX/debug-info.cpp
@@ -50,3 +50,8 @@
     B b;
   }
 }
+
+void foo() {
+  const wchar_t c = L'x';
+  wchar_t d = c;
+}
diff --git a/test/CodeGenCXX/default-arg-temps.cpp b/test/CodeGenCXX/default-arg-temps.cpp
index e523eb0..c441985 100644
--- a/test/CodeGenCXX/default-arg-temps.cpp
+++ b/test/CodeGenCXX/default-arg-temps.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o %t -triple=x86_64-apple-darwin9
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
 
 struct T {
   T();
@@ -13,20 +13,61 @@
         X(const X&, const T& t = T());
 };
 
+// CHECK: define void @_Z1gv()
 void g() {
-  // RUN: grep "call void @_ZN1TC1Ev" %t | count 4
-  // RUN: grep "call void @_ZN1TD1Ev" %t | count 4
-  f();
+  // CHECK:      call void @_ZN1TC1Ev([[T:%.*]]* [[AGG1:%.*]])
+  // CHECK-NEXT: call void @_Z1fRK1T([[T]]* [[AGG1]])
+  // CHECK-NEXT: call void @_ZN1TD1Ev([[T]]* [[AGG1]])
   f();
 
+  // CHECK-NEXT: call void @_ZN1TC1Ev([[T:%.*]]* [[AGG2:%.*]])
+  // CHECK-NEXT: call void @_Z1fRK1T([[T]]* [[AGG2]])
+  // CHECK-NEXT: call void @_ZN1TD1Ev([[T]]* [[AGG2]])
+  f();
+
+  // CHECK-NEXT: call void @_ZN1XC1Ev(
   X a;
+
+  // CHECK-NEXT: call void @_ZN1TC1Ev(
+  // CHECK-NEXT: call void @_ZN1XC1ERKS_RK1T(
+  // CHECK-NEXT: call void @_ZN1TD1Ev(
   X b(a);
+
+  // CHECK-NEXT: call void @_ZN1TC1Ev(
+  // CHECK-NEXT: call void @_ZN1XC1ERKS_RK1T(
+  // CHECK-NEXT: call void @_ZN1TD1Ev(
   X c = a;
 }
 
 
-// RUN: grep memset %t
 class obj{ int a; float b; double d; };
+// CHECK: define void @_Z1hv()
 void h() {
+  // CHECK: call void @llvm.memset.p0i8.i64(
   obj o = obj();
 }
+
+// PR7028 - mostly this shouldn't crash
+namespace test1 {
+  struct A { A(); };
+  struct B { B(); ~B(); };
+
+  struct C {
+    C(const B &file = B());
+  };
+  C::C(const B &file) {}
+
+  struct D {
+    C c;
+    A a;
+
+    // CHECK: define linkonce_odr void @_ZN5test11DC2Ev(
+    // CHECK:      call void @_ZN5test11BC1Ev(
+    // CHECK-NEXT: call void @_ZN5test11CC1ERKNS_1BE(
+    // CHECK-NEXT: call void @_ZN5test11BD1Ev(
+    // CHECK:      call void @_ZN5test11AC1Ev(
+    D() : c(), a() {}
+  };
+
+  D d;
+}
diff --git a/test/CodeGenCXX/dependent-type-member-pointer.cpp b/test/CodeGenCXX/dependent-type-member-pointer.cpp
new file mode 100644
index 0000000..41bb5e2
--- /dev/null
+++ b/test/CodeGenCXX/dependent-type-member-pointer.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// PR7736
+
+template <class scriptmemberptr> int InitMember(scriptmemberptr);
+
+template <class> 
+struct contentmap
+{
+  static void InitDataMap()
+  { InitMember(&contentmap::SizeHolder); }
+  int SizeHolder;
+};
+
+void ReadFrom( )
+{
+  contentmap<int>::InitDataMap();
+}
+
diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp
index d40b174..2eba30f 100644
--- a/test/CodeGenCXX/destructors.cpp
+++ b/test/CodeGenCXX/destructors.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -mconstructor-aliases | FileCheck %s
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -mconstructor-aliases -fexceptions | FileCheck %s
 
 // CHECK: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev
 // CHECK: @_ZN5test11MD2Ev = alias {{.*}} @_ZN5test11AD2Ev
@@ -6,6 +6,10 @@
 // CHECK: @_ZN5test11OD2Ev = alias {{.*}} @_ZN5test11AD2Ev
 // CHECK: @_ZN5test11SD2Ev = alias bitcast {{.*}} @_ZN5test11AD2Ev
 
+// CHECK: @_ZN5test312_GLOBAL__N_11DD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11DD2Ev
+// CHECK: @_ZN5test312_GLOBAL__N_11DD2Ev = alias internal bitcast {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
+// CHECK: @_ZN5test312_GLOBAL__N_11CD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
+
 struct A {
   int a;
   
@@ -28,6 +32,26 @@
 
 C::~C() { }
 
+namespace PR7526 {
+  extern void foo();
+  struct allocator {
+    ~allocator() throw();
+  };
+
+  struct allocator_derived : allocator { };
+
+  // CHECK: define void @_ZN6PR75269allocatorD2Ev
+  // CHECK: call void @__cxa_call_unexpected
+  allocator::~allocator() throw() { foo(); }
+
+  // CHECK: define linkonce_odr void @_ZN6PR752617allocator_derivedD1Ev
+  // CHECK-NOT: call void @__cxa_call_unexpected
+  // CHECK:     }
+  void foo() {
+    allocator_derived ad;
+  }
+}
+
 // PR5084
 template<typename T>
 class A1 {
@@ -147,3 +171,187 @@
   // CHECK: define void @_ZN5test21BD2Ev
   // CHECK: call void @_ZN5test21AD2Ev
 }
+
+// PR7142
+namespace test3 {
+  struct A { virtual ~A(); };
+  struct B { virtual ~B(); };
+  namespace { // internal linkage => deferred
+    struct C : A, B {}; // ~B() in D requires a this-adjustment thunk
+    struct D : C {};    // D::~D() is an alias to C::~C()
+  }
+
+  void test() {
+    new D; // Force emission of D's vtable
+  }
+
+  // Checked at top of file:
+  // @_ZN5test312_GLOBAL__N_11CD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
+
+  // More checks at end of file.
+
+}
+
+namespace test4 {
+  struct A { ~A(); };
+
+  // CHECK: define void @_ZN5test43fooEv()
+  // CHECK: call void @_ZN5test41AD1Ev
+  // CHECK: ret void
+  void foo() {
+    {
+      A a;
+      goto failure;
+    }
+
+  failure:
+    return;
+  }
+
+  // CHECK: define void @_ZN5test43barEi(
+  // CHECK:      [[X:%.*]] = alloca i32
+  // CHECK-NEXT: [[A:%.*]] = alloca
+  // CHECK:      br label
+  // CHECK:      [[TMP:%.*]] = load i32* [[X]]
+  // CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP]], 0
+  // CHECK-NEXT: br i1
+  // CHECK:      call void @_ZN5test41AD1Ev(
+  // CHECK:      br label
+  // CHECK:      [[TMP:%.*]] = load i32* [[X]]
+  // CHECK:      [[TMP2:%.*]] = add nsw i32 [[TMP]], -1
+  // CHECK:      store i32 [[TMP2]], i32* [[X]]
+  // CHECK:      br label
+  // CHECK:      ret void
+  void bar(int x) {
+    for (A a; x; ) {
+      x--;
+    }
+  }
+}
+
+// PR7575
+namespace test5 {
+  struct A { ~A(); };
+
+  // This is really unnecessarily verbose; we should be using phis,
+  // even at -O0.
+
+  // CHECK: define void @_ZN5test53fooEv()
+  // CHECK:      [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align
+  // CHECK-NEXT: [[IVAR:%.*]] = alloca i64
+  // CHECK:      [[ELEMSARRAY:%.*]] = bitcast [5 x [[A]]]* [[ELEMS]] to [[A]]
+  // CHECK-NEXT: store i64 5, i64* [[IVAR]]
+  // CHECK-NEXT: br label
+  // CHECK:      [[I:%.*]] = load i64* [[IVAR]]
+  // CHECK-NEXT: icmp ne i64 [[I]], 0
+  // CHECK-NEXT: br i1
+  // CHECK:      [[I:%.*]] = load i64* [[IVAR]]
+  // CHECK-NEXT: [[I2:%.*]] = sub i64 [[I]], 1
+  // CHECK-NEXT: getelementptr inbounds [[A]]* [[ELEMSARRAY]], i64 [[I2]]
+  // CHECK-NEXT: call void @_ZN5test51AD1Ev(
+  // CHECK-NEXT: br label
+  // CHECK:      [[I:%.*]] = load i64* [[IVAR]]
+  // CHECK-NEXT: [[I1:%.*]] = sub i64 [[I]], 1
+  // CHECK-NEXT: store i64 [[I1]], i64* [[IVAR]]
+  // CHECK-NEXT: br label
+  // CHECK:      ret void
+  void foo() {
+    A elems[5];
+  }
+}
+
+namespace test6 {
+  void opaque();
+
+  struct A { ~A(); };
+  template <unsigned> struct B { B(); ~B(); int _; };
+  struct C : B<0>, B<1>, virtual B<2>, virtual B<3> {
+    A x, y, z;
+
+    C();
+    ~C();
+  };
+
+  C::C() { opaque(); }
+  // CHECK: define void @_ZN5test61CC1Ev
+  // CHECK:   call void @_ZN5test61BILj2EEC2Ev
+  // CHECK:   invoke void @_ZN5test61BILj3EEC2Ev
+  // CHECK:   invoke void @_ZN5test61BILj0EEC2Ev
+  // CHECK:   invoke void @_ZN5test61BILj1EEC2Ev
+  // CHECK:   invoke void @_ZN5test66opaqueEv
+  // CHECK:   ret void
+  // FIXME: way too much EH cleanup code follows
+
+  C::~C() { opaque(); }
+  // CHECK: define void @_ZN5test61CD1Ev
+  // CHECK:   invoke void @_ZN5test61CD2Ev
+  // CHECK:   invoke void @_ZN5test61BILj3EED2Ev
+  // CHECK:   call void @_ZN5test61BILj2EED2Ev
+  // CHECK:   ret void
+  // CHECK:   invoke void @_ZN5test61BILj3EED2Ev
+  // CHECK:   invoke void @_ZN5test61BILj2EED2Ev
+
+  // CHECK: define void @_ZN5test61CD2Ev
+  // CHECK:   invoke void @_ZN5test66opaqueEv
+  // CHECK:   invoke void @_ZN5test61AD1Ev
+  // CHECK:   invoke void @_ZN5test61AD1Ev
+  // CHECK:   invoke void @_ZN5test61AD1Ev
+  // CHECK:   invoke void @_ZN5test61BILj1EED2Ev
+  // CHECK:   call void @_ZN5test61BILj0EED2Ev
+  // CHECK:   ret void
+  // CHECK:   invoke void @_ZN5test61AD1Ev
+  // CHECK:   invoke void @_ZN5test61AD1Ev
+  // CHECK:   invoke void @_ZN5test61AD1Ev
+  // CHECK:   invoke void @_ZN5test61BILj1EED2Ev
+  // CHECK:   invoke void @_ZN5test61BILj0EED2Ev
+}
+
+// Checks from test3:
+
+  // CHECK: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(
+  // CHECK: invoke void @_ZN5test312_GLOBAL__N_11DD1Ev(
+  // CHECK: call void @_ZdlPv({{.*}}) nounwind
+  // CHECK: ret void
+  // CHECK: call i8* @llvm.eh.exception(
+  // CHECK: call void @_ZdlPv({{.*}}) nounwind
+  // CHECK: call void @_Unwind_Resume_or_Rethrow
+
+  // Checked at top of file:
+  // @_ZN5test312_GLOBAL__N_11DD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11DD2Ev
+  // @_ZN5test312_GLOBAL__N_11DD2Ev = alias internal bitcast {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
+
+  // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD1Ev(
+  // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
+  // CHECK: call void @_ZN5test312_GLOBAL__N_11DD1Ev(
+  // CHECK: ret void
+
+  // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD0Ev(
+  // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
+  // CHECK: call void @_ZN5test312_GLOBAL__N_11DD0Ev(
+  // CHECK: ret void
+
+  // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(
+  // CHECK: invoke void @_ZN5test31BD2Ev(
+  // CHECK: call void @_ZN5test31AD2Ev(
+  // CHECK: ret void
+
+  // CHECK: declare void @_ZN5test31BD2Ev(
+  // CHECK: declare void @_ZN5test31AD2Ev(
+
+  // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(
+  // CHECK: invoke void @_ZN5test312_GLOBAL__N_11CD1Ev(
+  // CHECK: call void @_ZdlPv({{.*}}) nounwind
+  // CHECK: ret void
+  // CHECK: call i8* @llvm.eh.exception()
+  // CHECK: call void @_ZdlPv({{.*}}) nounwind
+  // CHECK: call void @_Unwind_Resume_or_Rethrow(
+
+  // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev(
+  // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
+  // CHECK: call void @_ZN5test312_GLOBAL__N_11CD1Ev(
+  // CHECK: ret void
+
+  // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD0Ev(
+  // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
+  // CHECK: call void @_ZN5test312_GLOBAL__N_11CD0Ev(
+  // CHECK: ret void
diff --git a/test/CodeGenCXX/dynamic-cast.cpp b/test/CodeGenCXX/dynamic-cast.cpp
index aeb2a64..9838e25 100644
--- a/test/CodeGenCXX/dynamic-cast.cpp
+++ b/test/CodeGenCXX/dynamic-cast.cpp
@@ -1,8 +1,17 @@
-// RUN: %clang_cc1 %s -emit-llvm-only
-
+// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -o - | FileCheck %s
 struct A { virtual void f(); };
 struct B : A { };
 
+// CHECK: {{define.*@_Z1fP1A}}
+B fail;
 const B& f(A *a) {
-  return dynamic_cast<const B&>(*a);
+  try {
+    // CHECK: call i8* @__dynamic_cast
+    // CHECK: br i1
+    // CHECK: invoke void @__cxa_bad_cast() noreturn
+    dynamic_cast<const B&>(*a);
+  } catch (...) {
+    // CHECK: call i8* @llvm.eh.exception
+  }
+  return fail;
 }
diff --git a/test/CodeGenCXX/dyncast.cpp b/test/CodeGenCXX/dyncast.cpp
index 127cdd8..906d44b 100644
--- a/test/CodeGenCXX/dyncast.cpp
+++ b/test/CodeGenCXX/dyncast.cpp
@@ -20,8 +20,6 @@
 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);
diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp
index f2629d1..0960ec3 100644
--- a/test/CodeGenCXX/eh.cpp
+++ b/test/CodeGenCXX/eh.cpp
@@ -38,6 +38,8 @@
 // CHECK:     define void @_Z5test2v()
 // CHECK:       [[FREEVAR:%.*]] = alloca i1
 // CHECK-NEXT:  [[EXNOBJVAR:%.*]] = alloca i8*
+// CHECK-NEXT:  [[EXNSLOTVAR:%.*]] = alloca i8*
+// CHECK-NEXT:  [[CLEANUPDESTVAR:%.*]] = alloca i32
 // CHECK-NEXT:  store i1 false, i1* [[FREEVAR]]
 // CHECK-NEXT:  [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
 // CHECK-NEXT:  store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]]
@@ -104,3 +106,311 @@
 //      :    [[HANDLER]]:  (can't check this in Release-Asserts builds)
 // CHECK:      {{%.*}} = call i32 @llvm.eh.typeid.for(i8* bitcast ({{%.*}}* @_ZTIN5test51AE to i8*))
 }
+
+namespace test6 {
+  template <class T> struct allocator {
+    ~allocator() throw() { }
+  };
+
+  void foo() {
+    allocator<int> a;
+  }
+}
+
+// PR7127
+namespace test7 {
+// CHECK:      define i32 @_ZN5test73fooEv() 
+  int foo() {
+// CHECK:      [[FREEEXNOBJ:%.*]] = alloca i1
+// CHECK-NEXT: [[EXNALLOCVAR:%.*]] = alloca i8*
+// CHECK-NEXT: [[CAUGHTEXNVAR:%.*]] = alloca i8*
+// CHECK-NEXT: [[INTCATCHVAR:%.*]] = alloca i32
+// CHECK-NEXT: [[EHCLEANUPDESTVAR:%.*]] = alloca i32
+// CHECK-NEXT: store i1 false, i1* [[FREEEXNOBJ]]
+    try {
+      try {
+// CHECK-NEXT: [[EXNALLOC:%.*]] = call i8* @__cxa_allocate_exception
+// CHECK-NEXT: store i8* [[EXNALLOC]], i8** [[EXNALLOCVAR]]
+// CHECK-NEXT: store i1 true, i1* [[FREEEXNOBJ]]
+// CHECK-NEXT: bitcast i8* [[EXNALLOC]] to i32*
+// CHECK-NEXT: store i32 1, i32*
+// CHECK-NEXT: store i1 false, i1* [[FREEEXNOBJ]]
+// CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXNALLOC]], i8* bitcast (i8** @_ZTIi to i8*), i8* null
+        throw 1;
+      }
+
+// CHECK:      [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception()
+// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]]
+// CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+// CHECK-NEXT: call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
+// CHECK-NEXT: icmp eq
+// CHECK-NEXT: br i1
+// CHECK:      load i8** [[CAUGHTEXNVAR]]
+// CHECK-NEXT: call i8* @__cxa_begin_catch
+// CHECK:      invoke void @__cxa_rethrow
+      catch (int) {
+        throw;
+      }
+    }
+// CHECK:      [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception()
+// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]]
+// CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null)
+// CHECK-NEXT: store i32 1, i32* [[EHCLEANUPDESTVAR]]
+// CHECK-NEXT: call void @__cxa_end_catch()
+// CHECK-NEXT: br label
+// CHECK:      load i8** [[CAUGHTEXNVAR]]
+// CHECK-NEXT: call i8* @__cxa_begin_catch
+// CHECK-NEXT: call void @__cxa_end_catch
+    catch (...) {
+    }
+// CHECK:      ret i32 0
+    return 0;
+  }
+}
+
+// Ordering of destructors in a catch handler.
+namespace test8 {
+  struct A { A(const A&); ~A(); };
+  void bar();
+
+  // CHECK: define void @_ZN5test83fooEv()
+  void foo() {
+    try {
+      // CHECK:      invoke void @_ZN5test83barEv()
+      bar();
+    } catch (A a) {
+      // CHECK:      call i8* @__cxa_get_exception_ptr
+      // CHECK-NEXT: bitcast
+      // CHECK-NEXT: invoke void @_ZN5test81AC1ERKS0_(
+      // CHECK:      call i8* @__cxa_begin_catch
+      // CHECK-NEXT: invoke void @_ZN5test81AD1Ev(
+      // CHECK:      call void @__cxa_end_catch()
+      // CHECK:      ret void
+    }
+  }
+}
+
+// Constructor function-try-block must rethrow on fallthrough.
+// rdar://problem/7696603
+namespace test9 {
+  void opaque();
+
+  struct A { A(); };
+
+  // CHECK:      define void @_ZN5test91AC1Ev
+  // CHECK:      call void @_ZN5test91AC2Ev
+  // CHECK-NEXT: ret void
+
+  // CHECK: define void @_ZN5test91AC2Ev(
+  A::A() try {
+  // CHECK:      invoke void @_ZN5test96opaqueEv()
+    opaque();
+  } catch (int x) {
+  // CHECK:      call i8* @__cxa_begin_catch
+  // CHECK:      invoke void @_ZN5test96opaqueEv()
+  // CHECK:      invoke void @__cxa_rethrow()
+    opaque();
+  }
+
+  // landing pad from first call to invoke
+  // CHECK:      call i8* @llvm.eh.exception
+  // CHECK:      call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+}
+
+// __cxa_end_catch can throw for some kinds of caught exceptions.
+namespace test10 {
+  void opaque();
+
+  struct A { ~A(); };
+  struct B { int x; };
+
+  // CHECK: define void @_ZN6test103fooEv()
+  void foo() {
+    A a; // force a cleanup context
+
+    try {
+    // CHECK:      invoke void @_ZN6test106opaqueEv()
+      opaque();
+    } catch (int i) {
+    // CHECK:      call i8* @__cxa_begin_catch
+    // CHECK-NEXT: bitcast
+    // CHECK-NEXT: load i32*
+    // CHECK-NEXT: store i32
+    // CHECK-NEXT: call void @__cxa_end_catch() nounwind
+    } catch (B a) {
+    // CHECK:      call i8* @__cxa_begin_catch
+    // CHECK-NEXT: bitcast
+    // CHECK-NEXT: bitcast
+    // CHECK-NEXT: bitcast
+    // CHECK-NEXT: call void @llvm.memcpy
+    // CHECK-NEXT: invoke void @__cxa_end_catch()
+    } catch (...) {
+    // CHECK:      call i8* @__cxa_begin_catch
+    // CHECK-NEXT: invoke void @__cxa_end_catch()
+    }
+
+    // CHECK: call void @_ZN6test101AD1Ev(
+  }
+}
+
+// __cxa_begin_catch returns pointers by value, even when catching by reference
+// <rdar://problem/8212123>
+namespace test11 {
+  void opaque();
+
+  // CHECK: define void @_ZN6test113fooEv()
+  void foo() {
+    try {
+      // CHECK:      invoke void @_ZN6test116opaqueEv()
+      opaque();
+    } catch (int**&p) {
+      // CHECK:      [[EXN:%.*]] = load i8**
+      // CHECK-NEXT: call i8* @__cxa_begin_catch(i8* [[EXN]]) nounwind
+      // CHECK-NEXT: [[ADJ1:%.*]] = getelementptr i8* [[EXN]], i32 32
+      // CHECK-NEXT: [[ADJ2:%.*]] = bitcast i8* [[ADJ1]] to i32***
+      // CHECK-NEXT: store i32*** [[ADJ2]], i32**** [[P:%.*]]
+      // CHECK-NEXT: call void @__cxa_end_catch() nounwind
+    }
+  }
+
+  struct A {};
+
+  // CHECK: define void @_ZN6test113barEv()
+  void bar() {
+    try {
+      // CHECK:      [[EXNSLOT:%.*]] = alloca i8*
+      // CHECK-NEXT: [[P:%.*]] = alloca [[A:%.*]]**,
+      // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]]*
+      // CHECK-NEXT: invoke void @_ZN6test116opaqueEv()
+      opaque();
+    } catch (A*&p) {
+      // CHECK:      [[EXN:%.*]] = load i8** [[EXNSLOT]]
+      // CHECK-NEXT: [[ADJ1:%.*]] = call i8* @__cxa_begin_catch(i8* [[EXN]]) nounwind
+      // CHECK-NEXT: [[ADJ2:%.*]] = bitcast i8* [[ADJ1]] to [[A]]*
+      // CHECK-NEXT: store [[A]]* [[ADJ2]], [[A]]** [[TMP]]
+      // CHECK-NEXT: store [[A]]** [[TMP]], [[A]]*** [[P]]
+      // CHECK-NEXT: call void @__cxa_end_catch() nounwind
+    }
+  }
+}
+
+// PR7686
+namespace test12 {
+  struct A { ~A(); };
+  bool opaque(const A&);
+
+  // CHECK: define void @_ZN6test124testEv()
+  void test() {
+    // CHECK: [[X:%.*]] = alloca [[A:%.*]],
+    // CHECK: [[EHCLEANUPDEST:%.*]] = alloca i32
+    // CHECK: [[Y:%.*]] = alloca [[A]]
+    // CHECK: [[Z:%.*]] = alloca [[A]]
+    // CHECK: [[CLEANUPDEST:%.*]] = alloca i32
+
+    A x;
+    // CHECK: invoke zeroext i1 @_ZN6test126opaqueERKNS_1AE(
+    if (opaque(x)) {
+      A y;
+      A z;
+
+      // CHECK: invoke void @_ZN6test121AD1Ev([[A]]* [[Z]])
+      // CHECK: invoke void @_ZN6test121AD1Ev([[A]]* [[Y]])
+
+      // It'd be great if something eliminated this switch.
+      // CHECK:      load i32* [[CLEANUPDEST]]
+      // CHECK-NEXT: switch i32
+      goto success;
+    }
+
+  success:
+    bool _ = true;
+
+    // CHECK: call void @_ZN6test121AD1Ev([[A]]* [[X]])
+    // CHECK-NEXT: ret void
+  }
+}
+
+// Reduced from some TableGen code that was causing a self-host crash.
+namespace test13 {
+  struct A { ~A(); };
+
+  void test0(int x) {
+    try {
+      switch (x) {
+      case 0:
+        break;
+      case 1:{
+        A a;
+        break;
+      }
+      default:
+        return;
+      }
+      return;
+    } catch (int x) {
+    }
+    return;
+  }
+
+  void test1(int x) {
+    A y;
+    try {
+      switch (x) {
+      default: break;
+      }
+    } catch (int x) {}
+  }
+}
+
+// rdar://problem/8231514
+namespace test14 {
+  struct A { ~A(); };
+  struct B { ~B(); };
+
+  B b();
+  void opaque();
+
+  void foo() {
+    A a;
+    try {
+      B str = b();
+      opaque();
+    } catch (int x) {
+    }
+  }
+}
+
+// rdar://problem/8231514
+// JumpDests shouldn't get confused by scopes that aren't normal cleanups.
+namespace test15 {
+  struct A { ~A(); };
+
+  bool opaque(int);
+
+  // CHECK: define void @_ZN6test153fooEv()
+  void foo() {
+    A a;
+
+    try {
+      // CHECK:      [[X:%.*]] = alloca i32
+      // CHECK:      store i32 10, i32* [[X]]
+      // CHECK-NEXT: br label
+      //   -> while.cond
+      int x = 10;
+
+      while (true) {
+        // CHECK:      load i32* [[X]]
+        // CHECK-NEXT: [[COND:%.*]] = invoke zeroext i1 @_ZN6test156opaqueEi
+        // CHECK:      br i1 [[COND]]
+        if (opaque(x))
+        // CHECK:      br label
+          break;
+
+        // CHECK:      br label
+      }
+      // CHECK:      br label
+    } catch (int x) { }
+
+    // CHECK: call void @_ZN6test151AD1Ev
+  }
+}
diff --git a/test/CodeGenCXX/empty-classes.cpp b/test/CodeGenCXX/empty-classes.cpp
new file mode 100644
index 0000000..59124e3
--- /dev/null
+++ b/test/CodeGenCXX/empty-classes.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s
+
+struct Empty { };
+
+struct A { 
+  explicit A(unsigned a = 0xffffffff) : a(a) { }
+  
+  unsigned a;
+};
+
+struct B : A, Empty { 
+  B() : A(), Empty() { }
+};
+
+struct C : A, Empty {
+  C() : A(), Empty() { }
+  C(const C& other) : A(0x12345678), Empty(other) { }
+};
+
+struct D : A, Empty {
+  D& operator=(const D& other) {
+    a = 0x87654321;
+    Empty::operator=(other);
+    
+    return *this;
+  }
+};
+
+#define CHECK(x) if (!(x)) return __LINE__
+
+// PR7012
+// CHECK: define i32 @_Z1fv()
+int f() {
+  B b1;
+
+  // Check that A::a is not overwritten by the Empty default constructor.
+  CHECK(b1.a == 0xffffffff);
+  
+  C c1;
+  C c2(c1);
+  
+  // Check that A::a has the value set in the C::C copy constructor.
+  CHECK(c2.a == 0x12345678);
+  
+  D d1, d2;
+  d2 = d1;
+
+  // Check that A::as has the value set in the D copy assignment operator.
+  CHECK(d2.a == 0x87654321);
+  
+  // 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/exceptions-no-rtti.cpp b/test/CodeGenCXX/exceptions-no-rtti.cpp
new file mode 100644
index 0000000..66b4c4a
--- /dev/null
+++ b/test/CodeGenCXX/exceptions-no-rtti.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fno-rtti -fexceptions %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// CHECK: @_ZTIN5test11AE = weak_odr constant
+// CHECK: @_ZTIN5test11BE = weak_odr constant
+// CHECK: @_ZTIN5test11CE = weak_odr constant
+// CHECK: @_ZTIN5test11DE = weak_odr constant
+// CHECK: @_ZTIPN5test11DE = weak_odr constant {{.*}} @_ZTIN5test11DE
+
+// PR6974: this shouldn't crash
+namespace test0 {
+  class err {};
+
+  void f(void) {
+    try {
+    } catch (err &) {
+    }
+  }
+}
+
+namespace test1 {
+  // These classes have key functions defined out-of-line.  Under
+  // normal circumstances, we wouldn't generate RTTI for them; under
+  // -fno-rtti, we generate RTTI only when required by EH.  But
+  // everything gets hidden visibility because we assume that all
+  // users are also compiled under -fno-rtti and therefore will be
+  // emitting RTTI regardless of key function.
+  class A { virtual void foo(); };
+  class B { virtual void foo(); };
+  class C { virtual void foo(); };
+  class D { virtual void foo(); };
+
+  void opaque();
+
+  void test0() {
+    throw A();
+  }
+
+  void test1() throw(B) {
+    opaque();
+  }
+
+  void test2() {
+    try {
+      opaque();
+    } catch (C&) {}
+  }
+
+  void test3(D *ptr) {
+    throw ptr;
+  };
+}
diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp
index 24d1a67..b829585 100644
--- a/test/CodeGenCXX/explicit-instantiation.cpp
+++ b/test/CodeGenCXX/explicit-instantiation.cpp
@@ -1,5 +1,8 @@
 // RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -o - %s | FileCheck %s
 
+// This check logically is attached to 'template int S<int>::i;' below.
+// CHECK: @_ZN1SIiE1iE = weak global i32
+
 template<typename T, typename U, typename Result>
 struct plus {
   Result operator()(const T& t, const U& u) const;
@@ -12,3 +15,31 @@
 
 // CHECK: define weak_odr i32 @_ZNK4plusIillEclERKiRKl
 template struct plus<int, long, long>;
+
+// Check that we emit definitions from explicit instantiations even when they
+// occur prior to the definition itself.
+template <typename T> struct S {
+  void f();
+  static void g();
+  static int i;
+  struct S2 {
+    void h();
+  };
+};
+
+// CHECK: define weak_odr void @_ZN1SIiE1fEv
+template void S<int>::f();
+
+// CHECK: define weak_odr void @_ZN1SIiE1gEv
+template void S<int>::g();
+
+// See the check line at the top of the file.
+template int S<int>::i;
+
+// CHECK: define weak_odr void @_ZN1SIiE2S21hEv
+template void S<int>::S2::h();
+
+template <typename T> void S<T>::f() {}
+template <typename T> void S<T>::g() {}
+template <typename T> int S<T>::i;
+template <typename T> void S<T>::S2::h() {}
diff --git a/test/CodeGenCXX/expr.cpp b/test/CodeGenCXX/expr.cpp
index d92cfb4..33e8e63 100644
--- a/test/CodeGenCXX/expr.cpp
+++ b/test/CodeGenCXX/expr.cpp
@@ -14,3 +14,24 @@
 // PR5514
 int a;
 void test2() { ++a+=10; }
+
+// PR7892
+int test3(const char*);
+int test3g = test3(__PRETTY_FUNCTION__);
+
+
+// PR7889
+struct test4A {
+  int j : 2;
+};
+int test4() {
+  test4A a;
+  (a.j = 2) = 3;
+}
+
+// Incomplete type in conditional operator.
+// Check operations on incomplete types.
+struct s5;
+struct s5 &f5_0(bool cond, struct s5 &a, struct s5 &b) {
+  return cond ? a : b;
+}
diff --git a/test/CodeGenCXX/global-dtor-no-atexit.cpp b/test/CodeGenCXX/global-dtor-no-atexit.cpp
index 81e2199..1e125e3 100644
--- a/test/CodeGenCXX/global-dtor-no-atexit.cpp
+++ b/test/CodeGenCXX/global-dtor-no-atexit.cpp
@@ -1,5 +1,8 @@
 // RUN: %clang_cc1 -triple x86_64 %s -fno-use-cxa-atexit -emit-llvm -o - | FileCheck %s
 
+// PR7097
+// RUN: %clang_cc1 -triple x86_64 %s -fno-use-cxa-atexit -mconstructor-aliases -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)
diff --git a/test/CodeGenCXX/global-init-darwin.cpp b/test/CodeGenCXX/global-init-darwin.cpp
new file mode 100644
index 0000000..20c13c6
--- /dev/null
+++ b/test/CodeGenCXX/global-init-darwin.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck %s
+
+struct A {
+  A();
+  ~A();
+};
+
+A a;
+A as[2];
+
+struct B {
+  B();
+  ~B();
+  int f();
+};
+
+int i = B().f();
+
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp
index 7cbd559..6ff9598 100644
--- a/test/CodeGenCXX/global-init.cpp
+++ b/test/CodeGenCXX/global-init.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck %s
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -fexceptions %s -o - |FileCheck %s
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck -check-prefix NOEXC %s
 
 struct A {
   A();
@@ -13,6 +14,9 @@
 
 // CHECK: @c = global %struct.C zeroinitializer, align 8
 
+// It's okay if we ever implement the IR-generation optimization to remove this.
+// CHECK: @_ZN5test3L3varE = internal constant i8* getelementptr inbounds ([7 x i8]* 
+
 // 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;
@@ -28,4 +32,52 @@
 // 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() {
+// <rdar://problem/7458115>
+namespace test1 {
+  int f();
+  const int x = f();   // This has side-effects and gets emitted immediately.
+  const int y = x - 1; // This gets deferred.
+  const int z = ~y;    // This also gets deferred, but gets "undeferred" before y.
+  int test() { return z; }
+// CHECK:      define i32 @_ZN5test14testEv()
+
+  // All of these initializers end up delayed, so we check them later.
+}
+
+// <rdar://problem/8246444>
+namespace test2 {
+  struct allocator { allocator(); ~allocator(); };
+  struct A { A(const allocator &a = allocator()); ~A(); };
+
+  A a;
+// CHECK: call void @_ZN5test29allocatorC1Ev(
+// CHECK: invoke void @_ZN5test21AC1ERKNS_9allocatorE(
+// CHECK: call void @_ZN5test29allocatorD1Ev(
+// CHECK: call i32 @__cxa_atexit({{.*}} @_ZN5test21AD1Ev {{.*}} @_ZN5test21aE
+}
+
+namespace test3 {
+  // Tested at the beginning of the file.
+  const char * const var = "string";
+  extern const char * const var;
+
+  const char *test() { return var; }
+}
+
+// CHECK:      define internal void [[TEST1_Z_INIT:@.*]]()
+// CHECK:        load i32* @_ZN5test1L1yE
+// CHECK-NEXT:   xor
+// CHECK-NEXT:   store i32 {{.*}}, i32* @_ZN5test1L1zE
+// CHECK:      define internal void [[TEST1_Y_INIT:@.*]]()
+// CHECK:        load i32* @_ZN5test1L1xE
+// CHECK-NEXT:   sub
+// CHECK-NEXT:   store i32 {{.*}}, i32* @_ZN5test1L1yE
+
+// At the end of the file, we check that y is initialized before z.
+
+// CHECK: define internal void @_GLOBAL__I_a() section "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK:   call void [[TEST1_Y_INIT]]
+// CHECK:   call void [[TEST1_Z_INIT]]
+
+// rdar://problem/8090834: this should be nounwind
+// CHECK-NOEXC: define internal void @_GLOBAL__I_a() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" {
diff --git a/test/CodeGenCXX/implicit-copy-assign-operator.cpp b/test/CodeGenCXX/implicit-copy-assign-operator.cpp
new file mode 100644
index 0000000..0ec89fc
--- /dev/null
+++ b/test/CodeGenCXX/implicit-copy-assign-operator.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10.0.0 -o - %s | FileCheck %s
+struct A { 
+  A &operator=(const A&);
+  A &operator=(A&);
+};
+
+struct B {
+  B &operator=(B&);
+};
+
+struct C {
+  virtual C& operator=(const C&);
+};
+
+struct POD {
+  int array[3][4];
+};
+
+struct CopyByValue {
+  CopyByValue(const CopyByValue&);
+  CopyByValue &operator=(CopyByValue);
+};
+
+struct D : A, B, virtual C { 
+  int scalar;
+  int scalar_array[2][3];
+  B class_member;
+  C class_member_array[2][3];
+  POD pod_array[2][3];
+
+  union {
+    int x;
+    float f[3];
+  };
+
+  CopyByValue by_value;
+};
+
+void test_D(D d1, D d2) {
+  d1 = d2;
+}
+
+// CHECK: define linkonce_odr %struct.D* @_ZN1DaSERS_
+// CHECK: {{call.*_ZN1AaSERS_}}
+// CHECK: {{call.*_ZN1BaSERS_}}
+// CHECK: {{call.*_ZN1CaSERKS_}}
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 24}}
+// CHECK: {{call.*_ZN1BaSERS_}}
+// CHECK: br
+// CHECK: {{call.*_ZN1CaSERKS_}}
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 288}}
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 12}}
+// CHECK: call void @_ZN11CopyByValueC1ERKS_
+// CHECK: {{call.*_ZN11CopyByValueaSES_}}
+// CHECK: ret
+
diff --git a/test/CodeGenCXX/implicit-copy-constructor.cpp b/test/CodeGenCXX/implicit-copy-constructor.cpp
new file mode 100644
index 0000000..a343dd1
--- /dev/null
+++ b/test/CodeGenCXX/implicit-copy-constructor.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+struct A { 
+  A();
+  A(const A&);
+  A(A&);
+  ~A();
+};
+
+struct B {
+  B();
+  B(B&);
+};
+
+struct C {
+  C() {}
+  C(C& other, A a = A());
+  int i, j;
+};
+
+struct POD {
+  int array[3][4];
+};
+
+struct D : A, B, virtual C { 
+  D();
+  int scalar;
+  int scalar_array[2][3];
+  B class_member;
+  C class_member_array[2][3];
+  POD pod_array[2][3];
+
+  union {
+    int x;
+    float f[3];
+  };
+};
+
+void f(D d) {
+  D d2(d);
+}
+
+// CHECK: define linkonce_odr void @_ZN1DC1ERS_
+// CHECK: call void @_ZN1AC1Ev
+// CHECK: call void @_ZN1CC2ERS_1A
+// CHECK: call void @_ZN1AD1Ev
+// CHECK: call void @_ZN1AC2ERS_
+// CHECK: call void @_ZN1BC2ERS_
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 24}}
+// CHECK: call void @_ZN1BC1ERS_
+// CHECK: br
+// CHECK: {{icmp ult.*, 2}}
+// CHECK: {{icmp ult.*, 3}}
+// CHECK: call void @_ZN1AC1Ev
+// CHECK: call void @_ZN1CC1ERS_1A
+// CHECK: call void @_ZN1AD1Ev
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 288}}
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 12}}
+// CHECK: ret void
+
+
+template<class T> struct X0 { void f0(T * ) { } };
+template <class > struct X1 { X1( X1& , int = 0 ) { } };
+struct X2 { X1<int> result; };
+void test_X2()
+{
+  typedef X2 impl;
+  typedef X0<impl> pimpl;
+  impl* i;
+  pimpl pdata;
+  pdata.f0( new impl(*i));
+}
diff --git a/test/CodeGenCXX/incomplete-member-function-pointer.cpp b/test/CodeGenCXX/incomplete-member-function-pointer.cpp
new file mode 100644
index 0000000..b97e44c
--- /dev/null
+++ b/test/CodeGenCXX/incomplete-member-function-pointer.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+// PR7040
+struct fake_tuple;
+struct connection {
+    void bar(fake_tuple);
+};
+void (connection::*a)(fake_tuple) = &connection::bar;
+void f() {
+  void (connection::*b)(fake_tuple) = &connection::bar;
+}
diff --git a/test/CodeGenCXX/instantiate-blocks.cpp b/test/CodeGenCXX/instantiate-blocks.cpp
new file mode 100644
index 0000000..e206582
--- /dev/null
+++ b/test/CodeGenCXX/instantiate-blocks.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -fblocks -emit-llvm -o - %s
+// rdar : // 6182276
+
+template <typename T> T foo(T t)
+{
+    void (^block)(int);
+    return 1;
+}
+
+int test1(void)
+{
+    int i = 1;
+    int b = 2;
+    i = foo(b);
+    return 0;
+}
+
+template <typename T, typename T1> void foo(T t, T1 r)
+{
+    T block_arg;
+    __block T1 byref_block_arg;
+
+    T1 (^block)(char, T, T1, double) =  
+	^ T1 (char ch, T arg, T1 arg2, double d1) { byref_block_arg = arg2;
+           					    return byref_block_arg + block_arg + arg; };
+
+    void (^block2)() = ^{};
+}
+
+void test2(void)
+{
+    foo(100, 'a');
+}
+
+namespace rdar6182276 {
+extern "C" {
+int printf(const char *, ...);
+}
+
+template <typename T> T foo(T t)
+{
+    void (^testing)(int) = ^(int bar) { printf("bar is %d\n", bar); };
+    printf("bar is\n");
+    return 1;
+}
+
+template <typename T> void gorf(T t)
+{
+    foo(t);
+}
+
+
+void test(void)
+{
+    gorf(2);
+}
+}
+
+
diff --git a/test/CodeGenCXX/internal-linkage.cpp b/test/CodeGenCXX/internal-linkage.cpp
index 4263891..9fdb727 100644
--- a/test/CodeGenCXX/internal-linkage.cpp
+++ b/test/CodeGenCXX/internal-linkage.cpp
@@ -17,3 +17,40 @@
 // CHECK: @anon2 = internal global
 X<Anon> anon2;
 
+// rdar: // 8071804
+char const * const xyzzy = "Hello, world!";
+extern char const * const xyzzy;
+
+char const * const *test1()
+{
+   // CHECK: @_ZL5xyzzy = internal constant
+    return &xyzzy;
+}
+
+static char const * const static_xyzzy = "Hello, world!";
+extern char const * const static_xyzzy;
+
+char const * const *test2()
+{
+    // CHECK: @_ZL12static_xyzzy = internal constant
+    return &static_xyzzy;
+}
+
+static char const * static_nonconst_xyzzy = "Hello, world!";
+extern char const * static_nonconst_xyzzy;
+
+char const * *test3()
+{
+    // CHECK: @_ZL21static_nonconst_xyzzy = internal global
+    return &static_nonconst_xyzzy;
+}
+
+
+char const * extern_nonconst_xyzzy = "Hello, world!";
+extern char const * extern_nonconst_xyzzy;
+
+char const * *test4()
+{
+    // CHECK: @extern_nonconst_xyzzy = global
+    return &extern_nonconst_xyzzy;
+}
diff --git a/test/CodeGenCXX/key-function-vtable.cpp b/test/CodeGenCXX/key-function-vtable.cpp
index 251a14e..15c058d 100644
--- a/test/CodeGenCXX/key-function-vtable.cpp
+++ b/test/CodeGenCXX/key-function-vtable.cpp
@@ -12,11 +12,11 @@
 struct testc { virtual void a(); };
 inline void testc::a() {}
 
-// Key functions with inline specifier (PR5705)
+// Functions with inline specifier are not key functions (PR5705)
 struct testd { inline virtual void a(); };
 void testd::a() {}
 
-// Key functions with inline specifier (PR5705)
+// Functions with inline specifier are not key functions (PR5705)
 struct teste { inline virtual void a(); };
 teste *testevar = new teste;
 
@@ -32,11 +32,20 @@
 }
 testg *testgvar = new testg;
 
+struct X0 { virtual ~X0(); };
+struct X1 : X0 {
+  virtual void f();
+};
+
+inline void X1::f() { }
+
+void use_X1(X1 *x1) { x1->f(); }
+
 // FIXME: The checks are extremely difficult to get right when the globals
 // aren't alphabetized
+// CHECK: @_ZTV2X1 = weak_odr constant
 // 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/lvalue-bitcasts.cpp b/test/CodeGenCXX/lvalue-bitcasts.cpp
new file mode 100644
index 0000000..8c5fa4a
--- /dev/null
+++ b/test/CodeGenCXX/lvalue-bitcasts.cpp
@@ -0,0 +1,163 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s
+
+struct X { int i; float f; };
+struct Y { X x; };
+
+// CHECK: define void @_Z21reinterpret_cast_testRiRfR1X
+void reinterpret_cast_test(int &ir, float &fr, X &xr) {
+  // CHECK: load float**
+  // CHECK: bitcast float*
+  // CHECK: load i32*
+  ir = reinterpret_cast<int&>(fr);
+  // CHECK: load
+  // CHECK: {{bitcast.*to i32\*}}
+  // CHECK: load i32*
+  ir = reinterpret_cast<int&>(xr);
+  // CHECK: load i32
+  // CHECK: {{bitcast.*to float\*}}
+  // CHECK: load float*
+  fr = reinterpret_cast<float&>(ir);
+  // CHECK: load
+  // CHECK: {{bitcast.*to float\*}}
+  // CHECK: load float*
+  fr = reinterpret_cast<float&>(xr);
+  // CHECK: load i32**
+  // CHECK: bitcast i32*
+  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+  xr = reinterpret_cast<X&>(ir);
+  // CHECK: load float**
+  // CHECK: bitcast float*
+  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+  xr = reinterpret_cast<X&>(fr);
+  _Complex float cf;
+  _Complex float &cfr = cf;
+  // CHECK: load i32**
+  // CHECK: bitcast i32*
+  // CHECK: load float*
+  // CHECK: load float*
+  cfr = reinterpret_cast<_Complex float&>(ir);
+  // CHECK: load float**
+  // CHECK: bitcast float*
+  // CHECK: load float*
+  // CHECK: load float*
+  cfr = reinterpret_cast<_Complex float&>(fr);
+  // CHECK: bitcast
+  // CHECK: load float*
+  // CHECK: load float*
+  cfr = reinterpret_cast<_Complex float&>(xr);
+  // CHECK: ret void
+}
+
+// CHECK: define void @_Z6c_castRiRfR1X
+void c_cast(int &ir, float &fr, X &xr) {
+  // CHECK: load float**
+  // CHECK: bitcast float*
+  // CHECK: load i32*
+  ir = (int&)fr;
+  // CHECK: load
+  // CHECK: {{bitcast.*to i32\*}}
+  // CHECK: load i32*
+  ir = (int&)xr;
+  // CHECK: load i32
+  // CHECK: {{bitcast.*to float\*}}
+  // CHECK: load float*
+  fr = (float&)ir;
+  // CHECK: load
+  // CHECK: {{bitcast.*to float\*}}
+  // CHECK: load float*
+  fr = (float&)xr;
+  // CHECK: load i32**
+  // CHECK: bitcast i32*
+  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+  xr = (X&)ir;
+  // CHECK: load float**
+  // CHECK: bitcast float*
+  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+  xr = (X&)fr;
+  _Complex float cf;
+  _Complex float &cfr = cf;
+  // CHECK: load i32**
+  // CHECK: bitcast i32*
+  // CHECK: load float*
+  // CHECK: load float*
+  cfr = (_Complex float&)ir;
+  // CHECK: load float**
+  // CHECK: bitcast float*
+  // CHECK: load float*
+  // CHECK: load float*
+  cfr = (_Complex float&)fr;
+  // CHECK: bitcast
+  // CHECK: load float*
+  // CHECK: load float*
+  cfr = (_Complex float&)xr;
+  // CHECK: ret void
+}
+
+// CHECK: define void @_Z15functional_castRiRfR1X
+void functional_cast(int &ir, float &fr, X &xr) {
+  typedef int &intref;
+  typedef float &floatref;
+  typedef X &Xref;
+  // CHECK: load float**
+  // CHECK: bitcast float*
+  // CHECK: load i32*
+  ir = intref(fr);
+  // CHECK: load
+  // CHECK: {{bitcast.*to i32\*}}
+  // CHECK: load i32*
+  ir = intref(xr);
+  // CHECK: load i32
+  // CHECK: {{bitcast.*to float\*}}
+  // CHECK: load float*
+  fr = floatref(ir);
+  // CHECK: load
+  // CHECK: {{bitcast.*to float\*}}
+  // CHECK: load float*
+  fr = floatref(xr);
+  // CHECK: load i32**
+  // CHECK: bitcast i32*
+  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+  xr = Xref(ir);
+  // CHECK: load float**
+  // CHECK: bitcast float*
+  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+  xr = Xref(fr);
+  typedef _Complex float &complex_float_ref;
+  _Complex float cf;
+  _Complex float &cfr = cf;
+  // CHECK: load i32**
+  // CHECK: bitcast i32*
+  // CHECK: load float*
+  // CHECK: load float*
+  cfr = complex_float_ref(ir);
+  // CHECK: load float**
+  // CHECK: bitcast float*
+  // CHECK: load float*
+  // CHECK: load float*
+  cfr = complex_float_ref(fr);
+  // CHECK: bitcast
+  // CHECK: load float*
+  // CHECK: load float*
+  cfr = complex_float_ref(xr);
+  // CHECK: ret void
+}
+
+namespace PR6437 {
+  struct in_addr {};
+  void copy( const struct in_addr &new_addr ) {
+    int addr = (int&)new_addr;
+  }
+}
+
+namespace PR7593 {
+  void foo(double &X, char *A) {
+    X = reinterpret_cast<double&>(A[4]);
+  }
+}
+
+namespace PR7344 {
+  void serialize_annotatable_id( void*& id )
+  {
+    unsigned long l_id = (unsigned long&)id;
+  }
+}
diff --git a/test/CodeGenCXX/mangle-address-space.cpp b/test/CodeGenCXX/mangle-address-space.cpp
new file mode 100644
index 0000000..fbbcbfa
--- /dev/null
+++ b/test/CodeGenCXX/mangle-address-space.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: define void @_Z2f0Pc
+void f0(char *p) { }
+// CHECK: define void @_Z2f0PU3AS1c
+void f0(char __attribute__((address_space(1))) *p) { }
diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp
index 6f1ca55..7322171 100644
--- a/test/CodeGenCXX/mangle-exprs.cpp
+++ b/test/CodeGenCXX/mangle-exprs.cpp
@@ -39,6 +39,6 @@
   // CHECK: define weak_odr void @_ZN5Casts7static_ILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
   template void static_<4>(void*);
 
-  // CHECK: define weak_odr i64 @_ZN5Casts1fILi6EEENS_1TIXT_EEEv
+  // CHECK: define weak_odr void @_ZN5Casts1fILi6EEENS_1TIXT_EEEv
   template T<6> f<6>();
 }
diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp
new file mode 100644
index 0000000..61f8a59
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ms.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-apple-darwin10 | FileCheck %s
+
+// CHECK: @"\01?a@@3HA"
+// CHECK: @"\01?b@N@@3HA"
+// CHECK: @c
+// CHECK: @"\01?d@foo@@0FB"
+// CHECK: @"\01?e@foo@@1JC"
+// CHECK: @"\01?f@foo@@2DD"
+// CHECK: @"\01?g@bar@@2HA"
+// CHECK: @"\01?h@@3QAHA"
+// CHECK: @"\01?i@@3PAY0BE@HA"
+// CHECK: @"\01?j@@3P6GHCE@ZA"
+// CHECK: @"\01?k@@3PTfoo@@DA"
+// CHECK: @"\01?l@@3P8foo@@AAHH@ZA"
+
+int a;
+
+namespace N { int b; }
+
+static int c;
+int _c(void) {return c;}
+// CHECK: @"\01?_c@@YAHXZ"
+
+class foo {
+  static const short d;
+protected:
+  static volatile long e;
+public:
+  static const volatile char f;
+  int operator+(int a);
+};
+
+struct bar {
+  static int g;
+};
+
+union baz {
+  int a;
+  char b;
+  double c;
+};
+
+enum quux {
+  qone,
+  qtwo,
+  qthree
+};
+
+// NOTE: The calling convention is supposed to be __thiscall by default,
+// but that needs to be fixed in Sema/AST.
+int foo::operator+(int a) {return a;}
+// CHECK: @"\01??Hfoo@@QAAHH@Z"
+
+const short foo::d = 0;
+volatile long foo::e;
+const volatile char foo::f = 'C';
+
+int bar::g;
+
+extern int * const h = &a;
+
+int i[10][20];
+
+int (__stdcall *j)(signed char, unsigned char);
+
+const volatile char foo::*k;
+
+int (foo::*l)(int);
+
+// Static functions are mangled, too.
+// Also make sure calling conventions, arglists, and throw specs work.
+static void __stdcall alpha(float a, double b) throw() {}
+bool __fastcall beta(long long a, wchar_t b) throw(signed char, unsigned char) {
+// CHECK: @"\01?beta@@YI_N_J_W@Z"
+  alpha(0.f, 0.0);
+  return false;
+}
+
+// CHECK: @"\01?alpha@@YGXMN@Z"
+
+// Make sure tag-type mangling works.
+void gamma(class foo, struct bar, union baz, enum quux) {}
+// CHECK: @"\01?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z"
+
+// Make sure pointer/reference-type mangling works.
+void delta(int * const a, const long &) {}
+// CHECK: @"\01?delta@@YAXQAHABJ@Z"
+
+// Array mangling.
+void epsilon(int a[][10][20]) {}
+// CHECK: @"\01?epsilon@@YAXQAY19BE@H@Z"
+
+// Blocks mangling (Clang extension).
+void zeta(int (^)(int, int)) {}
+// CHECK: @"\01?zeta@@YAXP_EAHHH@Z@Z"
+
diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp
index 062610b..9c1e978 100644
--- a/test/CodeGenCXX/mangle-subst-std.cpp
+++ b/test/CodeGenCXX/mangle-subst-std.cpp
@@ -1,5 +1,16 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
 
+// Check mangling of Vtables, VTTs, and construction vtables that
+// involve standard substitutions.
+
+// CHECK: @_ZTVSd = weak_odr constant 
+// CHECK: @_ZTCSd0_Si = internal constant 
+// CHECK: @_ZTCSd16_So = internal constant
+// CHECK: @_ZTTSd = weak_odr constant
+// CHECK: @_ZTVSo = weak_odr constant
+// CHECK: @_ZTTSo = weak_odr constant
+// CHECK: @_ZTVSi = weak_odr constant
+// CHECK: @_ZTTSi = weak_odr constant
 namespace std {
   struct A { A(); };
   
@@ -32,9 +43,30 @@
 void f(std::string) { }
 
 namespace std {
-  template<typename, typename> struct basic_istream { };
-  template<typename, typename> struct basic_ostream { };
-  template<typename, typename> struct basic_iostream { };
+  template<typename, typename> struct basic_ios { 
+    basic_ios(int);
+    virtual ~basic_ios();
+  };
+  template<typename charT, typename traits = char_traits<charT> > 
+  struct basic_istream : virtual public basic_ios<charT, traits> { 
+    basic_istream(int x) : basic_ios<charT, traits>(x), stored(x) { }
+
+    int stored;
+  };
+  template<typename charT, typename traits = char_traits<charT> > 
+  struct basic_ostream : virtual public basic_ios<charT, traits> { 
+    basic_ostream(int x) : basic_ios<charT, traits>(x), stored(x) { }
+
+    float stored;
+  };
+
+  template<typename charT, typename traits = char_traits<charT> > 
+    struct basic_iostream : public basic_istream<charT, traits>, 
+                            public basic_ostream<charT, traits> { 
+    basic_iostream(int x) : basic_istream<charT, traits>(x),
+                            basic_ostream<charT, traits>(x),
+                            basic_ios<charT, traits>(x) { }
+  };
 }
 
 // CHECK: _Z1fSi
@@ -61,3 +93,19 @@
 template<typename, typename, typename> struct basic_string { };
 typedef basic_string<char, std::char_traits<char>, std::allocator<char> > not_string;
 void f(not_string) { }
+
+// Manglings for instantiations caused by this function are at the
+// top of the test.
+void create_streams() {
+  std::basic_iostream<char> bio(17);
+}
+
+// Make sure we don't mangle 'std' as 'St' here.
+namespace N {
+  namespace std {
+    struct A { void f(); };
+    
+    // CHECK: define void @_ZN1N3std1A1fEv
+    void A::f() { }
+  }
+}
diff --git a/test/CodeGenCXX/mangle-subst.cpp b/test/CodeGenCXX/mangle-subst.cpp
index bd06869..d83a081 100644
--- a/test/CodeGenCXX/mangle-subst.cpp
+++ b/test/CodeGenCXX/mangle-subst.cpp
@@ -67,3 +67,16 @@
   // CHECK: @_ZN2NS1fERNS_1CE
   void f(C&) { } 
 }
+
+namespace Test1 {
+
+struct A { };
+struct B { };
+
+// CHECK: @_ZN5Test11fEMNS_1BEFvvENS_1AES3_
+void f(void (B::*)(), A, A) { }
+
+// CHECK: @_ZN5Test11fEMNS_1BEFvvENS_1AES3_MS0_FvS3_EMS3_FvvE
+void f(void (B::*)(), A, A, void (B::*)(A), void (A::*)()) { }
+
+}
diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp
index 8b097ff..6a29944 100644
--- a/test/CodeGenCXX/mangle-template.cpp
+++ b/test/CodeGenCXX/mangle-template.cpp
@@ -127,3 +127,20 @@
     f<int, X>();
   }
 }
+
+namespace test10 {
+  template<typename T>
+  struct X {
+    template<typename U>
+    struct definition {
+    };
+  };
+
+  // CHECK: _ZN6test101fIidEENS_1XIT_E10definitionIT0_EES2_S5_
+  template<typename T, typename U>
+  typename X<T>::template definition<U> f(T, U) { }
+
+  void g(int i, double d) {
+    f(i, d);
+  }
+}
diff --git a/test/CodeGenCXX/mangle-unnamed.cpp b/test/CodeGenCXX/mangle-unnamed.cpp
index 4aec7db..83b46d6 100644
--- a/test/CodeGenCXX/mangle-unnamed.cpp
+++ b/test/CodeGenCXX/mangle-unnamed.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s
 
 struct S {
   virtual ~S() { }
@@ -37,3 +37,35 @@
 };
 
 int f4() { return A().a(); }
+
+int f5() {
+  static union {
+    int a;
+  };
+  
+  // CHECK: _ZZ2f5vE1a
+  return a;
+}
+
+int f6() {
+  static union {
+    union {
+      int : 1;
+    };
+    int b;
+  };
+  
+  // CHECK: _ZZ2f6vE1b
+  return b;
+}
+
+int f7() {
+  static union {
+    union {
+      int b;
+    } a;
+  };
+  
+  // CHECK: _ZZ2f7vE1a
+  return a.b;
+}
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index 8f3d356..55357c7 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -477,3 +477,150 @@
   // CHECK: define weak_odr void @_ZN6test101fILc3EEEvNS_1SIXquLb0ELc97ET_EEE(
   template void f<(char) 3>(struct S<3>);
 }
+
+namespace test11 {
+  // CHECK: @_ZN6test111fEz
+  void f(...) { }
+
+  struct A {
+    void f(...);
+  };
+  
+  // CHECK: @_ZN6test111A1fEz
+  void A::f(...) { }
+}
+
+namespace test12 {
+
+  // CHECK: _ZN6test121fENS_1AILt33000EEE
+  template <unsigned short> struct A { };
+  void f(A<33000>) { }
+}
+
+// PR7446
+namespace test13 {
+  template <template <class> class T> class A {};
+  template <class U> class B {};
+
+  template <template<class> class T> void foo(const A<T> &a) {}
+
+  // CHECK: define weak_odr void @_ZN6test133fooINS_1BEEEvRKNS_1AIT_EE(
+  template void foo(const A<B> &a);
+}
+
+namespace test14 {
+  extern "C" {
+    struct S {
+      static int a(), x;
+    };
+    // CHECK: define i32 @_ZN6test141S1aEv
+    // CHECK: load i32* @_ZN6test141S1xE
+    int S::a() { return S::x; }
+  }
+}
+
+// rdar://problem/8204122
+namespace test15 {
+  enum E { e = 3 };
+  template <int I> struct S {};
+
+  template <int I> void f(S<I + e>) {}
+
+  // CHECK: define weak_odr void @_ZN6test151fILi7EEEvNS_1SIXplT_LNS_1EE3EEEE(
+  template void f<7>(S<7 + e>);
+}
+
+// rdar://problem/8125400.  Don't crash.
+namespace test16 {
+  static union {};
+  static union { union {}; };
+  static union { struct {}; };
+  static union { union { union {}; }; };
+  static union { union { struct {}; }; };
+  static union { struct { union {}; }; };
+  static union { struct { struct {}; }; };
+}
+
+// rdar://problem/8302148
+namespace test17 {
+  template <int N> struct A {};
+
+  struct B {
+    static int foo(void);
+  };
+
+  template <class T> A<sizeof(T::foo())> func(void);
+
+  // CHECK: define void @_ZN6test174testEv()
+  // CHECK: call {{.*}} @_ZN6test174funcINS_1BEEENS_1AIXszclsrT_3fooEEEEv()
+  void test() {
+    func<B>();
+  }
+}
+
+// PR7891
+namespace test18 {
+  struct A {
+    int operator+();
+    int operator-();
+    int operator*();
+    int operator&();
+  };
+  template <int (A::*)()> struct S {};
+
+  template <typename T> void f(S<&T::operator+>) {}
+  template void f<A>(S<&A::operator+>);
+
+  template <typename T> void f(S<&T::operator- >) {}
+  template void f<A>(S<&A::operator- >);
+
+  template <typename T> void f(S<&T::operator*>) {}
+  template void f<A>(S<&A::operator*>);
+
+  template <typename T> void f(S<&T::operator&>) {}
+  template void f<A>(S<&A::operator&>);
+
+  // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_plEEE
+  // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_miEEE
+  // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_mlEEE
+  // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_anEEE
+}
+
+// rdar://problem/8332117
+namespace test19 {
+  struct A {
+    template <typename T> int f();
+    int operator+();
+    operator int();
+    template <typename T> int operator-();
+  };
+
+  template <int (A::*)()> struct S {};
+
+  template <typename T> void g (S<&T::template f<int> >) {}
+  template <typename T> void g (S<&T::operator+ >) {}
+  template <typename T> void g (S<&T::operator int>) {}
+  template <typename T> void g (S<&T::template operator- <double> >) {}
+
+  // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_1fIiEEEE(
+  template void g<A>(S<&A::f<int> >);
+  // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_plEEE(
+  template void g<A>(S<&A::operator+>);
+  // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_cviEEE(
+  template void g<A>(S<&A::operator int>);
+  // CHECK: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_miIdEEEE(
+  template void g<A>(S<&A::operator-<double> >);
+}
+
+namespace test20 {
+  template <class T> T *f(const T&);
+  template <class T> T *f(T*);
+
+  // CHECK: define weak_odr void @_ZN6test205test0IiEEvDTcl1fIPT_ELi0EEE(
+  template <class T> void test0(decltype(f<T*>(0))) {}
+  template void test0<int>(decltype(f<int*>(0)));
+
+  // CHECK: define weak_odr void @_ZN6test205test1IiEEvDTcl1fIEcvT__EEE(
+  template <class T> void test1(decltype(f<>(T()))) {}
+  template void test1<int>(decltype(f<>(int())));
+}
diff --git a/test/CodeGenCXX/member-function-pointer-calls.cpp b/test/CodeGenCXX/member-function-pointer-calls.cpp
index e1f2eb7..6f0ef81 100644
--- a/test/CodeGenCXX/member-function-pointer-calls.cpp
+++ b/test/CodeGenCXX/member-function-pointer-calls.cpp
@@ -9,18 +9,17 @@
 }
 
 // CHECK: define i32 @_Z2g1v()
+// CHECK-NEXT: {{.*}}:
+// CHECK-NEXT: ret i32 1
 int g1() {
   A a;
-  
-  // CHECK: call i32 @_ZN1A3vf1Ev
-  // CHECK-NEXT: ret i32
   return f(&a, &A::vf1);
 }
 
+// CHECK: define i32 @_Z2g2v()
+// CHECK-NEXT: {{.*}}:
+// CHECK-NEXT: ret i32 2
 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
index f7c445b..78a571e 100644
--- a/test/CodeGenCXX/member-function-pointers.cpp
+++ b/test/CodeGenCXX/member-function-pointers.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-apple-darwin9 | FileCheck -check-prefix LP32 %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv7-unknown-unknown | FileCheck -check-prefix ARM %s
 
 struct A { int a; void f(); virtual void vf1(); virtual void vf2(); };
 struct B { int b; virtual void g(); };
@@ -12,10 +14,12 @@
 // 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
+// CHECK:      @pa3 = global %0 { i64 1, i64 0 }, align 8
+// CHECK-LP32: @pa3 = global %0 { i32 1, i32 0 }, align 4
 void (A::*pa3)() = &A::vf1;
 
-// CHECK: @pa4 = global %0 { i64 9, i64 0 }, align 8
+// CHECK:      @pa4 = global %0 { i64 9, i64 0 }, align 8
+// CHECK-LP32: @pa4 = global %0 { i32 5, i32 0 }, align 4
 void (A::*pa4)() = &A::vf2;
 
 // CHECK: @pc2 = global %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 16 }, align 8
@@ -25,42 +29,38 @@
 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)
+  // CHECK: store %0 zeroinitializer, %0* @pa
   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)
+  // Is this okay?  What are LLVM's volatile semantics for structs?
+  // CHECK: volatile store %0 zeroinitializer, %0* @vpa
   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)
+  // CHECK: [[TMP:%.*]] = load %0* @pa, align 8
+  // CHECK: [[TMPADJ:%.*]] = extractvalue %0 [[TMP]], 1
+  // CHECK: [[ADJ:%.*]] = add nsw i64 [[TMPADJ]], 16
+  // CHECK: [[RES:%.*]] = insertvalue %0 [[TMP]], i64 [[ADJ]], 1
+  // CHECK: store %0 [[RES]], %0* @pc, align 8
   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)
+  // CHECK: [[TMP:%.*]] = load %0* @pc, align 8
+  // CHECK: [[TMPADJ:%.*]] = extractvalue %0 [[TMP]], 1
+  // CHECK: [[ADJ:%.*]] = sub nsw i64 [[TMPADJ]], 16
+  // CHECK: [[RES:%.*]] = insertvalue %0 [[TMP]], i64 [[ADJ]], 1
+  // CHECK: store %0 [[RES]], %0* @pa, align 8
   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]]
+  // CHECK:      store %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }
   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]]
+  // CHECK:      store %0 { i64 1, i64 0 }
+  // CHECK-LP32: store %0 { i32 1, i32 0 }
   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]]
+  // CHECK:      store %0 { i64 9, i64 0 }
+  // CHECK-LP32: store %0 { i32 5, i32 0 }
   void (A::*pa4)() = &A::vf2;
 }
 
@@ -173,3 +173,39 @@
     void (A::*pf)(bool) = &A::f;
   }
 }
+
+// PR7027 
+namespace PR7027 {
+  struct X { void test( ); };
+  void testX() { &X::test; }
+}
+
+namespace test7 {
+  struct A { void foo(); virtual void vfoo(); };
+  struct B { void foo(); virtual void vfoo(); };
+  struct C : A, B { void foo(); virtual void vfoo(); };
+
+  // CHECK-ARM: @_ZN5test74ptr0E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71A3fooEv to i32), i32 0 }
+  // CHECK-ARM: @_ZN5test74ptr1E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71B3fooEv to i32), i32 8 }
+  // CHECK-ARM: @_ZN5test74ptr2E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71C3fooEv to i32), i32 0 }
+  // CHECK-ARM: @_ZN5test74ptr3E = global {{.*}} { i32 0, i32 1 }
+  // CHECK-ARM: @_ZN5test74ptr4E = global {{.*}} { i32 0, i32 9 }
+  // CHECK-ARM: @_ZN5test74ptr5E = global {{.*}} { i32 0, i32 1 }
+  void (C::*ptr0)() = &A::foo;
+  void (C::*ptr1)() = &B::foo;
+  void (C::*ptr2)() = &C::foo;
+  void (C::*ptr3)() = &A::vfoo;
+  void (C::*ptr4)() = &B::vfoo;
+  void (C::*ptr5)() = &C::vfoo;
+}
+
+namespace test8 {
+  struct X { };
+  typedef int (X::*pmf)(int);
+  
+  // CHECK: {{define.*_ZN5test81fEv}}
+  pmf f() {
+    // CHECK: {{ret.*zeroinitializer}}
+    return pmf();
+  }
+}
diff --git a/test/CodeGenCXX/member-functions.cpp b/test/CodeGenCXX/member-functions.cpp
index 087e62c..a60d24a 100644
--- a/test/CodeGenCXX/member-functions.cpp
+++ b/test/CodeGenCXX/member-functions.cpp
@@ -58,6 +58,6 @@
 void test3() {
   T t1, t2;
   
-  // RUN: grep "call i64 @_ZN1TplERKS_" %t
+  // RUN: grep "call void @_ZN1TplERKS_" %t
   T result = t1 + t2;
 }
diff --git a/test/CodeGenCXX/member-init-assignment.cpp b/test/CodeGenCXX/member-init-assignment.cpp
new file mode 100644
index 0000000..57ab7eb
--- /dev/null
+++ b/test/CodeGenCXX/member-init-assignment.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// PR7291
+
+struct Foo {
+  unsigned file_id;
+
+  Foo(unsigned arg);
+};
+
+Foo::Foo(unsigned arg) : file_id(arg = 42)
+{ }
+
+// CHECK: define void @_ZN3FooC2Ej
+// CHECK: [[ARG:%.*]] = alloca i32
+// CHECK: store i32 42, i32* [[ARG]]
+// CHECK: store i32 42, i32* %{{.*}}
+// CHECK: ret void
diff --git a/test/CodeGenCXX/member-initializers.cpp b/test/CodeGenCXX/member-initializers.cpp
index 81dcee7..244a164 100644
--- a/test/CodeGenCXX/member-initializers.cpp
+++ b/test/CodeGenCXX/member-initializers.cpp
@@ -16,7 +16,7 @@
 int f() {
   B b;
   
-  // CHECK: call i32 @_ZN1B1fEv
+  // CHECK: ret i32 2
   return b.i;
 }
 
diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp
index ca7c52f..42d7c9f 100644
--- a/test/CodeGenCXX/new.cpp
+++ b/test/CodeGenCXX/new.cpp
@@ -73,6 +73,10 @@
   new U[n];
 }
 
+// noalias
+// CHECK: declare noalias i8* @_Znam
+void *operator new[](size_t);
+
 void t9() {
   bool b;
 
@@ -90,9 +94,67 @@
   return new(1, 2, 3.45, 100) A;
 }
 
-struct B { };
-void t11() {
+// CHECK: define void @_Z3t11i
+struct B { int a; };
+struct Bmemptr { int Bmemptr::* memptr; int a; };
+
+void t11(int n) {
   // CHECK: call noalias i8* @_Znwm
   // CHECK: call void @llvm.memset.p0i8.i64(
   B* b = new B();
+
+  // CHECK: call noalias i8* @_Znam
+  // CHECK: {{call void.*llvm.memset.p0i8.i64.*i8 0, i64 %}}
+  B *b2 = new B[n]();
+
+  // CHECK: call noalias i8* @_Znam
+  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+  // CHECK: br
+  Bmemptr *b_memptr = new Bmemptr[n]();
+  
+  // CHECK: ret void
+}
+
+struct Empty { };
+
+// We don't need to initialize an empty class.
+// CHECK: define void @_Z3t12v
+void t12() {
+  // CHECK: call noalias i8* @_Znam
+  // CHECK-NOT: br
+  (void)new Empty[10];
+
+  // CHECK: call noalias i8* @_Znam
+  // CHECK-NOT: br
+  (void)new Empty[10]();
+
+  // CHECK: ret void
+}
+
+// Zero-initialization
+// CHECK: define void @_Z3t13i
+void t13(int n) {
+  // CHECK: call noalias i8* @_Znwm
+  // CHECK: store i32 0, i32*
+  (void)new int();
+
+  // CHECK: call noalias i8* @_Znam
+  // CHECK: {{call void.*llvm.memset.p0i8.i64.*i8 0, i64 %}}
+  (void)new int[n]();
+
+  // CHECK-NEXT: ret void
+}
+
+struct Alloc{
+  int x;
+  void* operator new[](size_t size);
+  void operator delete[](void* p);
+  ~Alloc();
+};
+
+void f() {
+  // CHECK: call i8* @_ZN5AllocnaEm(i64 808)
+  // CHECK: store i64 200
+  // CHECK: call void @_ZN5AllocdaEPv(i8*
+  delete[] new Alloc[10][20];
 }
diff --git a/test/CodeGenCXX/nonconst-init.cpp b/test/CodeGenCXX/nonconst-init.cpp
new file mode 100644
index 0000000..21129b9
--- /dev/null
+++ b/test/CodeGenCXX/nonconst-init.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+int a();
+// CHECK: call i32 @_Z1av()
+struct x {int x, y : 10;} x = {1, a()};
diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp
new file mode 100644
index 0000000..8d19b1e
--- /dev/null
+++ b/test/CodeGenCXX/nrvo.cpp
@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 -emit-llvm -O1 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -O1 -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s
+
+// Test code generation for the named return value optimization.
+class X {
+public:
+  X();
+  X(const X&);
+  ~X();
+};
+
+// CHECK: define void @_Z5test0v
+// CHECK-EH: define void @_Z5test0v
+X test0() {
+  X x;
+  // CHECK:          call void @_ZN1XC1Ev
+  // CHECK-NEXT:     ret void
+
+  // CHECK-EH:       call void @_ZN1XC1Ev
+  // CHECK-EH-NEXT:  ret void
+  return x;
+}
+
+// CHECK: define void @_Z5test1b(
+// CHECK-EH: define void @_Z5test1b(
+X test1(bool B) {
+  // CHECK:      tail call void @_ZN1XC1Ev
+  // CHECK-NEXT: ret void
+  X x;
+  if (B)
+    return (x);
+  return x;
+  // CHECK-EH:      tail call void @_ZN1XC1Ev
+  // CHECK-EH-NEXT: ret void
+}
+
+// CHECK: define void @_Z5test2b
+// CHECK-EH: define void @_Z5test2b
+X test2(bool B) {
+  // No NRVO.
+
+  X x;
+  X y;
+  if (B)
+    return y;
+  return x;
+
+  // CHECK: call void @_ZN1XC1Ev
+  // CHECK-NEXT: call void @_ZN1XC1Ev
+  // CHECK: call void @_ZN1XC1ERKS_
+  // CHECK: call void @_ZN1XC1ERKS_
+  // CHECK: call void @_ZN1XD1Ev
+  // CHECK: call void @_ZN1XD1Ev
+  // CHECK: ret void
+
+  // The block ordering in the -fexceptions IR is unfortunate.
+
+  // CHECK-EH:      call void @_ZN1XC1Ev
+  // CHECK-EH-NEXT: invoke void @_ZN1XC1Ev
+  // -> %invoke.cont, %lpad
+
+  // %invoke.cont:
+  // CHECK-EH:      br i1
+  // -> %if.then, %if.end
+
+  // %if.then: returning 'x'
+  // CHECK-EH:      invoke void @_ZN1XC1ERKS_
+  // -> %cleanup, %lpad1
+
+  // %lpad: landing pad for ctor of 'y', dtor of 'y'
+  // CHECK-EH:      call i8* @llvm.eh.exception()
+  // CHECK-EH: call i32 (i8*, i8*, ...)* @llvm.eh.selector
+  // CHECK-EH-NEXT: br label
+  // -> %eh.cleanup
+
+  // %lpad1: landing pad for return copy ctors, EH cleanup for 'y'
+  // CHECK-EH: invoke void @_ZN1XD1Ev
+  // -> %eh.cleanup, %terminate.lpad
+
+  // %if.end: returning 'y'
+  // CHECK-EH: invoke void @_ZN1XC1ERKS_
+  // -> %cleanup, %lpad1
+
+  // %cleanup: normal cleanup for 'y'
+  // CHECK-EH: invoke void @_ZN1XD1Ev
+  // -> %invoke.cont11, %lpad
+
+  // %invoke.cont11: normal cleanup for 'x'
+  // CHECK-EH:      call void @_ZN1XD1Ev
+  // CHECK-EH-NEXT: ret void
+
+  // %eh.cleanup:  EH cleanup for 'x'
+  // CHECK-EH: invoke void @_ZN1XD1Ev
+  // -> %invoke.cont17, %terminate.lpad
+
+  // %invoke.cont17: rethrow block for %eh.cleanup.
+  // This really should be elsewhere in the function.
+  // CHECK-EH:      call void @_Unwind_Resume_or_Rethrow
+  // CHECK-EH-NEXT: unreachable
+
+  // %terminate.lpad: terminate landing pad.
+  // CHECK-EH:      call i8* @llvm.eh.exception()
+  // CHECK-EH-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector
+  // CHECK-EH-NEXT: call void @_ZSt9terminatev()
+  // CHECK-EH-NEXT: unreachable
+
+}
+
+X test3(bool B) {
+  // FIXME: We don't manage to apply NRVO here, although we could.
+  {
+    X y;
+    return y;
+  }
+  X x;
+  return x;
+}
+
+extern "C" void exit(int) throw();
+
+// CHECK: define void @_Z5test4b
+X test4(bool B) {
+  {
+    // CHECK: tail call void @_ZN1XC1Ev
+    X x;
+    // CHECK: br i1
+    if (B)
+      return x;
+  }
+  // CHECK: tail call void @_ZN1XD1Ev
+  // CHECK: tail call void @exit(i32 1)
+  exit(1);
+}
diff --git a/test/CodeGenCXX/operator-new.cpp b/test/CodeGenCXX/operator-new.cpp
index f718fae..df3c114 100644
--- a/test/CodeGenCXX/operator-new.cpp
+++ b/test/CodeGenCXX/operator-new.cpp
@@ -11,7 +11,19 @@
 };
 
 void f1() {
-  // CHECK-SANE: declare noalias i8* @_Znwj(
-  // CHECK-SANENOT: declare i8* @_Znwj(
+  // SANE: declare noalias i8* @_Znwj(
+  // SANENOT: declare i8* @_Znwj(
   new teste();
 }
+
+
+// rdar://5739832 - operator new should check for overflow in multiply.
+void *f2(long N) {
+  return new int[N];
+  
+// SANE: call{{.*}}@llvm.umul.with.overflow
+// SANE: extractvalue
+// SANE: br i1
+// SANE: = phi {{.*}} [ {{.*}} ], [ -1,
+// SANE:  call noalias i8* @_Znaj(
+}
diff --git a/test/CodeGenCXX/pointers-to-data-members.cpp b/test/CodeGenCXX/pointers-to-data-members.cpp
index d96eb03..60c1661 100644
--- a/test/CodeGenCXX/pointers-to-data-members.cpp
+++ b/test/CodeGenCXX/pointers-to-data-members.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 | FileCheck %s
-
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 -O3 | FileCheck --check-prefix=CHECK-O3 %s
 struct A { int a; int b; };
 struct B { int b; };
 struct C : B, A { };
@@ -35,6 +35,21 @@
       int A::*pa;
     } s;
   } ss;
+  
+  struct A {
+    int A::*a;
+    int b;
+  };
+
+  struct B {
+    A a[10];
+    char c;
+    int B::*b;
+  };
+
+  struct C : A, B { int j; };
+  // CHECK: @_ZN8ZeroInit1cE = global %"struct.ZeroInit::C" { [16 x i8] c"\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00", [176 x i8] c"\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF", i32 0, [4 x i8] zeroinitializer }
+  C c;
 }
 
 // PR5674
@@ -50,15 +65,21 @@
 int C::*pc;
 
 void f() {
-  // CHECK: store i64 -1, i64* @_ZN5Casts2paE
+  // CHECK:      store i64 -1, i64* @_ZN5Casts2paE
   pa = 0;
 
-  // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 {{.*}}, 4
-  // CHECK: store i64 [[ADJ]], i64* @_ZN5Casts2pcE
+  // CHECK-NEXT: [[TMP:%.*]] = load i64* @_ZN5Casts2paE, align 8
+  // CHECK-NEXT: [[ADJ:%.*]] = add nsw i64 [[TMP]], 4
+  // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 [[TMP]], -1
+  // CHECK-NEXT: [[RES:%.*]] = select i1 [[ISNULL]], i64 [[TMP]], i64 [[ADJ]]
+  // CHECK-NEXT: store i64 [[RES]], i64* @_ZN5Casts2pcE
   pc = pa;
 
-  // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = sub i64 {{.*}}, 4
-  // CHECK: store i64 [[ADJ]], i64* @_ZN5Casts2paE
+  // CHECK-NEXT: [[TMP:%.*]] = load i64* @_ZN5Casts2pcE, align 8
+  // CHECK-NEXT: [[ADJ:%.*]] = sub nsw i64 [[TMP]], 4
+  // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 [[TMP]], -1
+  // CHECK-NEXT: [[RES:%.*]] = select i1 [[ISNULL]], i64 [[TMP]], i64 [[ADJ]]
+  // CHECK-NEXT: store i64 [[RES]], i64* @_ZN5Casts2paE
   pa = static_cast<int A::*>(pc);
 }
 
@@ -85,3 +106,86 @@
     if (0 == a) { }
   }
 }
+
+namespace ValueInit {
+
+struct A {
+  int A::*a;
+
+  char c;
+
+  A();
+};
+
+// CHECK: define void @_ZN9ValueInit1AC2Ev
+// CHECK: store i64 -1, i64*
+// CHECK: ret void
+A::A() : a() {}
+
+}
+
+namespace PR7139 {
+
+struct pair {
+  int first;
+  int second;
+};
+
+typedef int pair::*ptr_to_member_type;
+
+struct ptr_to_member_struct { 
+  ptr_to_member_type data;
+  int i;
+};
+
+struct A {
+  ptr_to_member_struct a;
+
+  A() : a() {}
+};
+
+// CHECK-O3: define zeroext i1 @_ZN6PR71395checkEv() nounwind readnone
+bool check() {
+  // CHECK-O3: ret i1 true
+  return A().a.data == 0;
+}
+
+// CHECK-O3: define zeroext i1 @_ZN6PR71396check2Ev() nounwind readnone
+bool check2() {
+  // CHECK-O3: ret i1 true
+  return ptr_to_member_type() == 0;
+}
+
+}
+
+namespace VirtualBases {
+
+struct A {
+  char c;
+  int A::*i;
+};
+
+// FIXME: A::i should be initialized to -1 here.
+struct B : virtual A { };
+B b;
+
+// FIXME: A::i should be initialized to -1 here.
+struct C : virtual A { int A::*i; };
+C c;
+
+// FIXME: C::A::i should be initialized to -1 here.
+struct D : C { int A::*i; };
+D d;
+
+}
+
+namespace Test1 {
+
+// Don't crash when A contains a bit-field.
+struct A {
+  int A::* a;
+  int b : 10;
+};
+A a;
+
+}
diff --git a/test/CodeGenCXX/pragma-visibility.cpp b/test/CodeGenCXX/pragma-visibility.cpp
new file mode 100644
index 0000000..05de786
--- /dev/null
+++ b/test/CodeGenCXX/pragma-visibility.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+#pragma GCC visibility push(hidden)
+struct x {
+  static int y;
+};
+#pragma GCC visibility pop
+int x::y = 10;
+// CHECK: @_ZN1x1yE = hidden global
+
+#pragma GCC visibility push(hidden)
+struct __attribute((visibility("default"))) x2 {
+  static int y;
+};
+int x2::y = 10;
+// CHECK: @_ZN2x21yE = global
+#pragma GCC visibility pop
+
+#pragma GCC visibility push(hidden)
+struct x3 {
+  static int y;
+} __attribute((visibility("default")));
+int x3::y = 10;
+// CHECK: @_ZN2x31yE = global
+#pragma GCC visibility pop
+
+#pragma GCC visibility push(hidden)
+template<class T> struct x4 {
+  static int y;
+};
+#pragma GCC visibility pop
+template<> int x4<int>::y = 10;
+// CHECK: @_ZN2x4IiE1yE = hidden global i32
+
+#pragma GCC visibility push(hidden)
+template<int x> int f() { return x; }
+extern "C" int g() { return f<3>(); }
+#pragma GCC visibility pop
+// CHECK: define hidden i32 @g()
+// CHECK: define linkonce_odr hidden i32 @_Z1fILi3EEiv()
+
+#pragma GCC visibility push(hidden)
+template<class T> struct x5 {
+  void y();
+};
+#pragma GCC visibility pop
+template<> void x5<int>::y() {}
+// CHECK: define hidden void @_ZN2x5IiE1yEv
+
+#pragma GCC visibility push(hidden)
+namespace n __attribute((visibility("default"))) {
+  void f() {}
+  // CHECK: define void @_ZN1n1fEv
+}
+#pragma GCC visibility pop
+
+namespace n __attribute((visibility("default")))  {
+  extern int foofoo; // FIXME: Shouldn't be necessary, but otherwise the pragma
+                     //        gets to Sema before the namespace!
+#pragma GCC visibility push(hidden)
+  void g() {}
+  // CHECK: define hidden void @_ZN1n1gEv
+#pragma GCC visibility pop
+}
+
+namespace n __attribute((visibility("hidden"))) {
+  extern int foofoo; // FIXME: Shouldn't be necessary, but otherwise the pragma
+                     //        gets to Sema before the namespace!
+  #pragma GCC visibility pop
+  void h() {}
+  // CHECK: define void @_ZN1n1hEv
+}
diff --git a/test/CodeGenCXX/reference-cast.cpp b/test/CodeGenCXX/reference-cast.cpp
new file mode 100644
index 0000000..585d1db
--- /dev/null
+++ b/test/CodeGenCXX/reference-cast.cpp
@@ -0,0 +1,170 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 -o - %s | FileCheck %s
+
+// PR6024
+extern int i;
+
+// CHECK: define i32* @_Z16lvalue_noop_castv() nounwind
+const int &lvalue_noop_cast() {
+  if (i == 0)
+    // CHECK: store i32 17, i32*
+    return (const int&)17;
+  else if (i == 1)
+    // CHECK: store i32 17, i32*
+    return static_cast<const int&>(17);
+    // CHECK: store i32 17, i32*
+  return 17;
+}
+
+// CHECK: define i16* @_Z20lvalue_integral_castv() 
+const short &lvalue_integral_cast() {
+  if (i == 0)
+    // CHECK: store i16 17, i16*
+    return (const short&)17;
+  else if (i == 1)
+    // CHECK: store i16 17, i16*
+    return static_cast<const short&>(17);
+  // CHECK: store i16 17, i16*
+  return 17;
+}
+
+// CHECK: define i16* @_Z29lvalue_floating_integral_castv()
+const short &lvalue_floating_integral_cast() {
+  if (i == 0)
+    // CHECK: store i16 17, i16*
+    return (const short&)17.5;
+  else if (i == 1)
+    // CHECK: store i16 17, i16*
+    return static_cast<const short&>(17.5);
+  // CHECK: store i16 17, i16*
+  return 17.5;
+}
+
+// CHECK: define float* @_Z29lvalue_integral_floating_castv()
+const float &lvalue_integral_floating_cast() {
+  if (i == 0)
+    // CHECK: store float 1.700000e+{{0*}}1, float*
+    return (const float&)17;
+  else if (i == 1)
+    // CHECK: store float 1.700000e+{{0*}}1, float*
+    return static_cast<const float&>(17);
+  // CHECK: store float 1.700000e+{{0*}}1, float*
+  return 17;
+}
+
+// CHECK: define float* @_Z20lvalue_floating_castv()
+const float &lvalue_floating_cast() {
+  if (i == 0)
+    // CHECK: store float 1.700000e+{{0*}}1, float*
+    return (const float&)17.0;
+  else if (i == 1)
+    // CHECK: store float 1.700000e+{{0*}}1, float*
+    return static_cast<const float&>(17.0);
+  // CHECK: store float 1.700000e+{{0*}}1, float*
+  return 17.0;
+}
+
+int get_int();
+
+// CHECK: define i8* @_Z24lvalue_integer_bool_castv()
+const bool &lvalue_integer_bool_cast() {
+  if (i == 0)
+    // CHECK: call i32 @_Z7get_intv()
+    // CHECK: store i8
+    return (const bool&)get_int();
+  else if (i == 1)
+    // CHECK: call i32 @_Z7get_intv()
+    // CHECK: store i8
+    return static_cast<const bool&>(get_int());
+  // CHECK: call i32 @_Z7get_intv()
+  // CHECK: store i8
+  return get_int();
+}
+
+float get_float();
+
+// CHECK: define i8* @_Z25lvalue_floating_bool_castv()
+const bool &lvalue_floating_bool_cast() {
+  if (i == 0)
+    // CHECK: call float @_Z9get_floatv()
+    // CHECK: fcmp une float
+    // CHECK: store i8
+    return (const bool&)get_float();
+  else if (i == 1)
+    // CHECK: call float @_Z9get_floatv()
+    // CHECK: fcmp une float
+    // CHECK: store i8
+    return static_cast<const bool&>(get_float());
+  // CHECK: call float @_Z9get_floatv()
+  // CHECK: fcmp une float
+  // CHECK: store i8
+  return get_float();
+}
+
+struct X { };
+typedef int X::*pm;
+typedef int (X::*pmf)(int);
+
+pm get_pointer_to_member_data();
+pmf get_pointer_to_member_function();
+
+// CHECK: define i8* @_Z26lvalue_ptrmem_to_bool_castv()
+const bool &lvalue_ptrmem_to_bool_cast() {
+  if (i == 0)
+    // CHECK: call i64 @_Z26get_pointer_to_member_datav()
+    // CHECK: store i8
+    // CHECK: store i8*
+    return (const bool&)get_pointer_to_member_data();
+  else if (i == 1)
+    // CHECK: call i64 @_Z26get_pointer_to_member_datav()
+    // CHECK: store i8
+    // CHECK: store i8*
+    return static_cast<const bool&>(get_pointer_to_member_data());
+  // CHECK: call i64 @_Z26get_pointer_to_member_datav()
+  // CHECK: store i8
+  // CHECK: store i8*
+  return get_pointer_to_member_data();
+}
+
+// CHECK: define i8* @_Z27lvalue_ptrmem_to_bool_cast2v
+const bool &lvalue_ptrmem_to_bool_cast2() {
+  if (i == 0)
+    // CHECK: {{call.*_Z30get_pointer_to_member_functionv}}
+    // CHECK: store i8
+    // CHECK: store i8*
+    return (const bool&)get_pointer_to_member_function();
+  else if (i == 1)
+    // CHECK: {{call.*_Z30get_pointer_to_member_functionv}}
+    // CHECK: store i8
+    // CHECK: store i8*
+    return static_cast<const bool&>(get_pointer_to_member_function());
+  // CHECK: {{call.*_Z30get_pointer_to_member_functionv}}
+  // CHECK: store i8
+  // CHECK: store i8*
+  return get_pointer_to_member_function();
+}
+
+_Complex double get_complex_double();
+
+// CHECK: {{define.*_Z2f1v}}
+const _Complex float &f1() {
+  if (i == 0)
+    // CHECK: {{call.*_Z18get_complex_doublev}}
+    // CHECK: fptrunc
+    // CHECK: fptrunc
+    // CHECK: store float
+    // CHECK: store float
+    return (const _Complex float&)get_complex_double();
+  else if (i == 1)
+    // CHECK: {{call.*_Z18get_complex_doublev}}
+    // CHECK: fptrunc
+    // CHECK: fptrunc
+    // CHECK: store float
+    // CHECK: store float
+    return static_cast<const _Complex float&>(get_complex_double());
+  // CHECK: {{call.*_Z18get_complex_doublev}}
+  // CHECK: fptrunc
+  // CHECK: fptrunc
+  // CHECK: store float
+  // CHECK: store float
+  return get_complex_double();
+}
diff --git a/test/CodeGenCXX/reference-in-block-args.cpp b/test/CodeGenCXX/reference-in-block-args.cpp
new file mode 100644
index 0000000..1ff1ae2
--- /dev/null
+++ b/test/CodeGenCXX/reference-in-block-args.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fblocks %s -emit-llvm -o %t
+// rdar: // 8041962
+
+extern "C" int printf(const char*, ...);
+
+struct ST {
+     int filler; 
+     int referrer;
+};
+
+void OUTER_BLOCK(void (^fixer)(ST& ref)) {
+    ST ref = {2, 100};
+    fixer(ref);
+}
+  
+void INNER_BLOCK(int (^largeDo) ()) {
+	printf("%d\n", largeDo());
+}
+
+void scan() {
+            OUTER_BLOCK(^(ST &ref) {
+                INNER_BLOCK(^() { return ref.referrer + ref.filler; });
+            });
+
+}
+
+int main() {
+    scan();
+}
diff --git a/test/CodeGenCXX/reference-in-blocks.cpp b/test/CodeGenCXX/reference-in-blocks.cpp
index c020bab..388ec7c 100644
--- a/test/CodeGenCXX/reference-in-blocks.cpp
+++ b/test/CodeGenCXX/reference-in-blocks.cpp
@@ -9,6 +9,26 @@
         T get() {return _i;};
 };
 
+// rdar: // 7495203
+class A {
+    public:
+	A() : field(10), d1(3.14) {}
+	void F();
+	void S() {
+	  printf(" field = %d\n", field);
+	  printf(" field = %f\n", d1);
+	}
+	int field;
+	double d1;
+};
+
+void A::F()
+    {
+	__block A &tlc = *this;
+	// crashed in code gen (radar 7495203)
+        ^{ tlc.S(); }();
+    }
+
 int main() {
 
         // works
@@ -16,6 +36,8 @@
 
         //crashes in godegen?
         void (^bl2)(range<int>& ) = ^(range<int>& i){printf("Hello Blocks %d\n", i.get()); };
+
+	A *a = new A;
+	a->F();
         return 0;
 }
-
diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp
index 5a5947d..d2ad980 100644
--- a/test/CodeGenCXX/references.cpp
+++ b/test/CodeGenCXX/references.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -verify -emit-llvm -o - %s | FileCheck %s
 void t1() {
   extern int& a;
   int b = a; 
@@ -150,8 +150,111 @@
 
 // PR6024
 // CHECK: @_Z2f2v()
-// CHECK: alloca
-// CHECK: store
-// CHECK: load
-// CHECK: ret
+// CHECK: alloca i32,
+// CHECK-NEXT: store
+// CHECK-NEXT: ret
 const int &f2() { return 0; }
+
+// Don't constant fold const reference parameters with default arguments to
+// their default arguments.
+namespace N1 {
+  const int foo = 1;
+  // CHECK: @_ZN2N14test
+  void test(const int& arg = foo) {
+    // Ensure this array is on the stack where we can set values instead of
+    // being a global constant.
+    // CHECK: %args_array = alloca
+    const int* const args_array[] = { &arg };
+  }
+}
+
+// Bind to subobjects while extending the life of the complete object.
+namespace N2 {
+  class X {
+  public:
+    X(const X&);
+    X &operator=(const X&);
+    ~X();
+  };
+
+  struct P {
+    X first;
+  };
+
+  P getP();
+
+  // CHECK: define void @_ZN2N21fEi
+  // CHECK: call void @_ZN2N24getPEv
+  // CHECK: getelementptr inbounds
+  // CHECK: store i32 17
+  // CHECK: call void @_ZN2N21PD1Ev
+  void f(int i) {
+    const X& xr = getP().first;
+    i = 17;
+  }
+
+  struct SpaceWaster {
+    int i, j;
+  };
+
+  struct ReallyHasX {
+    X x;
+  };
+
+  struct HasX : ReallyHasX { };
+
+  struct HasXContainer {
+    HasX has;
+  };
+
+  struct Y : SpaceWaster, HasXContainer { };
+  struct Z : SpaceWaster, Y { };
+
+  Z getZ();
+
+  // CHECK: define void @_ZN2N21gEi
+  // CHECK: call void @_ZN2N24getZEv
+  // CHECK: {{getelementptr inbounds.*i32 0, i32 0}}
+  // CHECK: {{getelementptr inbounds.*i32 0, i32 0}}
+  // CHECK: store i32 19
+  // CHECK: call void @_ZN2N21ZD1Ev
+  // CHECK: ret void
+  void g(int i) {
+    const X &xr = getZ().has.x;
+    i = 19;    
+  }
+}
+
+namespace N3 {
+
+// PR7326
+
+struct A {
+  explicit A(int);
+  ~A();
+};
+
+// CHECK: define internal void @__cxx_global_var_init
+// CHECK: call void @_ZN2N31AC1Ei(%"class.N2::X"* @_ZGRN2N35sA123E, i32 123)
+// CHECK: call i32 @__cxa_atexit
+// CHECK: ret void
+const A &sA123 = A(123);
+}
+
+namespace N4 {
+  
+struct A {
+  A();
+  ~A();
+};
+
+void f() {
+  // CHECK: define void @_ZN2N41fEv
+  // CHECK: call void @_ZN2N41AC1Ev(%"class.N2::X"* @_ZGRZN2N41fEvE2ar)
+  // CHECK: call i32 @__cxa_atexit
+  // CHECK: ret void
+  static const A& ar = A();
+  
+}
+}
+
diff --git a/test/CodeGenCXX/rtti-fundamental.cpp b/test/CodeGenCXX/rtti-fundamental.cpp
index 6826321..7f80d99 100644
--- a/test/CodeGenCXX/rtti-fundamental.cpp
+++ b/test/CodeGenCXX/rtti-fundamental.cpp
@@ -14,60 +14,60 @@
   __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
+// CHECK: @_ZTIv = constant
+// CHECK: @_ZTIPv = constant
+// CHECK: @_ZTIPKv = constant
+// CHECK: @_ZTIDi = constant
+// CHECK: @_ZTIPDi = constant
+// CHECK: @_ZTIPKDi = constant
+// CHECK: @_ZTIDs = constant
+// CHECK: @_ZTIPDs = constant
+// CHECK: @_ZTIPKDs = constant
+// CHECK: @_ZTIy = constant
+// CHECK: @_ZTIPy = constant
+// CHECK: @_ZTIPKy = constant
+// CHECK: @_ZTIx = constant
+// CHECK: @_ZTIPx = constant
+// CHECK: @_ZTIPKx = constant
+// CHECK: @_ZTIw = constant
+// CHECK: @_ZTIPw = constant
+// CHECK: @_ZTIPKw = constant
+// CHECK: @_ZTIt = constant
+// CHECK: @_ZTIPt = constant
+// CHECK: @_ZTIPKt = constant
+// CHECK: @_ZTIs = constant
+// CHECK: @_ZTIPs = constant
+// CHECK: @_ZTIPKs = constant
+// CHECK: @_ZTIm = constant
+// CHECK: @_ZTIPm = constant
+// CHECK: @_ZTIPKm = constant
+// CHECK: @_ZTIl = constant
+// CHECK: @_ZTIPl = constant
+// CHECK: @_ZTIPKl = constant
+// CHECK: @_ZTIj = constant
+// CHECK: @_ZTIPj = constant
+// CHECK: @_ZTIPKj = constant
+// CHECK: @_ZTIi = constant
+// CHECK: @_ZTIPi = constant
+// CHECK: @_ZTIPKi = constant
+// CHECK: @_ZTIh = constant
+// CHECK: @_ZTIPh = constant
+// CHECK: @_ZTIPKh = constant
+// CHECK: @_ZTIf = constant
+// CHECK: @_ZTIPf = constant
+// CHECK: @_ZTIPKf = constant
+// CHECK: @_ZTIe = constant
+// CHECK: @_ZTIPe = constant
+// CHECK: @_ZTIPKe = constant
+// CHECK: @_ZTId = constant
+// CHECK: @_ZTIPd = constant
+// CHECK: @_ZTIPKd = constant
+// CHECK: @_ZTIc = constant
+// CHECK: @_ZTIPc = constant
+// CHECK: @_ZTIPKc = constant
+// CHECK: @_ZTIb = constant
+// CHECK: @_ZTIPb = constant
+// CHECK: @_ZTIPKb = constant
+// CHECK: @_ZTIa = constant
+// CHECK: @_ZTIPa = constant
+// CHECK: @_ZTIPKa = constant
diff --git a/test/CodeGenCXX/rtti-layout.cpp b/test/CodeGenCXX/rtti-layout.cpp
index 1ad87fb..7128c4e 100644
--- a/test/CodeGenCXX/rtti-layout.cpp
+++ b/test/CodeGenCXX/rtti-layout.cpp
@@ -93,6 +93,14 @@
 #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)))
 
+struct B {
+  static int const volatile (*a)[10];
+  static int (*b)[10];
+  
+  static int const volatile (B::*c)[10];
+  static int (B::*d)[10];
+};
+
 // CHECK: define i32 @_Z1fv()
 int f() {
   // Vectors should be treated as fundamental types.
@@ -168,6 +176,12 @@
   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));
 
+  // Check that when stripping qualifiers off the pointee type, we correctly handle arrays.
+  CHECK(to<__pbase_type_info>(typeid(B::a)).__flags == (__pbase_type_info::__const_mask | __pbase_type_info::__volatile_mask));
+  CHECK(to<__pbase_type_info>(typeid(B::a)).__pointee == to<__pbase_type_info>(typeid(B::b)).__pointee);
+  CHECK(to<__pbase_type_info>(typeid(B::c)).__flags == (__pbase_type_info::__const_mask | __pbase_type_info::__volatile_mask));
+  CHECK(to<__pbase_type_info>(typeid(B::c)).__pointee == to<__pbase_type_info>(typeid(B::d)).__pointee);
+
   // Success!
   // CHECK: ret i32 0
   return 0;
diff --git a/test/CodeGenCXX/rtti-linkage.cpp b/test/CodeGenCXX/rtti-linkage.cpp
index b9eb5b4..efa336d 100644
--- a/test/CodeGenCXX/rtti-linkage.cpp
+++ b/test/CodeGenCXX/rtti-linkage.cpp
@@ -1,47 +1,58 @@
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fhidden-weak-vtables -emit-llvm -o - | sort | FileCheck %s
+
+// FIXME: Fails on Win32, dunno why.
+// XFAIL: win32
+
 #include <typeinfo>
 
-// CHECK: _ZTS1B = constant
-// CHECK: _ZTS1A = weak_odr constant
-// CHECK: _ZTI1A = weak_odr constant
+
+
+// CHECK: _ZTIN12_GLOBAL__N_11DE to
+
+
+
+// CHECK: _ZTI1A = weak_odr hidden 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: _ZTI1TILj0EE = weak_odr constant
+// CHECK: _ZTI1TILj1EE = weak_odr constant
+// CHECK: _ZTI1TILj2EE = external constant
+// CHECK: _ZTIA10_i = weak_odr hidden 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: _ZTIFvvE = weak_odr hidden constant
+// CHECK: _ZTIM1A1C = internal constant
+// CHECK: _ZTIM1AP1C = internal constant
+// CHECK: _ZTIM1CPS_ = internal constant
+// CHECK: _ZTIM1CS_ = internal constant
+// CHECK: _ZTIM1Ci = internal constant
+// CHECK: _ZTIN12_GLOBAL__N_11DE = internal constant
 // CHECK: _ZTIN12_GLOBAL__N_11EE = internal constant
+// CHECK: _ZTIP1C = internal constant
+// CHECK: _ZTIPFvvE = weak_odr hidden constant
+// CHECK: _ZTIPM1Ci = internal constant
+// CHECK: _ZTIPN12_GLOBAL__N_11DE = internal constant
+// CHECK: _ZTIPP1C = internal constant
+// CHECK: _ZTS1A = weak_odr constant
+// CHECK: _ZTS1B = constant
+// CHECK: _ZTS1C = internal constant
+// CHECK: _ZTS1F = weak_odr constant
+// CHECK: _ZTSA10_i = weak_odr constant
+// CHECK: _ZTSFN12_GLOBAL__N_11DEvE = internal constant
+// CHECK: _ZTSFvN12_GLOBAL__N_11DEE = internal constant
+// CHECK: _ZTSFvvE = weak_odr constant
+// CHECK: _ZTSM1A1C = internal constant
+// CHECK: _ZTSM1AP1C = internal constant
+// CHECK: _ZTSM1CPS_ = internal constant
+// CHECK: _ZTSM1CS_ = internal constant
+// CHECK: _ZTSM1Ci = internal constant
+// CHECK: _ZTSN12_GLOBAL__N_11DE = internal constant
+// CHECK: _ZTSN12_GLOBAL__N_11EE = internal constant
+// CHECK: _ZTSP1C = internal constant
+// CHECK: _ZTSPFvvE = weak_odr constant
+// CHECK: _ZTSPM1Ci = internal constant
+// CHECK: _ZTSPN12_GLOBAL__N_11DE = internal constant
+// CHECK: _ZTSPP1C = internal constant
 
 // A has no key function, so its RTTI data should be weak_odr.
 struct A { };
@@ -99,6 +110,25 @@
   
   (void)typeid(E);
   
-  // CHECK: _ZTIN12_GLOBAL__N_11DE to
   return typeid(getD());  
 }
+
+namespace Arrays {
+  struct A {
+    static const int a[10];
+  };
+  const std::type_info &f() {
+    return typeid(A::a);
+  }
+}
+
+template <unsigned N> class T {
+  virtual void anchor() {}
+};
+template class T<1>;
+template <> class T<2> { virtual void anchor(); };
+void t3() {
+  (void) typeid(T<0>);
+  (void) typeid(T<1>);
+  (void) typeid(T<2>);
+}
diff --git a/test/CodeGenCXX/sel-address.mm b/test/CodeGenCXX/sel-address.mm
new file mode 100644
index 0000000..c3db9a7
--- /dev/null
+++ b/test/CodeGenCXX/sel-address.mm
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -verify -emit-llvm -o %t
+// pr7390
+
+void f(const SEL& v2) {}
+void g() {
+  f(@selector(dealloc));
+
+  SEL s = @selector(dealloc);
+ SEL* ps = &s;
+
+ @selector(dealloc) = s;  // expected-error {{expression is not assignable}}
+
+ SEL* ps2 = &@selector(dealloc);
+}
diff --git a/test/CodeGenCXX/static-init-3.cpp b/test/CodeGenCXX/static-init-3.cpp
new file mode 100644
index 0000000..5bf76a6
--- /dev/null
+++ b/test/CodeGenCXX/static-init-3.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10.0.0 -o - %s | FileCheck %s
+
+// PR7050
+template<class T> struct X0 : public T { };
+
+template <class T>
+struct X1
+{
+     static T & instance;
+    // include this to provoke instantiation at pre-execution time
+    static void use(T const &) {}
+     static T & get() {
+        static X0<T> t;
+        use(instance);
+        return static_cast<T &>(t);
+    }
+};
+
+// CHECK: @_ZN2X1I2X2I1BEE8instanceE = weak global %struct.X0* null, align 8
+// CHECJ: @_ZN2X1I2X2I1AEE8instanceE = weak global %struct.X0* null, align 8
+template<class T> T & X1<T>::instance = X1<T>::get();
+
+class A { };
+class B : public A { };
+
+template<typename T> struct X2 {};
+X2< B > bg = X1< X2< B > >::get(); 
+X2< A > ag = X1< X2< A > >::get();
diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp
index a67d137..09b398a 100644
--- a/test/CodeGenCXX/static-init.cpp
+++ b/test/CodeGenCXX/static-init.cpp
@@ -2,8 +2,9 @@
 
 // CHECK: @_ZZ1hvE1i = internal global i32 0, align 4
 
-// CHECK: @_ZZ2h2vE1i = weak global i32 0
-// CHECK: @_ZGVZ2h2vE1i = weak global i64 0
+// CHECK: @_ZZN5test16getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16
+// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0
+// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0
 
 struct A {
   A();
@@ -11,7 +12,9 @@
 };
 
 void f() {
-  // CHECK: call void @_ZN1AC1Ev(
+  // CHECK: call i32 @__cxa_guard_acquire
+  // CHECK: call void @_ZN1AC1Ev
+  // CHECK: call void @__cxa_guard_release
   // 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;
 }
@@ -34,3 +37,24 @@
 void h3() {
   h2();
 }
+
+// PR6980: this shouldn't crash
+namespace test0 {
+  struct A { A(); };
+  __attribute__((noreturn)) int throw_exception();
+
+  void test() {
+    throw_exception();
+    static A r;
+  }
+}
+
+namespace test1 {
+  // CHECK: define internal i32 @_ZN5test16getvarEi(
+  static inline int getvar(int index) {
+    static const int var[] = { 1, 0, 2, 4 };
+    return var[index];
+  }
+
+  void test() { (void) getvar(2); }
+}
diff --git a/test/CodeGenCXX/static-local-in-local-class.cpp b/test/CodeGenCXX/static-local-in-local-class.cpp
index d9e044c..ebf560a 100644
--- a/test/CodeGenCXX/static-local-in-local-class.cpp
+++ b/test/CodeGenCXX/static-local-in-local-class.cpp
@@ -19,3 +19,15 @@
   }
   (void)i;
 }
+
+// pr7101
+void foo() {
+    static int n = 0;
+    struct Helper {
+        static void Execute() {
+            n++;
+        }
+    };
+    Helper::Execute();
+}
+
diff --git a/test/CodeGenCXX/template-instantiation.cpp b/test/CodeGenCXX/template-instantiation.cpp
index 4a38575..cb6c812 100644
--- a/test/CodeGenCXX/template-instantiation.cpp
+++ b/test/CodeGenCXX/template-instantiation.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -O1 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
 
 // CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant
 // CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE
diff --git a/test/CodeGenCXX/template-linkage.cpp b/test/CodeGenCXX/template-linkage.cpp
index ccd61a7..63a5c09 100644
--- a/test/CodeGenCXX/template-linkage.cpp
+++ b/test/CodeGenCXX/template-linkage.cpp
@@ -22,3 +22,23 @@
 template <typename T> inline void g(T) { }
 template void g<int>(int);
 
+template<typename T>
+struct X0 {
+  virtual ~X0() { }
+};
+
+template<typename T>
+struct X1 : X0<T> {
+  virtual void blarg();
+};
+
+template<typename T> void X1<T>::blarg() { }
+
+extern template struct X0<char>;
+extern template struct X1<char>;
+
+// CHECK: define linkonce_odr void @_ZN2X1IcED1Ev(
+void test_X1() {
+  X1<char> i1c;
+}
+
diff --git a/test/CodeGenCXX/template-static-var-defer.cpp b/test/CodeGenCXX/template-static-var-defer.cpp
new file mode 100644
index 0000000..fe18c21
--- /dev/null
+++ b/test/CodeGenCXX/template-static-var-defer.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | not grep define
+// PR7415
+class X {
+  template <class Dummy> struct COMTypeInfo {
+    static const int kIID;
+  };
+  static const int& GetIID() {return COMTypeInfo<int>::kIID;}
+};
+template <class Dummy> const int X::COMTypeInfo<Dummy>::kIID = 10;
+
+
+
diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp
index eb543cb..9a397ab 100644
--- a/test/CodeGenCXX/temporaries.cpp
+++ b/test/CodeGenCXX/temporaries.cpp
@@ -320,3 +320,21 @@
     f(1);
   }
 }
+
+namespace PR7556 {
+  struct A { ~A(); }; 
+  struct B { int i; ~B(); }; 
+  struct C { int C::*pm; ~C(); }; 
+  // CHECK: define void @_ZN6PR75563fooEv()
+  void foo() { 
+    // CHECK: call void @_ZN6PR75561AD1Ev
+    A(); 
+    // CHECK: call void @llvm.memset.p0i8.i64
+    // CHECK: call void @_ZN6PR75561BD1Ev
+    B();
+    // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+    // CHECK: call void @_ZN6PR75561CD1Ev
+    C();
+    // CHECK-NEXT: ret void
+  }
+}
diff --git a/test/CodeGenCXX/threadsafe-statics-exceptions.cpp b/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
new file mode 100644
index 0000000..c91590f
--- /dev/null
+++ b/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -emit-llvm -o - -fexceptions -triple x86_64-apple-darwin10 %s | FileCheck %s
+
+struct X {
+  X();
+  ~X();
+};
+
+struct Y { };
+
+// CHECK: define void @_Z1fv
+void f() {
+  // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZ1fvE1x)
+  // CHECK: invoke void @_ZN1XC1Ev
+  // CHECK: call void @__cxa_guard_release(i64* @_ZGVZ1fvE1x)
+  // CHECK-NEXT: call i32 @__cxa_atexit
+  // CHECK: br
+  static X x;
+
+  // CHECK: call i8* @__cxa_allocate_exception
+  // CHECK: call void @__cxa_throw
+  throw Y();
+
+  // Finally, the landing pad.
+  // CHECK: call i8* @llvm.eh.exception()
+  // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector
+  // CHECK: call void @__cxa_guard_abort(i64* @_ZGVZ1fvE1x)
+  // CHECK: call void @_Unwind_Resume_or_Rethrow
+  // CHECK: unreachable
+}
diff --git a/test/CodeGenCXX/throw-expression-dtor.cpp b/test/CodeGenCXX/throw-expression-dtor.cpp
new file mode 100644
index 0000000..f87657f
--- /dev/null
+++ b/test/CodeGenCXX/throw-expression-dtor.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -verify -fexceptions
+// PR7281
+
+class A {
+public:
+    ~A();
+};
+class B : public A {
+    void ice_throw();
+};
+void B::ice_throw() {
+    throw *this;
+}
diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp
index b91ba32..ba60385 100644
--- a/test/CodeGenCXX/thunks.cpp
+++ b/test/CodeGenCXX/thunks.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fhidden-weak-vtables -emit-llvm -o - | FileCheck -check-prefix=HIDDEN %s
 
 namespace Test1 {
 
@@ -86,9 +87,6 @@
 
 }
 
-// This is from Test5:
-// CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
-
 // Check that the thunk gets internal linkage.
 namespace {
 
@@ -106,7 +104,6 @@
   virtual void f();
 };
 
-// CHECK: define internal void @_ZThn8_N12_GLOBAL__N_11C1fEv(
 void C::f() { }
 
 }
@@ -134,4 +131,137 @@
 }
 }
 
+namespace Test6 {
+  struct X {
+    X();
+    X(const X&);
+    X &operator=(const X&);
+    ~X();
+  };
 
+  struct P {
+    P();
+    P(const P&);
+    ~P();
+    X first;
+    X second;
+  };
+
+  P getP();
+
+  struct Base1 {
+    int i;
+
+    virtual X f() { return X(); }
+  };
+
+  struct Base2 {
+    float real;
+
+    virtual X f() { return X(); }
+  };
+
+  struct Thunks : Base1, Base2 {
+    long l;
+
+    virtual X f();
+  };
+
+  // CHECK: define void @_ZThn16_N5Test66Thunks1fEv
+  // CHECK-NOT: memcpy
+  // CHECK: {{call void @_ZN5Test66Thunks1fEv.*sret}}
+  // CHECK: ret void
+  X Thunks::f() { return X(); }
+}
+
+namespace Test7 {
+  // PR7188
+  struct X {
+    X();
+    X(const X&);
+    X &operator=(const X&);
+    ~X();
+  };
+
+  struct Small { short s; };
+  struct Large {
+    char array[1024];
+  };
+
+  class A {
+  protected:
+    virtual void foo() = 0;
+  };
+
+  class B : public A {
+  protected:
+    virtual void bar() = 0;
+  };
+
+  class C : public A  {
+  protected:
+    virtual void baz(X, X&, _Complex float, Small, Small&, Large) = 0;
+  };
+
+  class D : public B,
+            public C {
+
+    void foo() {}
+    void bar() {}
+    void baz(X, X&, _Complex float, Small, Small&, Large);
+  };
+
+  void D::baz(X, X&, _Complex float, Small, Small&, Large) { }
+
+  // CHECK: define void @_ZThn8_N5Test71D3bazENS_1XERS1_CfNS_5SmallERS4_NS_5LargeE(
+  // CHECK-NOT: memcpy
+  // CHECK: ret void
+  void testD() { D d; }
+}
+
+namespace Test8 {
+  struct NonPOD { ~NonPOD(); int x, y, z; };
+  struct A { virtual void foo(); };
+  struct B { virtual void bar(NonPOD); };
+  struct C : A, B { virtual void bar(NonPOD); static void helper(NonPOD); };
+
+  // CHECK: define void @_ZN5Test81C6helperENS_6NonPODE([[NONPODTYPE:%.*]]*
+  void C::helper(NonPOD var) {}
+
+  // CHECK: define void @_ZThn8_N5Test81C3barENS_6NonPODE(
+  // CHECK-NOT: load [[NONPODTYPE]]*
+  // CHECK-NOT: memcpy
+  // CHECK: ret void
+  void C::bar(NonPOD var) {}
+}
+
+// PR7241: Emitting thunks for a method shouldn't require the vtable for
+// that class to be emitted.
+namespace Test9 {
+  struct A { virtual ~A() { } };
+  struct B : A { virtual void test() const {} };
+  struct C : B { C(); ~C(); };
+  struct D : C { D() {} };
+  void test() {
+    D d;
+  }
+}
+
+namespace Test10 {
+  struct A { virtual void foo(); };
+  struct B { virtual void foo(); };
+  struct C : A, B { void foo() {} };
+
+  // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test101C3fooEv
+  // CHECK-HIDDEN: define linkonce_odr hidden void @_ZThn8_N6Test101C3fooEv
+
+  void test() {
+    C c;
+  }
+}
+
+/**** The following has to go at the end of the file ****/
+
+// This is from Test5:
+// CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
+// CHECK: define internal void @_ZThn8_N12_GLOBAL__N_11C1fEv(
diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp
index 37891bd..c4eb1c8 100644
--- a/test/CodeGenCXX/value-init.cpp
+++ b/test/CodeGenCXX/value-init.cpp
@@ -23,3 +23,118 @@
   C c = { 17 } ;
   // CHECK: call void @_ZN1CD1Ev
 }
+
+enum enum_type { negative_number = -1, magic_number = 42 };
+
+class enum_holder
+{
+  enum_type m_enum;
+
+public:
+  enum_holder() : m_enum(magic_number) { }
+};
+
+struct enum_holder_and_int
+{
+  enum_holder e;
+  int i;
+};
+
+// CHECK: _Z24test_enum_holder_and_intv()
+void test_enum_holder_and_int() {
+  // CHECK: alloca
+  // CHECK-NEXT: bitcast
+  // CHECK-NEXT: call void @llvm.memset
+  // CHECK-NEXT: call void @_ZN19enum_holder_and_intC1Ev
+  enum_holder_and_int();
+  // CHECK-NEXT: ret void
+}
+
+// PR7834: don't crash.
+namespace test1 {
+  struct A {
+    int A::*f;
+    A();
+    A(const A&);
+    A &operator=(const A &);
+  };
+
+  struct B {
+    A base;
+  };
+
+  void foo() {
+    B();
+  }
+}
+
+namespace ptrmem {
+  struct S {
+    int mem1;
+    int S::*mem2;
+  };
+
+  // CHECK: define i32 @_ZN6ptrmem4testEPNS_1SE
+  int test(S *s) {
+    // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+    // CHECK: getelementptr
+    // CHECK: ret
+    return s->*S().mem2;
+  }
+}
+
+namespace zeroinit {
+  struct S { int i; };
+
+  // CHECK: define i32 @_ZN8zeroinit4testEv()
+  int test() {
+    // CHECK: call void @llvm.memset.p0i8.i64
+    // CHECK: getelementptr
+    // CHECK: ret i32
+    return S().i;
+  }
+
+  struct X0 {
+    X0() { }
+    int x;
+  };
+
+  struct X1 : X0 {
+    int x1;
+    void f();
+  };
+
+  // CHECK: define void @_ZN8zeroinit9testX0_X1Ev
+  void testX0_X1() {
+    // CHECK: call void @llvm.memset.p0i8.i64
+    // CHECK-NEXT: call void @_ZN8zeroinit2X1C1Ev
+    // CHECK-NEXT: call void @_ZN8zeroinit2X11fEv
+    X1().f();
+  }
+
+  template<typename>
+  struct X2 : X0 {
+    int x2;
+    void f();
+  };
+
+  template<typename>
+  struct X3 : X2<int> { 
+    X3() : X2<int>() { }
+  };
+  
+
+  // CHECK: define void @_ZN8zeroinit9testX0_X3Ev
+  void testX0_X3() {
+    // CHECK-NOT: call void @llvm.memset
+    // CHECK: call void @_ZN8zeroinit2X3IiEC1Ev
+    // CHECK: call void @_ZN8zeroinit2X2IiE1fEv
+    // CHECK-NEXT: ret void
+    X3<int>().f();
+  }
+
+  // CHECK: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev
+  // CHECK: call void @llvm.memset.p0i8.i64
+  // CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev
+  // CHECK-NEXT: ret void
+}
diff --git a/test/CodeGenCXX/virt-template-vtable.cpp b/test/CodeGenCXX/virt-template-vtable.cpp
index b968f38..d60cfb9 100644
--- a/test/CodeGenCXX/virt-template-vtable.cpp
+++ b/test/CodeGenCXX/virt-template-vtable.cpp
@@ -10,4 +10,13 @@
 };
 B::B() {}
 
+template class A<long>;
+
+extern template class A<short>;
+template class A<short>;
+
+
+// CHECK: @_ZTV1B = weak_odr constant
+// CHECK: @_ZTV1AIlE = weak_odr constant
+// CHECK: @_ZTV1AIsE = weak_odr constant
 // CHECK: @_ZTV1AIiE = weak_odr constant
diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp
deleted file mode 100644
index 1b0588f..0000000
--- a/test/CodeGenCXX/virt.cpp
+++ /dev/null
@@ -1,696 +0,0 @@
-// 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-destructor-call.cpp b/test/CodeGenCXX/virtual-base-destructor-call.cpp
index 7de9dd2..4618a03 100644
--- a/test/CodeGenCXX/virtual-base-destructor-call.cpp
+++ b/test/CodeGenCXX/virtual-base-destructor-call.cpp
@@ -27,6 +27,11 @@
 //  CHECK: call void @_ZN13basic_istreamIcED2Ev
 //  CHECK: }
 
+// basic_istream's base dtor is a no-op.
+//  CHECK: define linkonce_odr void @_ZN13basic_istreamIcED2Ev
+//  CHECK-NOT: call
+//  CHECK: }
+
 // basic_iostream's deleting dtor calls its complete dtor, then
 // operator delete().
 //  CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED0Ev
@@ -44,8 +49,3 @@
 //  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-functions-incomplete-types.cpp b/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
index 50e0435..052a019 100644
--- a/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
+++ b/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
@@ -9,6 +9,7 @@
 
 void B::f() { }
 
+// CHECK: define i32 @_ZN1D1gEv(%struct.B* %this)
 // CHECK: declare void @_ZN1B1gEv()
 
 struct C;
@@ -24,7 +25,6 @@
   int a;
 };
 
-// CHECK: define i64 @_ZN1D1gEv(%struct.B* %this)
 C D::g() {
   return C();
 }
diff --git a/test/CodeGenCXX/visibility-hidden-extern-templates.cpp b/test/CodeGenCXX/visibility-hidden-extern-templates.cpp
new file mode 100644
index 0000000..7629b77
--- /dev/null
+++ b/test/CodeGenCXX/visibility-hidden-extern-templates.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -O1 -emit-llvm -o - -fvisibility hidden %s | FileCheck %s
+
+template<typename T>
+struct X {
+  void f();
+  void g() { }
+};
+
+template<typename T> void X<T>::f() { }
+
+extern template struct X<int>;
+template struct X<int>;
+extern template struct X<char>;
+
+// <rdar://problem/8109763>
+void test_X(X<int> xi, X<char> xc) {
+  // CHECK: define weak_odr hidden void @_ZN1XIiE1fEv
+  xi.f();
+  // CHECK: define weak_odr hidden void @_ZN1XIiE1gEv
+  xi.g();
+  // CHECK: declare void @_ZN1XIcE1fEv
+  xc.f();
+  // CHECK: define available_externally void @_ZN1XIcE1gEv
+  xc.g();
+}
+
diff --git a/test/CodeGenCXX/visibility-inlines-hidden.cpp b/test/CodeGenCXX/visibility-inlines-hidden.cpp
new file mode 100644
index 0000000..bb1574f
--- /dev/null
+++ b/test/CodeGenCXX/visibility-inlines-hidden.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -fvisibility-inlines-hidden -emit-llvm -o - %s | FileCheck %s
+struct X0 {
+  void __attribute__((visibility("default"))) f1() { }
+  void f2() { }
+  void f3();
+  static void f5() { }
+  virtual void f6() { }
+};
+
+inline void X0::f3() { }
+
+template<typename T>
+struct X1 {
+  void __attribute__((visibility("default"))) f1() { }
+  void f2() { }
+  void f3();
+  void f4();
+  static void f5() { }
+  virtual void f6() { }
+};
+
+template<typename T>
+inline void X1<T>::f3() { }
+
+template<>
+inline void X1<int>::f4() { }
+
+struct __attribute__((visibility("default"))) X2 {
+  void f2() { }
+};
+
+void use(X0 *x0, X1<int> *x1, X2 *x2) {
+  // CHECK: define linkonce_odr void @_ZN2X02f1Ev
+  x0->f1();
+  // CHECK: define linkonce_odr hidden void @_ZN2X02f2Ev
+  x0->f2();
+  // CHECK: define linkonce_odr hidden void @_ZN2X02f3Ev
+  x0->f3();
+  // CHECK: define linkonce_odr hidden void @_ZN2X02f5Ev
+  X0::f5();
+  // CHECK: define linkonce_odr hidden void @_ZN2X02f6Ev
+  x0->X0::f6();
+  // CHECK: define linkonce_odr void @_ZN2X1IiE2f1Ev
+  x1->f1();
+  // CHECK: define linkonce_odr hidden void @_ZN2X1IiE2f2Ev
+  x1->f2();
+  // CHECK: define linkonce_odr hidden void @_ZN2X1IiE2f3Ev
+  x1->f3();
+  // CHECK: define linkonce_odr hidden void @_ZN2X1IiE2f4Ev
+  x1->f4();
+  // CHECK: define linkonce_odr hidden void @_ZN2X1IiE2f5Ev
+  X1<int>::f5();
+  // CHECK: define linkonce_odr hidden void @_ZN2X1IiE2f6Ev
+  x1->X1::f6();
+  // CHECK: define linkonce_odr hidden void @_ZN2X22f2Ev
+  x2->f2();
+}
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
index 5edd27b..ee3c179 100644
--- a/test/CodeGenCXX/visibility.cpp
+++ b/test/CodeGenCXX/visibility.cpp
@@ -5,7 +5,7 @@
 #define DEFAULT __attribute__((visibility("default")))
 
 // CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
-
+// CHECK: @_ZTVN5Test63fooE = weak_odr hidden constant 
 namespace Test1 {
   // CHECK: define hidden void @_ZN5Test11fEv
   void HIDDEN f() { }
@@ -64,3 +64,21 @@
     void g() { }
   }
 }
+
+// <rdar://problem/8091955>
+namespace Test6 {
+  struct HIDDEN foo {
+    foo() { }
+    void bonk();
+    virtual void bar() = 0;
+
+    virtual void zonk() {}
+  };
+
+  struct barc : public foo {
+    barc();
+    virtual void bar();
+  };
+
+  barc::barc() {}
+}
diff --git a/test/CodeGenCXX/volatile.cpp b/test/CodeGenCXX/volatile.cpp
new file mode 100644
index 0000000..58f433f
--- /dev/null
+++ b/test/CodeGenCXX/volatile.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// Check that IR gen doesn't try to do an lvalue-to-rvalue conversion
+// on a volatile reference result.  rdar://problem/8338198
+namespace test0 {
+  struct A {
+    A(const A& t);
+    A& operator=(const A& t);
+    volatile A& operator=(const volatile A& t) volatile;
+  };
+
+  volatile A *array;
+
+  // CHECK: define void @_ZN5test04testENS_1AE(
+  void test(A t) {
+    // CHECK:      [[ARR:%.*]] = load [[A:%.*]]** @_ZN5test05arrayE, align 8
+    // CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [[A]]* [[ARR]], i64 0
+    // CHECK-NEXT: [[TMP:%.*]] = call [[A]]* @_ZNV5test01AaSERVKS0_([[A]]* [[IDX]], [[A]]* [[T:%.*]])
+    // CHECK-NEXT: ret void
+    array[0] = t;
+  }
+}
+
+namespace test1 {
+  volatile int *x;
+
+  // CHECK: define void @_ZN5test14testEv()
+  void test() {
+    // CHECK:      [[TMP:%.*]] = load i32** @_ZN5test11xE, align 8
+    // *** FIXME: no! bad! should not be loaded! ***
+    // CHECK-NEXT: [[TMP1:%.*]] = volatile load i32* [[TMP]]
+    // CHECK-NEXT: ret void
+    *x;
+  }
+}
diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp
index f2f5179..60b46fe 100644
--- a/test/CodeGenCXX/vtable-layout.cpp
+++ b/test/CodeGenCXX/vtable-layout.cpp
@@ -1,4 +1,46 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts > %t 2>&1 
+// RUN: FileCheck --check-prefix=CHECK-1 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-2 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-3 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-4 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-5 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-6 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-7 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-8 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-9 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-10 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-11 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-12 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-13 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-14 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-15 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-16 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-17 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-18 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-19 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-20 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-21 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-22 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-23 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-24 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-25 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-26 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-27 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-28 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-29 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-30 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-31 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-32 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-33 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-34 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-35 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-36 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-37 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-38 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-39 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-40 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-41 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-42 %s < %t
 
 // For now, just verify this doesn't crash.
 namespace test0 {
@@ -11,11 +53,11 @@
 }
 
 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()
+// CHECK-1:      Vtable for 'Test1::A' (3 entries).
+// CHECK-1-NEXT:   0 | offset_to_top (0)
+// CHECK-1-NEXT:   1 | Test1::A RTTI
+// CHECK-1-NEXT:       -- (Test1::A, 0) vtable address --
+// CHECK-1-NEXT:   2 | void Test1::A::f()
 struct A {
   virtual void f();
 };
@@ -26,17 +68,17 @@
 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 &)
+// CHECK-2:      Vtable for 'Test2::A' (9 entries).
+// CHECK-2-NEXT:   0 | offset_to_top (0)
+// CHECK-2-NEXT:   1 | Test2::A RTTI
+// CHECK-2-NEXT:       -- (Test2::A, 0) vtable address --
+// CHECK-2-NEXT:   2 | void Test2::A::f()
+// CHECK-2-NEXT:   3 | void Test2::A::f() const
+// CHECK-2-NEXT:   4 | Test2::A *Test2::A::g(int)
+// CHECK-2-NEXT:   5 | Test2::A::~A() [complete]
+// CHECK-2-NEXT:   6 | Test2::A::~A() [deleting]
+// CHECK-2-NEXT:   7 | void Test2::A::h()
+// CHECK-2-NEXT:   8 | Test2::A &Test2::A::operator=(Test2::A const &)
 struct A {
   virtual void f();
   virtual void f() const;
@@ -50,14 +92,14 @@
 
 // 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]
+// CHECK-3:     Vtable for 'Test2::B' (6 entries).
+// CHECK-3-NEXT:  0 | offset_to_top (0)
+// CHECK-3-NEXT:  1 | Test2::B RTTI
+// CHECK-3-NEXT:    -- (Test2::B, 0) vtable address --
+// CHECK-3-NEXT:  2 | void Test2::B::f()
+// CHECK-3-NEXT:  3 | void Test2::B::g() [pure]
+// CHECK-3-NEXT:  4 | Test2::B::~B() [complete] [pure]
+// CHECK-3-NEXT:  5 | Test2::B::~B() [deleting] [pure]
 struct B {
   virtual void f();
   virtual void g() = 0;
@@ -73,52 +115,52 @@
 // 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()
+// CHECK-4:      Vtable for 'Test3::A' (3 entries).
+// CHECK-4-NEXT:   0 | offset_to_top (0)
+// CHECK-4-NEXT:   1 | Test3::A RTTI
+// CHECK-4-NEXT:       -- (Test3::A, 0) vtable address --
+// CHECK-4-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()
+// CHECK-5:     Vtable for 'Test3::B' (4 entries).
+// CHECK-5-NEXT:  0 | offset_to_top (0)
+// CHECK-5-NEXT:  1 | Test3::B RTTI
+// CHECK-5-NEXT:      -- (Test3::A, 0) vtable address --
+// CHECK-5-NEXT:      -- (Test3::B, 0) vtable address --
+// CHECK-5-NEXT:  2 | void Test3::B::f()
+// CHECK-5-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()
+// CHECK-6:     Vtable for 'Test3::C' (5 entries).
+// CHECK-6-NEXT:  0 | offset_to_top (0)
+// CHECK-6-NEXT:  1 | Test3::C RTTI
+// CHECK-6-NEXT:     -- (Test3::A, 0) vtable address --
+// CHECK-6-NEXT:     -- (Test3::C, 0) vtable address --
+// CHECK-6-NEXT:  2 | void Test3::A::f()
+// CHECK-6-NEXT:  3 | void Test3::C::g()
+// CHECK-6-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()
+// CHECK-7:     Vtable for 'Test3::D' (5 entries).
+// CHECK-7-NEXT:  0 | offset_to_top (0)
+// CHECK-7-NEXT:  1 | Test3::D RTTI
+// CHECK-7-NEXT:     -- (Test3::A, 0) vtable address --
+// CHECK-7-NEXT:     -- (Test3::B, 0) vtable address --
+// CHECK-7-NEXT:     -- (Test3::D, 0) vtable address --
+// CHECK-7-NEXT:  2 | void Test3::D::f()
+// CHECK-7-NEXT:  3 | void Test3::D::g()
+// CHECK-7-NEXT:  4 | void Test3::D::h()
 struct D : B {
   virtual void f();
   virtual void g();
@@ -140,14 +182,14 @@
   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()
+// CHECK-8:     Vtable for 'Test4::B' (4 entries).
+// CHECK-8-NEXT:  0 | offset_to_top (0)
+// CHECK-8-NEXT:  1 | Test4::B RTTI
+// CHECK-8-NEXT:      -- (Test4::A, 0) vtable address --
+// CHECK-8-NEXT:      -- (Test4::B, 0) vtable address --
+// CHECK-8-NEXT:  2 | Test4::R3 *Test4::B::f()
+// CHECK-8-NEXT:      [return adjustment: 4 non-virtual]
+// CHECK-8-NEXT:  3 | Test4::R3 *Test4::B::f()
 
 struct B : A {
   virtual R3 *f();
@@ -162,14 +204,14 @@
   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()
+// CHECK-9:     Vtable for 'Test4::D' (4 entries).
+// CHECK-9-NEXT:   0 | offset_to_top (0)
+// CHECK-9-NEXT:   1 | Test4::D RTTI
+// CHECK-9-NEXT:       -- (Test4::C, 0) vtable address --
+// CHECK-9-NEXT:       -- (Test4::D, 0) vtable address --
+// CHECK-9-NEXT:   2 | Test4::V2 *Test4::D::f()
+// CHECK-9-NEXT:       [return adjustment: 0 non-virtual, -24 vbase offset offset]
+// CHECK-9-NEXT:   3 | Test4::V2 *Test4::D::f()
 struct D : C {
   virtual V2 *f();
 };
@@ -178,14 +220,14 @@
 // 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()
+// CHECK-10:     Vtable for 'Test4::E' (4 entries).
+// CHECK-10-NEXT:   0 | offset_to_top (0)
+// CHECK-10-NEXT:   1 | Test4::E RTTI
+// CHECK-10-NEXT:       -- (Test4::A, 0) vtable address --
+// CHECK-10-NEXT:       -- (Test4::E, 0) vtable address --
+// CHECK-10-NEXT:   2 | Test4::V3 *Test4::E::f()
+// CHECK-10-NEXT:       [return adjustment: 4 non-virtual, -24 vbase offset offset]
+// CHECK-10-NEXT:   3 | Test4::V3 *Test4::E::f()
 
 struct E : A {
   virtual V3 *f();
@@ -194,14 +236,14 @@
 
 // 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]
+// CHECK-11:     Vtable for 'Test4::F' (5 entries).
+// CHECK-11-NEXT:   0 | offset_to_top (0)
+// CHECK-11-NEXT:   1 | Test4::F RTTI
+// CHECK-11-NEXT:       -- (Test4::A, 0) vtable address --
+// CHECK-11-NEXT:       -- (Test4::F, 0) vtable address --
+// CHECK-11-NEXT:   2 | Test4::R3 *Test4::F::f() [pure]
+// CHECK-11-NEXT:   3 | void Test4::F::g()
+// CHECK-11-NEXT:   4 | Test4::R3 *Test4::F::f() [pure]
 struct F : A {
   virtual void g();
   virtual R3 *f() = 0;
@@ -229,21 +271,21 @@
   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()
+// CHECK-12:     Vtable for 'Test5::C' (9 entries).
+// CHECK-12-NEXT:   0 | offset_to_top (0)
+// CHECK-12-NEXT:   1 | Test5::C RTTI
+// CHECK-12-NEXT:       -- (Test5::A, 0) vtable address --
+// CHECK-12-NEXT:       -- (Test5::B1, 0) vtable address --
+// CHECK-12-NEXT:       -- (Test5::C, 0) vtable address --
+// CHECK-12-NEXT:   2 | void Test5::B1::f()
+// CHECK-12-NEXT:   3 | void Test5::A::g()
+// CHECK-12-NEXT:   4 | void Test5::C::h()
+// CHECK-12-NEXT:   5 | offset_to_top (-16)
+// CHECK-12-NEXT:   6 | Test5::C RTTI
+// CHECK-12-NEXT:       -- (Test5::A, 16) vtable address --
+// CHECK-12-NEXT:       -- (Test5::B2, 16) vtable address --
+// CHECK-12-NEXT:   7 | void Test5::A::f()
+// CHECK-12-NEXT:   8 | void Test5::B2::g()
 struct C : B1, B2 {
   virtual void h();
 };
@@ -263,17 +305,17 @@
   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]
+// CHECK-13:     Vtable for 'Test6::C' (6 entries).
+// CHECK-13-NEXT:   0 | offset_to_top (0)
+// CHECK-13-NEXT:   1 | Test6::C RTTI
+// CHECK-13-NEXT:       -- (Test6::A1, 0) vtable address --
+// CHECK-13-NEXT:       -- (Test6::C, 0) vtable address --
+// CHECK-13-NEXT:   2 | void Test6::C::f()
+// CHECK-13-NEXT:   3 | offset_to_top (-16)
+// CHECK-13-NEXT:   4 | Test6::C RTTI
+// CHECK-13-NEXT:       -- (Test6::A2, 16) vtable address --
+// CHECK-13-NEXT:   5 | void Test6::C::f()
+// CHECK-13-NEXT:       [this adjustment: -16 non-virtual]
 struct C : A1, A2 {
   virtual void f();
 };
@@ -296,25 +338,25 @@
 
 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]
+// CHECK-14:     Vtable for 'Test7::D' (10 entries).
+// CHECK-14-NEXT:   0 | offset_to_top (0)
+// CHECK-14-NEXT:   1 | Test7::D RTTI
+// CHECK-14-NEXT:       -- (Test7::C, 0) vtable address --
+// CHECK-14-NEXT:       -- (Test7::D, 0) vtable address --
+// CHECK-14-NEXT:   2 | void Test7::C::c()
+// CHECK-14-NEXT:   3 | void Test7::D::f()
+// CHECK-14-NEXT:   4 | offset_to_top (-8)
+// CHECK-14-NEXT:   5 | Test7::D RTTI
+// CHECK-14-NEXT:       -- (Test7::A, 8) vtable address --
+// CHECK-14-NEXT:       -- (Test7::B1, 8) vtable address --
+// CHECK-14-NEXT:   6 | void Test7::D::f()
+// CHECK-14-NEXT:       [this adjustment: -8 non-virtual]
+// CHECK-14-NEXT:   7 | offset_to_top (-24)
+// CHECK-14-NEXT:   8 | Test7::D RTTI
+// CHECK-14-NEXT:       -- (Test7::A, 24) vtable address --
+// CHECK-14-NEXT:       -- (Test7::B2, 24) vtable address --
+// CHECK-14-NEXT:   9 | void Test7::D::f()
+// CHECK-14-NEXT:       [this adjustment: -24 non-virtual]
 struct D : C, B1, B2 {
   virtual void f();
 };
@@ -329,11 +371,11 @@
 
 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()
+// CHECK-15:     Vtable for 'Test8::B' (3 entries).
+// CHECK-15-NEXT:   0 | offset_to_top (0)
+// CHECK-15-NEXT:   1 | Test8::B RTTI
+// CHECK-15-NEXT:       -- (Test8::B, 0) vtable address --
+// CHECK-15-NEXT:   2 | void Test8::B::f()
 struct B : A { 
   virtual void f();
 };
@@ -348,13 +390,13 @@
 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()
+// CHECK-16:     Vtable for 'Test9::B' (5 entries).
+// CHECK-16-NEXT:   0 | vbase_offset (16)
+// CHECK-16-NEXT:   1 | vbase_offset (12)
+// CHECK-16-NEXT:   2 | offset_to_top (0)
+// CHECK-16-NEXT:   3 | Test9::B RTTI
+// CHECK-16-NEXT:       -- (Test9::B, 0) vtable address --
+// CHECK-16-NEXT:   4 | void Test9::B::f()
 struct B : virtual A1, virtual A2 {
   int b;
 
@@ -373,18 +415,18 @@
 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()
+// CHECK-17:     Vtable for 'Test10::C' (7 entries).
+// CHECK-17-NEXT:   0 | offset_to_top (0)
+// CHECK-17-NEXT:   1 | Test10::C RTTI
+// CHECK-17-NEXT:       -- (Test10::A1, 0) vtable address --
+// CHECK-17-NEXT:       -- (Test10::B, 0) vtable address --
+// CHECK-17-NEXT:       -- (Test10::C, 0) vtable address --
+// CHECK-17-NEXT:   2 | void Test10::A1::a1()
+// CHECK-17-NEXT:   3 | void Test10::C::f()
+// CHECK-17-NEXT:   4 | offset_to_top (-8)
+// CHECK-17-NEXT:   5 | Test10::C RTTI
+// CHECK-17-NEXT:       -- (Test10::A2, 8) vtable address --
+// CHECK-17-NEXT:   6 | void Test10::A2::a2()
 struct B : A1, A2 {
   int b;
 };
@@ -406,16 +448,16 @@
   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
+// CHECK-18:     Vtable for 'Test11::C' (8 entries).
+// CHECK-18-NEXT:   0 | vbase_offset (24)
+// CHECK-18-NEXT:   1 | vbase_offset (8)
+// CHECK-18-NEXT:   2 | offset_to_top (0)
+// CHECK-18-NEXT:   3 | Test11::C RTTI
+// CHECK-18-NEXT:       -- (Test11::C, 0) vtable address --
+// CHECK-18-NEXT:   4 | void Test11::C::f()
+// CHECK-18-NEXT:   5 | vbase_offset (16)
+// CHECK-18-NEXT:   6 | offset_to_top (-8)
+// CHECK-18-NEXT:   7 | Test11::C RTTI
 struct C : virtual B {
   virtual void f();
 };
@@ -427,32 +469,32 @@
 
 // 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()
+// CHECK-19:      Vtable for 'Test12::B' (19 entries).
+// CHECK-19-NEXT:    0 | vbase_offset (8)
+// CHECK-19-NEXT:    1 | offset_to_top (0)
+// CHECK-19-NEXT:    2 | Test12::B RTTI
+// CHECK-19-NEXT:        -- (Test12::B, 0) vtable address --
+// CHECK-19-NEXT:    3 | void Test12::B::f()
+// CHECK-19-NEXT:    4 | void Test12::B::a()
+// CHECK-19-NEXT:    5 | vcall_offset (32)
+// CHECK-19-NEXT:    6 | vcall_offset (16)
+// CHECK-19-NEXT:    7 | vcall_offset (-8)
+// CHECK-19-NEXT:    8 | vcall_offset (0)
+// CHECK-19-NEXT:    9 | offset_to_top (-8)
+// CHECK-19-NEXT:   10 | Test12::B RTTI
+// CHECK-19-NEXT:        -- (Test12::A, 8) vtable address --
+// CHECK-19-NEXT:        -- (Test12::A1, 8) vtable address --
+// CHECK-19-NEXT:   11 | void Test12::A1::a1()
+// CHECK-19-NEXT:   12 | void Test12::B::a()
+// CHECK-19-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-19-NEXT:   13 | offset_to_top (-24)
+// CHECK-19-NEXT:   14 | Test12::B RTTI
+// CHECK-19-NEXT:        -- (Test12::A2, 24) vtable address --
+// CHECK-19-NEXT:   15 | void Test12::A2::a2()
+// CHECK-19-NEXT:   16 | offset_to_top (-40)
+// CHECK-19-NEXT:   17 | Test12::B RTTI
+// CHECK-19-NEXT:        -- (Test12::A3, 40) vtable address --
+// CHECK-19-NEXT:   18 | void Test12::A3::a3()
 struct A1 {
   virtual void a1();
   int a;
@@ -493,16 +535,16 @@
   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()
+// CHECK-20:      Vtable for 'Test13::C' (6 entries).
+// CHECK-20-NEXT:    0 | vbase_offset (0)
+// CHECK-20-NEXT:    1 | vbase_offset (0)
+// CHECK-20-NEXT:    2 | vcall_offset (0)
+// CHECK-20-NEXT:    3 | offset_to_top (0)
+// CHECK-20-NEXT:    4 | Test13::C RTTI
+// CHECK-20-NEXT:        -- (Test13::A, 0) vtable address --
+// CHECK-20-NEXT:        -- (Test13::B, 0) vtable address --
+// CHECK-20-NEXT:        -- (Test13::C, 0) vtable address --
+// CHECK-20-NEXT:    5 | void Test13::C::f()
 struct C : virtual B, virtual A {
   virtual void f();
 };
@@ -522,16 +564,16 @@
 
 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()
+// CHECK-21:      Vtable for 'Test14::D' (5 entries).
+// CHECK-21-NEXT:    0 | vbase_offset (0)
+// CHECK-21-NEXT:    1 | vcall_offset (0)
+// CHECK-21-NEXT:    2 | offset_to_top (0)
+// CHECK-21-NEXT:    3 | Test14::D RTTI
+// CHECK-21-NEXT:        -- (Test14::A, 0) vtable address --
+// CHECK-21-NEXT:        -- (Test14::B, 0) vtable address --
+// CHECK-21-NEXT:        -- (Test14::C, 0) vtable address --
+// CHECK-21-NEXT:        -- (Test14::D, 0) vtable address --
+// CHECK-21-NEXT:    4 | void Test14::D::f()
 struct D : C, virtual B {
  virtual void f();
 };
@@ -547,22 +589,22 @@
 
 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()
+// CHECK-22:      Vtable for 'Test15::D' (11 entries).
+// CHECK-22-NEXT:    0 | vbase_offset (8)
+// CHECK-22-NEXT:    1 | vbase_offset (8)
+// CHECK-22-NEXT:    2 | offset_to_top (0)
+// CHECK-22-NEXT:    3 | Test15::D RTTI
+// CHECK-22-NEXT:        -- (Test15::A, 0) vtable address --
+// CHECK-22-NEXT:        -- (Test15::D, 0) vtable address --
+// CHECK-22-NEXT:    4 | void Test15::A::a()
+// CHECK-22-NEXT:    5 | void Test15::D::f()
+// CHECK-22-NEXT:    6 | vbase_offset (0)
+// CHECK-22-NEXT:    7 | vcall_offset (0)
+// CHECK-22-NEXT:    8 | offset_to_top (-8)
+// CHECK-22-NEXT:    9 | Test15::D RTTI
+// CHECK-22-NEXT:        -- (Test15::B, 8) vtable address --
+// CHECK-22-NEXT:        -- (Test15::C, 8) vtable address --
+// CHECK-22-NEXT:   10 | void Test15::B::b()
 struct D : A, virtual B, virtual C { 
   virtual void f();
 };
@@ -579,30 +621,30 @@
 
 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]
+// CHECK-23:      Vtable for 'Test16::D' (15 entries).
+// CHECK-23-NEXT:    0 | vbase_offset (8)
+// CHECK-23-NEXT:    1 | offset_to_top (0)
+// CHECK-23-NEXT:    2 | Test16::D RTTI
+// CHECK-23-NEXT:        -- (Test16::D, 0) vtable address --
+// CHECK-23-NEXT:    3 | void Test16::D::f()
+// CHECK-23-NEXT:    4 | Test16::D::~D() [complete]
+// CHECK-23-NEXT:    5 | Test16::D::~D() [deleting]
+// CHECK-23-NEXT:    6 | vcall_offset (-8)
+// CHECK-23-NEXT:    7 | offset_to_top (-8)
+// CHECK-23-NEXT:    8 | Test16::D RTTI
+// CHECK-23-NEXT:        -- (Test16::A, 8) vtable address --
+// CHECK-23-NEXT:        -- (Test16::C, 8) vtable address --
+// CHECK-23-NEXT:    9 | Test16::D::~D() [complete]
+// CHECK-23-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-23-NEXT:   10 | Test16::D::~D() [deleting]
+// CHECK-23-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-23-NEXT:   11 | offset_to_top (-16)
+// CHECK-23-NEXT:   12 | Test16::D RTTI
+// CHECK-23-NEXT:        -- (Test16::B, 16) vtable address --
+// CHECK-23-NEXT:   13 | Test16::D::~D() [complete]
+// CHECK-23-NEXT:        [this adjustment: -8 non-virtual, -24 vcall offset offset]
+// CHECK-23-NEXT:   14 | Test16::D::~D() [deleting]
+// CHECK-23-NEXT:        [this adjustment: -8 non-virtual, -24 vcall offset offset]
 struct D : virtual C {
   virtual void f();
 };
@@ -618,26 +660,26 @@
 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]
+// CHECK-24:      Vtable for 'Test17::E' (13 entries).
+// CHECK-24-NEXT:    0 | vbase_offset (0)
+// CHECK-24-NEXT:    1 | vbase_offset (8)
+// CHECK-24-NEXT:    2 | vbase_offset (0)
+// CHECK-24-NEXT:    3 | vbase_offset (0)
+// CHECK-24-NEXT:    4 | vcall_offset (0)
+// CHECK-24-NEXT:    5 | offset_to_top (0)
+// CHECK-24-NEXT:    6 | Test17::E RTTI
+// CHECK-24-NEXT:        -- (Test17::A, 0) vtable address --
+// CHECK-24-NEXT:        -- (Test17::B, 0) vtable address --
+// CHECK-24-NEXT:        -- (Test17::D, 0) vtable address --
+// CHECK-24-NEXT:        -- (Test17::E, 0) vtable address --
+// CHECK-24-NEXT:    7 | void Test17::E::f()
+// CHECK-24-NEXT:    8 | vbase_offset (-8)
+// CHECK-24-NEXT:    9 | vcall_offset (-8)
+// CHECK-24-NEXT:   10 | offset_to_top (-8)
+// CHECK-24-NEXT:   11 | Test17::E RTTI
+// CHECK-24-NEXT:        -- (Test17::C, 8) vtable address --
+// CHECK-24-NEXT:   12 | void Test17::E::f()
+// CHECK-24-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
 class E : virtual D {
   virtual void f();  
 };
@@ -662,97 +704,97 @@
   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-25:      Vtable for 'Test18::D' (24 entries).
+// CHECK-25-NEXT:    0 | vbase_offset (8)
+// CHECK-25-NEXT:    1 | vbase_offset (0)
+// CHECK-25-NEXT:    2 | vbase_offset (0)
+// CHECK-25-NEXT:    3 | vcall_offset (8)
+// CHECK-25-NEXT:    4 | vcall_offset (0)
+// CHECK-25-NEXT:    5 | offset_to_top (0)
+// CHECK-25-NEXT:    6 | Test18::D RTTI
+// CHECK-25-NEXT:        -- (Test18::A, 0) vtable address --
+// CHECK-25-NEXT:        -- (Test18::B, 0) vtable address --
+// CHECK-25-NEXT:        -- (Test18::D, 0) vtable address --
+// CHECK-25-NEXT:    7 | void Test18::D::f()
+// CHECK-25-NEXT:    8 | void Test18::C::g()
+// CHECK-25-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-25-NEXT:    9 | void Test18::D::h()
+// CHECK-25-NEXT:   10 | vcall_offset (0)
+// CHECK-25-NEXT:   11 | vcall_offset (-8)
+// CHECK-25-NEXT:   12 | vbase_offset (-8)
+// CHECK-25-NEXT:   13 | offset_to_top (-8)
+// CHECK-25-NEXT:   14 | Test18::D RTTI
+// CHECK-25-NEXT:        -- (Test18::A, 8) vtable address --
+// CHECK-25-NEXT:        -- (Test18::C, 8) vtable address --
+// CHECK-25-NEXT:   15 | void Test18::D::f()
+// CHECK-25-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-25-NEXT:   16 | void Test18::C::g()
+// CHECK-25-NEXT:   17 | vbase_offset (-16)
+// CHECK-25-NEXT:   18 | vcall_offset (-8)
+// CHECK-25-NEXT:   19 | vcall_offset (-16)
+// CHECK-25-NEXT:   20 | offset_to_top (-16)
+// CHECK-25-NEXT:   21 | Test18::D RTTI
+// CHECK-25-NEXT:        -- (Test18::B, 16) vtable address --
+// CHECK-25-NEXT:   22 | void Test18::D::f()
+// CHECK-25-NEXT:        [this adjustment: -8 non-virtual, -32 vcall offset offset]
+// CHECK-25-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-25:      Construction vtable for ('Test18::B', 0) in 'Test18::D' (7 entries).
+// CHECK-25-NEXT:    0 | vbase_offset (0)
+// CHECK-25-NEXT:    1 | vcall_offset (0)
+// CHECK-25-NEXT:    2 | vcall_offset (0)
+// CHECK-25-NEXT:    3 | offset_to_top (0)
+// CHECK-25-NEXT:    4 | Test18::B RTTI
+// CHECK-25-NEXT:        -- (Test18::A, 0) vtable address --
+// CHECK-25-NEXT:        -- (Test18::B, 0) vtable address --
+// CHECK-25-NEXT:    5 | void Test18::B::f()
+// CHECK-25-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-25:      Construction vtable for ('Test18::C', 8) in 'Test18::D' (20 entries).
+// CHECK-25-NEXT:    0 | vcall_offset (0)
+// CHECK-25-NEXT:    1 | vcall_offset (0)
+// CHECK-25-NEXT:    2 | vbase_offset (-8)
+// CHECK-25-NEXT:    3 | offset_to_top (0)
+// CHECK-25-NEXT:    4 | Test18::C RTTI
+// CHECK-25-NEXT:        -- (Test18::A, 8) vtable address --
+// CHECK-25-NEXT:        -- (Test18::C, 8) vtable address --
+// CHECK-25-NEXT:    5 | void Test18::A::f()
+// CHECK-25-NEXT:    6 | void Test18::C::g()
+// CHECK-25-NEXT:    7 | vbase_offset (-16)
+// CHECK-25-NEXT:    8 | vcall_offset (-8)
+// CHECK-25-NEXT:    9 | vcall_offset (0)
+// CHECK-25-NEXT:   10 | offset_to_top (-8)
+// CHECK-25-NEXT:   11 | Test18::C RTTI
+// CHECK-25-NEXT:        -- (Test18::B, 16) vtable address --
+// CHECK-25-NEXT:   12 | void Test18::B::f()
+// CHECK-25-NEXT:   13 | [unused] void Test18::C::g()
+// CHECK-25-NEXT:   14 | vcall_offset (8)
+// CHECK-25-NEXT:   15 | vcall_offset (16)
+// CHECK-25-NEXT:   16 | offset_to_top (8)
+// CHECK-25-NEXT:   17 | Test18::C RTTI
+// CHECK-25-NEXT:        -- (Test18::A, 0) vtable address --
+// CHECK-25-NEXT:   18 | void Test18::B::f()
+// CHECK-25-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-25-NEXT:   19 | void Test18::C::g()
+// CHECK-25-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()
+// CHECK-25:      Construction vtable for ('Test18::B', 16) in 'Test18::D' (13 entries).
+// CHECK-25-NEXT:    0 | vbase_offset (-16)
+// CHECK-25-NEXT:    1 | vcall_offset (-16)
+// CHECK-25-NEXT:    2 | vcall_offset (0)
+// CHECK-25-NEXT:    3 | offset_to_top (0)
+// CHECK-25-NEXT:    4 | Test18::B RTTI
+// CHECK-25-NEXT:        -- (Test18::B, 16) vtable address --
+// CHECK-25-NEXT:    5 | void Test18::B::f()
+// CHECK-25-NEXT:    6 | [unused] void Test18::A::g()
+// CHECK-25-NEXT:    7 | vcall_offset (0)
+// CHECK-25-NEXT:    8 | vcall_offset (16)
+// CHECK-25-NEXT:    9 | offset_to_top (16)
+// CHECK-25-NEXT:   10 | Test18::B RTTI
+// CHECK-25-NEXT:        -- (Test18::A, 0) vtable address --
+// CHECK-25-NEXT:   11 | void Test18::B::f()
+// CHECK-25-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-25-NEXT:   12 | void Test18::A::g()
 struct D : virtual B, virtual C, virtual A 
 {
   virtual void f();
@@ -782,27 +824,27 @@
   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]
+// CHECK-26:      Vtable for 'Test19::D' (13 entries).
+// CHECK-26-NEXT:    0 | vbase_offset (24)
+// CHECK-26-NEXT:    1 | offset_to_top (0)
+// CHECK-26-NEXT:    2 | Test19::D RTTI
+// CHECK-26-NEXT:        -- (Test19::C, 0) vtable address --
+// CHECK-26-NEXT:        -- (Test19::D, 0) vtable address --
+// CHECK-26-NEXT:    3 | void Test19::C::c()
+// CHECK-26-NEXT:    4 | void Test19::D::f()
+// CHECK-26-NEXT:    5 | offset_to_top (-8)
+// CHECK-26-NEXT:    6 | Test19::D RTTI
+// CHECK-26-NEXT:        -- (Test19::A, 8) vtable address --
+// CHECK-26-NEXT:        -- (Test19::B, 8) vtable address --
+// CHECK-26-NEXT:    7 | void Test19::D::f()
+// CHECK-26-NEXT:        [this adjustment: -8 non-virtual]
+// CHECK-26-NEXT:    8 | void Test19::B::g()
+// CHECK-26-NEXT:    9 | vcall_offset (-24)
+// CHECK-26-NEXT:   10 | offset_to_top (-24)
+// CHECK-26-NEXT:   11 | Test19::D RTTI
+// CHECK-26-NEXT:        -- (Test19::A, 24) vtable address --
+// CHECK-26-NEXT:   12 | void Test19::D::f()
+// CHECK-26-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
 struct D : C, B, virtual A {
   virtual void f();
 };
@@ -821,20 +863,20 @@
 
 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()
+// CHECK-27:      Vtable for 'Test20::C' (9 entries).
+// CHECK-27-NEXT:    0 | offset_to_top (0)
+// CHECK-27-NEXT:    1 | Test20::C RTTI
+// CHECK-27-NEXT:        -- (Test20::A, 0) vtable address --
+// CHECK-27-NEXT:        -- (Test20::C, 0) vtable address --
+// CHECK-27-NEXT:    2 | void Test20::C::f() [pure]
+// CHECK-27-NEXT:    3 | void Test20::A::g()
+// CHECK-27-NEXT:    4 | void Test20::C::h()
+// CHECK-27-NEXT:    5 | offset_to_top (-8)
+// CHECK-27-NEXT:    6 | Test20::C RTTI
+// CHECK-27-NEXT:        -- (Test20::A, 8) vtable address --
+// CHECK-27-NEXT:        -- (Test20::B, 8) vtable address --
+// CHECK-27-NEXT:    7 | void Test20::C::f() [pure]
+// CHECK-27-NEXT:    8 | void Test20::A::g()
 struct C : A, B { 
   virtual void f() = 0;
   virtual void h();
@@ -856,36 +898,36 @@
 
 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-28:      Vtable for 'Test21::F' (16 entries).
+// CHECK-28-NEXT:    0 | vbase_offset (8)
+// CHECK-28-NEXT:    1 | vbase_offset (0)
+// CHECK-28-NEXT:    2 | vbase_offset (0)
+// CHECK-28-NEXT:    3 | vbase_offset (0)
+// CHECK-28-NEXT:    4 | vbase_offset (0)
+// CHECK-28-NEXT:    5 | vcall_offset (0)
+// CHECK-28-NEXT:    6 | offset_to_top (0)
+// CHECK-28-NEXT:    7 | Test21::F RTTI
+// CHECK-28-NEXT:        -- (Test21::A, 0) vtable address --
+// CHECK-28-NEXT:        -- (Test21::B, 0) vtable address --
+// CHECK-28-NEXT:        -- (Test21::C, 0) vtable address --
+// CHECK-28-NEXT:        -- (Test21::D, 0) vtable address --
+// CHECK-28-NEXT:        -- (Test21::F, 0) vtable address --
+// CHECK-28-NEXT:    8 | void Test21::F::f()
+// CHECK-28-NEXT:    9 | vbase_offset (-8)
+// CHECK-28-NEXT:   10 | vbase_offset (-8)
+// CHECK-28-NEXT:   11 | vbase_offset (-8)
+// CHECK-28-NEXT:   12 | vcall_offset (-8)
+// CHECK-28-NEXT:   13 | offset_to_top (-8)
+// CHECK-28-NEXT:   14 | Test21::F RTTI
+// CHECK-28-NEXT:        -- (Test21::E, 8) vtable address --
+// CHECK-28-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
+// CHECK-28:      Virtual base offset offsets for 'Test21::F' (5 entries).
+// CHECK-28-NEXT:    Test21::A | -32
+// CHECK-28-NEXT:    Test21::B | -40
+// CHECK-28-NEXT:    Test21::C | -48
+// CHECK-28-NEXT:    Test21::D | -56
+// CHECK-28-NEXT:    Test21::E | -64
 class F : virtual D, virtual E {
   virtual void f();
 };
@@ -904,22 +946,22 @@
   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-29:      Vtable for 'Test22::C' (8 entries).
+// CHECK-29-NEXT:    0 | vbase_offset (16)
+// CHECK-29-NEXT:    1 | vbase_offset (12)
+// CHECK-29-NEXT:    2 | offset_to_top (0)
+// CHECK-29-NEXT:    3 | Test22::C RTTI
+// CHECK-29-NEXT:        -- (Test22::C, 0) vtable address --
+// CHECK-29-NEXT:    4 | void Test22::C::f()
+// CHECK-29-NEXT:    5 | vbase_offset (-4)
+// CHECK-29-NEXT:    6 | offset_to_top (-16)
+// CHECK-29-NEXT:    7 | Test22::C RTTI
+// CHECK-29-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
+// CHECK-29:      Construction vtable for ('Test22::V2', 16) in 'Test22::C' (3 entries).
+// CHECK-29-NEXT:    0 | vbase_offset (-4)
+// CHECK-29-NEXT:    1 | offset_to_top (0)
+// CHECK-29-NEXT:    2 | Test22::V2 RTTI
 
 struct C : virtual V1, virtual V2 {
   int c; 
@@ -943,34 +985,34 @@
   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-30:      Vtable for 'Test23::D' (7 entries).
+// CHECK-30-NEXT:    0 | vbase_offset (20)
+// CHECK-30-NEXT:    1 | vbase_offset (24)
+// CHECK-30-NEXT:    2 | offset_to_top (0)
+// CHECK-30-NEXT:    3 | Test23::D RTTI
+// CHECK-30-NEXT:        -- (Test23::C, 0) vtable address --
+// CHECK-30-NEXT:        -- (Test23::D, 0) vtable address --
+// CHECK-30-NEXT:    4 | vbase_offset (-4)
+// CHECK-30-NEXT:    5 | offset_to_top (-24)
+// CHECK-30-NEXT:    6 | Test23::D RTTI
+// CHECK-30-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-30:      Construction vtable for ('Test23::C', 0) in 'Test23::D' (7 entries).
+// CHECK-30-NEXT:    0 | vbase_offset (20)
+// CHECK-30-NEXT:    1 | vbase_offset (24)
+// CHECK-30-NEXT:    2 | offset_to_top (0)
+// CHECK-30-NEXT:    3 | Test23::C RTTI
+// CHECK-30-NEXT:        -- (Test23::C, 0) vtable address --
+// CHECK-30-NEXT:    4 | vbase_offset (-4)
+// CHECK-30-NEXT:    5 | offset_to_top (-24)
+// CHECK-30-NEXT:    6 | Test23::C RTTI
+// CHECK-30-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 --
+// CHECK-30:      Construction vtable for ('Test23::B', 24) in 'Test23::D' (3 entries).
+// CHECK-30-NEXT:    0 | vbase_offset (-4)
+// CHECK-30-NEXT:    1 | offset_to_top (0)
+// CHECK-30-NEXT:    2 | Test23::B RTTI
+// CHECK-30-NEXT:        -- (Test23::B, 24) vtable address --
 
 struct D : virtual A, virtual B, C {
   int d;
@@ -978,7 +1020,7 @@
   void f();
 };
 void D::f() { } 
-
+  D d;
 }
 
 namespace Test24 {
@@ -992,43 +1034,43 @@
 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-31:      Vtable for 'Test24::D' (10 entries).
+// CHECK-31-NEXT:    0 | vbase_offset (0)
+// CHECK-31-NEXT:    1 | vcall_offset (0)
+// CHECK-31-NEXT:    2 | offset_to_top (0)
+// CHECK-31-NEXT:    3 | Test24::D RTTI
+// CHECK-31-NEXT:        -- (Test24::A, 0) vtable address --
+// CHECK-31-NEXT:        -- (Test24::B, 0) vtable address --
+// CHECK-31-NEXT:        -- (Test24::D, 0) vtable address --
+// CHECK-31-NEXT:    4 | void Test24::D::f()
+// CHECK-31-NEXT:    5 | vbase_offset (-8)
+// CHECK-31-NEXT:    6 | vcall_offset (-8)
+// CHECK-31-NEXT:    7 | offset_to_top (-8)
+// CHECK-31-NEXT:    8 | Test24::D RTTI
+// CHECK-31-NEXT:        -- (Test24::C, 8) vtable address --
+// CHECK-31-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-31:      Construction vtable for ('Test24::B', 0) in 'Test24::D' (5 entries).
+// CHECK-31-NEXT:    0 | vbase_offset (0)
+// CHECK-31-NEXT:    1 | vcall_offset (0)
+// CHECK-31-NEXT:    2 | offset_to_top (0)
+// CHECK-31-NEXT:    3 | Test24::B RTTI
+// CHECK-31-NEXT:        -- (Test24::A, 0) vtable address --
+// CHECK-31-NEXT:        -- (Test24::B, 0) vtable address --
+// CHECK-31-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()
+// CHECK-31:      Construction vtable for ('Test24::C', 8) in 'Test24::D' (9 entries).
+// CHECK-31-NEXT:    0 | vbase_offset (-8)
+// CHECK-31-NEXT:    1 | vcall_offset (-8)
+// CHECK-31-NEXT:    2 | offset_to_top (0)
+// CHECK-31-NEXT:    3 | Test24::C RTTI
+// CHECK-31-NEXT:        -- (Test24::C, 8) vtable address --
+// CHECK-31-NEXT:    4 | [unused] void Test24::A::f()
+// CHECK-31-NEXT:    5 | vcall_offset (0)
+// CHECK-31-NEXT:    6 | offset_to_top (8)
+// CHECK-31-NEXT:    7 | Test24::C RTTI
+// CHECK-31-NEXT:        -- (Test24::A, 0) vtable address --
+// CHECK-31-NEXT:    8 | void Test24::A::f()
 struct D : B, C {
   virtual void f();
 };
@@ -1047,44 +1089,44 @@
 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-32:      Vtable for 'Test25::C' (11 entries).
+// CHECK-32-NEXT:    0 | vbase_offset (0)
+// CHECK-32-NEXT:    1 | vcall_offset (0)
+// CHECK-32-NEXT:    2 | offset_to_top (0)
+// CHECK-32-NEXT:    3 | Test25::C RTTI
+// CHECK-32-NEXT:        -- (Test25::A, 0) vtable address --
+// CHECK-32-NEXT:        -- (Test25::C, 0) vtable address --
+// CHECK-32-NEXT:        -- (Test25::V, 0) vtable address --
+// CHECK-32-NEXT:    4 | void Test25::V::f()
+// CHECK-32-NEXT:    5 | void Test25::C::g()
+// CHECK-32-NEXT:    6 | vbase_offset (-8)
+// CHECK-32-NEXT:    7 | vcall_offset (-8)
+// CHECK-32-NEXT:    8 | offset_to_top (-8)
+// CHECK-32-NEXT:    9 | Test25::C RTTI
+// CHECK-32-NEXT:        -- (Test25::B, 8) vtable address --
+// CHECK-32-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-32:      Construction vtable for ('Test25::A', 0) in 'Test25::C' (5 entries).
+// CHECK-32-NEXT:    0 | vbase_offset (0)
+// CHECK-32-NEXT:    1 | vcall_offset (0)
+// CHECK-32-NEXT:    2 | offset_to_top (0)
+// CHECK-32-NEXT:    3 | Test25::A RTTI
+// CHECK-32-NEXT:        -- (Test25::A, 0) vtable address --
+// CHECK-32-NEXT:        -- (Test25::V, 0) vtable address --
+// CHECK-32-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()
+// CHECK-32:      Construction vtable for ('Test25::B', 8) in 'Test25::C' (9 entries).
+// CHECK-32-NEXT:    0 | vbase_offset (-8)
+// CHECK-32-NEXT:    1 | vcall_offset (-8)
+// CHECK-32-NEXT:    2 | offset_to_top (0)
+// CHECK-32-NEXT:    3 | Test25::B RTTI
+// CHECK-32-NEXT:        -- (Test25::B, 8) vtable address --
+// CHECK-32-NEXT:    4 | [unused] void Test25::V::f()
+// CHECK-32-NEXT:    5 | vcall_offset (0)
+// CHECK-32-NEXT:    6 | offset_to_top (8)
+// CHECK-32-NEXT:    7 | Test25::B RTTI
+// CHECK-32-NEXT:        -- (Test25::V, 0) vtable address --
+// CHECK-32-NEXT:    8 | void Test25::V::f()
 struct C : A, virtual V, B {
   virtual void g();
 };
@@ -1109,37 +1151,37 @@
   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-33:      Vtable for 'Test26::D' (15 entries).
+// CHECK-33-NEXT:    0 | vbase_offset (8)
+// CHECK-33-NEXT:    1 | vbase_offset (8)
+// CHECK-33-NEXT:    2 | vbase_offset (0)
+// CHECK-33-NEXT:    3 | vcall_offset (0)
+// CHECK-33-NEXT:    4 | offset_to_top (0)
+// CHECK-33-NEXT:    5 | Test26::D RTTI
+// CHECK-33-NEXT:        -- (Test26::B, 0) vtable address --
+// CHECK-33-NEXT:        -- (Test26::D, 0) vtable address --
+// CHECK-33-NEXT:    6 | void Test26::B::c()
+// CHECK-33-NEXT:    7 | void Test26::D::d()
+// CHECK-33-NEXT:    8 | vcall_offset (0)
+// CHECK-33-NEXT:    9 | vbase_offset (0)
+// CHECK-33-NEXT:   10 | vcall_offset (0)
+// CHECK-33-NEXT:   11 | offset_to_top (-8)
+// CHECK-33-NEXT:   12 | Test26::D RTTI
+// CHECK-33-NEXT:        -- (Test26::A, 8) vtable address --
+// CHECK-33-NEXT:        -- (Test26::C, 8) vtable address --
+// CHECK-33-NEXT:   13 | void Test26::A::a()
+// CHECK-33-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()
+// CHECK-33:      Construction vtable for ('Test26::C', 8) in 'Test26::D' (7 entries).
+// CHECK-33-NEXT:    0 | vcall_offset (0)
+// CHECK-33-NEXT:    1 | vbase_offset (0)
+// CHECK-33-NEXT:    2 | vcall_offset (0)
+// CHECK-33-NEXT:    3 | offset_to_top (0)
+// CHECK-33-NEXT:    4 | Test26::C RTTI
+// CHECK-33-NEXT:        -- (Test26::A, 8) vtable address --
+// CHECK-33-NEXT:        -- (Test26::C, 8) vtable address --
+// CHECK-33-NEXT:    5 | void Test26::A::a()
+// CHECK-33-NEXT:    6 | void Test26::C::b()
 class D : virtual B, virtual C {
   virtual void d();
 };
@@ -1168,39 +1210,39 @@
   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-34:      Vtable for 'Test27::E' (13 entries).
+// CHECK-34-NEXT:    0 | vbase_offset (16)
+// CHECK-34-NEXT:    1 | offset_to_top (0)
+// CHECK-34-NEXT:    2 | Test27::E RTTI
+// CHECK-34-NEXT:        -- (Test27::A, 0) vtable address --
+// CHECK-34-NEXT:        -- (Test27::D, 0) vtable address --
+// CHECK-34-NEXT:        -- (Test27::E, 0) vtable address --
+// CHECK-34-NEXT:    3 | void Test27::A::a()
+// CHECK-34-NEXT:    4 | void Test27::D::d()
+// CHECK-34-NEXT:    5 | void Test27::E::e()
+// CHECK-34-NEXT:    6 | offset_to_top (-8)
+// CHECK-34-NEXT:    7 | Test27::E RTTI
+// CHECK-34-NEXT:        -- (Test27::C, 8) vtable address --
+// CHECK-34-NEXT:    8 | void Test27::C::c()
+// CHECK-34-NEXT:    9 | vcall_offset (0)
+// CHECK-34-NEXT:   10 | offset_to_top (-16)
+// CHECK-34-NEXT:   11 | Test27::E RTTI
+// CHECK-34-NEXT:        -- (Test27::B, 16) vtable address --
+// CHECK-34-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()
+// CHECK-34:      Construction vtable for ('Test27::D', 0) in 'Test27::E' (9 entries).
+// CHECK-34-NEXT:    0 | vbase_offset (16)
+// CHECK-34-NEXT:    1 | offset_to_top (0)
+// CHECK-34-NEXT:    2 | Test27::D RTTI
+// CHECK-34-NEXT:        -- (Test27::A, 0) vtable address --
+// CHECK-34-NEXT:        -- (Test27::D, 0) vtable address --
+// CHECK-34-NEXT:    3 | void Test27::A::a()
+// CHECK-34-NEXT:    4 | void Test27::D::d()
+// CHECK-34-NEXT:    5 | vcall_offset (0)
+// CHECK-34-NEXT:    6 | offset_to_top (-16)
+// CHECK-34-NEXT:    7 | Test27::D RTTI
+// CHECK-34-NEXT:        -- (Test27::B, 16) vtable address --
+// CHECK-34-NEXT:    8 | void Test27::B::b()
 struct E : D {
   virtual void e();
 };
@@ -1228,45 +1270,45 @@
 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-35:      Vtable for 'Test28::E' (14 entries).
+// CHECK-35-NEXT:    0 | vbase_offset (8)
+// CHECK-35-NEXT:    1 | offset_to_top (0)
+// CHECK-35-NEXT:    2 | Test28::E RTTI
+// CHECK-35-NEXT:        -- (Test28::D, 0) vtable address --
+// CHECK-35-NEXT:        -- (Test28::E, 0) vtable address --
+// CHECK-35-NEXT:    3 | void Test28::E::e()
+// CHECK-35-NEXT:    4 | vcall_offset (8)
+// CHECK-35-NEXT:    5 | vcall_offset (0)
+// CHECK-35-NEXT:    6 | vcall_offset (0)
+// CHECK-35-NEXT:    7 | offset_to_top (-8)
+// CHECK-35-NEXT:    8 | Test28::E RTTI
+// CHECK-35-NEXT:        -- (Test28::A, 8) vtable address --
+// CHECK-35-NEXT:        -- (Test28::C, 8) vtable address --
+// CHECK-35-NEXT:    9 | void Test28::A::a()
+// CHECK-35-NEXT:   10 | void Test28::C::c()
+// CHECK-35-NEXT:   11 | offset_to_top (-16)
+// CHECK-35-NEXT:   12 | Test28::E RTTI
+// CHECK-35-NEXT:        -- (Test28::B, 16) vtable address --
+// CHECK-35-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()
+// CHECK-35:      Construction vtable for ('Test28::D', 0) in 'Test28::E' (13 entries).
+// CHECK-35-NEXT:    0 | vbase_offset (8)
+// CHECK-35-NEXT:    1 | offset_to_top (0)
+// CHECK-35-NEXT:    2 | Test28::D RTTI
+// CHECK-35-NEXT:        -- (Test28::D, 0) vtable address --
+// CHECK-35-NEXT:    3 | vcall_offset (8)
+// CHECK-35-NEXT:    4 | vcall_offset (0)
+// CHECK-35-NEXT:    5 | vcall_offset (0)
+// CHECK-35-NEXT:    6 | offset_to_top (-8)
+// CHECK-35-NEXT:    7 | Test28::D RTTI
+// CHECK-35-NEXT:        -- (Test28::A, 8) vtable address --
+// CHECK-35-NEXT:        -- (Test28::C, 8) vtable address --
+// CHECK-35-NEXT:    8 | void Test28::A::a()
+// CHECK-35-NEXT:    9 | void Test28::C::c()
+// CHECK-35-NEXT:   10 | offset_to_top (-16)
+// CHECK-35-NEXT:   11 | Test28::D RTTI
+// CHECK-35-NEXT:        -- (Test28::B, 16) vtable address --
+// CHECK-35-NEXT:   12 | void Test28::B::b()
 struct E : D {
   virtual void e();
 };
@@ -1286,17 +1328,17 @@
   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()
+// CHECK-36:      Vtable for 'Test29::B' (6 entries).
+// CHECK-36-NEXT:    0 | vbase_offset (0)
+// CHECK-36-NEXT:    1 | vcall_offset (0)
+// CHECK-36-NEXT:    2 | offset_to_top (0)
+// CHECK-36-NEXT:    3 | Test29::B RTTI
+// CHECK-36-NEXT:        -- (Test29::A, 0) vtable address --
+// CHECK-36-NEXT:        -- (Test29::B, 0) vtable address --
+// CHECK-36-NEXT:    4 | Test29::V2 *Test29::B::f()
+// CHECK-36-NEXT:        [return adjustment: 0 non-virtual, -24 vbase offset offset]
+// CHECK-36-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-36-NEXT:    5 | Test29::V2 *Test29::B::f()
 struct B : virtual A {
   virtual V2 *f();
 };
@@ -1342,22 +1384,22 @@
   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]
+// CHECK-37:      Vtable for 'Test31::D' (11 entries).
+// CHECK-37-NEXT:    0 | vbase_offset (0)
+// CHECK-37-NEXT:    1 | vbase_offset (8)
+// CHECK-37-NEXT:    2 | vcall_offset (0)
+// CHECK-37-NEXT:    3 | offset_to_top (0)
+// CHECK-37-NEXT:    4 | Test31::D RTTI
+// CHECK-37-NEXT:        -- (Test31::B, 0) vtable address --
+// CHECK-37-NEXT:        -- (Test31::D, 0) vtable address --
+// CHECK-37-NEXT:    5 | void Test31::D::f()
+// CHECK-37-NEXT:    6 | vbase_offset (-8)
+// CHECK-37-NEXT:    7 | vcall_offset (-8)
+// CHECK-37-NEXT:    8 | offset_to_top (-8)
+// CHECK-37-NEXT:    9 | Test31::D RTTI
+// CHECK-37-NEXT:        -- (Test31::C, 8) vtable address --
+// CHECK-37-NEXT:   10 | void Test31::D::f()
+// CHECK-37-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
 struct D : virtual C {
   virtual void f();
 };
@@ -1377,10 +1419,10 @@
 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
+// CHECK-38:      Virtual base offset offsets for 'Test32::E' (3 entries).
+// CHECK-38-NEXT:    Test32::A | -32
+// CHECK-38-NEXT:    Test32::B | -24
+// CHECK-38-NEXT:    Test32::D | -40
 struct E : C, virtual D {
   virtual void f();
 };
@@ -1410,45 +1452,45 @@
   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()
+// CHECK-39:      Vtable for 'Test33::F' (30 entries).
+// CHECK-39-NEXT:    0 | vbase_offset (24)
+// CHECK-39-NEXT:    1 | vbase_offset (16)
+// CHECK-39-NEXT:    2 | vbase_offset (16)
+// CHECK-39-NEXT:    3 | vbase_offset (8)
+// CHECK-39-NEXT:    4 | offset_to_top (0)
+// CHECK-39-NEXT:    5 | Test33::F RTTI
+// CHECK-39-NEXT:        -- (Test33::A, 0) vtable address --
+// CHECK-39-NEXT:        -- (Test33::F, 0) vtable address --
+// CHECK-39-NEXT:    6 | void Test33::A::a()
+// CHECK-39-NEXT:    7 | void Test33::F::f()
+// CHECK-39-NEXT:    8 | vcall_offset (0)
+// CHECK-39-NEXT:    9 | vcall_offset (0)
+// CHECK-39-NEXT:   10 | vbase_offset (16)
+// CHECK-39-NEXT:   11 | vbase_offset (8)
+// CHECK-39-NEXT:   12 | vbase_offset (8)
+// CHECK-39-NEXT:   13 | offset_to_top (-8)
+// CHECK-39-NEXT:   14 | Test33::F RTTI
+// CHECK-39-NEXT:        -- (Test33::A, 8) vtable address --
+// CHECK-39-NEXT:        -- (Test33::E, 8) vtable address --
+// CHECK-39-NEXT:   15 | void Test33::A::a()
+// CHECK-39-NEXT:   16 | void Test33::E::e()
+// CHECK-39-NEXT:   17 | vbase_offset (0)
+// CHECK-39-NEXT:   18 | vcall_offset (0)
+// CHECK-39-NEXT:   19 | vbase_offset (8)
+// CHECK-39-NEXT:   20 | vbase_offset (0)
+// CHECK-39-NEXT:   21 | vcall_offset (0)
+// CHECK-39-NEXT:   22 | offset_to_top (-16)
+// CHECK-39-NEXT:   23 | Test33::F RTTI
+// CHECK-39-NEXT:        -- (Test33::A, 16) vtable address --
+// CHECK-39-NEXT:        -- (Test33::C, 16) vtable address --
+// CHECK-39-NEXT:        -- (Test33::D, 16) vtable address --
+// CHECK-39-NEXT:   24 | void Test33::A::a()
+// CHECK-39-NEXT:   25 | void Test33::C::c()
+// CHECK-39-NEXT:   26 | vcall_offset (0)
+// CHECK-39-NEXT:   27 | offset_to_top (-24)
+// CHECK-39-NEXT:   28 | Test33::F RTTI
+// CHECK-39-NEXT:        -- (Test33::B, 24) vtable address --
+// CHECK-39-NEXT:   29 | void Test33::B::b()
 struct F : virtual E, A {
   virtual void f();
 };
@@ -1475,36 +1517,36 @@
   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()
+// CHECK-40:      Construction vtable for ('Test34::E', 0) in 'Test34::F' (22 entries).
+// CHECK-40-NEXT:    0 | vbase_offset (0)
+// CHECK-40-NEXT:    1 | vbase_offset (8)
+// CHECK-40-NEXT:    2 | vcall_offset (0)
+// CHECK-40-NEXT:    3 | offset_to_top (0)
+// CHECK-40-NEXT:    4 | Test34::E RTTI
+// CHECK-40-NEXT:        -- (Test34::A, 0) vtable address --
+// CHECK-40-NEXT:        -- (Test34::E, 0) vtable address --
+// CHECK-40-NEXT:    5 | void Test34::A::a()
+// CHECK-40-NEXT:    6 | void Test34::E::e()
+// CHECK-40-NEXT:    7 | vcall_offset (8)
+// CHECK-40-NEXT:    8 | vcall_offset (0)
+// CHECK-40-NEXT:    9 | vbase_offset (-8)
+// CHECK-40-NEXT:   10 | offset_to_top (-8)
+// CHECK-40-NEXT:   11 | Test34::E RTTI
+// CHECK-40-NEXT:        -- (Test34::A, 8) vtable address --
+// CHECK-40-NEXT:        -- (Test34::D, 8) vtable address --
+// CHECK-40-NEXT:   12 | void Test34::A::a()
+// CHECK-40-NEXT:   13 | vbase_offset (-16)
+// CHECK-40-NEXT:   14 | vcall_offset (-16)
+// CHECK-40-NEXT:   15 | offset_to_top (-16)
+// CHECK-40-NEXT:   16 | Test34::E RTTI
+// CHECK-40-NEXT:        -- (Test34::B, 16) vtable address --
+// CHECK-40-NEXT:        -- (Test34::C, 16) vtable address --
+// CHECK-40-NEXT:   17 | [unused] void Test34::A::a()
+// CHECK-40-NEXT:   18 | void Test34::C::c()
+// CHECK-40-NEXT:   19 | offset_to_top (-24)
+// CHECK-40-NEXT:   20 | Test34::E RTTI
+// CHECK-40-NEXT:        -- (Test34::A, 24) vtable address --
+// CHECK-40-NEXT:   21 | void Test34::A::a()
 struct F : E {
   virtual void f();
 };
@@ -1543,55 +1585,55 @@
 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-41:      Vtable for 'Test35::H' (32 entries).
+// CHECK-41-NEXT:    0 | vbase_offset (32)
+// CHECK-41-NEXT:    1 | vbase_offset (0)
+// CHECK-41-NEXT:    2 | vcall_offset (0)
+// CHECK-41-NEXT:    3 | vcall_offset (0)
+// CHECK-41-NEXT:    4 | vbase_offset (16)
+// CHECK-41-NEXT:    5 | vbase_offset (8)
+// CHECK-41-NEXT:    6 | offset_to_top (0)
+// CHECK-41-NEXT:    7 | Test35::H RTTI
+// CHECK-41-NEXT:        -- (Test35::C, 0) vtable address --
+// CHECK-41-NEXT:        -- (Test35::D, 0) vtable address --
+// CHECK-41-NEXT:        -- (Test35::F, 0) vtable address --
+// CHECK-41-NEXT:        -- (Test35::H, 0) vtable address --
+// CHECK-41-NEXT:    8 | void Test35::C::c()
+// CHECK-41-NEXT:    9 | void Test35::D::d()
+// CHECK-41-NEXT:   10 | void Test35::H::h()
+// CHECK-41-NEXT:   11 | vbase_offset (0)
+// CHECK-41-NEXT:   12 | vbase_offset (24)
+// CHECK-41-NEXT:   13 | vcall_offset (0)
+// CHECK-41-NEXT:   14 | vbase_offset (8)
+// CHECK-41-NEXT:   15 | offset_to_top (-8)
+// CHECK-41-NEXT:   16 | Test35::H RTTI
+// CHECK-41-NEXT:        -- (Test35::B, 8) vtable address --
+// CHECK-41-NEXT:        -- (Test35::G, 8) vtable address --
+// CHECK-41-NEXT:   17 | void Test35::B::b()
+// CHECK-41-NEXT:   18 | vcall_offset (0)
+// CHECK-41-NEXT:   19 | offset_to_top (-16)
+// CHECK-41-NEXT:   20 | Test35::H RTTI
+// CHECK-41-NEXT:        -- (Test35::A, 16) vtable address --
+// CHECK-41-NEXT:   21 | void Test35::A::a()
+// CHECK-41-NEXT:   22 | vcall_offset (0)
+// CHECK-41-NEXT:   23 | vcall_offset (0)
+// CHECK-41-NEXT:   24 | vcall_offset (0)
+// CHECK-41-NEXT:   25 | vbase_offset (-16)
+// CHECK-41-NEXT:   26 | vbase_offset (-24)
+// CHECK-41-NEXT:   27 | offset_to_top (-32)
+// CHECK-41-NEXT:   28 | Test35::H RTTI
+// CHECK-41-NEXT:        -- (Test35::C, 32) vtable address --
+// CHECK-41-NEXT:        -- (Test35::D, 32) vtable address --
+// CHECK-41-NEXT:        -- (Test35::E, 32) vtable address --
+// CHECK-41-NEXT:   29 | void Test35::C::c()
+// CHECK-41-NEXT:   30 | void Test35::D::d()
+// CHECK-41-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
+// CHECK-41:      Virtual base offset offsets for 'Test35::H' (4 entries).
+// CHECK-41-NEXT:    Test35::A | -32
+// CHECK-41-NEXT:    Test35::B | -24
+// CHECK-41-NEXT:    Test35::D | -56
+// CHECK-41-NEXT:    Test35::E | -64
 struct H : F, G {
  virtual void h();
 };
@@ -1613,24 +1655,24 @@
  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]
+// CHECK-42:      Vtable for 'Test36::D' (12 entries).
+// CHECK-42-NEXT:    0 | vbase_offset (8)
+// CHECK-42-NEXT:    1 | vbase_offset (8)
+// CHECK-42-NEXT:    2 | vcall_offset (0)
+// CHECK-42-NEXT:    3 | offset_to_top (0)
+// CHECK-42-NEXT:    4 | Test36::D RTTI
+// CHECK-42-NEXT:        -- (Test36::C, 0) vtable address --
+// CHECK-42-NEXT:        -- (Test36::D, 0) vtable address --
+// CHECK-42-NEXT:    5 | void Test36::C::f()
+// CHECK-42-NEXT:    6 | void Test36::D::g()
+// CHECK-42-NEXT:    7 | vbase_offset (0)
+// CHECK-42-NEXT:    8 | vcall_offset (-8)
+// CHECK-42-NEXT:    9 | offset_to_top (-8)
+// CHECK-42-NEXT:   10 | Test36::D RTTI
+// CHECK-42-NEXT:        -- (Test36::A, 8) vtable address --
+// CHECK-42-NEXT:        -- (Test36::B, 8) vtable address --
+// CHECK-42-NEXT:   11 | void Test36::C::f()
+// CHECK-42-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
 struct D : virtual B, C {
  virtual void g();
 };
diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp
index c75efe2..cf988d1 100644
--- a/test/CodeGenCXX/vtable-linkage.cpp
+++ b/test/CodeGenCXX/vtable-linkage.cpp
@@ -1,4 +1,21 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fhidden-weak-vtables -emit-llvm -o %t.hidden
+// RUN: FileCheck --check-prefix=CHECK-1 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-2 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-2-HIDDEN %s < %t.hidden
+// RUN: FileCheck --check-prefix=CHECK-3 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-4 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-5 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-5-HIDDEN %s < %t.hidden
+// RUN: FileCheck --check-prefix=CHECK-6 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-6-HIDDEN %s < %t.hidden
+// RUN: FileCheck --check-prefix=CHECK-7 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-8 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-9 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-10 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-11 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-12 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-13 %s < %t
 
 namespace {
   struct A {
@@ -71,81 +88,112 @@
 template struct F<short>;
 extern template struct F<int>;
 
-void use_F(F<char> &fc) {
+void use_F() {
+  F<char> fc;
+  fc.foo();
   F<int> fi;
-  (void)fi;
+  fi.foo();
   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
+// CHECK-1: @_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
+// C has no key function, so its vtable should have weak_odr linkage
+// and hidden visibility (rdar://problem/7523229).
+// CHECK-2: @_ZTV1C = weak_odr constant
+// CHECK-2: @_ZTS1C = weak_odr constant
+// CHECK-2: @_ZTI1C = weak_odr constant
+// CHECK-2-HIDDEN: @_ZTV1C = weak_odr hidden constant
+// CHECK-2-HIDDEN: @_ZTS1C = weak_odr constant
+// CHECK-2-HIDDEN: @_ZTI1C = weak_odr hidden 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
+// CHECK-3: @_ZTV1D = constant
+// CHECK-3: @_ZTS1D = constant
+// CHECK-3: @_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
+// CHECK-4: @_ZTV1EIcE = constant
+// CHECK-4: @_ZTS1EIcE = constant
+// CHECK-4: @_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
+// CHECK-5: @_ZTV1EIsE = weak_odr constant
+// CHECK-5: @_ZTS1EIsE = weak_odr constant
+// CHECK-5: @_ZTI1EIsE = weak_odr constant
+// CHECK-5-HIDDEN: @_ZTV1EIsE = weak_odr constant
+// CHECK-5-HIDDEN: @_ZTS1EIsE = weak_odr constant
+// CHECK-5-HIDDEN: @_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
+// CHECK-6: @_ZTV1FIsE = weak_odr constant
+// CHECK-6: @_ZTS1FIsE = weak_odr constant
+// CHECK-6: @_ZTI1FIsE = weak_odr constant
+// CHECK-6-HIDDEN: @_ZTV1FIsE = weak_odr constant
+// CHECK-6-HIDDEN: @_ZTS1FIsE = weak_odr constant
+// CHECK-6-HIDDEN: @_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
+// CHECK-7: @_ZTV1EIlE = weak_odr constant
+// CHECK-7: @_ZTS1EIlE = weak_odr constant
+// CHECK-7: @_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
+// CHECK-8: @_ZTV1FIlE = weak_odr constant
+// CHECK-8: @_ZTS1FIlE = weak_odr constant
+// CHECK-8: @_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
+// CHECK-9: @_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
+// CHECK-10: @_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
+// CHECK-11: @"_ZTV3$_0" = internal constant
+// CHECK-11: @"_ZTS3$_0" = internal constant
+// CHECK-11: @"_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
+// CHECK-12: @_ZTVN12_GLOBAL__N_11AE = internal constant
+// CHECK-12: @_ZTSN12_GLOBAL__N_11AE = internal constant
+// CHECK-12: @_ZTIN12_GLOBAL__N_11AE = internal constant
 
+// F<char> is an explicit specialization without a key function, so
+// its vtable should have weak_odr linkage.
+// CHECK-13: @_ZTV1FIcE = weak_odr constant
+// CHECK-13: @_ZTS1FIcE = weak_odr constant
+// CHECK-13: @_ZTI1FIcE = weak_odr constant
 
+// RUN: FileCheck --check-prefix=CHECK-G %s < %t
+//
+// CHECK-G: @_ZTV1GIiE = weak_odr constant
+template <typename T>
+class G {
+public:
+  G() {}
+  virtual void f0();
+  virtual void f1();
+};
+template <>
+void G<int>::f1() {}
+template <typename T>
+void G<T>::f0() {}
+void G_f0()  { new G<int>(); }
diff --git a/test/CodeGenCXX/x86_32-arguments.cpp b/test/CodeGenCXX/x86_32-arguments.cpp
index f8d6551..e94e2ca 100644
--- a/test/CodeGenCXX/x86_32-arguments.cpp
+++ b/test/CodeGenCXX/x86_32-arguments.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
 
 // Non-trivial dtors, should both be passed indirectly.
 struct S {
   ~S();
-  int s;
+  short s;
 };
 
 // CHECK: define void @_Z1fv(%struct.S* sret %
@@ -13,6 +13,7 @@
 
 // Non-trivial dtors, should both be passed indirectly.
 class C {
+public:
   ~C();
   double c;
 };
@@ -22,3 +23,94 @@
 
 // CHECK: define void @_Z1f1C(%class.C*) 
 void f(C) { }
+
+
+
+
+// PR7058 - Missing byval on MI thunk definition.
+
+// CHECK: define void @_ZThn4_N18BasicAliasAnalysis13getModRefInfoE8CallSite
+// ...
+// CHECK: %struct.CallSite* byval %CS)
+struct CallSite {
+  unsigned Ptr;
+  CallSite(unsigned XX) : Ptr(XX) {}
+};
+
+struct AliasAnalysis {
+  virtual void xyz();
+  virtual void getModRefInfo(CallSite CS) = 0;
+};
+
+struct ModulePass {
+  virtual void xx();
+};
+
+struct BasicAliasAnalysis : public ModulePass, public AliasAnalysis {
+  void getModRefInfo(CallSite CS);
+};
+
+void BasicAliasAnalysis::getModRefInfo(CallSite CS) {
+}
+
+// Check various single element struct type conditions.
+//
+// PR7098.
+
+// CHECK: define i64 @_Z2f0v()
+struct s0_0 { int x; };
+struct s0_1 : s0_0 { int* y; };
+s0_1 f0() { return s0_1(); }
+
+// CHECK: define i32 @_Z2f1v()
+struct s1_0 { int x; };
+struct s1_1 : s1_0 { };
+s1_1 f1() { return s1_1(); }
+
+// CHECK: define double @_Z2f2v()
+struct s2_0 { double x; };
+struct s2_1 : s2_0 { };
+s2_1 f2() { return s2_1(); }
+
+// CHECK: define double @_Z2f3v()
+struct s3_0 { };
+struct s3_1 { double x; };
+struct s3_2 : s3_0, s3_1 { };
+s3_2 f3() { return s3_2(); }
+
+// CHECK: define i64 @_Z2f4v()
+struct s4_0 { float x; };
+struct s4_1 { float x; };
+struct s4_2 : s4_0, s4_1 { };
+s4_2 f4() { return s4_2(); }
+
+// CHECK: define i32 @_Z2f5v()
+struct s5 { s5(); int &x; };
+s5 f5() { return s5(); }
+
+// CHECK: define i32 @_Z4f6_0M2s6i(i32 %a)
+// CHECK: define i64 @_Z4f6_1M2s6FivE(%{{.*}} byval)
+// FIXME: It would be nice to avoid byval on the previous case.
+struct s6 {};
+typedef int s6::* s6_mdp;
+typedef int (s6::*s6_mfp)();
+s6_mdp f6_0(s6_mdp a) { return a; }
+s6_mfp f6_1(s6_mfp a) { return a; }
+
+// CHECK: define double @_Z2f7v()
+struct s7_0 { unsigned : 0; };
+struct s7_1 { double x; };
+struct s7 : s7_0, s7_1 { };
+s7 f7() { return s7(); }
+
+// CHECK: define void @_Z2f8v(%struct.s8* sret %agg.result)
+struct s8_0 { };
+struct s8_1 { double x; };
+struct s8 { s8_0 a; s8_1 b; };
+s8 f8() { return s8(); }
+
+// CHECK: define void @_Z2f9v(%struct.s9* sret %agg.result)
+struct s9_0 { unsigned : 0; };
+struct s9_1 { double x; };
+struct s9 { s9_0 a; s9_1 b; };
+s9 f9() { return s9(); }
diff --git a/test/CodeGenCXX/x86_64-arguments.cpp b/test/CodeGenCXX/x86_64-arguments.cpp
index 7ebbedc..cd09768 100644
--- a/test/CodeGenCXX/x86_64-arguments.cpp
+++ b/test/CodeGenCXX/x86_64-arguments.cpp
@@ -1,27 +1,102 @@
 // 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]])
+// CHECK: define void @_Z2f05f0_s1(i64 %a0.coerce0, i8* %a0.coerce1)
 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]])
+// CHECK: define void @_Z2f15f1_s1(i64 %a0.coerce0, double %a0.coerce1)
 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]])
+// CHECK: define void @_Z2f25f2_s1(i64 %a0.coerce0, i64 %a0.coerce1)
 void f2(f2_s1 a0) { }
 
 // PR5831
+// CHECK: define void @_Z2f34s3_1(i64 %x.coerce)
 struct s3_0 {};
 struct s3_1 { struct s3_0 a; long b; };
 void f3(struct s3_1 x) {}
+
+// CHECK: define i64 @_Z4f4_0M2s4i(i64 %a)
+// CHECK: define {{.*}} @_Z4f4_1M2s4FivE(i64 %a.coerce0, i64 %a.coerce1)
+struct s4 {};
+typedef int s4::* s4_mdp;
+typedef int (s4::*s4_mfp)();
+s4_mdp f4_0(s4_mdp a) { return a; }
+s4_mfp f4_1(s4_mfp a) { return a; }
+
+
+namespace PR7523 {
+struct StringRef {
+  char *a;
+};
+
+void AddKeyword(StringRef, int x);
+
+void foo() {
+  // CHECK: define void @_ZN6PR75233fooEv()
+  // CHECK: call void @_ZN6PR752310AddKeywordENS_9StringRefEi(i8* {{.*}}, i32 4)
+  AddKeyword(StringRef(), 4);
+}
+}
+
+namespace PR7742 { // Also rdar://8250764
+  struct s2 {
+    float a[2];
+  };
+  
+  struct c2 : public s2 {};
+  
+  // CHECK: define double @_ZN6PR77423fooEPNS_2c2E(%"struct.PR7742::c2"* %P)
+  c2 foo(c2 *P) {
+  }
+  
+}
+
+namespace PR5179 {
+  struct B {};
+
+  struct B1 : B {
+    int* pa;
+  };
+
+  struct B2 : B {
+    B1 b1;
+  };
+
+  // CHECK: define i8* @_ZN6PR51793barENS_2B2E(i32* %b2.coerce)
+  const void *bar(B2 b2) {
+    return b2.b1.pa;
+  }
+}
+
+namespace test5 {
+  struct Xbase { };
+  struct Empty { };
+  struct Y;
+  struct X : public Xbase {
+    Empty empty;
+    Y f();
+  };
+  struct Y : public X { 
+    Empty empty;
+  };
+  X getX();
+  int takeY(const Y&, int y);
+  void g() {
+    // rdar://8340348 - The temporary for the X object needs to have a defined
+    // address when passed into X::f as 'this'.
+    takeY(getX().f(), 42);
+  }
+  // CHECK: void @_ZN5test51gEv()
+  // CHECK: alloca %"struct.test5::Y"
+  // CHECK: alloca %"struct.test5::X"
+  // CHECK: alloca %"struct.test5::Y"
+}
diff --git a/test/CodeGenObjC/assign.m b/test/CodeGenObjC/assign.m
new file mode 100644
index 0000000..87e3834
--- /dev/null
+++ b/test/CodeGenObjC/assign.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple x86_64 -emit-llvm -o - %s | FileCheck %s
+
+struct s0 {
+  int x;
+};
+
+@interface C0
+@property int x0;
+@property _Complex int x1;
+@property struct s0 x2;
+@end
+
+// Check that we get exactly the message sends we expect, and no more.
+//
+// CHECK: define void @f0
+void f0(C0 *a) {
+// CHECK: objc_msgSend
+  int l0 = (a.x0 = 1);
+
+// CHECK: objc_msgSend
+  _Complex int l1 = (a.x1 = 1);
+
+// CHECK: objc_msgSend
+  struct s0 l2 = (a.x2 = (struct s0) { 1 });
+
+// CHECK: objc_msgSend
+// CHECK: objc_msgSend
+  int l3 = (a.x0 += 1);
+
+// CHECK: objc_msgSend
+// CHECK: objc_msgSend
+  _Complex int l4 = (a.x1 += 1);
+
+// CHECK-NOT: objc_msgSend
+// CHECK: }
+}
diff --git a/test/CodeGenObjC/atomic-aggregate-property.m b/test/CodeGenObjC/atomic-aggregate-property.m
index 2896d37..93eeca8 100644
--- a/test/CodeGenObjC/atomic-aggregate-property.m
+++ b/test/CodeGenObjC/atomic-aggregate-property.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10  -fobjc-nonfragile-abi -fobjc-gc -emit-llvm -o - %s | FileCheck -check-prefix LP64 %s
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10  -fobjc-nonfragile-abi -fobjc-gc -emit-llvm -o - %s | FileCheck -check-prefix LP64 %s
 // rdar: // 7849824
 
 struct s {
diff --git a/test/CodeGenObjC/bitfield_encoding.m b/test/CodeGenObjC/bitfield_encoding.m
new file mode 100644
index 0000000..03cf9bf
--- /dev/null
+++ b/test/CodeGenObjC/bitfield_encoding.m
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o %t %s
+// RUN: grep "ib1b14" %t | count 1
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fgnu-runtime -emit-llvm -o %t %s
+// RUN: grep "ib32i1b33i14" %t | count 1
+
+struct foo{
+	int a;
+	int b:1;
+	int c:14;
+};
+
+const char *encoding = @encode(struct foo);
diff --git a/test/CodeGenObjC/block-var-layout.m b/test/CodeGenObjC/block-var-layout.m
new file mode 100644
index 0000000..bf9ba8d
--- /dev/null
+++ b/test/CodeGenObjC/block-var-layout.m
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fblocks -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
+// RUN: %clang_cc1 -x objective-c++ -fblocks -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
+
+struct S {
+    int i1;
+    id o1;
+    struct V {
+     int i2;
+     id o2;
+    } v1;
+    int i3;
+    id o3;
+};
+
+__weak id wid;
+void x(id y) {}
+void y(int a) {}
+
+void f() {
+    __block int byref_int = 0;
+    char ch = 'a';
+    char ch1 = 'b';
+    char ch2 = 'c';
+    short sh = 2;
+    const id bar = (id)0;
+    id baz = 0;
+    __strong void *strong_void_sta;
+    __block id byref_bab = (id)0;
+    __block void *bl_var1;
+    int i; double dob;
+
+    void (^b)() = ^{
+        byref_int = sh + ch+ch1+ch2 ;
+        x(bar);
+        x(baz);
+        x((id)strong_void_sta);
+        x(byref_bab);
+    };    
+    b();
+
+// Test 2
+    void (^c)() = ^{
+        byref_int = sh + ch+ch1+ch2 ;
+        x(bar);
+        x(baz);
+        x((id)strong_void_sta);
+        x(wid);
+        bl_var1 = 0;
+        x(byref_bab);
+    };    
+    c();
+
+// Test 3
+void (^d)() = ^{
+        byref_int = sh + ch+ch1+ch2 ;
+        x(bar);
+        x(baz);
+        x(wid);
+        bl_var1 = 0; 
+        y(i + dob);
+        x(byref_bab);
+    };    
+    d();
+
+// Test4
+    struct S s2;
+    void (^e)() = ^{
+        x(s2.o1);
+    };    
+    e();
+}
+
+// Test 5 (unions/structs and their nesting):
+void Test5() {
+struct S5 {
+    int i1;
+    id o1;
+    struct V {
+     int i2;
+     id o2;
+    } v1;
+    int i3;
+    union UI {
+        void * i1;
+        id o1;
+        int i3;
+        id o3;
+    }ui;
+};
+
+union U {
+        void * i1;
+        id o1;
+        int i3;
+        id o3;
+}ui;
+
+struct S5 s2;
+union U u2;
+void (^c)() = ^{
+    x(s2.ui.o1);
+    x(u2.o1);
+};
+c();
+
+}
+
+// CHECK-LP64: L_OBJC_CLASS_NAME_:
+// CHECK-LP64-NEXT: .asciz      "A\024"
+
+// CHECK-LP64: L_OBJC_CLASS_NAME_1:
+// CHECK-LP64-NEXT: .asciz   "A\025"
+
+// CHECK-LP64: L_OBJC_CLASS_NAME_6:
+// CHECK-LP64-NEXT: .asciz   "A\023!"
+
+// CHECK-LP64: L_OBJC_CLASS_NAME_11:
+// CHECK-LP64-NEXT: .asciz   "Q\021\021"
+
+// CHECK-LP64: L_OBJC_CLASS_NAME_14:
+// CHECK-LP64-NEXT: .asciz   "Q\021\022p"
diff --git a/test/CodeGenObjC/blocks-1.m b/test/CodeGenObjC/blocks-1.m
index 76bfd59..1ac9c30 100644
--- a/test/CodeGenObjC/blocks-1.m
+++ b/test/CodeGenObjC/blocks-1.m
@@ -8,6 +8,16 @@
 // RUN: grep "_Block_object_assign" %t | count 4
 // RUN: grep "objc_read_weak" %t | count 2
 // RUN: grep "objc_assign_weak" %t | count 3
+// RUN: %clang_cc1 -x objective-c++ %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
 
diff --git a/test/CodeGenObjC/blocks-2.m b/test/CodeGenObjC/blocks-2.m
index 15160cc..0062e84 100644
--- a/test/CodeGenObjC/blocks-2.m
+++ b/test/CodeGenObjC/blocks-2.m
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 %s -emit-llvm -o %t -fobjc-gc -fblocks -triple i386-apple-darwin10
 // RUN: grep "objc_assign_strongCast" %t | count 2
+// RUN: %clang_cc1 -x objective-c++ %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.
 
diff --git a/test/CodeGenObjC/blocks-5.m b/test/CodeGenObjC/blocks-5.m
new file mode 100644
index 0000000..2d48b46
--- /dev/null
+++ b/test/CodeGenObjC/blocks-5.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -fblocks -o %t %s
+
+// rdar: // 8064140
+
+@interface IDEWorkspaceDocument 
+{
+  id _defaultEditorStateTree;
+}
+- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id key, id obj, unsigned char *stop))block ;
+@end
+
+
+
+int foo();
+extern void DVT (volatile const void * object, volatile const void * selector, const char * functionName); 
+@implementation IDEWorkspaceDocument
+
+- (void)stateSavingDefaultEditorStatesForURLs {
+ [_defaultEditorStateTree enumerateKeysAndObjectsUsingBlock:^(id identifier, id urlsToEditorStates, unsigned char *stop) {
+  do{ 
+if (foo() ) 
+  DVT(&self,&_cmd,__PRETTY_FUNCTION__);
+
+}while(0); 
+
+  do{ 
+       DVT(&self,&_cmd,__PRETTY_FUNCTION__);
+    }while(0); 
+
+
+ }];
+
+}
+
+- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id key, id obj, unsigned char *stop))block {}
+
+@end
diff --git a/test/CodeGenObjC/blocks-ivar-debug.m b/test/CodeGenObjC/blocks-ivar-debug.m
new file mode 100644
index 0000000..d0cf1f1
--- /dev/null
+++ b/test/CodeGenObjC/blocks-ivar-debug.m
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -g %s -fblocks -S -o %t
+// Radar 7959934
+
+@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/CodeGenObjC/blocks.m b/test/CodeGenObjC/blocks.m
index 8ba319e..b96a8d9 100644
--- a/test/CodeGenObjC/blocks.m
+++ b/test/CodeGenObjC/blocks.m
@@ -19,7 +19,7 @@
 -(void) im0;
 @end
 
-// RUN: grep 'define internal i32 @"__-\[A im0\]_block_invoke_"' %t
+// RUN: grep 'define internal i32 @"__8-\[A im0\]_block_invoke_0"' %t
 @implementation A
 -(void) im0 {
   (void) ^{ return 1; }();
@@ -31,5 +31,11 @@
 -(void) im1 {
   ^(void) { [self im0]; }();
 }
+-(void) im2 {
+  ^{ [super im0]; }();
+}
+-(void) im3 {
+  ^{ ^{[super im0];}(); }();
+}
 @end
 
diff --git a/test/CodeGenObjC/category-class.m b/test/CodeGenObjC/category-class.m
new file mode 100644
index 0000000..22d1973
--- /dev/null
+++ b/test/CodeGenObjC/category-class.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9  -emit-llvm -o - %s | FileCheck %s
+// PR7431
+
+// CHECK: module asm "\09.lazy_reference .objc_class_name_A"
+// CHECK: module asm "\09.objc_category_name_A_foo=0"
+// CHECK: module asm "\09.globl .objc_category_name_A_foo"
+
+@interface A
+@end
+@interface A(foo)
+- (void)foo_myStuff;
+@end
+@implementation A(foo)
+- (void)foo_myStuff {
+}
+@end
+
diff --git a/test/CodeGenObjC/debug-info-linkagename.m b/test/CodeGenObjC/debug-info-linkagename.m
index 2b10e2b..b606e5d 100644
--- a/test/CodeGenObjC/debug-info-linkagename.m
+++ b/test/CodeGenObjC/debug-info-linkagename.m
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1  -g -S -o %t %s
-// RUN: not grep 001 %t
+// RUN: not grep "001-[F bar" %t
+// Linkage name should not use 001 prefix in debug info.
 
 @interface F 
 -(int) bar;
diff --git a/test/CodeGenObjC/default-property-synthesis.m b/test/CodeGenObjC/default-property-synthesis.m
new file mode 100644
index 0000000..b3eeb22
--- /dev/null
+++ b/test/CodeGenObjC/default-property-synthesis.m
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi2 -emit-llvm -o %t %s
+// rdar://7923851.
+
+// Superclass declares property. Subclass redeclares the same property.
+// Do not @synthesize-by-default in the subclass. P1
+// Superclass declares a property. Subclass declares a different property with the same name
+// (such as different type or attributes). Do not @synthesize-by-default in the subclass. P2
+// Superclass conforms to a protocol that declares a property. Subclass redeclares the 
+// same property.  Do not @synthesize-by-default in the subclass. P3
+// Superclass conforms to a protocol that declares a property. Subclass conforms to the 
+// same protocol or a derived protocol. Do not @synthesize-by-default in the subclass. P4
+
+
+@protocol PROTO
+  @property int P3;
+  @property int P4;
+@end
+
+@protocol PROTO1 <PROTO> 
+  @property int IMP1;
+@end
+
+@interface Super <PROTO>
+  @property int P1;
+  @property (copy) id P2;
+@end
+
+@interface Sub : Super <PROTO1>
+  @property int P1;
+  @property (nonatomic, retain) id P2; // expected-warning {{property 'P2' 'copy' attribute does not match the property inherited from 'Super'}} \
+				       // expected-warning {{property 'P2' 'atomic' attribute does not match the property inherited from 'Super'}}
+  @property int P3;
+  @property int IMP2;
+@end
+
+@implementation Sub 
+@end
+
diff --git a/test/CodeGenObjC/dot-syntax-2.m b/test/CodeGenObjC/dot-syntax-2.m
new file mode 100644
index 0000000..020868a
--- /dev/null
+++ b/test/CodeGenObjC/dot-syntax-2.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// rdar: // 8062778
+
+@interface NSDictionary @end
+
+@interface NSMutableDictionary : NSDictionary
+@end
+
+@interface MutableMyClass 
+- (NSMutableDictionary *)myDict;
+- (void)setMyDict:(NSDictionary *)myDict;
+
+- (NSMutableDictionary *)myLang;
+- (void)setMyLang:(NSDictionary *)myLang;
+@end
+
+@interface AnotherClass @end
+
+@implementation AnotherClass
+- (void)foo
+{
+    MutableMyClass * myObject;
+    NSDictionary * newDict;
+    myObject.myDict = newDict; 
+    myObject.myLang = newDict;
+}
+@end
diff --git a/test/CodeGenObjC/exceptions.m b/test/CodeGenObjC/exceptions.m
index a74dee9..b431e37 100644
--- a/test/CodeGenObjC/exceptions.m
+++ b/test/CodeGenObjC/exceptions.m
@@ -1,11 +1,8 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -O2 -o - %s | FileCheck %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 {
@@ -16,3 +13,123 @@
   } @catch (id e) {
   }
 }
+
+// CHECK: define void @f1()
+void f1() {
+  extern void foo(void);
+
+  while (1) {
+    // CHECK:      call void @objc_exception_try_enter
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: call i32 @_setjmp(
+    // CHECK-NEXT: icmp
+    // CHECK-NEXT: br i1
+    @try {
+    // CHECK:      call void asm sideeffect "", "*m"
+    // CHECK-NEXT: call void @foo()
+      foo();
+    // CHECK-NEXT: call void @objc_exception_try_exit
+    // CHECK-NEXT: ret void
+
+    // CHECK:      call void asm sideeffect "", "=*m"
+    // CHECK-NEXT: ret void
+    } @finally {
+      break;
+    }
+  }
+}
+
+// Test that modifications to local variables are respected under
+// optimization.  rdar://problem/8160285
+
+// CHECK: define i32 @f2()
+int f2() {
+  extern void foo(void);
+
+  // CHECK:        [[X:%.*]] = alloca i32
+  // CHECK:        store i32 5, i32* [[X]]
+  int x = 0;
+  x += 5;
+
+  // CHECK:        [[SETJMP:%.*]] = call i32 @_setjmp
+  // CHECK-NEXT:   [[CAUGHT:%.*]] = icmp eq i32 [[SETJMP]], 0
+  // CHECK-NEXT:   br i1 [[CAUGHT]]
+  @try {
+    // If the optimizers ever figure out how to make this store 6,
+    // that's okay.
+    // CHECK:      [[T1:%.*]] = load i32* [[X]]
+    // CHECK-NEXT: [[T2:%.*]] = add nsw i32 [[T1]], 1
+    // CHECK-NEXT: store i32 [[T2]], i32* [[X]]
+    x++;
+    // CHECK-NEXT: call void asm sideeffect "", "*m,*m"(i32* [[X]]
+    // CHECK-NEXT: call void @foo()
+    // CHECK-NEXT: call void @objc_exception_try_exit
+    // CHECK-NEXT: [[T:%.*]] = load i32* [[X]]
+    // CHECK-NEXT: ret i32 [[T]]
+    foo();
+  } @catch (id) {
+    // Landing pad.  Note that we elide the re-enter.
+    // CHECK:      call void asm sideeffect "", "=*m,=*m"(i32* [[X]]
+    // CHECK-NEXT: call i8* @objc_exception_extract
+    // CHECK-NEXT: [[T1:%.*]] = load i32* [[X]]
+    // CHECK-NEXT: [[T2:%.*]] = add nsw i32 [[T1]], -1
+
+    // This store is dead.
+    // CHECK-NEXT: store i32 [[T2]], i32* [[X]]
+
+    // CHECK-NEXT: ret i32 [[T2]]
+    x--;
+  }
+  return x;
+}
+
+// Test that the cleanup destination is saved when entering a finally
+// block.  rdar://problem/8293901
+// CHECK: define void @f3()
+void f3() {
+  extern void f3_helper(int, int*);
+
+  // CHECK:      [[X:%.*]] = alloca i32
+  // CHECK:      store i32 0, i32* [[X]]
+  int x = 0;
+
+  // CHECK:      call void @objc_exception_try_enter(
+  // CHECK:      call i32 @_setjmp
+  // CHECK-NEXT: icmp eq
+  // CHECK-NEXT: br i1
+
+  @try {
+    // CHECK:    call void @f3_helper(i32 0, i32* [[X]])
+    // CHECK:    call void @objc_exception_try_exit(
+    f3_helper(0, &x);
+  } @finally {
+    // CHECK:    [[DEST1:%.*]] = phi i32 [ 0, {{%.*}} ], [ 3, {{%.*}} ]
+    // CHECK:    call void @objc_exception_try_enter
+    // CHECK:    call i32 @_setjmp
+    @try {
+      // CHECK:  call void @f3_helper(i32 1, i32* [[X]])
+      // CHECK:  call void @objc_exception_try_exit(
+      f3_helper(1, &x);
+    } @finally {
+      // CHECK:  [[DEST2:%.*]] = phi i32 [ 0, {{%.*}} ], [ 5, {{%.*}} ]
+      // CHECK:  call void @f3_helper(i32 2, i32* [[X]])
+      f3_helper(2, &x);
+
+      // This loop is large enough to dissuade the optimizer from just
+      // duplicating the finally block.
+      while (x) f3_helper(3, &x);
+
+      // This is a switch or maybe some chained branches, but relying
+      // on a specific result from the optimizer is really unstable.
+      // CHECK:  [[DEST2]]
+    }
+
+      // This is a switch or maybe some chained branches, but relying
+      // on a specific result from the optimizer is really unstable.
+    // CHECK:    [[DEST1]]
+  }
+
+  // CHECK:      call void @f3_helper(i32 4, i32* [[X]])
+  // CHECK-NEXT: ret void
+  f3_helper(4, &x);
+}
diff --git a/test/CodeGenObjC/for-in.m b/test/CodeGenObjC/for-in.m
index 354ff32..7e6098a 100644
--- a/test/CodeGenObjC/for-in.m
+++ b/test/CodeGenObjC/for-in.m
@@ -23,7 +23,7 @@
 
   p("array.length: %d\n", [array count]);
   unsigned index = 0;
-  for (NSString *i in array) {
+  for (NSString *i in array) {	// expected-warning {{collection expression type 'NSArray *' may not respond}}
     p("element %d: %s\n", index++, [i cString]);
   }
 }
@@ -33,7 +33,7 @@
 
   p("array.length: %d\n", [array count]);
   unsigned index = 0;
-  for (NSString *i in array) {
+  for (NSString *i in array) {	// expected-warning {{collection expression type 'NSArray *' may not respond}}
     index++;
     if (index == 10)
       continue;
diff --git a/test/CodeGenObjC/fpret.m b/test/CodeGenObjC/fpret.m
new file mode 100644
index 0000000..4884888
--- /dev/null
+++ b/test/CodeGenObjC/fpret.m
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -o - %s | \
+// RUN:   FileCheck --check-prefix=CHECK-X86_32 %s
+//
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | \
+// RUN:   FileCheck --check-prefix=CHECK-X86_64 %s
+//
+// RUN: %clang_cc1 -triple armv7-apple-darwin10 -emit-llvm -target-abi apcs-gnu -o - %s | \
+// RUN:   FileCheck --check-prefix=CHECK-ARMV7 %s
+
+@interface A
+-(float) floatValue;
+-(double) doubleValue;
+-(long double) longDoubleValue;
+@end
+
+
+// CHECK-X86_32: define void @t0()
+// CHECK-X86_32: call float bitcast {{.*}} @objc_msgSend_fpret to
+// CHECK-X86_32: call double {{.*}} @objc_msgSend_fpret(
+// CHECK-X86_32: call x86_fp80 bitcast {{.*}} @objc_msgSend_fpret to
+// CHECK-X86_32: }
+//
+// CHECK-X86_64: define void @t0()
+// CHECK-X86_64: call float bitcast {{.*}} @objc_msgSend to
+// CHECK-X86_64: call double bitcast {{.*}} @objc_msgSend to
+// CHECK-X86_64: call x86_fp80 bitcast {{.*}} @objc_msgSend_fpret to
+// CHECK-X86_64: }
+//
+// CHECK-ARMV7: define void @t0()
+// CHECK-ARMV7: call float bitcast {{.*}} @objc_msgSend to
+// CHECK-ARMV7: call double bitcast {{.*}} @objc_msgSend to
+// CHECK-ARMV7: call double bitcast {{.*}} @objc_msgSend to
+// CHECK-ARMV7: }
+void t0() {
+  [(A*)0 floatValue];
+  [(A*)0 doubleValue];
+  [(A*)0 longDoubleValue];
+}
diff --git a/test/CodeGenObjC/gnu-exceptions.m b/test/CodeGenObjC/gnu-exceptions.m
new file mode 100644
index 0000000..6790a29
--- /dev/null
+++ b/test/CodeGenObjC/gnu-exceptions.m
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -fexceptions -fgnu-runtime -o - %s | FileCheck %s
+
+void opaque(void);
+void log(int i);
+
+@class C;
+
+// CHECK: define void @test0() {
+void test0() {
+  @try {
+    // CHECK: invoke void @opaque()
+    opaque();
+
+    // CHECK: call void @log(i32 1)
+
+  } @catch (C *c) {
+    // CHECK: call i8* @llvm.eh.exception()
+    // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} @__gnu_objc_personality_v0
+    // CHECK: br i1
+
+    // CHECK: call void @log(i32 0)
+
+    // CHECK: call void @objc_exception_throw
+
+    log(0);
+  }
+
+  log(1);
+}
diff --git a/test/CodeGenObjC/ivar-layout-64-bitfields.m b/test/CodeGenObjC/ivar-layout-64-bitfields.m
index 1b6a16b..9710e16 100644
--- a/test/CodeGenObjC/ivar-layout-64-bitfields.m
+++ b/test/CodeGenObjC/ivar-layout-64-bitfields.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s
 @interface I
 {
   struct {
diff --git a/test/CodeGenObjC/ivar-layout-64.m b/test/CodeGenObjC/ivar-layout-64.m
index 60ce1df..f227bfc 100644
--- a/test/CodeGenObjC/ivar-layout-64.m
+++ b/test/CodeGenObjC/ivar-layout-64.m
@@ -4,6 +4,12 @@
 // 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
+// RUNX: llvm-gcc -ObjC++ -m64 -fobjc-gc -emit-llvm -S -o %t %s &&
+// RUN: %clang_cc1 -x objective-c++ -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
 
 /*
 
diff --git a/test/CodeGenObjC/ivar-layout-no-optimize.m b/test/CodeGenObjC/ivar-layout-no-optimize.m
index e7fd130..7760f94 100644
--- a/test/CodeGenObjC/ivar-layout-no-optimize.m
+++ b/test/CodeGenObjC/ivar-layout-no-optimize.m
@@ -1,5 +1,7 @@
 // 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
+// RUN: %clang_cc1 -x objective-c++ -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;
diff --git a/test/CodeGenObjC/ivar-layout-nonfragile-abi2.m b/test/CodeGenObjC/ivar-layout-nonfragile-abi2.m
new file mode 100644
index 0000000..b474caa
--- /dev/null
+++ b/test/CodeGenObjC/ivar-layout-nonfragile-abi2.m
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi2 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi2 -emit-llvm -o %t %s
+// rdar: // 7824380
+
+@interface Super {
+  int ivar_super_a : 5;
+}
+@end
+
+@interface A : Super {
+@public
+  int ivar_a : 5;
+}
+@end
+
+int f0(A *a) {
+  return a->ivar_a;
+}
+
+@interface A () {
+@public
+  int ivar_ext_a : 5;
+  int ivar_ext_b : 5;
+}@end
+
+int f1(A *a) {
+  return a->ivar_ext_a + a->ivar_a;
+}
+
+@interface A () {
+@public
+  int ivar_ext2_a : 5;
+  int ivar_ext2_b : 5;
+}@end
+
+int f2(A* a) {
+  return a->ivar_ext2_a + a->ivar_ext_a + a->ivar_a;
+}
+
+@implementation A {
+@public
+  int ivar_b : 5;
+  int ivar_c : 5;
+  int ivar_d : 5;
+}
+@end
+
+int f3(A *a) {  
+  return a->ivar_d + a->ivar_ext2_a + a->ivar_ext_a + a->ivar_a;
+}
+
diff --git a/test/CodeGenObjC/metadata_symbols.m b/test/CodeGenObjC/metadata_symbols.m
index 921168c..3163946 100644
--- a/test/CodeGenObjC/metadata_symbols.m
+++ b/test/CodeGenObjC/metadata_symbols.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -emit-llvm -o %t %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -emit-llvm -fexceptions -o %t %s
 // RUN: FileCheck -check-prefix=CHECK-X86_64 < %t %s
 // RUN: grep '@"OBJC_EHTYPE_$_EH3"' %t | count 3
 
@@ -33,8 +33,8 @@
 // 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]"
+// CHECK-ARMV6: define internal void @"\01-[A im0]"
+// CHECK-ARMV6: define internal void @"\01-[A(Cat) im1]"
 
 @interface A
 @end
diff --git a/test/CodeGenObjC/objc-gc-aggr-assign.m b/test/CodeGenObjC/objc-gc-aggr-assign.m
new file mode 100644
index 0000000..9fd64d5
--- /dev/null
+++ b/test/CodeGenObjC/objc-gc-aggr-assign.m
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o - %s | FileCheck -check-prefix C %s
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o - %s | FileCheck -check-prefix CP %s
+
+static int count;
+
+typedef struct S {
+   int ii;
+} SS;
+
+struct type_s {
+   SS may_recurse;
+   id id_val;
+};
+
+@interface NamedObject
+{
+  struct type_s type_s_ivar;
+}
+- (void) setSome : (struct type_s) arg;
+- (struct type_s) getSome;
+@property(assign) struct type_s aggre_prop;
+@end
+
+@implementation NamedObject 
+- (void) setSome : (struct type_s) arg
+  {
+     type_s_ivar = arg;
+  }
+- (struct type_s) getSome 
+  {
+    return type_s_ivar;
+  }
+@synthesize aggre_prop = type_s_ivar;
+@end
+
+struct type_s some = {{1234}, (id)0};
+
+struct type_s get(void)
+{
+  return some;
+}
+
+void f(const struct type_s *in, struct type_s *out) {
+  *out = *in;
+}
+
+#ifdef __cplusplus
+struct Derived : type_s { };
+
+void foo(Derived* src, Derived* dest) {
+        *dest = *src;
+}
+#endif
+
+// CHECK-C: call i8* @objc_memmove_collectable
+// CHECK-C: call i8* @objc_memmove_collectable
+// CHECK-C: call i8* @objc_memmove_collectable
+
+// CHECK-CP: call i8* @objc_memmove_collectable
+// CHECK-CP: call i8* @objc_memmove_collectable
+// CHECK-CP: call i8* @objc_memmove_collectable
+// CHECK-CP: call i8* @objc_memmove_collectable
diff --git a/test/CodeGenObjC/objc2-new-gc-api-strongcast.m b/test/CodeGenObjC/objc2-new-gc-api-strongcast.m
index 1ff2dd3..0413910 100644
--- a/test/CodeGenObjC/objc2-new-gc-api-strongcast.m
+++ b/test/CodeGenObjC/objc2-new-gc-api-strongcast.m
@@ -1,9 +1,11 @@
 // 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
+// RUN: %clang_cc1 -x objective-c++ -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);
+DSATextSearch **_uniqueIdToIdentifierArray = (0);
 void foo (int _nextId)
 {
 	_uniqueIdToIdentifierArray[_nextId] = 0;  // objc_assign_strongCast
diff --git a/test/CodeGenObjC/objc2-no-write-barrier.m b/test/CodeGenObjC/objc2-no-write-barrier.m
index 544c329..a0ebc10 100644
--- a/test/CodeGenObjC/objc2-no-write-barrier.m
+++ b/test/CodeGenObjC/objc2-no-write-barrier.m
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s
 // RUN: grep 'objc_assign' %t | count 0
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s
+// RUN: grep 'objc_assign' %t | count 0
 
 typedef struct {
     int ival;
diff --git a/test/CodeGenObjC/objc2-retain-codegen.m b/test/CodeGenObjC/objc2-retain-codegen.m
index 2c3317a..9f66206 100644
--- a/test/CodeGenObjC/objc2-retain-codegen.m
+++ b/test/CodeGenObjC/objc2-retain-codegen.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fobjc-gc-only -emit-llvm -o %t %s
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-unknown-unknown -fobjc-gc-only -emit-llvm -o %t %s
 
 @interface I0 {
   I0 *_f0;
diff --git a/test/CodeGenObjC/objc2-strong-cast-1.m b/test/CodeGenObjC/objc2-strong-cast-1.m
index 509f21a..b79f8a0 100644
--- a/test/CodeGenObjC/objc2-strong-cast-1.m
+++ b/test/CodeGenObjC/objc2-strong-cast-1.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fobjc-gc -emit-llvm -o %t %s
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-unknown-unknown -fobjc-gc -emit-llvm -o %t %s
 
 @interface I {
   __attribute__((objc_gc(strong))) int *i_IdocumentIDs;
diff --git a/test/CodeGenObjC/objc2-strong-cast.m b/test/CodeGenObjC/objc2-strong-cast.m
index 9ef463c..7291c4e 100644
--- a/test/CodeGenObjC/objc2-strong-cast.m
+++ b/test/CodeGenObjC/objc2-strong-cast.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fobjc-gc -emit-llvm -o %t %s
+// RUN: %clang_cc1 -x objective-c++ -fobjc-gc -emit-llvm -o %t %s
 
 @interface I {
   __attribute__((objc_gc(strong))) signed long *_documentIDs;
diff --git a/test/CodeGenObjC/objc2-weak-assign.m b/test/CodeGenObjC/objc2-weak-assign.m
index 42fa773..74c0c00 100644
--- a/test/CodeGenObjC/objc2-weak-assign.m
+++ b/test/CodeGenObjC/objc2-weak-assign.m
@@ -1,5 +1,7 @@
 // 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
+// RUN: %clang_cc1 -x objective-c++ -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;
diff --git a/test/CodeGenObjC/objc2-weak-compare.m b/test/CodeGenObjC/objc2-weak-compare.m
index cb8ca5f..8cba1a9 100644
--- a/test/CodeGenObjC/objc2-weak-compare.m
+++ b/test/CodeGenObjC/objc2-weak-compare.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s
+// RUN: %clang_cc1 -x objective-c++ -triple i386-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s
 
 @interface PBXTarget 
 {
@@ -10,6 +11,7 @@
 - Meth;
 @end
 
+extern void foo();
 @implementation PBXTarget
 - Meth {
 	if (_lastKnownTarget != result)
diff --git a/test/CodeGenObjC/objc2-weak-ivar-debug.m b/test/CodeGenObjC/objc2-weak-ivar-debug.m
index a6fb7fa..8f7acd7 100644
--- a/test/CodeGenObjC/objc2-weak-ivar-debug.m
+++ b/test/CodeGenObjC/objc2-weak-ivar-debug.m
@@ -1,5 +1,7 @@
 // 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
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin9 -fobjc-gc -g -emit-llvm -o - %s
+// RUN: %clang_cc1 -x objective-c++ -triple i386-apple-darwin9 -fobjc-gc -g -emit-llvm -o - %s
 
 // rdar://7252252
 @interface Loop {
diff --git a/test/CodeGenObjC/objc2-weak-ivar.m b/test/CodeGenObjC/objc2-weak-ivar.m
index cfe1e95..8c91a80 100644
--- a/test/CodeGenObjC/objc2-weak-ivar.m
+++ b/test/CodeGenObjC/objc2-weak-ivar.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s
 @class NSObject;
 
 @interface Foo  {
diff --git a/test/CodeGenObjC/objc2-write-barrier-2.m b/test/CodeGenObjC/objc2-write-barrier-2.m
index 9a76c6e..74cd7ea 100644
--- a/test/CodeGenObjC/objc2-write-barrier-2.m
+++ b/test/CodeGenObjC/objc2-write-barrier-2.m
@@ -2,6 +2,10 @@
 // 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
+// RUN: %clang_cc1 -x objective-c++ -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);
diff --git a/test/CodeGenObjC/objc2-write-barrier-3.m b/test/CodeGenObjC/objc2-write-barrier-3.m
index 626083b..cb72cc0 100644
--- a/test/CodeGenObjC/objc2-write-barrier-3.m
+++ b/test/CodeGenObjC/objc2-write-barrier-3.m
@@ -1,6 +1,9 @@
 // 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
+// RUN: %clang_cc1 -x objective-c++ -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;
diff --git a/test/CodeGenObjC/objc2-write-barrier-4.m b/test/CodeGenObjC/objc2-write-barrier-4.m
index 11b4ab4..ab30649 100644
--- a/test/CodeGenObjC/objc2-write-barrier-4.m
+++ b/test/CodeGenObjC/objc2-write-barrier-4.m
@@ -1,6 +1,9 @@
 // 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
+// RUN: %clang_cc1 -x objective-c++ -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
diff --git a/test/CodeGenObjC/objc2-write-barrier-5.m b/test/CodeGenObjC/objc2-write-barrier-5.m
index babe26d..373df0c 100644
--- a/test/CodeGenObjC/objc2-write-barrier-5.m
+++ b/test/CodeGenObjC/objc2-write-barrier-5.m
@@ -1,6 +1,9 @@
 // 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
+// RUN: %clang_cc1 -x objective-c++ -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 
 {
diff --git a/test/CodeGenObjC/objc2-write-barrier.m b/test/CodeGenObjC/objc2-write-barrier.m
index 0934e0a..08b65de 100644
--- a/test/CodeGenObjC/objc2-write-barrier.m
+++ b/test/CodeGenObjC/objc2-write-barrier.m
@@ -1,6 +1,9 @@
 // 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
+// RUN: %clang_cc1 -x objective-c++ -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;
@@ -49,9 +52,9 @@
 
 
 // The test cases
-void *rhs = 0;
+void* rhs = 0;
 
-#define ASSIGNTEST(expr, global) expr = rhs
+#define ASSIGNTEST(expr, global) expr = (typeof(expr))rhs
 
 int testGlobals() {
   // Everything in this function generates assign_global intercepts
diff --git a/test/CodeGenObjC/property-category-impl.m b/test/CodeGenObjC/property-category-impl.m
new file mode 100644
index 0000000..80a18cb
--- /dev/null
+++ b/test/CodeGenObjC/property-category-impl.m
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -fobjc-nonfragile-abi -emit-llvm -o - %s | FileCheck %s
+
+// rdar : // 8093297
+
+@interface Foo @end
+
+@protocol Proto
+@property (readonly) int proto_property;
+@end
+
+@interface Foo (Category) <Proto> @end
+
+@implementation Foo (Category)
+-(int)proto_property { return 0; }
+@end
+
+
+// CHECK: l_OBJC_$_PROP_LIST_Foo_$_Category" = internal global
+// CHECK: l_OBJC_$_CATEGORY_Foo_$_Category" = internal global
+// CHECK: l_OBJC_$_PROP_LIST_Foo_$_Category
diff --git a/test/CodeGenObjC/property-complex.m b/test/CodeGenObjC/property-complex.m
index 59200eb..071d0b1 100644
--- a/test/CodeGenObjC/property-complex.m
+++ b/test/CodeGenObjC/property-complex.m
@@ -1,5 +1,5 @@
-// 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
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -o %t %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -o %t %s
 
 @interface I0 {
 @public
diff --git a/test/CodeGenObjC/protocols.m b/test/CodeGenObjC/protocols.m
index 0f24a1c..6dadb11 100644
--- a/test/CodeGenObjC/protocols.m
+++ b/test/CodeGenObjC/protocols.m
@@ -1,8 +1,9 @@
-// RUN: %clang_cc1 -emit-llvm %s -o %t
+// RUN: %clang_cc1 -emit-llvm-only %s
 
 void p(const char*, ...);
 
 @interface Root
++(int) maxValue;
 -(int) conformsTo: (id) x;
 @end
 
@@ -48,3 +49,9 @@
 
   return 0;
 }
+
+// rdar://problem/7992749
+typedef Root<P1> P1Object;
+int test10() {
+  return [P1Object maxValue];
+}
diff --git a/test/CodeGenObjC/return-objc-object.mm b/test/CodeGenObjC/return-objc-object.mm
new file mode 100644
index 0000000..95cce23
--- /dev/null
+++ b/test/CodeGenObjC/return-objc-object.mm
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64 -emit-llvm -o - %s | FileCheck %s
+
+@protocol P1 @end
+@interface NSOperationQueue 
+{
+  char ch[64];
+  double d;
+}
+@end
+
+NSOperationQueue &f();
+NSOperationQueue<P1> &f1();
+
+void call_once() {
+  f();
+  f1();
+}
+// CHECK: call %0* @_Z1fv()
+// CHECK: call %0* @_Z2f1v()  
diff --git a/test/CodeGenObjC/super-dotsyntax-struct-property.m b/test/CodeGenObjC/super-dotsyntax-struct-property.m
new file mode 100644
index 0000000..aac4c1d
--- /dev/null
+++ b/test/CodeGenObjC/super-dotsyntax-struct-property.m
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -fobjc-nonfragile-abi -emit-llvm %s -o -  | FileCheck %s
+// rdar: // 8203426
+
+
+typedef double CGFloat;
+struct CGPoint {
+  CGFloat x;
+  CGFloat y;
+};
+typedef struct CGPoint CGPoint;
+
+
+
+struct CGSize {
+  CGFloat width;
+  CGFloat height;
+};
+typedef struct CGSize CGSize;
+
+
+struct CGRect {
+  CGPoint origin;
+  CGSize size;
+};
+typedef struct CGRect CGRect;
+
+@interface UIView {
+}
+@property CGRect frame;
+@end
+
+@interface crashclass : UIView {
+
+}
+
+@end
+
+@implementation crashclass
+- (void)setFrame:(CGRect)frame
+{
+        super.frame = frame;
+	[super setFrame:frame];
+}
+
+@end
+// CHECK-NOT: declare void @objc_msgSendSuper2_stret
+// CHECK: declare i8* @objc_msgSendSuper2
diff --git a/test/CodeGenObjC/synchronized.m b/test/CodeGenObjC/synchronized.m
index 1af8234..2a80906 100644
--- a/test/CodeGenObjC/synchronized.m
+++ b/test/CodeGenObjC/synchronized.m
@@ -1,6 +1,4 @@
-// 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
+// RUN: %clang_cc1 -emit-llvm -triple=i686-apple-darwin9 -o - %s -O2 | FileCheck %s
 
 @interface MyClass
 {
@@ -10,31 +8,71 @@
 
 @implementation MyClass
 
+// CHECK: define internal void @"\01-[MyClass method]"
 - (void)method
 {
-	@synchronized(self)
-	{
-	}
+  // CHECK: call void @objc_sync_enter
+  // CHECK: call void @objc_exception_try_enter
+  // CHECK: call i32 @_setjmp
+  @synchronized(self) {
+  }
 }
 
 @end
 
+// CHECK: define void @foo(
 void foo(id a) {
+  // CHECK: [[A:%.*]] = alloca i8*
+  // CHECK: [[SYNC:%.*]] = alloca i8*
+
+  // CHECK:      store i8* [[AVAL:%.*]], i8** [[A]]
+  // CHECK-NEXT: call void @objc_sync_enter(i8* [[AVAL]])
+  // CHECK-NEXT: store i8* [[AVAL]], i8** [[SYNC]]
+  // CHECK-NEXT: call void @objc_exception_try_enter
+  // CHECK:      call i32 @_setjmp
   @synchronized(a) {
+    // This is unreachable, but the optimizers can't know that.
+    // CHECK: call void asm sideeffect "", "=*m,=*m,=*m"(i8** [[A]], i8** [[SYNC]]
+    // CHECK: call void @objc_sync_exit
+    // CHECK: call i8* @objc_exception_extract
+    // CHECK: call void @objc_exception_throw
+    // CHECK: unreachable
+
+    // CHECK:      call void @objc_exception_try_exit
+    // CHECK:      [[T:%.*]] = load i8** [[SYNC]]
+    // CHECK-NEXT: call void @objc_sync_exit
+    // CHECK: ret void
     return;
   }
+
 }
 
+// CHECK: define i32 @f0(
 int f0(id a) {
+  // TODO: we can optimize the ret to a constant if we can figure out
+  // either that x isn't stored to within the synchronized block or
+  // that the synchronized block can't longjmp.
+
+  // CHECK: [[X:%.*]] = alloca i32
+  // CHECK: store i32 1, i32* [[X]]
   int x = 0;
   @synchronized((x++, a)) {    
   }
-  return x; // ret i32 1
+
+  // CHECK: [[T:%.*]] = load i32* [[X]]
+  // CHECK: ret i32 [[T]]
+  return x;
 }
 
+// CHECK: define void @f1(
 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.
+  // Check that the return doesn't go through the cleanup.
+  extern void opaque(void);
+  opaque();
+
+  // CHECK: call void @opaque()
+  // CHECK-NEXT: ret void
+
   @synchronized(({ return; }), a) {
     return;
   }
diff --git a/test/CodeGenObjC/unwind-fn.m b/test/CodeGenObjC/unwind-fn.m
index 0aa8cde..5bfc7dc 100644
--- a/test/CodeGenObjC/unwind-fn.m
+++ b/test/CodeGenObjC/unwind-fn.m
@@ -1,8 +1,8 @@
-// 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
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -emit-llvm -fexceptions -o - %s | FileCheck --check-prefix=DEFAULT_EH %s
+// RUN: %clang_cc1 -fsjlj-exceptions -fobjc-nonfragile-abi -fexceptions -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*)
+// SJLJ_EH: declare void @_Unwind_SjLj_Resume_or_Rethrow(i8*)
 
 void f1(), f2();
 void f0() {
diff --git a/test/CodeGenObjC/x86_64-struct-return-gc.m b/test/CodeGenObjC/x86_64-struct-return-gc.m
index c62a33f..8022d59 100644
--- a/test/CodeGenObjC/x86_64-struct-return-gc.m
+++ b/test/CodeGenObjC/x86_64-struct-return-gc.m
@@ -9,7 +9,7 @@
 void Coerce_test(void) {
   struct Coerce c;
   
-  // CHECK: call i64 @coerce_func
+  // CHECK: call i8* @coerce_func
   // CHECK: call i8* @objc_memmove_collectable(
   c = coerce_func();
 }
diff --git a/test/CodeGenObjCXX/copyable-property-object.mm b/test/CodeGenObjCXX/copyable-property-object.mm
new file mode 100644
index 0000000..8962c53
--- /dev/null
+++ b/test/CodeGenObjCXX/copyable-property-object.mm
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fobjc-gc -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+struct POD {
+  int array[3][4];
+  id objc_obj;
+};
+
+struct D  { 
+  POD pod_array[2][3];
+};
+
+@interface I
+{
+  D Property1;
+}
+@property D Property1;
+- (D) val;
+- (void) set : (D) d1;
+@end
+
+@implementation I
+@synthesize Property1;
+- (D) val { return Property1; }
+- (void) set : (D) d1 { Property1 = d1; }
+@end
+// CHECK: {{call.*@objc_memmove_collectable}}
+// CHECK: {{call.*@objc_memmove_collectable}}
+
diff --git a/test/CodeGenObjCXX/encode.mm b/test/CodeGenObjCXX/encode.mm
new file mode 100644
index 0000000..83fb31e
--- /dev/null
+++ b/test/CodeGenObjCXX/encode.mm
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// CHECK: v17@0:8{vector<float, float, float>=}16
+// CHECK: {vector<float, float, float>=}
+// CHECK: v24@0:816
+
+template <typename T1, typename T2, typename T3> struct vector {
+  vector();
+  vector(T1,T2,T3);
+};
+
+typedef vector< float, float, float > vector3f;
+
+@interface SceneNode
+{
+ vector3f position;
+}
+
+@property (assign, nonatomic) vector3f position;
+
+@end
+
+@interface MyOpenGLView
+{
+@public
+  vector3f position;
+}
+@property vector3f position;
+@end
+
+@implementation MyOpenGLView
+
+@synthesize position;
+
+-(void)awakeFromNib {
+ SceneNode *sn;
+ vector3f VF3(1.0, 1.0, 1.0);
+ [sn setPosition:VF3];
+}
+@end
+
+
+class Int3 { int x, y, z; };
+
+// Enforce @encoding for member pointers.
+@interface MemPtr {}
+- (void) foo: (int (Int3::*)) member;
+@end
+@implementation MemPtr
+- (void) foo: (int (Int3::*)) member {
+}
+@end
diff --git a/test/CodeGenObjCXX/exceptions.mm b/test/CodeGenObjCXX/exceptions.mm
new file mode 100644
index 0000000..00de88c
--- /dev/null
+++ b/test/CodeGenObjCXX/exceptions.mm
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-nonfragile-abi -fexceptions -o - %s | FileCheck %s
+
+@interface OCType @end
+void opaque();
+
+namespace test0 {
+
+  // CHECK: define void @_ZN5test03fooEv
+  void foo() {
+    try {
+      // CHECK: invoke void @_Z6opaquev
+      opaque();
+    } catch (OCType *T) {
+      // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} @__objc_personality_v0 {{.*}} @"OBJC_EHTYPE_$_OCType"
+    }
+  }
+}
diff --git a/test/CodeGenObjCXX/foreach-statement.mm b/test/CodeGenObjCXX/foreach-statement.mm
new file mode 100644
index 0000000..d0ad5b3
--- /dev/null
+++ b/test/CodeGenObjCXX/foreach-statement.mm
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// rdar: // 8027844
+
+// CHECK: call void @llvm.memset
+
+int main() {
+    id foo;
+    for (id a in foo) {
+    }
+}
diff --git a/test/CodeGenObjCXX/implicit-copy-assign-operator.mm b/test/CodeGenObjCXX/implicit-copy-assign-operator.mm
new file mode 100644
index 0000000..16ae147
--- /dev/null
+++ b/test/CodeGenObjCXX/implicit-copy-assign-operator.mm
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -fobjc-gc -emit-llvm -triple x86_64-apple-darwin10.0.0 -o - %s | FileCheck %s
+struct A { 
+  A &operator=(const A&);
+  A &operator=(A&);
+};
+
+struct B {
+  B &operator=(B&);
+};
+
+struct C {
+  virtual C& operator=(const C&);
+};
+
+struct POD {
+  id myobjc;
+  int array[3][4];
+};
+
+struct CopyByValue {
+  CopyByValue(const CopyByValue&);
+  CopyByValue &operator=(CopyByValue);
+};
+
+struct D : A, B, virtual C { 
+  int scalar;
+  int scalar_array[2][3];
+  B class_member;
+  C class_member_array[2][3];
+  POD pod_array[2][3];
+
+  union {
+    int x;
+    float f[3];
+  };
+
+  CopyByValue by_value;
+};
+
+void test_D(D d1, D d2) {
+  d1 = d2;
+}
+
+// CHECK: define linkonce_odr %struct.D* @_ZN1DaSERS_
+// CHECK: {{call.*_ZN1AaSERS_}}
+// CHECK: {{call.*_ZN1BaSERS_}}
+// CHECK: {{call.*_ZN1CaSERKS_}}
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 24}}
+// CHECK: {{call.*_ZN1BaSERS_}}
+// CHECK: br
+// CHECK: {{call.*_ZN1CaSERKS_}}
+// CHECK: {{call.*@objc_memmove_collectable}}
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 12}}
+// CHECK: call void @_ZN11CopyByValueC1ERKS_
+// CHECK: {{call.*_ZN11CopyByValueaSES_}}
+// CHECK: ret
+
diff --git a/test/CodeGenObjCXX/implicit-copy-constructor.mm b/test/CodeGenObjCXX/implicit-copy-constructor.mm
new file mode 100644
index 0000000..489fd97
--- /dev/null
+++ b/test/CodeGenObjCXX/implicit-copy-constructor.mm
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -fobjc-gc -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+struct A { 
+  A();
+  A(const A&);
+  A(A&);
+  ~A();
+};
+
+struct B {
+  B();
+  B(B&);
+};
+
+struct C {
+  C() {}
+  C(C& other, A a = A());
+  int i, j;
+};
+
+struct POD {
+  id myobjc;
+  int array[3][4];
+};
+
+struct D : A, B, virtual C { 
+  D();
+  int scalar;
+  int scalar_array[2][3];
+  B class_member;
+  C class_member_array[2][3];
+  POD pod_array[2][3];
+
+  union {
+    int x;
+    float f[3];
+  };
+};
+
+void f(D d) {
+  D d2(d);
+}
+
+// CHECK: define linkonce_odr void @_ZN1DC1ERS_
+// CHECK: call void @_ZN1AC1Ev
+// CHECK: call void @_ZN1CC2ERS_1A
+// CHECK: call void @_ZN1AD1Ev
+// CHECK: call void @_ZN1AC2ERS_
+// CHECK: call void @_ZN1BC2ERS_
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 24}}
+// CHECK: call void @_ZN1BC1ERS_
+// CHECK: br
+// CHECK: {{icmp ult.*, 2}}
+// CHECK: {{icmp ult.*, 3}}
+// CHECK: call void @_ZN1AC1Ev
+// CHECK: call void @_ZN1CC1ERS_1A
+// CHECK: call void @_ZN1AD1Ev
+// CHECK: {{call.*@objc_memmove_collectable}}
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 12}}
+// CHECK: ret void
+
+
+template<class T> struct X0 { void f0(T * ) { } };
+template <class > struct X1 { X1( X1& , int = 0 ) { } };
+struct X2 { X1<int> result; };
+void test_X2()
+{
+  typedef X2 impl;
+  typedef X0<impl> pimpl;
+  impl* i;
+  pimpl pdata;
+  pdata.f0( new impl(*i));
+}
diff --git a/test/CodeGenObjCXX/ivar-objects.mm b/test/CodeGenObjCXX/ivar-objects.mm
new file mode 100644
index 0000000..d0432ed
--- /dev/null
+++ b/test/CodeGenObjCXX/ivar-objects.mm
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// CHECK: -[A .cxx_construct]
+// CHECK: -[A .cxx_destruct]
+
+@interface NSObject 
+- alloc;
+- init;
+- (void) release;
+@end
+
+extern "C" int printf(const char *, ...);
+
+int count = 17;
+struct X {
+  X() : value(count++) { printf( "X::X()\n"); }
+  ~X() { printf( "X::~X()\n"); }
+  int value;
+};
+
+struct Y {
+  Y() : value(count++) { printf( "Y::Y()\n"); }
+  ~Y() { printf( "Y::~Y()\n"); }
+  int value;
+};
+
+@interface Super : NSObject {
+  Y yvar;
+  Y yvar1;
+  Y ya[3];
+}
+- (void)finalize;
+@end
+
+@interface A : Super {
+  X xvar;
+  X xvar1;
+  X xvar2;
+  X xa[2][2];
+}
+
+- (void)print;
+- (void)finalize;
+@end
+
+@implementation Super
+- (void)print {
+  printf( "yvar.value = %d\n", yvar.value);
+  printf( "yvar1.value = %d\n", yvar1.value);
+  printf( "ya[0..2] = %d %d %d\n", ya[0].value, ya[1].value, ya[2].value);
+}
+- (void)finalize {}
+@end
+
+@implementation A
+- (void)print {
+  printf( "xvar.value = %d\n", xvar.value);
+  printf( "xvar1.value = %d\n", xvar1.value);
+  printf( "xvar2.value = %d\n", xvar2.value);
+  printf( "xa[0..1][0..1] = %d %d %d %d\n",
+                   xa[0][0].value, xa[0][1].value, xa[1][0].value, xa[1][1].value);
+  [super print];
+}
+- (void)finalize { [super finalize]; }
+@end
+
+int main() {
+  A *a = [[A alloc] init];
+  [a print];
+  [a release];
+}
+
+// rdar: // 7468090
+class S {
+public:
+	S& operator = (const S&);
+};
+
+@interface I {
+  S position;
+}
+@property(assign, nonatomic) S position;
+@end
+
+@implementation I
+	@synthesize position;
+@end
diff --git a/test/CodeGenObjCXX/mangle-blocks.mm b/test/CodeGenObjCXX/mangle-blocks.mm
new file mode 100644
index 0000000..9f57557
--- /dev/null
+++ b/test/CodeGenObjCXX/mangle-blocks.mm
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -emit-llvm -fblocks -o - -triple x86_64-apple-darwin10 %s | FileCheck %s
+
+// CHECK: @_ZGVN3foo20__foo_block_invoke_05valueE = internal global i64 0
+
+int f();
+
+void foo() {
+  // CHECK: define internal i32 @__foo_block_invoke_0
+  // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVN3foo20__foo_block_invoke_05value
+  (void)^(int x) { 
+    static int value = f();
+    return x + value;
+  };
+}
+
+// CHECK: define internal i32 @__block_global_0
+int i = ^(int x) { return x;}(i);
+
+@interface A
+- (void)method;
+@end
+
+@implementation A
+- (void)method { 
+  // CHECK: define internal signext i8 @"__11-[A method]_block_invoke_0"
+  (void)^(int x) {
+    // CHECK: @"_ZN11-[A method]30__11-[A method]_block_invoke_04nameE"
+    static const char *name = "hello";
+    return name[x];
+  };
+}
+@end
+
+void foo(int) {
+  (void)^(int x) { 
+    static const char *name = "hello";
+    return name[x];
+  };
+}
+
+namespace N {
+  // CHECK: define internal signext i8 @__bar_block_invoke_0
+  void bar() {
+    (void)^(int x) { 
+      // CHECK: @_ZN1N3bar20__bar_block_invoke_04nameE
+      static const char *name = "hello";
+      return name[x];
+    };
+  }
+}
diff --git a/test/CodeGenObjCXX/method-local-extern-mangle.mm b/test/CodeGenObjCXX/method-local-extern-mangle.mm
new file mode 100644
index 0000000..794075d
--- /dev/null
+++ b/test/CodeGenObjCXX/method-local-extern-mangle.mm
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// CHECK: @gGlobals = external global
+
+@interface I
+- (int) Meth;
+@end
+
+@implementation I
+- (int) Meth {
+    extern int gGlobals;
+    return gGlobals;
+}
+@end
diff --git a/test/CodeGenObjCXX/property-derived-to-base-conv.mm b/test/CodeGenObjCXX/property-derived-to-base-conv.mm
new file mode 100644
index 0000000..ada1202
--- /dev/null
+++ b/test/CodeGenObjCXX/property-derived-to-base-conv.mm
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fobjc-gc -triple x86_64-apple-darwin10 -emit-llvm -o - %s
+// rdar: // 7501812
+
+struct A { int member; };
+struct B : A { };
+
+@interface BInt {
+@private
+  B *b;
+}
+- (B)value;
+- (void)setValue : (B) arg;
+@property B value;
+@end
+
+void g(BInt *bint) {
+  bint.value.member = 17;
+}
+
diff --git a/test/CodeGenObjCXX/property-objects.mm b/test/CodeGenObjCXX/property-objects.mm
new file mode 100644
index 0000000..662dacc
--- /dev/null
+++ b/test/CodeGenObjCXX/property-objects.mm
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fobjc-nonfragile-abi -emit-llvm -o - | FileCheck %s
+// CHECK-NOT: callq	_objc_msgSend_stret
+// CHECK: call void @_ZN1SC1ERKS_
+// CHECK: call %class.S* @_ZN1SaSERKS_
+// CHECK: call %class.S* @_ZN6CGRectaSERKS_
+
+class S {
+public:
+	S& operator = (const S&);
+	S (const S&);
+	S ();
+};
+
+struct CGRect {
+	CGRect & operator = (const CGRect &);
+};
+
+@interface I {
+  S position;
+  CGRect bounds;
+}
+@property(assign, nonatomic) S position;
+@property CGRect bounds;
+@property CGRect frame;
+- (void)setFrame:(CGRect)frameRect;
+- (CGRect)frame;
+- (void) initWithOwner;
+@end
+
+@implementation I
+@synthesize position;
+@synthesize bounds;
+@synthesize frame;
+- (void)setFrame:(CGRect)frameRect {}
+- (CGRect)frame {return bounds;}
+
+- (void)initWithOwner {
+  I* _labelLayer;
+  CGRect labelLayerFrame = self.bounds;
+  labelLayerFrame = self.bounds;
+  _labelLayer.frame = labelLayerFrame;
+}
+@end
+
+int main() {
+  I *i;
+  S s1;
+  i.position = s1;
+  return 0;
+}
+
diff --git a/test/CodeGenObjCXX/references.mm b/test/CodeGenObjCXX/references.mm
new file mode 100644
index 0000000..8875fd6
--- /dev/null
+++ b/test/CodeGenObjCXX/references.mm
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct A { ~A(); };
+
+@interface B {
+  A a;
+}
+
+- (const A&)getA;
+@end
+
+@implementation B 
+
+- (const A&)getA {
+  return a;
+}
+
+@end
+
+// CHECK: define void @_Z1fP1B
+// CHECK: objc_msgSend to
+// CHECK-NOT: call void @_ZN1AD1Ev
+// CHECK: ret void
+void f(B* b) {
+  (void)[b getA];
+}
+
+// PR7741
+@protocol P1 @end
+@protocol P2 @end
+@protocol P3 @end
+@interface foo<P1> {} @end
+@interface bar : foo <P1, P2> {} @end
+typedef bar baz;
+void f5(foo&);
+void f5b(foo<P1>&);
+void f5c(foo<P2>&);
+void f5d(foo<P3>&);
+void f6(baz* x) { 
+  f5(*x); 
+  f5b(*x); 
+  f5c(*x); 
+  f5d(*x);
+  (void)((foo&)*x);  
+}
diff --git a/test/CodeGenObjCXX/rtti.mm b/test/CodeGenObjCXX/rtti.mm
new file mode 100644
index 0000000..27d24cb
--- /dev/null
+++ b/test/CodeGenObjCXX/rtti.mm
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// PR7864.  This all follows GCC's lead.
+
+namespace std { class type_info; }
+
+// CHECK: @_ZTI1A = weak_odr constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS1A
+@interface A
+@end
+
+// CHECK: @_ZTI1B = weak_odr constant {{.*}}@_ZTVN10__cxxabiv120__si_class_type_infoE{{.*}}@_ZTS1B{{.*}}@_ZTI1A
+@interface B : A
+@end
+
+// CHECK: @_ZTIP1B = weak_odr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP1B{{.*}}), i32 0, {{.*}}@_ZTI1B
+// CHECK: @_ZTI11objc_object = weak_odr constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS11objc_object
+// CHECK: @_ZTIP11objc_object = weak_odr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP11objc_object{{.*}}@_ZTI11objc_object
+// CHECK: @_ZTI10objc_class = weak_odr constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS10objc_class
+// CHECK: @_ZTIP10objc_class = weak_odr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP10objc_class{{.*}}@_ZTI10objc_class
+
+@protocol P;
+
+int main() {
+  // CHECK: store {{.*}} @_ZTIP1B
+  // CHECK: store {{.*}} @_ZTI1B
+  const std::type_info &t1 = typeid(B*);
+  const std::type_info &t2 = typeid(B);
+
+  // CHECK: store {{.*}} @_ZTIP11objc_object
+  // CHECK: store {{.*}} @_ZTI11objc_object
+  id i = 0;
+  const std::type_info &t3 = typeid(i);
+  const std::type_info &t4 = typeid(*i);
+
+  // CHECK: store {{.*}} @_ZTIP10objc_class
+  // CHECK: store {{.*}} @_ZTI10objc_class
+  Class c = 0;
+  const std::type_info &t5 = typeid(c);
+  const std::type_info &t6 = typeid(*c);
+
+  // CHECK: store {{.*}} @_ZTIP11objc_object
+  // CHECK: store {{.*}} @_ZTI11objc_object
+  id<P> i2 = 0;
+  const std::type_info &t7 = typeid(i2);
+  const std::type_info &t8 = typeid(*i2);
+
+  // CHECK: store {{.*}} @_ZTIP10objc_class
+  // CHECK: store {{.*}} @_ZTI10objc_class
+  Class<P> c2 = 0;
+  const std::type_info &t9 = typeid(c2);
+  const std::type_info &t10 = typeid(*c2);
+}
diff --git a/test/CodeGenObjCXX/selector-expr-lvalue.mm b/test/CodeGenObjCXX/selector-expr-lvalue.mm
new file mode 100644
index 0000000..0305451
--- /dev/null
+++ b/test/CodeGenObjCXX/selector-expr-lvalue.mm
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -emit-llvm -o - %s 
+// PR7390
+
+@interface NSObject {}
+- (void)respondsToSelector:(const SEL&)s : (SEL*)s1;
+- (void) setPriority:(int)p;
+- (void)Meth;
+@end
+
+@implementation  NSObject
+- (void)Meth {
+    [self respondsToSelector:@selector(setPriority:) : &@selector(setPriority:)];
+}
+- (void) setPriority:(int)p{}
+- (void)respondsToSelector:(const SEL&)s : (SEL*)s1 {}
+@end
diff --git a/test/Coverage/ast-printing.cpp b/test/Coverage/ast-printing.cpp
index 1a75fb4..0de5642 100644
--- a/test/Coverage/ast-printing.cpp
+++ b/test/Coverage/ast-printing.cpp
@@ -1,7 +1,7 @@
 // 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 -ast-print-xml -o %t %s
 // RUN: %clang_cc1 -print-decl-contexts %s
 // RUN: %clang_cc1 -fdump-record-layouts %s
 
diff --git a/test/Coverage/parse-callbacks.c b/test/Coverage/parse-callbacks.c
deleted file mode 100644
index 02f3a83..0000000
--- a/test/Coverage/parse-callbacks.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// 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
deleted file mode 100644
index f023d3d..0000000
--- a/test/Coverage/parse-callbacks.m
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: %clang_cc1 -parse-noop %s
-// RUN: %clang_cc1 -parse-print-callbacks %s
-
-#include "objc-language-features.inc"
diff --git a/test/Driver/Wp-args.c b/test/Driver/Wp-args.c
new file mode 100644
index 0000000..e072263
--- /dev/null
+++ b/test/Driver/Wp-args.c
@@ -0,0 +1,13 @@
+// Check that we extract -MD from '-Wp,-MD,FOO', which is used by a number of
+// major projects (e.g., FireFox and the Linux Kernel).
+
+// RUN: %clang --ccc-host-triple i386-pc-linux-gnu -### \
+// RUN:   -Wp,-MD,FOO.d -fsyntax-only %s 2> %t
+// RUN: FileCheck < %t %s
+//
+// CHECK: "-cc1"
+// CHECK-NOT: -MD
+// CHECK: "-dependency-file" "FOO.d"
+// CHECK: "-MT"
+//
+// PR4062
diff --git a/test/Driver/Xlinker-args.c b/test/Driver/Xlinker-args.c
new file mode 100644
index 0000000..b009bff
--- /dev/null
+++ b/test/Driver/Xlinker-args.c
@@ -0,0 +1,9 @@
+// Check that we extract --no-demangle from '-Xlinker' and '-Wl,', since that
+// was a collect2 argument.
+
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### \
+// RUN:   -Xlinker one -Xlinker --no-demangle \
+// RUN:   -Wl,two,--no-demangle,three -Xlinker four %s 2> %t
+// RUN: FileCheck < %t %s
+//
+// CHECK: "one" "two" "three" "four"
diff --git a/test/Driver/arch.c b/test/Driver/arch.c
new file mode 100644
index 0000000..69693ee
--- /dev/null
+++ b/test/Driver/arch.c
@@ -0,0 +1,3 @@
+// RUN: %clang -ccc-host-triple armv7a-unknown-linux-gnueabi -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: target triple = "armv7-unknown-linux-gnueabi"
diff --git a/test/Driver/at_file.c b/test/Driver/at_file.c
new file mode 100644
index 0000000..4ad2a5f
--- /dev/null
+++ b/test/Driver/at_file.c
@@ -0,0 +1,30 @@
+// RUN: %clang -E %s @%s.args -o %t.log
+// RUN: FileCheck --input-file=%t.log %s
+
+// CHECK: bar1
+// CHECK-NEXT: bar2 zed2
+// CHECK-NEXT: bar3 zed3
+// CHECK-NEXT: bar4 zed4
+// CHECK-NEXT: bar5 zed5
+// CHECK-NEXT: 'bar6 zed6'
+// CHECK-NEXT: "bar7 zed7"
+// CHECK-NEXT: foo8bar8zed8
+// CHECK-NEXT: foo9'bar9'zed9
+// CHECK-NEXT: foo10"bar10"zed10
+// CHECK: bar
+// CHECK: zed12
+
+foo1
+foo2
+foo3
+foo4
+foo5
+foo6
+foo7
+foo8
+foo9
+foo10
+#ifdef foo11
+bar
+#endif
+foo12
diff --git a/test/Driver/at_file.c.args b/test/Driver/at_file.c.args
new file mode 100644
index 0000000..9a2b4ee
--- /dev/null
+++ b/test/Driver/at_file.c.args
@@ -0,0 +1,11 @@
+-Dfoo1=bar1 -Dfoo2="bar2 zed2"
+-Dfoo3='bar3 zed3'
+"-Dfoo4=bar4 zed4"
+'-Dfoo5=bar5 zed5'
+-Dfoo6="'bar6 zed6'"
+-Dfoo7='"bar7 zed7"'
+-Dfoo8=foo8"bar8"zed8
+-Dfoo9=foo9\'bar9\'zed9
+-Dfoo10=foo10\"bar10\"zed10
+-D foo11
+-Dfoo12=zed12\
diff --git a/test/Driver/bindings.c b/test/Driver/bindings.c
index 2271ab5..b825420 100644
--- a/test/Driver/bindings.c
+++ b/test/Driver/bindings.c
@@ -15,12 +15,6 @@
 // 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
 
@@ -48,7 +42,7 @@
 // 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: %clang -ccc-host-triple i386-apple-darwin9 -no-integrated-as -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/clang_f_opts.c b/test/Driver/clang_f_opts.c
index f1d6759..50bce3b 100644
--- a/test/Driver/clang_f_opts.c
+++ b/test/Driver/clang_f_opts.c
@@ -1,10 +1,12 @@
-// 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 -### -S -fasm -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 -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-asm -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: -fgnu-keywords
 // CHECK-OPTIONS1: -fblocks
 // CHECK-OPTIONS1: -fpascal-strings
 
+// CHECK_OPTIONS2: -fno-gnu-keywords
 // CHECK-OPTIONS2: -fmath-errno
 // CHECK-OPTIONS2: -fno-builtin
 // CHECK-OPTIONS2: -fshort-wchar
diff --git a/test/Driver/cxx-pth.cpp b/test/Driver/cxx-pth.cpp
deleted file mode 100644
index e349691..0000000
--- a/test/Driver/cxx-pth.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-// 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
index 6410df0..7d4cdbf 100644
--- a/test/Driver/darwin-as.c
+++ b/test/Driver/darwin-as.c
@@ -1,10 +1,16 @@
 // 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"
 
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -### \
+// RUN:   -arch armv6 -x assembler -c %s 2>%t
+// RUN: FileCheck -check-prefix=ARMV6 --input-file %t %s
+//
+// CHECK-ARMV6: as{{(.exe)?}}" "-arch" "armv6" "-o"
+
diff --git a/test/Driver/darwin-cc.c b/test/Driver/darwin-cc.c
index 7a3a378..b068bb4 100644
--- a/test/Driver/darwin-cc.c
+++ b/test/Driver/darwin-cc.c
@@ -1,5 +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
+// RUN: grep ' ".*cc1" "-E" "-nostdinc" "-v" "-I" "ARG0" "-FARG1" "-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" "-m32" "-mkernel" "-mtune=core2" "-mmacosx-version-min=10.6.0" "-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" "-m32" "-mkernel" "-mtune=core2" "-mmacosx-version-min=10.6.0" "-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
index 7ce6137..3394e4e 100644
--- a/test/Driver/darwin-debug-flags.c
+++ b/test/Driver/darwin-debug-flags.c
@@ -2,10 +2,8 @@
 // <rdar://problem/7256886>
 
 // CHECK: !1 = metadata !{
-// CHECK: -cc1
-// CHECK: -triple i386-apple-darwin9
-// CHECK: -g
-// CHECK: -Os
+// CHECK: -g -Os
+// CHECK: -mmacosx-version-min=10.5.0
 // CHECK: [ DW_TAG_compile_unit ]
 
 int x;
diff --git a/test/Driver/darwin-dsymutil.c b/test/Driver/darwin-dsymutil.c
new file mode 100644
index 0000000..f1ffcdc
--- /dev/null
+++ b/test/Driver/darwin-dsymutil.c
@@ -0,0 +1,38 @@
+// Check that we run dsymutil properly with multiple -arch options.
+//
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -ccc-print-phases \
+// RUN:   -arch i386 -arch x86_64 %s -g 2> %t
+// RUN: FileCheck -check-prefix=CHECK-MULTIARCH-ACTIONS < %t %s
+//
+// CHECK-MULTIARCH-ACTIONS: 0: input, "{{.*}}darwin-dsymutil.c", c
+// CHECK-MULTIARCH-ACTIONS: 1: preprocessor, {0}, cpp-output
+// CHECK-MULTIARCH-ACTIONS: 2: compiler, {1}, assembler
+// CHECK-MULTIARCH-ACTIONS: 3: assembler, {2}, object
+// CHECK-MULTIARCH-ACTIONS: 4: linker, {3}, image
+// CHECK-MULTIARCH-ACTIONS: 5: bind-arch, "i386", {4}, image
+// CHECK-MULTIARCH-ACTIONS: 6: bind-arch, "x86_64", {4}, image
+// CHECK-MULTIARCH-ACTIONS: 7: lipo, {5, 6}, image
+// CHECK-MULTIARCH-ACTIONS: 8: dsymutil, {7}, dSYM
+//
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -ccc-print-bindings \
+// RUN:   -arch i386 -arch x86_64 %s -g 2> %t
+// RUN: FileCheck -check-prefix=CHECK-MULTIARCH-BINDINGS < %t %s
+//
+// CHECK-MULTIARCH-BINDINGS: "x86_64-apple-darwin10" - "darwin::Lipo", inputs: [{{.*}}, {{.*}}], output: "a.out"
+// CHECK-MULTIARCH-BINDINGS: # "x86_64-apple-darwin10" - "darwin::Dsymutil", inputs: ["a.out"], output: "a.out.dSYM"
+
+// Check output name derivation.
+//
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -ccc-print-bindings \
+// RUN:   -o foo %s -g 2> %t
+// RUN: FileCheck -check-prefix=CHECK-OUTPUT-NAME < %t %s
+//
+// CHECK-OUTPUT-NAME: "x86_64-apple-darwin10" - "darwin::Link", inputs: [{{.*}}], output: "foo"
+// CHECK-OUTPUT-NAME: "x86_64-apple-darwin10" - "darwin::Dsymutil", inputs: ["foo"], output: "foo.dSYM"
+
+// Check that we only use dsymutil when needed.
+//
+// RUN: touch %t.o
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -ccc-print-bindings \
+// RUN:   -o foo %t.o -g 2> %t
+// RUN: grep "Dsymutil" %t | count 0
diff --git a/test/Driver/darwin-iphone-defaults.m b/test/Driver/darwin-iphone-defaults.m
index 97ac4a4..62a9403 100644
--- a/test/Driver/darwin-iphone-defaults.m
+++ b/test/Driver/darwin-iphone-defaults.m
@@ -1,4 +1,4 @@
-// RUN: %clang -ccc-host-triple i386-apple-darwin9 -arch armv7 -flto -S -o - %s | FileCheck %s
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -miphoneos-version-min=3.0 -arch armv7 -flto -S -o - %s | FileCheck %s
 
 // CHECK: @f0
 // CHECK-NOT: ssp
diff --git a/test/Driver/darwin-ld.c b/test/Driver/darwin-ld.c
index 76ddaa8..074957d 100644
--- a/test/Driver/darwin-ld.c
+++ b/test/Driver/darwin-ld.c
@@ -3,20 +3,6 @@
 // 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
@@ -33,11 +19,7 @@
 // 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
+// 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" "-LARG2" "-lgomp".* "-filelist" "FOO" "-lFOO" "-lgcov" "-allow_stack_execute" "-T" "ARG4" "-FARG1"' %t.log
 
 // Check linker changes that came with new linkedit format.
 // RUN: touch %t.o
@@ -74,3 +56,38 @@
 // LINK_IPHONE_3_1: ld"
 // LINK_IPHONE_3_1-NOT: -lbundle1.o
 // LINK_IPHONE_3_1: -lSystem
+
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -fpie %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_EXPLICIT_PIE %s < %t.log
+//
+// LINK_EXPLICIT_PIE: ld"
+// LINK_EXPLICIT_PIE: "-pie"
+
+// RUN: %clang -ccc-host-triple i386-apple-darwin9 -### -fno-pie %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_EXPLICIT_NO_PIE %s < %t.log
+//
+// LINK_EXPLICIT_NO_PIE: ld"
+// LINK_EXPLICIT_NO_PIE: "-no_pie"
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -### %t.o \
+// RUN:   -mlinker-version=100 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_NEWER_DEMANGLE %s < %t.log
+//
+// LINK_NEWER_DEMANGLE: ld"
+// LINK_NEWER_DEMANGLE: "-demangle"
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -### %t.o \
+// RUN:   -mlinker-version=100 -Wl,--no-demangle 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_NEWER_NODEMANGLE %s < %t.log
+//
+// LINK_NEWER_NODEMANGLE: ld"
+// LINK_NEWER_NODEMANGLE-NOT: "-demangle"
+// LINK_NEWER_NODEMANGLE: "-lSystem"
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -### %t.o \
+// RUN:   -mlinker-version=95 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_OLDER_NODEMANGLE %s < %t.log
+//
+// LINK_OLDER_NODEMANGLE: ld"
+// LINK_OLDER_NODEMANGLE-NOT: "-demangle"
+// LINK_OLDER_NODEMANGLE: "-lSystem"
diff --git a/test/Driver/darwin-objc-options.m b/test/Driver/darwin-objc-options.m
new file mode 100644
index 0000000..bc0b12c
--- /dev/null
+++ b/test/Driver/darwin-objc-options.m
@@ -0,0 +1,19 @@
+// Check miscellaneous Objective-C options.
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -S -### %s \
+// RUN:   -arch x86_64 -fobjc-abi-version=1 2> %t
+// RUN: FileCheck --check-prefix CHECK-X86_64_ABI1 < %t %s
+
+// CHECK-CHECK-X86_64_ABI1: "-cc1"
+// CHECK-CHECK-X86_64_ABI1-NOT: -fobjc-nonfragile-abi
+// CHECK-CHECK-X86_64_ABI1-NOT: -fobjc-dispatch-method
+// CHECK-CHECK-X86_64_ABI1: darwin-objc-options
+
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -S -### %s \
+// RUN:   -arch i386 -fobjc-abi-version=2 2> %t
+// RUN: FileCheck --check-prefix CHECK-I386_ABI2 < %t %s
+
+// CHECK-CHECK-I386_ABI2: "-cc1"
+// CHECK-CHECK-I386_ABI2: -fobjc-nonfragile-abi
+// CHECK-CHECK-I386_ABI2-NOT: -fobjc-dispatch-method
+// CHECK-CHECK-I386_ABI2: darwin-objc-options
diff --git a/test/Driver/darwin-xarch.c b/test/Driver/darwin-xarch.c
new file mode 100644
index 0000000..cd7fa84
--- /dev/null
+++ b/test/Driver/darwin-xarch.c
@@ -0,0 +1,8 @@
+// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -### \
+// RUN:   -arch i386 -Xarch_i386 -mmacosx-version-min=10.4 \
+// RUN:   -arch x86_64 -Xarch_x86_64 -mmacosx-version-min=10.5 \
+// RUN:   -c %s 2> %t
+// RUN: FileCheck < %t %s
+//
+// CHECK: clang{{.*}}" "-cc1" "-triple" "i386-apple-darwin8.0.0" 
+// CHECK: clang{{.*}}" "-cc1" "-triple" "x86_64-apple-darwin9.0.0" 
diff --git a/test/Driver/freebsd.c b/test/Driver/freebsd.c
index 3deee46..e8bc223 100644
--- a/test/Driver/freebsd.c
+++ b/test/Driver/freebsd.c
@@ -1,7 +1,21 @@
-// 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
+// RUN: %clang -ccc-clang-archs "" -ccc-host-triple powerpc64-pc-freebsd8 %s -### 2> %t
+// RUN: FileCheck --check-prefix=CHECK-PPC < %t %s
+//
+// CHECK-PPC: clang{{.*}}" "-cc1" "-triple" "powerpc64-pc-freebsd8"
+// CHECK-PPC: as{{.*}}" "-o" "{{.*}}.o" "{{.*}}.s
+// CHECK-PPC: 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"
 
-// 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"
+
+// Check that -m32 properly adjusts the toolchain flags.
+//
+// RUN: %clang -ccc-host-triple x86_64-pc-freebsd8 -m32 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-LIB32 < %t %s
+//
+// CHECK-LIB32: clang{{.*}}" "-cc1" "-triple" "i386-pc-freebsd8"
+// CHECK-LIB32: as{{.*}}" "--32"
+// CHECK-LIB32: ld{{.*}}" {{.*}} "-m" "elf_i386_fbsd"
+//
+// RUN: %clang -ccc-host-triple x86_64-pc-freebsd8 -m32 -print-search-dirs %s > %t
+// RUN: FileCheck --check-prefix=CHECK-LIB32PATHS < %t %s
+//
+// CHECK-LIB32PATHS: libraries: ={{.*}}:/usr/lib32
diff --git a/test/Driver/gcc_forward.c b/test/Driver/gcc_forward.c
new file mode 100644
index 0000000..c584a4e
--- /dev/null
+++ b/test/Driver/gcc_forward.c
@@ -0,0 +1,13 @@
+// Check that we don't try to forward -Xclang or -mlinker-version to GCC.
+//
+// RUN: %clang -ccc-host-triple powerpc-unknown-unknown \
+// RUN:   -ccc-clang-archs i386 -c %s \
+// RUN:   -Xclang foo-bar \
+// RUN:   -mlinker-version=10 -### 2> %t
+// RUN: FileCheck < %t %s
+//
+// CHECK: gcc{{.*}}"
+// CHECK-NOT: "-mlinker-version=10"
+// CHECK-NOT: "-Xclang"
+// CHECK-NOT: "foo-bar"
+// CHECK: gcc_forward
diff --git a/test/Driver/lto.c b/test/Driver/lto.c
index 4543ffc..22b4788 100644
--- a/test/Driver/lto.c
+++ b/test/Driver/lto.c
@@ -1,15 +1,14 @@
-// -emit-llvm, -flto, and -O4 all cause a switch to llvm-bc object
-// files.
+// -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: grep '2: compiler, {1}, lto-bc' %t.log
 // RUN: %clang -ccc-print-phases -c %s -O4 2> %t.log
-// RUN: grep '2: compiler, {1}, llvm-bc' %t.log
+// RUN: grep '2: compiler, {1}, lto-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 '2: compiler, {1}, lto-bc' %t.log
 // RUN: grep '3: linker, {2}, image' %t.log
 
 // llvm-bc and llvm-ll outputs need to match regular suffixes
diff --git a/test/Driver/option-aliases.c b/test/Driver/option-aliases.c
new file mode 100644
index 0000000..38bf4b1
--- /dev/null
+++ b/test/Driver/option-aliases.c
@@ -0,0 +1,11 @@
+// RUN: %clang -ccc-print-options \
+// RUN:  --save-temps --undefine-macro=FOO --undefine-macro FOO \
+// RUN: --param=FOO --output=FOO 2> %t
+// RUN: FileCheck --check-prefix=CHECK-OPTIONS < %t %s
+
+// CHECK-OPTIONS: Option 0 - Name: "-ccc-print-options", Values: {}
+// CHECK-OPTIONS: Option 1 - Name: "-save-temps", Values: {}
+// CHECK-OPTIONS: Option 2 - Name: "-U", Values: {"FOO"}
+// CHECK-OPTIONS: Option 3 - Name: "-U", Values: {"FOO"}
+// CHECK-OPTIONS: Option 4 - Name: "--param", Values: {"FOO"}
+// CHECK-OPTIONS: Option 5 - Name: "-o", Values: {"FOO"}
diff --git a/test/Driver/rewrite-objc.m b/test/Driver/rewrite-objc.m
index 38993fc..ac77d79 100644
--- a/test/Driver/rewrite-objc.m
+++ b/test/Driver/rewrite-objc.m
@@ -1,6 +1,10 @@
 // RUN: %clang -ccc-host-triple unknown -rewrite-objc %s -o - -### 2>&1 | \
 // RUN:   FileCheck -check-prefix=TEST0 %s
-// TEST0: clang{{.*}}" "-rewrite-objc"
+// TEST0: clang{{.*}}" "-cc1"
+// TEST0: "-rewrite-objc"
+// FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency instead.
+// TEST0: "-fmessage-length" "0" "-fdiagnostics-show-option"
+// TEST0: rewrite-objc.m"
 
 // RUN: not %clang -ccc-no-clang -ccc-host-triple unknown -rewrite-objc %s -o - -### 2>&1 | \
 // RUN:   FileCheck -check-prefix=TEST1 %s
diff --git a/test/FixIt/fixit.c b/test/FixIt/fixit.c
index b799fa3..890fb10 100644
--- a/test/FixIt/fixit.c
+++ b/test/FixIt/fixit.c
@@ -38,3 +38,6 @@
   int x = y ? 1 4+foobar;
   return x;
 }
+
+// CHECK: typedef int int_t;
+typedef typedef int int_t;
diff --git a/test/FixIt/no-typo.c b/test/FixIt/no-typo.c
new file mode 100644
index 0000000..05947e8
--- /dev/null
+++ b/test/FixIt/no-typo.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -fno-spell-checking -verify %s
+typedef struct {
+  float x, y;
+} Point;
+
+point p1; // expected-error{{unknown type name 'point'}}
diff --git a/test/FixIt/typo.cpp b/test/FixIt/typo.cpp
index 5b9e68b..077aa9c 100644
--- a/test/FixIt/typo.cpp
+++ b/test/FixIt/typo.cpp
@@ -12,7 +12,8 @@
   typedef basic_string<char> string; // expected-note 2{{'string' declared here}}
 }
 
-namespace otherstd { // expected-note 2{{'otherstd' declared here}}
+namespace otherstd { // expected-note 2{{'otherstd' declared here}} \
+                     // expected-note{{namespace 'otherstd' defined here}}
   using namespace std;
 }
 
@@ -29,6 +30,13 @@
   return radious * pi; // expected-error{{did you mean 'radius'?}}
 }
 
+using namespace othestd; // expected-error{{no namespace named 'othestd'; did you mean 'otherstd'?}}
+namespace blargh = otherstd; // expected-note 3{{namespace 'blargh' defined here}}
+using namespace ::blarg; // expected-error{{no namespace named 'blarg' in the global namespace; did you mean 'blargh'?}}
+
+namespace wibble = blarg; // expected-error{{no namespace named 'blarg'; did you mean 'blargh'?}}
+namespace wobble = ::blarg; // expected-error{{no namespace named 'blarg' in the global namespace; did you mean 'blargh'?}}
+
 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'?}}
diff --git a/test/FixIt/typo.m b/test/FixIt/typo.m
index f161bb8..6853ab6 100644
--- a/test/FixIt/typo.m
+++ b/test/FixIt/typo.m
@@ -1,17 +1,18 @@
-// 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: *
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -DNON_FIXITS -verify %s
+// RUN: %clang -E -P %s -o %t
+// RUN: %clang_cc1 -x objective-c -fsyntax-only -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fixit %t  || true
+// RUN: %clang_cc1 -x objective-c -fsyntax-only -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -pedantic -Werror %t
 
 @interface NSString // expected-note{{'NSString' declared here}}
 + (int)method:(int)x;
 @end
 
+#ifdef NON_FIXITS
 void test() {
   // FIXME: not providing fix-its
   NSstring *str = @"A string"; // expected-error{{use of undeclared identifier 'NSstring'; did you mean 'NSString'?}}
 }
+#endif
 
 @protocol P1
 @optional
@@ -23,7 +24,8 @@
   int his_ivar; // expected-note 2{{'his_ivar' declared here}}
   float wibble;
 }
-
+- (void)methodA;
++ (void)methodA;
 @property int his_prop; // expected-note{{'his_prop' declared here}}
 @end
 
@@ -39,6 +41,8 @@
 
 @implementation A
 @synthesize his_prop = his_ivar;
+- (void)methodA { }
++ (void)methodA { }
 @end
 
 @implementation B
@@ -80,18 +84,23 @@
   a->vale = 17; // expected-error{{'Collide' does not have a member named 'vale'; did you mean 'value'?}}
 }
 
+#ifdef NON_FIXITS
 @interface Derived : Collid // expected-error{{cannot find interface declaration for 'Collid', superclass of 'Derived'; did you mean 'Collide'?}}
 @end
+#endif
 
+#ifdef NON_FIXITS
 @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
+#endif
 
 @interface Super
-- (int)method;
+- (int)method; // expected-note{{using}}
+- (int)method2;
 @end
 
 @interface Sub : Super
@@ -105,6 +114,18 @@
   
 @end
 
+double *isupper(int);
+
+@interface Sub2 : Super
+- (int)method2;
+@end
+
+@implementation Sub2
+- (int)method2 {
+  return [supper method2]; // expected-error{{unknown receiver 'supper'; did you mean 'super'?}}
+}
+@end
+
 @interface Ivar
 @end
 
@@ -112,29 +133,24 @@
 @property (retain) id ivar;
 @end
 
+#ifdef NON_FIXITS
 @interface User <Proto>
-- (void)method;
+- (void)method; // expected-note{{also found}}
 @end
 
 @implementation User
 @synthesize ivar;
 
 - (void)method {
-    [ivar method]; // Test that we don't correct 'ivar' to 'Ivar'
+  // Test that we don't correct 'ivar' to 'Ivar'  e
+  [ivar method]; // expected-warning{{multiple methods named 'method' found}}
 }
 @end
+#endif
 
-@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'
+void f(A *a) {
+  f(a) // expected-error{{expected ';' after expression}}
+  [a methodA] // expected-error{{expected ';' after expression}}
+  [A methodA] // expected-error{{expected ';' after expression}}
 }
-@end
+
diff --git a/test/Frontend/Inputs/lit.local.cfg b/test/Frontend/Inputs/lit.local.cfg
new file mode 100644
index 0000000..e6f55ee
--- /dev/null
+++ b/test/Frontend/Inputs/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = []
diff --git a/test/Frontend/Inputs/test.h b/test/Frontend/Inputs/test.h
new file mode 100644
index 0000000..98cc459
--- /dev/null
+++ b/test/Frontend/Inputs/test.h
@@ -0,0 +1 @@
+#include "test2.h"
diff --git a/test/Frontend/Inputs/test2.h b/test/Frontend/Inputs/test2.h
new file mode 100644
index 0000000..6d1a0d4
--- /dev/null
+++ b/test/Frontend/Inputs/test2.h
@@ -0,0 +1 @@
+int x;
diff --git a/test/Frontend/Inputs/test3.h b/test/Frontend/Inputs/test3.h
new file mode 100644
index 0000000..92ff4b8
--- /dev/null
+++ b/test/Frontend/Inputs/test3.h
@@ -0,0 +1 @@
+int y;
diff --git a/test/Frontend/darwin-version.c b/test/Frontend/darwin-version.c
index 1c866ee..151d3a9 100644
--- a/test/Frontend/darwin-version.c
+++ b/test/Frontend/darwin-version.c
@@ -1,4 +1,7 @@
 // RUN: %clang -ccc-host-triple armv6-apple-darwin9 -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 '1050' | count 1
+// RUN: %clang -ccc-host-triple armv6-apple-darwin9 -miphoneos-version-min=3.0 -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
diff --git a/test/Frontend/ir-support-codegen.ll b/test/Frontend/ir-support-codegen.ll
new file mode 100644
index 0000000..046b3af
--- /dev/null
+++ b/test/Frontend/ir-support-codegen.ll
@@ -0,0 +1,8 @@
+; RUN: %clang_cc1 -S -o - %s | FileCheck %s
+
+target triple = "x86_64-apple-darwin10"
+
+; CHECK: .globl _f0
+define i32 @f0() nounwind ssp {
+       ret i32 0
+}
diff --git a/test/Frontend/ir-support-errors.ll b/test/Frontend/ir-support-errors.ll
new file mode 100644
index 0000000..98227d4
--- /dev/null
+++ b/test/Frontend/ir-support-errors.ll
@@ -0,0 +1,8 @@
+; RUN: %clang_cc1 -S -o - %s 2>&1 | FileCheck %s
+
+target triple = "x86_64-apple-darwin10"
+
+define i32 @f0() nounwind ssp {
+; CHECK: {{.*}}ir-support-errors.ll:7:16: error: expected value token
+       ret i32 x
+}
diff --git a/test/Frontend/lit.local.cfg b/test/Frontend/lit.local.cfg
new file mode 100644
index 0000000..4c13598
--- /dev/null
+++ b/test/Frontend/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.c', '.cpp', '.m', '.mm', '.ll', '.bc']
diff --git a/test/Frontend/preprocessed-output-macro-first-token.c b/test/Frontend/preprocessed-output-macro-first-token.c
new file mode 100644
index 0000000..06b78c2
--- /dev/null
+++ b/test/Frontend/preprocessed-output-macro-first-token.c
@@ -0,0 +1,5 @@
+// This is the first thing other than comments and preprocessor stuff in the
+// file.
+//
+// RUN: %clang_cc1 -fms-extensions -E %s
+#pragma comment(lib, "somelib")
diff --git a/test/Frontend/print-header-includes.c b/test/Frontend/print-header-includes.c
new file mode 100644
index 0000000..7773d20
--- /dev/null
+++ b/test/Frontend/print-header-includes.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -include Inputs/test3.h -E -H -o %t.out %s 2> %t.err
+// RUN: FileCheck < %t.err %s
+
+// CHECK-NOT: test3.h
+// CHECK: . {{.*test.h}}
+// CHECK: .. {{.*test2.h}}
+
+#include "Inputs/test.h"
diff --git a/test/Frontend/unknown-pragmas.c b/test/Frontend/unknown-pragmas.c
new file mode 100644
index 0000000..53a5a45
--- /dev/null
+++ b/test/Frontend/unknown-pragmas.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -Eonly -Wall -verify %s
+// RUN: %clang_cc1 -E -dM -Wall -verify %s
+
+#pragma adgohweopihweotnwet
diff --git a/test/Headers/int64-type.c b/test/Headers/int64-type.c
new file mode 100644
index 0000000..16b42d2
--- /dev/null
+++ b/test/Headers/int64-type.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -verify %s -ffreestanding
+
+#include <stdint.h>
+typedef unsigned long long uint64_t;
diff --git a/test/Headers/x86-intrinsics-headers.c b/test/Headers/x86-intrinsics-headers.c
index 24c2d92..ba833ec 100644
--- a/test/Headers/x86-intrinsics-headers.c
+++ b/test/Headers/x86-intrinsics-headers.c
@@ -1,32 +1,19 @@
 // RUN: %clang -fsyntax-only %s
 // RUN: %clang -fsyntax-only -fno-lax-vector-conversions %s
-// RUN: %clang -fsyntax-only -x c++ %s
+// RUN: %clangxx -fsyntax-only -x c++ %s
 
 #if defined(i386) || defined(__x86_64__)
 
-#  if defined(__MMX__)
-#include <emmintrin.h>
+#ifdef __MMX__
 #include <mm_malloc.h>
-#  endif
+#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__)
+#ifdef __SSE4_2__
+// nmmintrin forwards to smmintrin.
 #include <nmmintrin.h>
-#  endif
+#endif
+
+// immintrin includes all other intel intrinsic headers.
+#include <immintrin.h>
 
 #endif
diff --git a/test/Index/Inputs/crash-recovery-code-complete-remap.c b/test/Index/Inputs/crash-recovery-code-complete-remap.c
new file mode 100644
index 0000000..50a8658
--- /dev/null
+++ b/test/Index/Inputs/crash-recovery-code-complete-remap.c
@@ -0,0 +1,12 @@
+// RUN: echo env CINDEXTEST_EDITING=1 \
+// RUN:   not c-index-test -test-load-source-reparse 1 local \
+// RUN:   -remap-file="%s;%S/Inputs/crash-recovery-code-complete-remap.c" \
+// RUN:   %s 2> %t.err
+// RUN: FileCheck < %t.err -check-prefix=CHECK-CODE-COMPLETE-CRASH %s
+// CHECK-CODE-COMPLETE-CRASH: Unable to reparse translation unit
+//
+// XFAIL: win32
+
+#warning parsing original file
+
+#pragma clang __debug crash
diff --git a/test/Index/Inputs/crash-recovery-reparse-remap.c b/test/Index/Inputs/crash-recovery-reparse-remap.c
new file mode 100644
index 0000000..0357dbe
--- /dev/null
+++ b/test/Index/Inputs/crash-recovery-reparse-remap.c
@@ -0,0 +1,11 @@
+
+#warning parsing remapped file
+
+
+
+int x;
+
+#pragma clang __debug crash
+
+int x;
+
diff --git a/test/Index/Inputs/preamble-reparse-1.c b/test/Index/Inputs/preamble-reparse-1.c
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/test/Index/Inputs/preamble-reparse-1.c
@@ -0,0 +1,2 @@
+
+
diff --git a/test/Index/Inputs/preamble-reparse-2.c b/test/Index/Inputs/preamble-reparse-2.c
new file mode 100644
index 0000000..6d1a0d4
--- /dev/null
+++ b/test/Index/Inputs/preamble-reparse-2.c
@@ -0,0 +1 @@
+int x;
diff --git a/test/Index/Inputs/preamble.h b/test/Index/Inputs/preamble.h
new file mode 100644
index 0000000..b59c234
--- /dev/null
+++ b/test/Index/Inputs/preamble.h
@@ -0,0 +1,6 @@
+inline int bar(int i) {
+  int *ptr = 0;
+  float *ptr1;
+  ptr = ptr1;
+  return 0;
+}
diff --git a/test/Index/Inputs/prefix.h b/test/Index/Inputs/prefix.h
new file mode 100644
index 0000000..82ba2da
--- /dev/null
+++ b/test/Index/Inputs/prefix.h
@@ -0,0 +1,4 @@
+#ifndef PREFIX_H
+#define PREFIX_H
+int foo(int);
+#endif
diff --git a/test/Index/TestClassDecl.m b/test/Index/TestClassDecl.m
index b55c862..09a7d48 100644
--- a/test/Index/TestClassDecl.m
+++ b/test/Index/TestClassDecl.m
@@ -1,4 +1,4 @@
-// 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 -write-pch %t.ast -fobjc-nonfragile-abi -fblocks -x objective-c %s 
 // 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
 
diff --git a/test/Index/annotate-tokens-include.c b/test/Index/annotate-tokens-include.c
new file mode 100644
index 0000000..3c3c43b
--- /dev/null
+++ b/test/Index/annotate-tokens-include.c
@@ -0,0 +1,6 @@
+#include "annotate-tokens-include.h"
+
+// RUN: c-index-test -test-annotate-tokens=%s:1:1:2:1 %s | FileCheck %s
+// CHECK: Identifier: "include" [1:2 - 1:9] preprocessing directive=
+// CHECK: Literal: ""annotate-tokens-include.h"" [1:10 - 1:37] preprocessing directive=
+
diff --git a/test/Index/annotate-tokens-include.h b/test/Index/annotate-tokens-include.h
new file mode 100644
index 0000000..5d5f8f0
--- /dev/null
+++ b/test/Index/annotate-tokens-include.h
@@ -0,0 +1 @@
+int foo();
diff --git a/test/Index/annotate-tokens-pp.c b/test/Index/annotate-tokens-pp.c
index 485786e..55ee763 100644
--- a/test/Index/annotate-tokens-pp.c
+++ b/test/Index/annotate-tokens-pp.c
@@ -7,7 +7,25 @@
 #include "foo.h"
 #undef BAR
 
-// RUN: c-index-test -test-annotate-tokens=%s:2:1:9:1 -I%S/Inputs %s | FileCheck %s
+#define REVERSE_MACRO(x,y) y + x
+#define TWICE_MACRO(y) y + y
+
+void test_macro_args() {
+  int z = 1;
+  int t = 2;
+  int k = REVERSE_MACRO(t,z);
+  int j = TWICE_MACRO(k + k);
+  int w = j + j;
+}
+
+#define fun_with_macro_bodies(x, y) do { if (x) y } while (0) 
+
+void test() {
+  int x = 10;
+  fun_with_macro_bodies(x, { int z = x; ++z; });
+}
+
+// RUN: c-index-test -test-annotate-tokens=%s:2:1:26: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
@@ -56,3 +74,114 @@
 // 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=
+// CHECK: Punctuation: "#" [10:1 - 10:2] preprocessing directive=
+// CHECK: Identifier: "define" [10:2 - 10:8] preprocessing directive=
+// CHECK: Identifier: "REVERSE_MACRO" [10:9 - 10:22] macro definition=REVERSE_MACRO
+// CHECK: Punctuation: "(" [10:22 - 10:23] preprocessing directive=
+// CHECK: Identifier: "x" [10:23 - 10:24] preprocessing directive=
+// CHECK: Punctuation: "," [10:24 - 10:25] preprocessing directive=
+// CHECK: Identifier: "y" [10:25 - 10:26] preprocessing directive=
+// CHECK: Punctuation: ")" [10:26 - 10:27] preprocessing directive=
+// CHECK: Identifier: "y" [10:28 - 10:29] preprocessing directive=
+// CHECK: Punctuation: "+" [10:30 - 10:31] preprocessing directive=
+// CHECK: Identifier: "x" [10:32 - 10:33] preprocessing directive=
+// CHECK: Punctuation: "#" [11:1 - 11:2] preprocessing directive=
+// CHECK: Identifier: "define" [11:2 - 11:8] preprocessing directive=
+// CHECK: Identifier: "TWICE_MACRO" [11:9 - 11:20] macro definition=TWICE_MACRO
+// CHECK: Punctuation: "(" [11:20 - 11:21] preprocessing directive=
+// CHECK: Identifier: "y" [11:21 - 11:22] preprocessing directive=
+// CHECK: Punctuation: ")" [11:22 - 11:23] preprocessing directive=
+// CHECK: Identifier: "y" [11:24 - 11:25] preprocessing directive=
+// CHECK: Punctuation: "+" [11:26 - 11:27] preprocessing directive=
+// CHECK: Identifier: "y" [11:28 - 11:29] preprocessing directive=
+// CHECK: Keyword: "void" [13:1 - 13:5] FunctionDecl=test_macro_args:13:6 (Definition)
+// CHECK: Identifier: "test_macro_args" [13:6 - 13:21] FunctionDecl=test_macro_args:13:6 (Definition)
+// CHECK: Punctuation: "(" [13:21 - 13:22] FunctionDecl=test_macro_args:13:6 (Definition)
+// CHECK: Punctuation: ")" [13:22 - 13:23] FunctionDecl=test_macro_args:13:6 (Definition)
+// CHECK: Punctuation: "{" [13:24 - 13:25] UnexposedStmt=
+// CHECK: Keyword: "int" [14:3 - 14:6] VarDecl=z:14:7 (Definition)
+// CHECK: Identifier: "z" [14:7 - 14:8] VarDecl=z:14:7 (Definition)
+// CHECK: Punctuation: "=" [14:9 - 14:10] VarDecl=z:14:7 (Definition)
+// CHECK: Literal: "1" [14:11 - 14:12] UnexposedExpr=
+// CHECK: Punctuation: ";" [14:12 - 14:13] UnexposedStmt=
+// CHECK: Keyword: "int" [15:3 - 15:6] VarDecl=t:15:7 (Definition)
+// CHECK: Identifier: "t" [15:7 - 15:8] VarDecl=t:15:7 (Definition)
+// CHECK: Punctuation: "=" [15:9 - 15:10] VarDecl=t:15:7 (Definition)
+// CHECK: Literal: "2" [15:11 - 15:12] UnexposedExpr=
+// CHECK: Punctuation: ";" [15:12 - 15:13] UnexposedStmt=
+// CHECK: Keyword: "int" [16:3 - 16:6] VarDecl=k:16:7 (Definition)
+// CHECK: Identifier: "k" [16:7 - 16:8] VarDecl=k:16:7 (Definition)
+// CHECK: Punctuation: "=" [16:9 - 16:10] VarDecl=k:16:7 (Definition)
+// CHECK: Identifier: "REVERSE_MACRO" [16:11 - 16:24] macro instantiation=REVERSE_MACRO:10:9
+// CHECK: Punctuation: "(" [16:24 - 16:25] UnexposedStmt=
+// CHECK: Identifier: "t" [16:25 - 16:26] DeclRefExpr=t:15:7
+// CHECK: Punctuation: "," [16:26 - 16:27] UnexposedStmt=
+// CHECK: Identifier: "z" [16:27 - 16:28] DeclRefExpr=z:14:7
+// CHECK: Punctuation: ")" [16:28 - 16:29] UnexposedStmt=
+// CHECK: Punctuation: ";" [16:29 - 16:30] UnexposedStmt=
+// CHECK: Keyword: "int" [17:3 - 17:6] VarDecl=j:17:7 (Definition)
+// CHECK: Identifier: "j" [17:7 - 17:8] VarDecl=j:17:7 (Definition)
+// CHECK: Punctuation: "=" [17:9 - 17:10] VarDecl=j:17:7 (Definition)
+// CHECK: Identifier: "TWICE_MACRO" [17:11 - 17:22] macro instantiation=TWICE_MACRO:11:9
+// CHECK: Punctuation: "(" [17:22 - 17:23] UnexposedStmt=
+// CHECK: Identifier: "k" [17:23 - 17:24] DeclRefExpr=k:16:7
+// CHECK: Punctuation: "+" [17:25 - 17:26] UnexposedStmt=
+// CHECK: Identifier: "k" [17:27 - 17:28] DeclRefExpr=k:16:7
+// CHECK: Punctuation: ")" [17:28 - 17:29] UnexposedStmt=
+// CHECK: Punctuation: ";" [17:29 - 17:30] UnexposedStmt=
+// CHECK: Keyword: "int" [18:3 - 18:6] VarDecl=w:18:7 (Definition)
+// CHECK: Identifier: "w" [18:7 - 18:8] VarDecl=w:18:7 (Definition)
+// CHECK: Punctuation: "=" [18:9 - 18:10] VarDecl=w:18:7 (Definition)
+// CHECK: Identifier: "j" [18:11 - 18:12] DeclRefExpr=j:17:7
+// CHECK: Punctuation: "+" [18:13 - 18:14] UnexposedExpr=
+// CHECK: Identifier: "j" [18:15 - 18:16] DeclRefExpr=j:17:7
+// CHECK: Punctuation: ";" [18:16 - 18:17] UnexposedStmt=
+// CHECK: Punctuation: "}" [19:1 - 19:2] UnexposedStmt=
+// CHECK: Punctuation: "#" [21:1 - 21:2] preprocessing directive=
+// CHECK: Identifier: "define" [21:2 - 21:8] preprocessing directive=
+// CHECK: Identifier: "fun_with_macro_bodies" [21:9 - 21:30] macro definition=fun_with_macro_bodies
+// CHECK: Punctuation: "(" [21:30 - 21:31] preprocessing directive=
+// CHECK: Identifier: "x" [21:31 - 21:32] preprocessing directive=
+// CHECK: Punctuation: "," [21:32 - 21:33] preprocessing directive=
+// CHECK: Identifier: "y" [21:34 - 21:35] preprocessing directive=
+// CHECK: Punctuation: ")" [21:35 - 21:36] preprocessing directive=
+// CHECK: Keyword: "do" [21:37 - 21:39] preprocessing directive=
+// CHECK: Punctuation: "{" [21:40 - 21:41] preprocessing directive=
+// CHECK: Keyword: "if" [21:42 - 21:44] preprocessing directive=
+// CHECK: Punctuation: "(" [21:45 - 21:46] preprocessing directive=
+// CHECK: Identifier: "x" [21:46 - 21:47] preprocessing directive=
+// CHECK: Punctuation: ")" [21:47 - 21:48] preprocessing directive=
+// CHECK: Identifier: "y" [21:49 - 21:50] preprocessing directive=
+// CHECK: Punctuation: "}" [21:51 - 21:52] preprocessing directive=
+// CHECK: Keyword: "while" [21:53 - 21:58] preprocessing directive=
+// CHECK: Punctuation: "(" [21:59 - 21:60] preprocessing directive=
+// CHECK: Literal: "0" [21:60 - 21:61] preprocessing directive=
+// CHECK: Punctuation: ")" [21:61 - 21:62] preprocessing directive=
+// CHECK: Keyword: "void" [23:1 - 23:5] FunctionDecl=test:23:6 (Definition)
+// CHECK: Identifier: "test" [23:6 - 23:10] FunctionDecl=test:23:6 (Definition)
+// CHECK: Punctuation: "(" [23:10 - 23:11] FunctionDecl=test:23:6 (Definition)
+// CHECK: Punctuation: ")" [23:11 - 23:12] FunctionDecl=test:23:6 (Definition)
+// CHECK: Punctuation: "{" [23:13 - 23:14] UnexposedStmt=
+// CHECK: Keyword: "int" [24:3 - 24:6] VarDecl=x:24:7 (Definition)
+// CHECK: Identifier: "x" [24:7 - 24:8] VarDecl=x:24:7 (Definition)
+// CHECK: Punctuation: "=" [24:9 - 24:10] VarDecl=x:24:7 (Definition)
+// CHECK: Literal: "10" [24:11 - 24:13] UnexposedExpr=
+// CHECK: Punctuation: ";" [24:13 - 24:14] UnexposedStmt=
+// CHECK: Identifier: "fun_with_macro_bodies" [25:3 - 25:24] macro instantiation=fun_with_macro_bodies:21:9
+// CHECK: Punctuation: "(" [25:24 - 25:25] UnexposedStmt=
+// CHECK: Identifier: "x" [25:25 - 25:26] DeclRefExpr=x:24:7
+// CHECK: Punctuation: "," [25:26 - 25:27] UnexposedStmt=
+// CHECK: Punctuation: "{" [25:28 - 25:29] UnexposedStmt=
+// CHECK: Keyword: "int" [25:30 - 25:33] UnexposedStmt=
+// CHECK: Identifier: "z" [25:34 - 25:35] VarDecl=z:25:3 (Definition)
+// CHECK: Punctuation: "=" [25:36 - 25:37] UnexposedStmt=
+// CHECK: Identifier: "x" [25:38 - 25:39] DeclRefExpr=x:24:7
+// CHECK: Punctuation: ";" [25:39 - 25:40] UnexposedStmt=
+// CHECK: Punctuation: "++" [25:41 - 25:43] UnexposedExpr=
+// CHECK: Identifier: "z" [25:43 - 25:44] DeclRefExpr=z:25:3
+// CHECK: Punctuation: ";" [25:44 - 25:45] UnexposedStmt=
+// CHECK: Punctuation: "}" [25:46 - 25:47] UnexposedStmt=
+// CHECK: Punctuation: ")" [25:47 - 25:48] UnexposedStmt=
+// CHECK: Punctuation: ";" [25:48 - 25:49] UnexposedStmt=
+// CHECK: Punctuation: "}" [26:1 - 26:2] UnexposedStmt=
+
diff --git a/test/Index/annotate-tokens.c b/test/Index/annotate-tokens.c
index 7fbf9cc..e251596 100644
--- a/test/Index/annotate-tokens.c
+++ b/test/Index/annotate-tokens.c
@@ -9,57 +9,70 @@
   const char * hello = "Hello";
 }
 
-// RUN: c-index-test -test-annotate-tokens=%s:4:1:9:32 %s | FileCheck %s
+typedef int Int;
+void g(int i, ...) {
+  __builtin_va_list va;
+  (void)__builtin_va_arg(va, Int);
+  (void)__builtin_types_compatible_p(Int, Int);
+}
+
+// RUN: c-index-test -test-annotate-tokens=%s:4:1:17:1 %s | FileCheck %s
 // CHECK: Identifier: "T" [4:3 - 4:4] TypeRef=T:1:13
-// CHECK: Punctuation: "*" [4:4 - 4:5]
+// CHECK: Punctuation: "*" [4:4 - 4:5] VarDecl=t_ptr:4:6 (Definition)
 // 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: Punctuation: "=" [4:12 - 4:13] VarDecl=t_ptr:4:6 (Definition)
+// CHECK: Punctuation: "(" [4:14 - 4:15] UnexposedExpr=ptr:3:14
 // CHECK: Identifier: "T" [4:15 - 4:16] TypeRef=T:1:13
-// CHECK: Punctuation: "*" [4:17 - 4:18]
-// CHECK: Punctuation: ")" [4:18 - 4:19]
+// CHECK: Punctuation: "*" [4:17 - 4:18] UnexposedExpr=ptr:3:14
+// CHECK: Punctuation: ")" [4:18 - 4:19] UnexposedExpr=ptr:3:14
 // 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: Punctuation: ";" [4:22 - 4:23] UnexposedStmt=
+// CHECK: Punctuation: "(" [5:3 - 5:4] UnexposedExpr=
+// CHECK: Keyword: "void" [5:4 - 5:8] UnexposedExpr=
+// CHECK: Punctuation: ")" [5:8 - 5:9] UnexposedExpr=
+// CHECK: Keyword: "sizeof" [5:9 - 5:15] UnexposedExpr=
+// CHECK: Punctuation: "(" [5:15 - 5:16] UnexposedExpr=
 // 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: Punctuation: ")" [5:17 - 5:18] UnexposedExpr=
+// CHECK: Punctuation: ";" [5:18 - 5:19] UnexposedStmt=
+// CHECK: Comment: "/* A comment */" [6:3 - 6:18] UnexposedStmt=
+// CHECK: Keyword: "struct" [7:3 - 7:9] UnexposedStmt=
 // 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: Punctuation: "=" [7:14 - 7:15] VarDecl=x:7:12 (Definition)
+// CHECK: Punctuation: "(" [7:16 - 7:17] UnexposedExpr=
+// CHECK: Keyword: "struct" [7:17 - 7:23] UnexposedExpr=
 // 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: Punctuation: ")" [7:25 - 7:26] UnexposedExpr=
+// CHECK: Punctuation: "{" [7:26 - 7:27] UnexposedExpr=
+// CHECK: Literal: "1" [7:27 - 7:28] UnexposedExpr=
+// CHECK: Punctuation: "," [7:28 - 7:29] UnexposedExpr=
+// CHECK: Literal: "2" [7:30 - 7:31] UnexposedExpr=
+// CHECK: Punctuation: "}" [7:31 - 7:32] UnexposedExpr=
+// CHECK: Punctuation: ";" [7:32 - 7:33] UnexposedStmt=
+// CHECK: Keyword: "void" [8:3 - 8:7] VarDecl=xx:8:9 (Definition)
+// CHECK: Punctuation: "*" [8:8 - 8:9] VarDecl=xx:8:9 (Definition)
 // CHECK: Identifier: "xx" [8:9 - 8:11] VarDecl=xx:8:9 (Definition)
-// CHECK: Punctuation: "=" [8:12 - 8:13]
+// CHECK: Punctuation: "=" [8:12 - 8:13] VarDecl=xx:8:9 (Definition)
 // 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: Punctuation: "?" [8:18 - 8:19] UnexposedExpr=
+// CHECK: Punctuation: ":" [8:20 - 8:21] UnexposedExpr=
+// CHECK: Punctuation: "&" [8:22 - 8:23] UnexposedExpr=
 // 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: Punctuation: ";" [8:24 - 8:25] UnexposedStmt=
+// CHECK: Keyword: "const" [9:3 - 9:8] UnexposedStmt=
+// CHECK: Keyword: "char" [9:9 - 9:13] VarDecl=hello:9:16 (Definition)
+// CHECK: Punctuation: "*" [9:14 - 9:15] VarDecl=hello:9:16 (Definition)
 // 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]
+// CHECK: Punctuation: "=" [9:22 - 9:23] VarDecl=hello:9:16 (Definition)
+// CHECK: Literal: ""Hello"" [9:24 - 9:31] UnexposedExpr=
+// CHECK: Punctuation: ";" [9:31 - 9:32] UnexposedStmt=
+// CHECK: Punctuation: "}" [10:1 - 10:2] UnexposedStmt=
+// CHECK: Keyword: "__builtin_va_arg" [15:9 - 15:25] UnexposedExpr=
+// CHECK: Identifier: "Int" [15:30 - 15:33] TypeRef=Int:12:13
+// CHECK: Keyword: "__builtin_types_compatible_p" [16:9 - 16:37] UnexposedExpr=
+// CHECK: Identifier: "Int" [16:38 - 16:41] TypeRef=Int:12:13
+// CHECK: Punctuation: "," [16:41 - 16:42] UnexposedExpr=
+// CHECK: Identifier: "Int" [16:43 - 16:46] TypeRef=Int:12:13
 // 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.cpp b/test/Index/annotate-tokens.cpp
new file mode 100644
index 0000000..dca7af2
--- /dev/null
+++ b/test/Index/annotate-tokens.cpp
@@ -0,0 +1,23 @@
+struct bonk { };
+void test(bonk X) {
+    X = X;
+}
+
+// RUN: c-index-test -test-annotate-tokens=%s:1:1:5:5 %s
+// CHECK: Keyword: "struct" [1:1 - 1:7] StructDecl=bonk:1:8 (Definition)
+// CHECK: Identifier: "bonk" [1:8 - 1:12] StructDecl=bonk:1:8 (Definition)
+// CHECK: Punctuation: "{" [1:13 - 1:14] StructDecl=bonk:1:8 (Definition)
+// CHECK: Punctuation: "}" [1:15 - 1:16] StructDecl=bonk:1:8 (Definition)
+// CHECK: Punctuation: ";" [1:16 - 1:17]
+// CHECK: Keyword: "void" [2:1 - 2:5] FunctionDecl=test:2:6 (Definition)
+// CHECK: Identifier: "test" [2:6 - 2:10] FunctionDecl=test:2:6 (Definition)
+// CHECK: Punctuation: "(" [2:10 - 2:11] FunctionDecl=test:2:6 (Definition)
+// CHECK: Identifier: "bonk" [2:11 - 2:15] TypeRef=struct bonk:1:8
+// CHECK: Identifier: "X" [2:16 - 2:17] ParmDecl=X:2:16 (Definition)
+// CHECK: Punctuation: ")" [2:17 - 2:18] FunctionDecl=test:2:6 (Definition)
+// CHECK: Punctuation: "{" [2:19 - 2:20] UnexposedStmt=
+// CHECK: Identifier: "X" [3:5 - 3:6] DeclRefExpr=X:2:16
+// CHECK: Punctuation: "=" [3:7 - 3:8] DeclRefExpr=operator=:1:8
+// CHECK: Identifier: "X" [3:9 - 3:10] DeclRefExpr=X:2:16
+// CHECK: Punctuation: ";" [3:10 - 3:11] UnexposedStmt=
+// CHECK: Punctuation: "}" [4:1 - 4:2] UnexposedStmt=
diff --git a/test/Index/annotate-tokens.m b/test/Index/annotate-tokens.m
index ce399d3..336951b 100644
--- a/test/Index/annotate-tokens.m
+++ b/test/Index/annotate-tokens.m
@@ -9,51 +9,343 @@
 }
 @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]
+// From <rdar://problem/7971430>, the 'barType' referenced in the ivar
+// declarations should be annotated as TypeRefs.
+typedef int * barType;
+@interface Bar
+{
+    barType iVar;
+    barType iVar1, iVar2;
+}
+@end
+@implementation Bar
+- (void) method
+{
+    barType local = iVar;
+}
+@end
+
+// From <rdar://problem/7967123>.  The ranges for attributes are not
+// currently stored, causing most of the tokens to be falsely annotated.
+// Since there are no source ranges for attributes, we currently don't
+// annotate them.
+@interface IBActionTests
+- (IBAction) actionMethod:(id)arg;
+- (void)foo:(int)x;
+@end
+extern int ibaction_test(void);
+@implementation IBActionTests
+- (IBAction) actionMethod:(id)arg
+{
+    ibaction_test();
+    [self foo:0];
+}
+- (void) foo:(int)x
+{
+  (void) x;
+}
+@end
+
+// From <rdar://problem/7961995>.  Essentially the same issue as 7967123,
+// but impacting code marked as IBOutlets.
+@interface IBOutletTests
+{
+    IBOutlet char * anOutlet;
+}
+- (IBAction) actionMethod:(id)arg;
+@property IBOutlet int * aPropOutlet;
+@end
+
+// From <rdar://problem/7974151>.  The first 'foo:' wasn't being annotated as 
+// being part of the Objective-C message expression since the argument
+// was expanded from a macro.
+
+#define VAL 0
+
+@interface R7974151
+- (int) foo:(int)arg;
+- (int) method;
+@end
+
+@implementation R7974151
+- (int) foo:(int)arg {
+  return arg;
+}
+- (int) method
+{
+    int local = [self foo:VAL];
+    int second = [self foo:0];
+    return local;
+}
+@end
+
+// RUN: c-index-test -test-annotate-tokens=%s:1:1:80:4 %s -DIBOutlet='__attribute__((iboutlet))' -DIBAction='void)__attribute__((ibaction)' | FileCheck %s
+// CHECK: Punctuation: "@" [1:1 - 1:2] ObjCInterfaceDecl=Foo:1:12
+// CHECK: Keyword: "interface" [1:2 - 1:11] ObjCInterfaceDecl=Foo:1:12
 // 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: Punctuation: "(" [2:3 - 2:4] ObjCInstanceMethodDecl=compare::2:1
+// CHECK: Keyword: "int" [2:4 - 2:7] ObjCInstanceMethodDecl=compare::2:1
+// CHECK: Punctuation: ")" [2:7 - 2:8] ObjCInstanceMethodDecl=compare::2:1
+// CHECK: Identifier: "compare" [2:8 - 2:15] ObjCInstanceMethodDecl=compare::2:1
+// CHECK: Punctuation: ":" [2:15 - 2:16] ObjCInstanceMethodDecl=compare::2:1
+// CHECK: Punctuation: "(" [2:16 - 2:17] ObjCInstanceMethodDecl=compare::2:1
 // CHECK: Identifier: "Foo" [2:17 - 2:20] ObjCClassRef=Foo:1:12
-// CHECK: Punctuation: "*" [2:20 - 2:21]
-// CHECK: Punctuation: ")" [2:21 - 2:22]
+// CHECK: Punctuation: "*" [2:20 - 2:21] ParmDecl=other:2:22 (Definition)
+// CHECK: Punctuation: ")" [2:21 - 2:22] ParmDecl=other:2:22 (Definition)
 // 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: ";" [2:27 - 2:28] ObjCInstanceMethodDecl=compare::2:1
+// CHECK: Punctuation: "@" [3:1 - 3:2] ObjCInterfaceDecl=Foo:1:12
+// CHECK: Keyword: "end" [3:2 - 3:5] ObjCInterfaceDecl=Foo:1:12
 // 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: Keyword: "implementation" [5:2 - 5:16] ObjCImplementationDecl=Foo:5:1 (Definition)
+// CHECK: Identifier: "Foo" [5:17 - 5:20] ObjCImplementationDecl=Foo:5:1 (Definition)
 // 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: Punctuation: "(" [6:3 - 6:4] ObjCInstanceMethodDecl=compare::6:1 (Definition)
+// CHECK: Keyword: "int" [6:4 - 6:7] ObjCInstanceMethodDecl=compare::6:1 (Definition)
+// CHECK: Punctuation: ")" [6:7 - 6:8] ObjCInstanceMethodDecl=compare::6:1 (Definition)
+// CHECK: Identifier: "compare" [6:8 - 6:15] ObjCInstanceMethodDecl=compare::6:1 (Definition)
+// CHECK: Punctuation: ":" [6:15 - 6:16] ObjCInstanceMethodDecl=compare::6:1 (Definition)
+// CHECK: Punctuation: "(" [6:16 - 6:17] ObjCInstanceMethodDecl=compare::6:1 (Definition)
 // CHECK: Identifier: "Foo" [6:17 - 6:20] ObjCClassRef=Foo:1:12
-// CHECK: Punctuation: "*" [6:20 - 6:21]
-// CHECK: Punctuation: ")" [6:21 - 6:22]
+// CHECK: Punctuation: "*" [6:20 - 6:21] ParmDecl=other:6:22 (Definition)
+// CHECK: Punctuation: ")" [6:21 - 6:22] ParmDecl=other:6:22 (Definition)
 // 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: Punctuation: "{" [6:28 - 6:29] UnexposedStmt=
+// CHECK: Keyword: "return" [7:3 - 7:9] UnexposedStmt=
+// CHECK: Literal: "0" [7:10 - 7:11] UnexposedExpr=
+// CHECK: Punctuation: ";" [7:11 - 7:12] UnexposedStmt=
+// CHECK: Punctuation: "(" [8:3 - 8:4] UnexposedExpr=
+// CHECK: Keyword: "void" [8:4 - 8:8] UnexposedExpr=
+// CHECK: Punctuation: ")" [8:8 - 8:9] UnexposedExpr=
+// CHECK: Punctuation: "@" [8:9 - 8:10] UnexposedExpr=
+// CHECK: Keyword: "encode" [8:10 - 8:16] UnexposedExpr=
+// CHECK: Punctuation: "(" [8:16 - 8:17] UnexposedExpr=
 // 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]
+// CHECK: Punctuation: ")" [8:20 - 8:21] UnexposedExpr=
+// CHECK: Punctuation: ";" [8:21 - 8:22] UnexposedStmt=
+// CHECK: Punctuation: "}" [9:1 - 9:2] UnexposedStmt=
+// CHECK: Punctuation: "@" [10:1 - 10:2] ObjCImplementationDecl=Foo:5:1 (Definition)
+// CHECK: Keyword: "end" [10:2 - 10:5]
+// CHECK: Keyword: "typedef" [14:1 - 14:8]
+// CHECK: Keyword: "int" [14:9 - 14:12]
+// CHECK: Punctuation: "*" [14:13 - 14:14]
+// CHECK: Identifier: "barType" [14:15 - 14:22] TypedefDecl=barType:14:15 (Definition)
+// CHECK: Punctuation: ";" [14:22 - 14:23]
+// CHECK: Punctuation: "@" [15:1 - 15:2] ObjCInterfaceDecl=Bar:15:12
+// CHECK: Keyword: "interface" [15:2 - 15:11] ObjCInterfaceDecl=Bar:15:12
+// CHECK: Identifier: "Bar" [15:12 - 15:15] ObjCInterfaceDecl=Bar:15:12
+// CHECK: Punctuation: "{" [16:1 - 16:2] ObjCInterfaceDecl=Bar:15:12
+// CHECK: Identifier: "barType" [17:5 - 17:12] TypeRef=barType:14:15
+// CHECK: Identifier: "iVar" [17:13 - 17:17] ObjCIvarDecl=iVar:17:13 (Definition)
+// CHECK: Punctuation: ";" [17:17 - 17:18] ObjCInterfaceDecl=Bar:15:12
+// CHECK: Identifier: "barType" [18:5 - 18:12] TypeRef=barType:14:15
+// CHECK: Identifier: "iVar1" [18:13 - 18:18] ObjCIvarDecl=iVar1:18:13 (Definition)
+// CHECK: Punctuation: "," [18:18 - 18:19] ObjCIvarDecl=iVar2:18:20 (Definition)
+// CHECK: Identifier: "iVar2" [18:20 - 18:25] ObjCIvarDecl=iVar2:18:20 (Definition)
+// CHECK: Punctuation: ";" [18:25 - 18:26] ObjCInterfaceDecl=Bar:15:12
+// CHECK: Punctuation: "}" [19:1 - 19:2] ObjCInterfaceDecl=Bar:15:12
+// CHECK: Punctuation: "@" [20:1 - 20:2] ObjCInterfaceDecl=Bar:15:12
+// CHECK: Keyword: "end" [20:2 - 20:5] ObjCInterfaceDecl=Bar:15:12
+// CHECK: Punctuation: "@" [21:1 - 21:2] ObjCImplementationDecl=Bar:21:1 (Definition)
+// CHECK: Keyword: "implementation" [21:2 - 21:16] ObjCImplementationDecl=Bar:21:1 (Definition)
+// CHECK: Identifier: "Bar" [21:17 - 21:20] ObjCImplementationDecl=Bar:21:1 (Definition)
+// CHECK: Punctuation: "-" [22:1 - 22:2] ObjCInstanceMethodDecl=method:22:1 (Definition)
+// CHECK: Punctuation: "(" [22:3 - 22:4] ObjCInstanceMethodDecl=method:22:1 (Definition)
+// CHECK: Keyword: "void" [22:4 - 22:8] ObjCInstanceMethodDecl=method:22:1 (Definition)
+// CHECK: Punctuation: ")" [22:8 - 22:9] ObjCInstanceMethodDecl=method:22:1 (Definition)
+// CHECK: Identifier: "method" [22:10 - 22:16] ObjCInstanceMethodDecl=method:22:1 (Definition)
+// CHECK: Punctuation: "{" [23:1 - 23:2] UnexposedStmt=
+// CHECK: Identifier: "barType" [24:5 - 24:12] TypeRef=barType:14:15
+// CHECK: Identifier: "local" [24:13 - 24:18] VarDecl=local:24:13 (Definition)
+// CHECK: Punctuation: "=" [24:19 - 24:20] VarDecl=local:24:13 (Definition)
+// CHECK: Identifier: "iVar" [24:21 - 24:25] MemberRefExpr=iVar:17:13
+// CHECK: Punctuation: ";" [24:25 - 24:26] UnexposedStmt=
+// CHECK: Punctuation: "}" [25:1 - 25:2] UnexposedStmt=
+// CHECK: Punctuation: "@" [26:1 - 26:2] ObjCImplementationDecl=Bar:21:1 (Definition)
+// CHECK: Keyword: "end" [26:2 - 26:5]
+// CHECK: Punctuation: "@" [32:1 - 32:2] ObjCInterfaceDecl=IBActionTests:32:12
+// CHECK: Keyword: "interface" [32:2 - 32:11] ObjCInterfaceDecl=IBActionTests:32:12
+// CHECK: Identifier: "IBActionTests" [32:12 - 32:25] ObjCInterfaceDecl=IBActionTests:32:12
+// CHECK: Punctuation: "-" [33:1 - 33:2] ObjCInstanceMethodDecl=actionMethod::33:1
+// CHECK: Punctuation: "(" [33:3 - 33:4] ObjCInstanceMethodDecl=actionMethod::33:1
+// CHECK: Identifier: "IBAction" [33:4 - 33:12] macro instantiation=IBAction
+// CHECK: Punctuation: ")" [33:12 - 33:13] ObjCInstanceMethodDecl=actionMethod::33:1
+// CHECK: Identifier: "actionMethod" [33:14 - 33:26] ObjCInstanceMethodDecl=actionMethod::33:1
+// CHECK: Punctuation: ":" [33:26 - 33:27] ObjCInstanceMethodDecl=actionMethod::33:1
+// CHECK: Punctuation: "(" [33:27 - 33:28] ObjCInstanceMethodDecl=actionMethod::33:1
+// CHECK: Identifier: "id" [33:28 - 33:30] TypeRef=id:0:0
+// CHECK: Punctuation: ")" [33:30 - 33:31] ParmDecl=arg:33:31 (Definition)
+// CHECK: Identifier: "arg" [33:31 - 33:34] ParmDecl=arg:33:31 (Definition)
+// CHECK: Punctuation: ";" [33:34 - 33:35] ObjCInstanceMethodDecl=actionMethod::33:1
+// CHECK: Punctuation: "-" [34:1 - 34:2] ObjCInstanceMethodDecl=foo::34:1
+// CHECK: Punctuation: "(" [34:3 - 34:4] ObjCInstanceMethodDecl=foo::34:1
+// CHECK: Keyword: "void" [34:4 - 34:8] ObjCInstanceMethodDecl=foo::34:1
+// CHECK: Punctuation: ")" [34:8 - 34:9] ObjCInstanceMethodDecl=foo::34:1
+// CHECK: Identifier: "foo" [34:9 - 34:12] ObjCInstanceMethodDecl=foo::34:1
+// CHECK: Punctuation: ":" [34:12 - 34:13] ObjCInstanceMethodDecl=foo::34:1
+// CHECK: Punctuation: "(" [34:13 - 34:14] ObjCInstanceMethodDecl=foo::34:1
+// CHECK: Keyword: "int" [34:14 - 34:17] ParmDecl=x:34:18 (Definition)
+// CHECK: Punctuation: ")" [34:17 - 34:18] ParmDecl=x:34:18 (Definition)
+// CHECK: Identifier: "x" [34:18 - 34:19] ParmDecl=x:34:18 (Definition)
+// CHECK: Punctuation: ";" [34:19 - 34:20] ObjCInstanceMethodDecl=foo::34:1
+// CHECK: Punctuation: "@" [35:1 - 35:2] ObjCInterfaceDecl=IBActionTests:32:12
+// CHECK: Keyword: "end" [35:2 - 35:5] ObjCInterfaceDecl=IBActionTests:32:12
+// CHECK: Keyword: "extern" [36:1 - 36:7]
+// CHECK: Keyword: "int" [36:8 - 36:11] FunctionDecl=ibaction_test:36:12
+// CHECK: Identifier: "ibaction_test" [36:12 - 36:25] FunctionDecl=ibaction_test:36:12
+// CHECK: Punctuation: "(" [36:25 - 36:26] FunctionDecl=ibaction_test:36:12
+// CHECK: Keyword: "void" [36:26 - 36:30] FunctionDecl=ibaction_test:36:12
+// CHECK: Punctuation: ")" [36:30 - 36:31] FunctionDecl=ibaction_test:36:12
+// CHECK: Punctuation: ";" [36:31 - 36:32]
+// CHECK: Punctuation: "@" [37:1 - 37:2] ObjCImplementationDecl=IBActionTests:37:1 (Definition)
+// CHECK: Keyword: "implementation" [37:2 - 37:16] ObjCImplementationDecl=IBActionTests:37:1 (Definition)
+// CHECK: Identifier: "IBActionTests" [37:17 - 37:30] ObjCImplementationDecl=IBActionTests:37:1 (Definition)
+// CHECK: Punctuation: "-" [38:1 - 38:2] ObjCInstanceMethodDecl=actionMethod::38:1 (Definition)
+// CHECK: Punctuation: "(" [38:3 - 38:4] ObjCInstanceMethodDecl=actionMethod::38:1 (Definition)
+// CHECK: Identifier: "IBAction" [38:4 - 38:12] macro instantiation=IBAction
+// CHECK: Punctuation: ")" [38:12 - 38:13] ObjCInstanceMethodDecl=actionMethod::38:1 (Definition)
+// CHECK: Identifier: "actionMethod" [38:14 - 38:26] ObjCInstanceMethodDecl=actionMethod::38:1 (Definition)
+// CHECK: Punctuation: ":" [38:26 - 38:27] ObjCInstanceMethodDecl=actionMethod::38:1 (Definition)
+// CHECK: Punctuation: "(" [38:27 - 38:28] ObjCInstanceMethodDecl=actionMethod::38:1 (Definition)
+// CHECK: Identifier: "id" [38:28 - 38:30] TypeRef=id:0:0
+// CHECK: Punctuation: ")" [38:30 - 38:31] ParmDecl=arg:38:31 (Definition)
+// CHECK: Identifier: "arg" [38:31 - 38:34] ParmDecl=arg:38:31 (Definition)
+// CHECK: Punctuation: "{" [39:1 - 39:2] UnexposedStmt=
+// CHECK: Identifier: "ibaction_test" [40:5 - 40:18] DeclRefExpr=ibaction_test:36:12
+// CHECK: Punctuation: "(" [40:18 - 40:19] CallExpr=ibaction_test:36:12
+// CHECK: Punctuation: ")" [40:19 - 40:20] CallExpr=ibaction_test:36:12
+// CHECK: Punctuation: ";" [40:20 - 40:21] UnexposedStmt=
+// CHECK: Punctuation: "[" [41:5 - 41:6] ObjCMessageExpr=foo::34:1
+// CHECK: Identifier: "self" [41:6 - 41:10] DeclRefExpr=self:0:0
+// CHECK: Identifier: "foo" [41:11 - 41:14] ObjCMessageExpr=foo::34:1
+// CHECK: Punctuation: ":" [41:14 - 41:15] ObjCMessageExpr=foo::34:1
+// CHECK: Literal: "0" [41:15 - 41:16] UnexposedExpr=
+// CHECK: Punctuation: "]" [41:16 - 41:17] ObjCMessageExpr=foo::34:1
+// CHECK: Punctuation: ";" [41:17 - 41:18] UnexposedStmt=
+// CHECK: Punctuation: "}" [42:1 - 42:2] UnexposedStmt=
+// CHECK: Punctuation: "-" [43:1 - 43:2] ObjCInstanceMethodDecl=foo::43:1 (Definition)
+// CHECK: Punctuation: "(" [43:3 - 43:4] ObjCInstanceMethodDecl=foo::43:1 (Definition)
+// CHECK: Keyword: "void" [43:4 - 43:8] ObjCInstanceMethodDecl=foo::43:1 (Definition)
+// CHECK: Punctuation: ")" [43:8 - 43:9] ObjCInstanceMethodDecl=foo::43:1 (Definition)
+// CHECK: Identifier: "foo" [43:10 - 43:13] ObjCInstanceMethodDecl=foo::43:1 (Definition)
+// CHECK: Punctuation: ":" [43:13 - 43:14] ObjCInstanceMethodDecl=foo::43:1 (Definition)
+// CHECK: Punctuation: "(" [43:14 - 43:15] ObjCInstanceMethodDecl=foo::43:1 (Definition)
+// CHECK: Keyword: "int" [43:15 - 43:18] ParmDecl=x:43:19 (Definition)
+// CHECK: Punctuation: ")" [43:18 - 43:19] ParmDecl=x:43:19 (Definition)
+// CHECK: Identifier: "x" [43:19 - 43:20] ParmDecl=x:43:19 (Definition)
+// CHECK: Punctuation: "{" [44:1 - 44:2] UnexposedStmt=
+// CHECK: Punctuation: "(" [45:3 - 45:4] UnexposedExpr=x:43:19
+// CHECK: Keyword: "void" [45:4 - 45:8] UnexposedExpr=x:43:19
+// CHECK: Punctuation: ")" [45:8 - 45:9] UnexposedExpr=x:43:19
+// CHECK: Identifier: "x" [45:10 - 45:11] DeclRefExpr=x:43:19
+// CHECK: Punctuation: ";" [45:11 - 45:12] UnexposedStmt=
+// CHECK: Punctuation: "}" [46:1 - 46:2] UnexposedStmt=
+// CHECK: Punctuation: "@" [47:1 - 47:2] ObjCImplementationDecl=IBActionTests:37:1 (Definition)
+// CHECK: Keyword: "end" [47:2 - 47:5]
+// CHECK: Punctuation: "@" [51:1 - 51:2] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Keyword: "interface" [51:2 - 51:11] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Identifier: "IBOutletTests" [51:12 - 51:25] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Punctuation: "{" [52:1 - 52:2] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Identifier: "IBOutlet" [53:5 - 53:13] macro instantiation=IBOutlet
+// CHECK: Keyword: "char" [53:14 - 53:18] ObjCIvarDecl=anOutlet:53:21 (Definition)
+// CHECK: Punctuation: "*" [53:19 - 53:20] ObjCIvarDecl=anOutlet:53:21 (Definition)
+// CHECK: Identifier: "anOutlet" [53:21 - 53:29] ObjCIvarDecl=anOutlet:53:21 (Definition)
+// CHECK: Punctuation: ";" [53:29 - 53:30] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Punctuation: "}" [54:1 - 54:2] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Punctuation: "-" [55:1 - 55:2] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Punctuation: "(" [55:3 - 55:4] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Identifier: "IBAction" [55:4 - 55:12] macro instantiation=IBAction
+// CHECK: Punctuation: ")" [55:12 - 55:13] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Identifier: "actionMethod" [55:14 - 55:26] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Punctuation: ":" [55:26 - 55:27] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Punctuation: "(" [55:27 - 55:28] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Identifier: "id" [55:28 - 55:30] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Punctuation: ")" [55:30 - 55:31] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Identifier: "arg" [55:31 - 55:34] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Punctuation: ";" [55:34 - 55:35] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Punctuation: "@" [56:1 - 56:2] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Keyword: "property" [56:2 - 56:10] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Identifier: "IBOutlet" [56:11 - 56:19] macro instantiation=IBOutlet
+// CHECK: Keyword: "int" [56:20 - 56:23] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Punctuation: "*" [56:24 - 56:25] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Identifier: "aPropOutlet" [56:26 - 56:37] ObjCPropertyDecl=aPropOutlet:56:26
+// CHECK: Punctuation: ";" [56:37 - 56:38] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Punctuation: "@" [57:1 - 57:2] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Keyword: "end" [57:2 - 57:5] ObjCInterfaceDecl=IBOutletTests:51:12
+// CHECK: Punctuation: "#" [63:1 - 63:2] preprocessing directive=
+// CHECK: Identifier: "define" [63:2 - 63:8] preprocessing directive=
+// CHECK: Identifier: "VAL" [63:9 - 63:12] macro definition=VAL
+// CHECK: Literal: "0" [63:13 - 63:14] preprocessing directive=
+// CHECK: Punctuation: "@" [65:1 - 65:2] ObjCInterfaceDecl=R7974151:65:12
+// CHECK: Keyword: "interface" [65:2 - 65:11] ObjCInterfaceDecl=R7974151:65:12
+// CHECK: Identifier: "R7974151" [65:12 - 65:20] ObjCInterfaceDecl=R7974151:65:12
+// CHECK: Punctuation: "-" [66:1 - 66:2] ObjCInstanceMethodDecl=foo::66:1
+// CHECK: Punctuation: "(" [66:3 - 66:4] ObjCInstanceMethodDecl=foo::66:1
+// CHECK: Keyword: "int" [66:4 - 66:7] ObjCInstanceMethodDecl=foo::66:1
+// CHECK: Punctuation: ")" [66:7 - 66:8] ObjCInstanceMethodDecl=foo::66:1
+// CHECK: Identifier: "foo" [66:9 - 66:12] ObjCInstanceMethodDecl=foo::66:1
+// CHECK: Punctuation: ":" [66:12 - 66:13] ObjCInstanceMethodDecl=foo::66:1
+// CHECK: Punctuation: "(" [66:13 - 66:14] ObjCInstanceMethodDecl=foo::66:1
+// CHECK: Keyword: "int" [66:14 - 66:17] ParmDecl=arg:66:18 (Definition)
+// CHECK: Punctuation: ")" [66:17 - 66:18] ParmDecl=arg:66:18 (Definition)
+// CHECK: Identifier: "arg" [66:18 - 66:21] ParmDecl=arg:66:18 (Definition)
+// CHECK: Punctuation: ";" [66:21 - 66:22] ObjCInstanceMethodDecl=foo::66:1
+// CHECK: Punctuation: "-" [67:1 - 67:2] ObjCInstanceMethodDecl=method:67:1
+// CHECK: Punctuation: "(" [67:3 - 67:4] ObjCInstanceMethodDecl=method:67:1
+// CHECK: Keyword: "int" [67:4 - 67:7] ObjCInstanceMethodDecl=method:67:1
+// CHECK: Punctuation: ")" [67:7 - 67:8] ObjCInstanceMethodDecl=method:67:1
+// CHECK: Identifier: "method" [67:9 - 67:15] ObjCInstanceMethodDecl=method:67:1
+// CHECK: Punctuation: ";" [67:15 - 67:16] ObjCInstanceMethodDecl=method:67:1
+// CHECK: Punctuation: "@" [68:1 - 68:2] ObjCInterfaceDecl=R7974151:65:12
+// CHECK: Keyword: "end" [68:2 - 68:5] ObjCInterfaceDecl=R7974151:65:12
+// CHECK: Punctuation: "@" [70:1 - 70:2] ObjCImplementationDecl=R7974151:70:1 (Definition)
+// CHECK: Keyword: "implementation" [70:2 - 70:16] ObjCImplementationDecl=R7974151:70:1 (Definition)
+// CHECK: Identifier: "R7974151" [70:17 - 70:25] ObjCImplementationDecl=R7974151:70:1 (Definition)
+// CHECK: Punctuation: "-" [71:1 - 71:2] ObjCInstanceMethodDecl=foo::71:1 (Definition)
+// CHECK: Punctuation: "(" [71:3 - 71:4] ObjCInstanceMethodDecl=foo::71:1 (Definition)
+// CHECK: Keyword: "int" [71:4 - 71:7] ObjCInstanceMethodDecl=foo::71:1 (Definition)
+// CHECK: Punctuation: ")" [71:7 - 71:8] ObjCInstanceMethodDecl=foo::71:1 (Definition)
+// CHECK: Identifier: "foo" [71:9 - 71:12] ObjCInstanceMethodDecl=foo::71:1 (Definition)
+// CHECK: Punctuation: ":" [71:12 - 71:13] ObjCInstanceMethodDecl=foo::71:1 (Definition)
+// CHECK: Punctuation: "(" [71:13 - 71:14] ObjCInstanceMethodDecl=foo::71:1 (Definition)
+// CHECK: Keyword: "int" [71:14 - 71:17] ParmDecl=arg:71:18 (Definition)
+// CHECK: Punctuation: ")" [71:17 - 71:18] ParmDecl=arg:71:18 (Definition)
+// CHECK: Identifier: "arg" [71:18 - 71:21] ParmDecl=arg:71:18 (Definition)
+// CHECK: Punctuation: "{" [71:22 - 71:23] UnexposedStmt=
+// CHECK: Keyword: "return" [72:3 - 72:9] UnexposedStmt=
+// CHECK: Identifier: "arg" [72:10 - 72:13] DeclRefExpr=arg:71:18
+// CHECK: Punctuation: ";" [72:13 - 72:14] UnexposedStmt=
+// CHECK: Punctuation: "}" [73:1 - 73:2] UnexposedStmt=
+// CHECK: Punctuation: "-" [74:1 - 74:2] ObjCInstanceMethodDecl=method:74:1 (Definition)
+// CHECK: Punctuation: "(" [74:3 - 74:4] ObjCInstanceMethodDecl=method:74:1 (Definition)
+// CHECK: Keyword: "int" [74:4 - 74:7] ObjCInstanceMethodDecl=method:74:1 (Definition)
+// CHECK: Punctuation: ")" [74:7 - 74:8] ObjCInstanceMethodDecl=method:74:1 (Definition)
+// CHECK: Identifier: "method" [74:9 - 74:15] ObjCInstanceMethodDecl=method:74:1 (Definition)
+// CHECK: Punctuation: "{" [75:1 - 75:2] UnexposedStmt=
+// CHECK: Keyword: "int" [76:5 - 76:8] VarDecl=local:76:9 (Definition)
+// CHECK: Identifier: "local" [76:9 - 76:14] VarDecl=local:76:9 (Definition)
+// CHECK: Punctuation: "=" [76:15 - 76:16] VarDecl=local:76:9 (Definition)
+// CHECK: Punctuation: "[" [76:17 - 76:18] ObjCMessageExpr=foo::66:1
+// CHECK: Identifier: "self" [76:18 - 76:22] DeclRefExpr=self:0:0
+// CHECK: Identifier: "foo" [76:23 - 76:26] ObjCMessageExpr=foo::66:1
+// CHECK: Punctuation: ":" [76:26 - 76:27] ObjCMessageExpr=foo::66:1
+// CHECK: Identifier: "VAL" [76:27 - 76:30] macro instantiation=VAL:63:9
+// CHECK: Punctuation: "]" [76:30 - 76:31] ObjCMessageExpr=foo::66:1
+// CHECK: Punctuation: ";" [76:31 - 76:32] UnexposedStmt=
+// CHECK: Keyword: "int" [77:5 - 77:8] VarDecl=second:77:9 (Definition)
+// CHECK: Identifier: "second" [77:9 - 77:15] VarDecl=second:77:9 (Definition)
+// CHECK: Punctuation: "=" [77:16 - 77:17] VarDecl=second:77:9 (Definition)
+// CHECK: Punctuation: "[" [77:18 - 77:19] ObjCMessageExpr=foo::66:1
+// CHECK: Identifier: "self" [77:19 - 77:23] DeclRefExpr=self:0:0
+// CHECK: Identifier: "foo" [77:24 - 77:27] ObjCMessageExpr=foo::66:1
+// CHECK: Punctuation: ":" [77:27 - 77:28] ObjCMessageExpr=foo::66:1
+// CHECK: Literal: "0" [77:28 - 77:29] UnexposedExpr=
+// CHECK: Punctuation: "]" [77:29 - 77:30] ObjCMessageExpr=foo::66:1
+// CHECK: Punctuation: ";" [77:30 - 77:31] UnexposedStmt=
+// CHECK: Keyword: "return" [78:5 - 78:11] UnexposedStmt=
+// CHECK: Identifier: "local" [78:12 - 78:17] DeclRefExpr=local:76:9
+// CHECK: Punctuation: ";" [78:17 - 78:18] UnexposedStmt=
+// CHECK: Punctuation: "}" [79:1 - 79:2] UnexposedStmt=
+// CHECK: Punctuation: "@" [80:1 - 80:2] ObjCImplementationDecl=R7974151:70:1 (Definition)
+// CHECK: Keyword: "end" [80:2 - 80:5]
diff --git a/test/Index/blocks.c b/test/Index/blocks.c
new file mode 100644
index 0000000..08241cb
--- /dev/null
+++ b/test/Index/blocks.c
@@ -0,0 +1,29 @@
+// RUN: c-index-test -test-load-source local -fblocks %s | FileCheck %s
+
+typedef int int_t;
+struct foo { long x; };
+
+void test() {
+  static struct foo _foo;
+  ^ int_t(struct foo *foo) { return (int_t) foo->x; }(&_foo);
+}
+
+// TODO: expose the BlockExpr, CastExpr, and UnaryOperatorExpr here
+
+// CHECK: blocks.c:3:13: TypedefDecl=int_t:3:13 (Definition) Extent=[3:13 - 3:18]
+// CHECK: blocks.c:4:8: StructDecl=foo:4:8 (Definition) Extent=[4:1 - 4:23]
+// CHECK: blocks.c:4:19: FieldDecl=x:4:19 (Definition) Extent=[4:19 - 4:20]
+// CHECK: blocks.c:6:6: FunctionDecl=test:6:6 (Definition) Extent=[6:6 - 9:2]
+// CHECK: blocks.c:7:21: VarDecl=_foo:7:21 (Definition) Extent=[7:17 - 7:25]
+// CHECK: blocks.c:7:17: TypeRef=struct foo:4:8 Extent=[7:17 - 7:20]
+// CHECK: blocks.c:8:3: CallExpr= Extent=[8:3 - 8:61]
+// CHECK: blocks.c:8:3: UnexposedExpr= Extent=[8:3 - 8:54]
+// CHECK: blocks.c:8:5: TypeRef=int_t:3:13 Extent=[8:5 - 8:10]
+// CHECK: blocks.c:8:23: ParmDecl=foo:8:23 (Definition) Extent=[8:18 - 8:26]
+// CHECK: blocks.c:8:18: TypeRef=struct foo:4:8 Extent=[8:18 - 8:21]
+// CHECK: blocks.c:8:37: UnexposedExpr=x:4:19 Extent=[8:37 - 8:51]
+// CHECK: blocks.c:8:38: TypeRef=int_t:3:13 Extent=[8:38 - 8:43]
+// CHECK: blocks.c:8:50: MemberRefExpr=x:4:19 Extent=[8:45 - 8:51]
+// CHECK: blocks.c:8:45: DeclRefExpr=foo:8:23 Extent=[8:45 - 8:48]
+// CHECK: blocks.c:8:55: UnexposedExpr= Extent=[8:55 - 8:60]
+// CHECK: blocks.c:8:56: DeclRefExpr=_foo:7:21 Extent=[8:56 - 8:60]
diff --git a/test/Index/c-index-api-loadTU-test.m b/test/Index/c-index-api-loadTU-test.m
index 5b2f86e..5fe7cd6 100644
--- a/test/Index/c-index-api-loadTU-test.m
+++ b/test/Index/c-index-api-loadTU-test.m
@@ -6,7 +6,7 @@
   __attribute__((iboutlet)) id myoutlet;
 }
 - (void) __attribute__((ibaction)) myMessage:(id)msg;
-- foo;
+- foo __attribute__((deprecated));
 + fooC;
 
 @end
@@ -54,15 +54,31 @@
   main(someEnum, (const char **)bee);
 }
 
+// Test attribute traversal.
+#define IBOutlet __attribute__((iboutlet))
+#define IBOutletCollection(ClassName) __attribute__((iboutletcollection(ClassName)))
+#define IBAction void)__attribute__((ibaction)
+
+@interface TestAttributes {
+  IBOutlet char * anOutlet;
+  IBOutletCollection(id) id anOutletCollection;
+}
+- (IBAction) actionMethod:(id)arg;
+@end
+
+typedef struct X0 X1;
+struct X0;
+struct X0  {};
+
 // 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: <invalid loc>:0:0: attribute(iboutlet)=
 // 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: <invalid loc>:0:0: attribute(ibaction)=
 // 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:9:1: ObjCInstanceMethodDecl=foo:9:1 (deprecated) Extent=[9:1 - 9:35]
 // 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]
@@ -81,27 +97,29 @@
 // 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:38:4: ObjCClassRef=Foo:4:12 Extent=[38:4 - 38:7]
 // 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: <invalid loc>:0:0: UnexposedStmt= Extent=[46:42 - 55:2]
+// CHECK: <invalid loc>:0:0: 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: <invalid loc>:0:0: 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: <invalid loc>:0:0: 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:49:17: ObjCClassRef=Foo:4:12 Extent=[49:17 - 49:20]
+// CHECK: <invalid loc>:0:0: 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]
@@ -121,4 +139,19 @@
 // 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]
+// CHECK: c-index-api-loadTU-test.m:62:12: ObjCInterfaceDecl=TestAttributes:62:12 Extent=[62:1 - 67:5]
+// CHECK: c-index-api-loadTU-test.m:63:19: ObjCIvarDecl=anOutlet:63:19 (Definition) Extent=[63:19 - 63:27]
+// CHECK: <invalid loc>:0:0: attribute(iboutlet)=
+// CHECK: c-index-api-loadTU-test.m:64:29: ObjCIvarDecl=anOutletCollection:64:29 (Definition) Extent=[64:29 - 64:47]
+// CHECK: <invalid loc>:0:0: attribute(iboutletcollection)= [IBOutletCollection=ObjCObjectPointer]
+// CHECK: c-index-api-loadTU-test.m:64:26: TypeRef=id:0:0 Extent=[64:26 - 64:28]
+// CHECK: c-index-api-loadTU-test.m:66:1: ObjCInstanceMethodDecl=actionMethod::66:1 Extent=[66:1 - 66:35]
+// CHECK: <invalid loc>:0:0: attribute(ibaction)=
+// CHECK: c-index-api-loadTU-test.m:66:31: ParmDecl=arg:66:31 (Definition) Extent=[66:28 - 66:34]
+// CHECK: c-index-api-loadTU-test.m:66:28: TypeRef=id:0:0 Extent=[66:28 - 66:30]
+// CHECK: c-index-api-loadTU-test.m:69:16: StructDecl=X0:69:16 Extent=[69:9 - 69:18]
+// CHECK: c-index-api-loadTU-test.m:69:19: TypedefDecl=X1:69:19 (Definition) Extent=[69:19 - 69:21]
+// CHECK: c-index-api-loadTU-test.m:69:16: TypeRef=struct X0:71:8 Extent=[69:16 - 69:18]
+// CHECK: c-index-api-loadTU-test.m:70:8: StructDecl=X0:70:8 Extent=[70:1 - 70:10]
+// CHECK: c-index-api-loadTU-test.m:71:8: StructDecl=X0:71:8 (Definition) Extent=[71:1 - 71:14]
 
diff --git a/test/Index/cindex-from-source.m b/test/Index/cindex-from-source.m
index 86e794d..f226e45 100644
--- a/test/Index/cindex-from-source.m
+++ b/test/Index/cindex-from-source.m
@@ -7,3 +7,6 @@
 // CHECK: cindex-from-source.m:9:1: TypeRef=t0:1:13 Extent=[9:1 - 9:3]
 struct s0 {};
 t0 g0;
+
+// RUN: c-index-test -test-load-source-reparse 5 local %s -include %t.pfx.h > %t
+// RUN: FileCheck %s < %t
diff --git a/test/Index/code-complete-errors.c b/test/Index/code-complete-errors.c
index 29c2a86..01c298c 100644
--- a/test/Index/code-complete-errors.c
+++ b/test/Index/code-complete-errors.c
@@ -1,7 +1,7 @@
 _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
+  int x, y;; // CHECK: code-complete-errors.c:4:12: warning: extra ';' inside a struct
 }; // 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
diff --git a/test/Index/code-completion.cpp b/test/Index/code-completion.cpp
index 670b13f..354e746 100644
--- a/test/Index/code-completion.cpp
+++ b/test/Index/code-completion.cpp
@@ -15,9 +15,9 @@
   double member;
   operator int() const;
 };
-
+struct W { };
 struct Z get_Z();
-
+namespace N { }
 void test_Z() {
   // RUN: c-index-test -code-completion-at=%s:23:11 %s | FileCheck -check-prefix=CHECK-MEMBER %s
   get_Z().member = 17;
@@ -33,6 +33,10 @@
   overloaded(Z(), 0);
 }
 
+Z::operator int() const {
+  return 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}
@@ -52,3 +56,12 @@
 // 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 )}
+
+// RUN: c-index-test -code-completion-at=%s:37:10 %s | FileCheck -check-prefix=CHECK-EXPR %s
+// CHECK-EXPR: NotImplemented:{TypedText int} (65)
+// CHECK-EXPR: NotImplemented:{TypedText long} (65)
+// CHECK-EXPR: FieldDecl:{ResultType double}{TypedText member} (10)
+// CHECK-EXPR: FieldDecl:{ResultType int}{Text X::}{TypedText member} (5)
+// CHECK-EXPR: FieldDecl:{ResultType float}{Text Y::}{TypedText member} (11)
+// CHECK-EXPR: FunctionDecl:{ResultType void}{TypedText memfunc}{LeftParen (}{Optional {Placeholder int i}}{RightParen )} (22)
+// CHECK-EXPR: NotImplemented:{TypedText N}{Text ::} (75)
diff --git a/test/Index/complete-at-directives.m b/test/Index/complete-at-directives.m
index 811bca0..219d434 100644
--- a/test/Index/complete-at-directives.m
+++ b/test/Index/complete-at-directives.m
@@ -5,26 +5,26 @@
 @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}
+// RUN: c-index-test -code-completion-at=%s:2:2 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: {TypedText class}{HorizontalSpace  }{Placeholder name}
 // 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
+// RUN: c-index-test -code-completion-at=%s:3:2 -Xclang -code-completion-patterns %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
+// RUN: c-index-test -code-completion-at=%s:6:2 -Xclang -code-completion-patterns %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}
+// RUN: c-index-test -code-completion-at=%s:2:1 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: NotImplemented:{TypedText @class}{HorizontalSpace  }{Placeholder name}
 // 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}
@@ -34,24 +34,19 @@
 // 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
+// RUN: c-index-test -code-completion-at=%s:3:1 -Xclang -code-completion-patterns %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
+// RUN: c-index-test -code-completion-at=%s:2:23 -Xclang -code-completion-patterns %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
+// RUN: c-index-test -code-completion-at=%s:2:22 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC7 %s
 // CHECK-CC7: NotImplemented:{TypedText @package}
 // CHECK-CC7: NotImplemented:{TypedText @private}
 // CHECK-CC7: NotImplemented:{TypedText @protected}
diff --git a/test/Index/complete-at-exprstmt.m b/test/Index/complete-at-exprstmt.m
index 87e554f..cccfa26 100644
--- a/test/Index/complete-at-exprstmt.m
+++ b/test/Index/complete-at-exprstmt.m
@@ -9,18 +9,28 @@
   @synchronized (@encode(MyClass)) { }
 }
 @end
-// RUN: c-index-test -code-completion-at=%s:9:4 %s | FileCheck -check-prefix=CHECK-CC1 %s
+
+@interface A
++ (int)add:(int)x to:(int)y;
++ (int)add:(int)x to:(int)y plus:(int)z;
+@end
+
+void f() {
+  @selector(add:to:);
+}
+
+// RUN: c-index-test -code-completion-at=%s:9:4 -Xclang -code-completion-patterns %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
+// RUN: c-index-test -code-completion-at=%s:9:19 -Xclang -code-completion-patterns %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
+// RUN: c-index-test -code-completion-at=%s:9:3 -Xclang -code-completion-patterns %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 )}
@@ -35,3 +45,11 @@
 // CHECK-CC3: ObjCInterfaceDecl:{TypedText MyClass}
 // CHECK-CC3: TypedefDecl:{TypedText SEL}
 // CHECK-CC3: NotImplemented:{ResultType MyClass *}{TypedText self}
+// RUN: c-index-test -code-completion-at=%s:19:13 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: NotImplemented:{TypedText add:to:} (30)
+// CHECK-CC4: NotImplemented:{TypedText add:to:plus:} (30)
+// CHECK-CC4: NotImplemented:{TypedText myMethod:} (30)
+// RUN: c-index-test -code-completion-at=%s:19:17 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: NotImplemented:{Informative add:}{TypedText to:} (30)
+// CHECK-CC5: NotImplemented:{Informative add:}{TypedText to:plus:} (30)
+
diff --git a/test/Index/complete-blocks.m b/test/Index/complete-blocks.m
new file mode 100644
index 0000000..7233efb
--- /dev/null
+++ b/test/Index/complete-blocks.m
@@ -0,0 +1,24 @@
+// The line and column layout of this test is significant. Run lines
+// are at the end.
+typedef void (^block_t)(float f, double d);
+void f(int (^block)(int x, int y));
+void g(block_t b);
+
+void test_f() {
+
+}
+
+@interface A
+- method:(int (^)(int x, int y))b;
+- method2:(block_t)b;
+@end
+
+void test_A(A *a) {
+  [a method:0];
+}
+// RUN: c-index-test -code-completion-at=%s:8:1 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: FunctionDecl:{ResultType void}{TypedText f}{LeftParen (}{Placeholder int (^)(int x, int y)}{RightParen )} (45)
+// CHECK-CC1: FunctionDecl:{ResultType void}{TypedText g}{LeftParen (}{Placeholder void (^)(float f, double d)}{RightParen )} (45)
+// RUN: c-index-test -code-completion-at=%s:17:6 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType id}{TypedText method2:}{Placeholder void (^)(float f, double d)} (20)
+// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType id}{TypedText method:}{Placeholder int (^)(int x, int y)} (20)
diff --git a/test/Index/complete-declarators.cpp b/test/Index/complete-declarators.cpp
new file mode 100644
index 0000000..61d7765
--- /dev/null
+++ b/test/Index/complete-declarators.cpp
@@ -0,0 +1,39 @@
+// This test is line- and column-sensitive, so test commands are at the bottom.
+namespace N {
+  struct X {
+    int f(X);
+  };
+}
+
+int g(int a);
+
+struct Y { };
+
+struct Z {
+  int member;
+  friend int N::X::f(N::X);
+};
+
+// RUN: c-index-test -code-completion-at=%s:8:5 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: NotImplemented:{TypedText const} (30)
+// CHECK-CC1: NotImplemented:{TypedText N}{Text ::} (75)
+// CHECK-CC1: NotImplemented:{TypedText operator} (30)
+// CHECK-CC1: NotImplemented:{TypedText volatile} (30)
+// RUN: c-index-test -code-completion-at=%s:8:11 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: NotImplemented:{TypedText const} (30)
+// CHECK-CC2-NOT: NotImplemented:{TypedText N}{Text ::} (75)
+// CHECK-CC2-NOT: NotImplemented:{TypedText operator} (30)
+// CHECK-CC2: NotImplemented:{TypedText volatile} (30)
+// RUN: c-index-test -code-completion-at=%s:13:7 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: NotImplemented:{TypedText const} (30)
+// CHECK-CC3-NOT: NotImplemented:{TypedText N}{Text ::} (75)
+// CHECK-CC3: NotImplemented:{TypedText operator} (30)
+// CHECK-CC3: NotImplemented:{TypedText volatile} (30)
+// RUN: c-index-test -code-completion-at=%s:14:14 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: NotImplemented:{TypedText const} (30)
+// CHECK-CC4: NotImplemented:{TypedText N}{Text ::} (75)
+// CHECK-CC4: NotImplemented:{TypedText operator} (30)
+// CHECK-CC4: NotImplemented:{TypedText volatile} (30)
+// CHECK-CC4: StructDecl:{TypedText Y} (65)
+// CHECK-CC4: StructDecl:{TypedText Z} (20)
+
diff --git a/test/Index/complete-declarators.m b/test/Index/complete-declarators.m
new file mode 100644
index 0000000..3a69282
--- /dev/null
+++ b/test/Index/complete-declarators.m
@@ -0,0 +1,45 @@
+// This test is line- and column-sensitive, so test commands are at the bottom.
+@protocol P
+- (int)method:(id)param1;
+@end
+
+@interface A <P>
+- (int)method:(id)param1;
+
+@property int prop1;
+@end
+
+@implementation A
+- (int)method:(id)param1 {
+  int q2;
+  for(id q in param1) {
+    int y;
+  }
+  id q;
+  for(q in param1) {
+    int y;
+  }
+}
+@end
+
+// RUN: c-index-test -code-completion-at=%s:7:19 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1-NOT: NotImplemented:{TypedText extern} (30)
+// CHECK-CC1: NotImplemented:{TypedText param1} (30)
+// RUN: c-index-test -code-completion-at=%s:9:15 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: c-index-test -code-completion-at=%s:15:10 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: c-index-test -code-completion-at=%s:16:9 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: NotImplemented:{TypedText const} (30)
+// CHECK-CC2-NOT: int
+// CHECK-CC2: NotImplemented:{TypedText restrict} (30)
+// CHECK-CC2: NotImplemented:{TypedText volatile} (30)
+// RUN: c-index-test -code-completion-at=%s:15:15 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ParmDecl:{ResultType id}{TypedText param1} (8)
+// CHECK-CC3-NOT: VarDecl:{ResultType int}{TypedText q2} (8)
+// CHECK-CC3-NOT: VarDecl:{ResultType id}{TypedText q} (8)
+// CHECK-CC3: NotImplemented:{ResultType A *}{TypedText self} (8)
+// CHECK-CC3: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
+// RUN: c-index-test -code-completion-at=%s:15:15 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ParmDecl:{ResultType id}{TypedText param1} (8)
+// CHECK-CC4-NOT: VarDecl:{ResultType int}{TypedText q2} (8)
+// CHECK-CC4: NotImplemented:{ResultType A *}{TypedText self} (8)
+// CHECK-CC4: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
diff --git a/test/Index/complete-exprs.c b/test/Index/complete-exprs.c
index efc82f9..35fe404 100644
--- a/test/Index/complete-exprs.c
+++ b/test/Index/complete-exprs.c
@@ -1,15 +1,53 @@
 // Note: the run lines follow their respective tests, since line/column
 // matter in this test.
 
-int f(int);
+int f(int) __attribute__((unavailable));
 
 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
+struct X __attribute__((deprecated)) f1 = { 17 };
+void f2() { f1(17); }
+
+const char *str = "Hello, \nWorld";
+
+void f3(const char*, ...) __attribute__((sentinel(0)));
+
+#define NULL __null
+void f4(const char* str) {
+  f3(str, NULL);
+}
+// RUN: c-index-test -code-completion-at=%s:7:9 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:7:9 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: NotImplemented:{TypedText __PRETTY_FUNCTION__} (60)
+// CHECK-CC1: macro definition:{TypedText __VERSION__} (70)
+// CHECK-CC1: FunctionDecl:{ResultType int}{TypedText f}{LeftParen (}{Placeholder int}{RightParen )} (12) (unavailable)
+// CHECK-CC1-NOT: NotImplemented:{TypedText float} (65)
+// CHECK-CC1: ParmDecl:{ResultType int}{TypedText j} (2)
+// CHECK-CC1: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:7:9 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:7:14 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:7:14 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: macro definition:{TypedText __VERSION__} (70)
+// CHECK-CC3: FunctionDecl:{ResultType int}{TypedText f}{LeftParen (}{Placeholder int}{RightParen )} (50)
+// CHECK-CC3-NOT: NotImplemented:{TypedText float} (65)
+// CHECK-CC3: ParmDecl:{ResultType int}{TypedText j} (8)
+// CHECK-CC3: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expressio
+
+// RUN: c-index-test -code-completion-at=%s:7:18 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: c-index-test -code-completion-at=%s:7:22 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: c-index-test -code-completion-at=%s:7:2 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: macro definition:{TypedText __VERSION__} (70)
+// CHECK-CC2: FunctionDecl:{ResultType int}{TypedText f}{LeftParen (}{Placeholder int}{RightParen )} (50)
+// CHECK-CC2: NotImplemented:{TypedText float} (65)
+// CHECK-CC2: ParmDecl:{ResultType int}{TypedText j} (8)
+// CHECK-CC2: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
+// RUN: c-index-test -code-completion-at=%s:11:16 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: FunctionDecl:{ResultType int}{TypedText f}{LeftParen (}{Placeholder int}{RightParen )} (50)
+// CHECK-CC4: VarDecl:{ResultType struct X}{TypedText f1} (50) (deprecated)
+
+// RUN: c-index-test -code-completion-at=%s:19:3 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC6 %s
+// CHECK-CC6: FunctionDecl:{ResultType void}{TypedText f3}{LeftParen (}{Placeholder char const *}{Placeholder , ...}{Text , NULL}{RightParen )} (45)
+// CHECK-CC6: NotImplemented:{TypedText void} (65)
+// CHECK-CC6: NotImplemented:{TypedText volatile} (65)
diff --git a/test/Index/complete-hiding.c b/test/Index/complete-hiding.c
new file mode 100644
index 0000000..f2e1775
--- /dev/null
+++ b/test/Index/complete-hiding.c
@@ -0,0 +1,29 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+struct StructA { };
+struct StructB { };
+struct StructC { };
+int ValueA;
+int ValueB;
+
+void f() {
+
+  int ValueA = 0;
+  int StructA = 0;
+  struct StructB { };
+  
+  struct StructA sa = { };
+}
+
+// RUN: c-index-test -code-completion-at=%s:16:3 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:16:3 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: VarDecl:{ResultType int}{TypedText StructA} (8)
+// CHECK-CC1: VarDecl:{ResultType int}{TypedText ValueA} (8)
+// CHECK-CC1-NOT: VarDecl:{ResultType int}{TypedText ValueA} (50)
+// CHECK-CC1: VarDecl:{ResultType int}{TypedText ValueB} (50)
+// RUN: c-index-test -code-completion-at=%s:16:10 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: StructDecl:{TypedText StructA} (65)
+// CHECK-CC2-NOT: StructDecl:{TypedText StructB} (65)
+// CHECK-CC2: StructDecl:{TypedText StructC} (65)
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:16:10 %s | FileCheck -check-prefix=CHECK-CC2 %s
diff --git a/test/Index/complete-macros.c b/test/Index/complete-macros.c
index c33d8c0..26a63b1 100644
--- a/test/Index/complete-macros.c
+++ b/test/Index/complete-macros.c
@@ -2,10 +2,26 @@
 // matter in this test.
 
 #define FOO(Arg1,Arg2) foobar
-
+#define nil 0
 void f() {
 
 }
 
+void g(int);
+
+void f2() {
+  int *ip = nil;
+  ip = nil;
+  g(nil);
+}
+
 // RUN: c-index-test -code-completion-at=%s:7:1 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 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 )}
+// RUN: c-index-test -code-completion-at=%s:13:13 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: c-index-test -code-completion-at=%s:14:8 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:14:8 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: macro definition:{TypedText nil} (30)
+// RUN: c-index-test -code-completion-at=%s:15:5 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:15:5 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: macro definition:{TypedText nil} (60)
diff --git a/test/Index/complete-member-access.m b/test/Index/complete-member-access.m
index 2502d77..82efb95 100644
--- a/test/Index/complete-member-access.m
+++ b/test/Index/complete-member-access.m
@@ -26,5 +26,5 @@
 // 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}
+// CHECK-CC2: ObjCIvarDecl:{ResultType int}{TypedText IVar} (20)
+// CHECK-CC2: ObjCIvarDecl:{ResultType int}{TypedText SuperIVar} (22)
diff --git a/test/Index/complete-memfunc-cvquals.cpp b/test/Index/complete-memfunc-cvquals.cpp
new file mode 100644
index 0000000..6635bed
--- /dev/null
+++ b/test/Index/complete-memfunc-cvquals.cpp
@@ -0,0 +1,86 @@
+// The run lines are below, because this test is line- and
+// column-number sensitive.
+struct Foo {
+  void babble() const volatile;
+  void bar();
+  void baz() const;
+  void bingo() volatile;
+  void theend() const volatile;
+};
+
+template<typename T>
+struct smart_ptr {
+  T *operator->();
+  const T* operator->() const;
+};
+
+void text(Foo f, Foo *fp, const Foo &fc, const Foo *fcp,
+          smart_ptr<Foo> sf, const smart_ptr<Foo> &sfc, Foo volatile *fvp) {
+  f.bar();
+  fp->bar();
+  fc.baz();
+  fcp->baz();
+  sf->bar();
+  sfc->baz();
+  fvp->babble();
+}
+
+void Foo::bar() {
+  
+}
+
+void Foo::baz() const {
+
+}
+
+void Foo::bingo() volatile {
+
+}
+
+// Check member access expressions.
+// RUN: c-index-test -code-completion-at=%s:19:5 %s | FileCheck -check-prefix=CHECK-NOQUALS %s
+// RUN: c-index-test -code-completion-at=%s:20:7 %s | FileCheck -check-prefix=CHECK-NOQUALS %s
+// RUN: c-index-test -code-completion-at=%s:23:7 %s | FileCheck -check-prefix=CHECK-NOQUALS %s
+// CHECK-NOQUALS: FunctionDecl:{ResultType void}{TypedText babble}{LeftParen (}{RightParen )}{Informative  const volatile} (20)
+// CHECK-NOQUALS: FunctionDecl:{ResultType void}{TypedText bar}{LeftParen (}{RightParen )} (19)
+// CHECK-NOQUALS: FunctionDecl:{ResultType void}{TypedText baz}{LeftParen (}{RightParen )}{Informative  const} (20)
+// CHECK-NOQUALS: FunctionDecl:{ResultType void}{TypedText bingo}{LeftParen (}{RightParen )}{Informative  volatile} (20)
+// RUN: c-index-test -code-completion-at=%s:21:6 %s | FileCheck -check-prefix=CHECK-CONST %s
+// RUN: c-index-test -code-completion-at=%s:22:8 %s | FileCheck -check-prefix=CHECK-CONST %s
+// RUN: c-index-test -code-completion-at=%s:24:8 %s | FileCheck -check-prefix=CHECK-CONST %s
+// CHECK-CONST: FunctionDecl:{ResultType void}{TypedText babble}{LeftParen (}{RightParen )}{Informative  const volatile} (20)
+// CHECK-CONST-NOT: bar
+// CHECK-CONST: FunctionDecl:{ResultType void}{TypedText baz}{LeftParen (}{RightParen )}{Informative  const} (19)
+// CHECK-CONST-NOT: bingo
+// CHECK-CONST: theend
+// RUN: c-index-test -code-completion-at=%s:25:8 %s | FileCheck -check-prefix=CHECK-VOLATILE %s
+// CHECK-VOLATILE: FunctionDecl:{ResultType void}{TypedText babble}{LeftParen (}{RightParen )}{Informative  const volatile} (20)
+// CHECK-VOLATILE-NOT: baz
+// CHECK-VOLATILE: FunctionDecl:{ResultType void}{TypedText bingo}{LeftParen (}{RightParen )}{Informative  volatile} (19)
+
+// Check implicit member access expressions.
+// RUN: c-index-test -code-completion-at=%s:29:2 %s | FileCheck -check-prefix=CHECK-IMPLICIT-NOQUALS %s
+// CHECK-IMPLICIT-NOQUALS: FunctionDecl:{ResultType void}{TypedText babble}{LeftParen (}{RightParen )}{Informative  const volatile} (15)
+// CHECK-IMPLICIT-NOQUALS: FunctionDecl:{ResultType void}{TypedText bar}{LeftParen (}{RightParen )} (14)
+// CHECK-IMPLICIT-NOQUALS: FunctionDecl:{ResultType void}{TypedText baz}{LeftParen (}{RightParen )}{Informative  const} (15)
+// CHECK-IMPLICIT-NOQUALS: FunctionDecl:{ResultType void}{TypedText bingo}{LeftParen (}{RightParen )}{Informative  volatile} (15)
+
+// RUN: c-index-test -code-completion-at=%s:33:1 %s | FileCheck -check-prefix=CHECK-IMPLICIT-CONST %s
+// CHECK-IMPLICIT-CONST: FunctionDecl:{ResultType void}{TypedText babble}{LeftParen (}{RightParen )}{Informative  const volatile} (15)
+// CHECK-IMPLICIT-CONST-NOT: bar
+// CHECK-IMPLICIT-CONST: FunctionDecl:{ResultType void}{TypedText baz}{LeftParen (}{RightParen )}{Informative  const} (14)
+// CHECK-IMPLICIT-CONST-NOT: bingo
+// CHECK-IMPLICIT-CONST: theend
+
+// RUN: c-index-test -code-completion-at=%s:37:1 %s | FileCheck -check-prefix=CHECK-IMPLICIT-VOLATILE %s
+// CHECK-IMPLICIT-VOLATILE: FunctionDecl:{ResultType void}{TypedText babble}{LeftParen (}{RightParen )}{Informative  const volatile} (15)
+// CHECK-IMPLICIT-VOLATILE-NOT: baz
+// CHECK-IMPLICIT-VOLATILE: FunctionDecl:{ResultType void}{TypedText bingo}{LeftParen (}{RightParen )}{Informative  volatile} (14)
+
+// RUN: c-index-test -code-completion-at=%s:4:17 %s | FileCheck -check-prefix=CHECK-CVQUAL-AFTER %s
+// CHECK-CVQUAL-AFTER: NotImplemented:{TypedText const} (30)
+// CHECK-CVQUAL-AFTER: NotImplemented:{TypedText volatile} (30)
+
+// RUN: c-index-test -code-completion-at=%s:4:23 %s | FileCheck -check-prefix=CHECK-CVQUAL-AFTER2 %s
+// CHECK-CVQUAL-AFTER2-NOT: NotImplemented:{TypedText const} (30)
+// CHECK-CVQUAL-AFTER2: NotImplemented:{TypedText volatile} (30)
diff --git a/test/Index/complete-method-decls.m b/test/Index/complete-method-decls.m
index c18994e..1324ae4 100644
--- a/test/Index/complete-method-decls.m
+++ b/test/Index/complete-method-decls.m
@@ -42,41 +42,118 @@
 - (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 
+@interface C
+- (int)first:(int)x second:(float)y third:(double)z;
+- (id)first:(int)xx second2:(float)y2 third:(double)z;
+- (void*)first:(int)xxx second3:(float)y3 third:(double)z;
+@end
 
+@interface D
+- (int)first:(int)x second2:(float)y third:(double)z;
+@end
+
+@implementation D
+- (int)first:(int)x second2:(float)y third:(double)z { }
+@end
+
+@interface Passing
+- (oneway void)method:(in id x);
+@end
+
+// RUN: c-index-test -code-completion-at=%s:17:3 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText abc}
+// CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text int}{RightParen )}{TypedText getInt}
+// CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText getSelf}
+// CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText initWithInt}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}
+// CHECK-CC1: ObjCInstanceMethodDecl:{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: ObjCInstanceMethodDecl:{TypedText abc}
+// CHECK-CC2-NEXT: ObjCInstanceMethodDecl:{TypedText getSelf}
+// CHECK-CC2: ObjCInstanceMethodDecl:{TypedText initWithInt}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}
+// CHECK-CC2: ObjCInstanceMethodDecl:{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: ObjCInstanceMethodDecl:{TypedText abc}
+// CHECK-CC3-NEXT: ObjCInstanceMethodDecl:{TypedText getSelf}
+// CHECK-CC3: ObjCInstanceMethodDecl:{TypedText init}
+// CHECK-CC3: ObjCInstanceMethodDecl:{TypedText initWithInt}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}
+// CHECK-CC3: ObjCInstanceMethodDecl:{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 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText abc}{HorizontalSpace  }{LeftBrace {}{VerticalSpace  }{Text return}{HorizontalSpace  }{Placeholder expression}{SemiColon ;}{VerticalSpace  }{RightBrace }} (32)
+// CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text int}{RightParen )}{TypedText getInt}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text int}{RightParen )}{TypedText getSecondValue}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText getSelf}{HorizontalSpace  }{LeftBrace {}{VerticalSpace  }{Text return}{HorizontalSpace  }{Placeholder expression}{SemiColon ;}{VerticalSpace  }{RightBrace }} (30)
+// CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText initWithInt}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC4: ObjCInstanceMethodDecl:{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: ObjCInstanceMethodDecl:{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 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: ObjCInstanceMethodDecl:{TypedText getInt}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC5: ObjCInstanceMethodDecl:{TypedText getSecondValue}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC5-NOT: {TypedText getSelf}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// CHECK-CC5: ObjCInstanceMethodDecl:{TypedText setValue}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{LeftBrace {}{VerticalSpace
+// RUN: c-index-test -code-completion-at=%s:37:7 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC6 %s
+// CHECK-CC6: ObjCInstanceMethodDecl:{TypedText abc}{HorizontalSpace  }{LeftBrace {}{VerticalSpace 
+// CHECK-CC6-NOT: getSelf
+// CHECK-CC6: ObjCInstanceMethodDecl:{TypedText initWithInt}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{LeftBrace {}{VerticalSpace 
+// CHECK-CC6: ObjCInstanceMethodDecl:{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 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC7 %s
+// CHECK-CC7: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText categoryFunction}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{LeftBrace {}{VerticalSpace 
+// RUN: c-index-test -code-completion-at=%s:52:21 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC8 %s
+// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType id}{Informative first:}{TypedText second2:}{Text (float)y2}{HorizontalSpace  }{Text third:}{Text (double)z} (20)
+// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType void *}{Informative first:}{TypedText second3:}{Text (float)y3}{HorizontalSpace  }{Text third:}{Text (double)z} (20)
+// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative first:}{TypedText second:}{Text (float)y}{HorizontalSpace  }{Text third:}{Text (double)z} (5)
+// RUN: c-index-test -code-completion-at=%s:52:19 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC9 %s
+// CHECK-CC9: NotImplemented:{TypedText x} (30)
+// CHECK-CC9: NotImplemented:{TypedText xx} (30)
+// CHECK-CC9: NotImplemented:{TypedText xxx} (30)
+// RUN: c-index-test -code-completion-at=%s:52:36 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CCA %s
+// CHECK-CCA: NotImplemented:{TypedText y2} (30)
+// RUN: c-index-test -code-completion-at=%s:56:3 %s | FileCheck -check-prefix=CHECK-CCB %s
+// CHECK-CCB: ObjCInstanceMethodDecl:{LeftParen (}{Text int}{RightParen )}{TypedText first}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{Text second2}{Colon :}{LeftParen (}{Text float}{RightParen )}{Text y}{HorizontalSpace  }{Text third}{Colon :}{LeftParen (}{Text double}{RightParen )}{Text z} (30)
+// RUN: c-index-test -code-completion-at=%s:56:8 %s | FileCheck -check-prefix=CHECK-CCC %s
+// CHECK-CCC: ObjCInstanceMethodDecl:{TypedText first}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace  }{Text second2}{Colon :}{LeftParen (}{Text float}{RightParen )}{Text y}{HorizontalSpace  }{Text third}{Colon :}{LeftParen (}{Text double}{RightParen )}{Text z} (30)
+// RUN: c-index-test -code-completion-at=%s:56:21 %s | FileCheck -check-prefix=CHECK-CCD %s
+// FIXME: These results could be more precise.
+// CHECK-CCD: ObjCInstanceMethodDecl:{ResultType id}{Informative first:}{TypedText second2:}{Text (float)y2}{HorizontalSpace  }{Text third:}{Text (double)z} (20)
+// CHECK-CCD: ObjCInstanceMethodDecl:{ResultType int}{Informative first:}{TypedText second2:}{Text (float)y}{HorizontalSpace  }{Text third:}{Text (double)z} (5)
+// CHECK-CCD: ObjCInstanceMethodDecl:{ResultType void *}{Informative first:}{TypedText second3:}{Text (float)y3}{HorizontalSpace  }{Text third:}{Text (double)z} (20)
+// CHECK-CCD: ObjCInstanceMethodDecl:{ResultType int}{Informative first:}{TypedText second:}{Text (float)y}{HorizontalSpace  }{Text third:}{Text (double)z} (5)
+// RUN: c-index-test -code-completion-at=%s:56:38 %s | FileCheck -check-prefix=CHECK-CCE %s
+// CHECK-CCE: ObjCInstanceMethodDecl:{ResultType id}{Informative first:}{Informative second2:}{TypedText third:}{Text (double)z} (20)
+// CHECK-CCE: ObjCInstanceMethodDecl:{ResultType int}{Informative first:}{Informative second2:}{TypedText third:}{Text (double)z} (5)
+// RUN: c-index-test -code-completion-at=%s:60:4 %s | FileCheck -check-prefix=CHECK-CCF %s
+// CHECK-CCF: ObjCInterfaceDecl:{TypedText A} (65)
+// CHECK-CCF: ObjCInterfaceDecl:{TypedText B} (65)
+// CHECK-CCF: NotImplemented:{TypedText bycopy} (30)
+// CHECK-CCF: NotImplemented:{TypedText byref} (30)
+// CHECK-CCF: NotImplemented:{TypedText in} (30)
+// CHECK-CCF: NotImplemented:{TypedText inout} (30)
+// CHECK-CCF: NotImplemented:{TypedText oneway} (30)
+// CHECK-CCF: NotImplemented:{TypedText out} (30)
+// CHECK-CCF: NotImplemented:{TypedText unsigned} (65)
+// CHECK-CCF: NotImplemented:{TypedText void} (65)
+// CHECK-CCF: NotImplemented:{TypedText volatile} (65)
+// RUN: c-index-test -code-completion-at=%s:60:11 %s | FileCheck -check-prefix=CHECK-CCG %s
+// CHECK-CCG: ObjCInterfaceDecl:{TypedText A} (65)
+// CHECK-CCG: ObjCInterfaceDecl:{TypedText B} (65)
+// CHECK-CCG-NOT: NotImplemented:{TypedText bycopy} (30)
+// CHECK-CCG-NOT: NotImplemented:{TypedText byref} (30)
+// CHECK-CCG: NotImplemented:{TypedText in} (30)
+// CHECK-CCG: NotImplemented:{TypedText inout} (30)
+// CHECK-CCG-NOT: NotImplemented:{TypedText oneway} (30)
+// CHECK-CCG: NotImplemented:{TypedText out} (30)
+// CHECK-CCG: NotImplemented:{TypedText unsigned} (65)
+// CHECK-CCG: NotImplemented:{TypedText void} (65)
+// CHECK-CCG: NotImplemented:{TypedText volatile} (65)
+// RUN: c-index-test -code-completion-at=%s:60:24 %s | FileCheck -check-prefix=CHECK-CCF %s
+// RUN: c-index-test -code-completion-at=%s:60:26 %s | FileCheck -check-prefix=CHECK-CCH %s
+// CHECK-CCH: ObjCInterfaceDecl:{TypedText A} (65)
+// CHECK-CCH: ObjCInterfaceDecl:{TypedText B} (65)
+// CHECK-CCH: NotImplemented:{TypedText bycopy} (30)
+// CHECK-CCH: NotImplemented:{TypedText byref} (30)
+// CHECK-CCH-NOT: NotImplemented:{TypedText in} (30)
+// CHECK-CCH: NotImplemented:{TypedText inout} (30)
+// CHECK-CCH: NotImplemented:{TypedText oneway} (30)
+// CHECK-CCH: NotImplemented:{TypedText out} (30)
+// CHECK-CCH: NotImplemented:{TypedText unsigned} (65)
+// CHECK-CCH: NotImplemented:{TypedText void} (65)
+// CHECK-CCH: NotImplemented:{TypedText volatile} (65)
diff --git a/test/Index/complete-natural.m b/test/Index/complete-natural.m
new file mode 100644
index 0000000..e1aba39
--- /dev/null
+++ b/test/Index/complete-natural.m
@@ -0,0 +1,56 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+const char *in_string = "string";
+char in_char = 'a';
+// in comment
+/* in comment */
+#warning blarg
+#error blarg
+#pragma mark this is the spot
+// RUN: c-index-test -code-completion-at=%s:4:32 %s > %t
+// RUN: echo "DONE" >> %t
+// RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
+// CHECK-CC1-NOT: :
+// CHECK-CC1: DONE
+// RUN: c-index-test -code-completion-at=%s:5:18 %s > %t
+// RUN: echo "DONE" >> %t
+// RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
+// RUN: c-index-test -code-completion-at=%s:6:7 %s > %t
+// RUN: echo "DONE" >> %t
+// RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
+// RUN: c-index-test -code-completion-at=%s:7:7 %s > %t
+// RUN: echo "DONE" >> %t
+// RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
+// RUN: c-index-test -code-completion-at=%s:8:10 %s > %t
+// RUN: echo "DONE" >> %t
+// RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
+// RUN: c-index-test -code-completion-at=%s:9:9 %s > %t
+// RUN: echo "DONE" >> %t
+// RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
+// RUN: c-index-test -code-completion-at=%s:10:19 %s > %t
+// RUN: echo "DONE" >> %t
+// RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
+
+// Same tests as above, but with completion caching.
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:4:32 %s > %t
+// RUN: echo "DONE" >> %t
+// RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:5:18 %s > %t
+// RUN: echo "DONE" >> %t
+// RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:6:7 %s > %t
+// RUN: echo "DONE" >> %t
+// RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:7:7 %s > %t
+// RUN: echo "DONE" >> %t
+// RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:8:10 %s > %t
+// RUN: echo "DONE" >> %t
+// RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:9:9 %s > %t
+// RUN: echo "DONE" >> %t
+// RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:10:19 %s > %t
+// RUN: echo "DONE" >> %t
+// RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
diff --git a/test/Index/complete-objc-message-id.m b/test/Index/complete-objc-message-id.m
index a75ee4a..be42b9b 100644
--- a/test/Index/complete-objc-message-id.m
+++ b/test/Index/complete-objc-message-id.m
@@ -26,6 +26,11 @@
   [[b superclass] B_method];
 }
 
+@implementation Unrelated
++ (id)alloc {
+  return [A alloc];
+}
+@end
 // 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
@@ -40,3 +45,10 @@
 // CHECK-CC3: ObjCInstanceMethodDecl:{ResultType id}{TypedText retain}
 
 
+// RUN: c-index-test -code-completion-at=%s:31:13 %s | FileCheck -check-prefix=CHECK-SELECTOR-PREF %s
+// CHECK-SELECTOR-PREF: ObjCClassMethodDecl:{ResultType id}{TypedText alloc} (17)
+// CHECK-SELECTOR-PREF: ObjCClassMethodDecl:{ResultType Class}{TypedText class} (20)
+// CHECK-SELECTOR-PREF: ObjCClassMethodDecl:{ResultType id}{TypedText init} (20)
+// CHECK-SELECTOR-PREF: ObjCClassMethodDecl:{ResultType id}{TypedText new} (20)
+// CHECK-SELECTOR-PREF: ObjCClassMethodDecl:{ResultType Class}{TypedText superclass} (20)
+
diff --git a/test/Index/complete-objc-message.m b/test/Index/complete-objc-message.m
index e65a056..231e1d9 100644
--- a/test/Index/complete-objc-message.m
+++ b/test/Index/complete-objc-message.m
@@ -1,6 +1,6 @@
 // Note: the run lines follow their respective tests, since line/column
 // matter in this test.
-
+#define nil (void*)0
 @protocol FooTestProtocol
 + protocolClassMethod;
 - protocolInstanceMethod : (int)value;
@@ -51,7 +51,7 @@
   return 3;
 }
 @end
-
+MyClass *getMyClass();
 @implementation MySubClass
 + (int)MySubClassMethod {
   return 2;
@@ -96,9 +96,9 @@
 }
 
 @interface Ellipsis
-- (int)Method:(int)i, ...;
+- (int)Method:(int)i, ...; 
+- (int)SentinelMethod:(int)i, ... __attribute__((sentinel(0,1)));
 @end
-
 void f(Ellipsis *e) {
   [e Method:1, 2, 3];
 }
@@ -122,6 +122,18 @@
   [id Method:1 Arg1:1 OtherArg:ovl];
 }
 
+@interface A
+- (void)method1;
+@end 
+
+@interface B : A
+- (void)method2;
+@end
+
+void test_ranking(B *b) {
+  [b method1];
+}
+
 // 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}
@@ -160,18 +172,18 @@
 // 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-NEXT: ObjCInterfaceDecl:{TypedText Foo}
+// CHECK-CCA-NOT: FunctionDecl:{ResultType void}{TypedText func}{LeftParen (}{RightParen )}
+// CHECK-CCA:FunctionDecl:{ResultType MyClass *}{TypedText getMyClass}{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 , ...}
+// CHECK-CCB: ObjCInstanceMethodDecl:{ResultType int}{TypedText SentinelMethod:}{Placeholder (int)i}{Placeholder , ...}{Text , nil}
 // 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}
@@ -188,29 +200,21 @@
 // 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-NOT: 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
@@ -220,9 +224,6 @@
 // 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}
@@ -230,4 +231,6 @@
 // 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}
-
+// RUN: c-index-test -code-completion-at=%s:134:6 %s | FileCheck -check-prefix=CHECK-CCI %s
+// CHECK-CCI: ObjCInstanceMethodDecl:{ResultType void}{TypedText method1} (22)
+// CHECK-CCI: ObjCInstanceMethodDecl:{ResultType void}{TypedText method2} (20)
diff --git a/test/Index/complete-preprocessor.m b/test/Index/complete-preprocessor.m
new file mode 100644
index 0000000..1873dad
--- /dev/null
+++ b/test/Index/complete-preprocessor.m
@@ -0,0 +1,80 @@
+// The line and column layout of this test is significant. Run lines
+// are at the end.
+
+#if 1
+#endif
+
+#define FOO(a, b) a##b
+#define BAR
+#ifdef FOO
+#endif
+#if defined(FOO)
+#endif
+
+FOO(in,t) value;
+
+// RUN: c-index-test -code-completion-at=%s:4:2 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: NotImplemented:{TypedText define}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText define}{HorizontalSpace  }{Placeholder macro}{LeftParen (}{Placeholder args}{RightParen )} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText error}{HorizontalSpace  }{Placeholder message} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText if}{HorizontalSpace  }{Placeholder condition} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText ifdef}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText ifndef}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText import}{HorizontalSpace  }{Text "}{Placeholder header}{Text "} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText import}{HorizontalSpace  }{Text <}{Placeholder header}{Text >} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText include}{HorizontalSpace  }{Text "}{Placeholder header}{Text "} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText include}{HorizontalSpace  }{Text <}{Placeholder header}{Text >} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText include_next}{HorizontalSpace  }{Text "}{Placeholder header}{Text "} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText include_next}{HorizontalSpace  }{Text <}{Placeholder header}{Text >} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText line}{HorizontalSpace  }{Placeholder number} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText line}{HorizontalSpace  }{Placeholder number}{HorizontalSpace  }{Text "}{Placeholder filename}{Text "} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText pragma}{HorizontalSpace  }{Placeholder arguments} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText undef}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC1-NEXT: NotImplemented:{TypedText warning}{HorizontalSpace  }{Placeholder message} (30)
+// RUN: c-index-test -code-completion-at=%s:5:2 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: NotImplemented:{TypedText define}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText define}{HorizontalSpace  }{Placeholder macro}{LeftParen (}{Placeholder args}{RightParen )} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText elif}{HorizontalSpace  }{Placeholder condition} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText else} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText endif} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText error}{HorizontalSpace  }{Placeholder message} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText if}{HorizontalSpace  }{Placeholder condition} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText ifdef}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText ifndef}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText import}{HorizontalSpace  }{Text "}{Placeholder header}{Text "} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText import}{HorizontalSpace  }{Text <}{Placeholder header}{Text >} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText include}{HorizontalSpace  }{Text "}{Placeholder header}{Text "} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText include}{HorizontalSpace  }{Text <}{Placeholder header}{Text >} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText include_next}{HorizontalSpace  }{Text "}{Placeholder header}{Text "} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText include_next}{HorizontalSpace  }{Text <}{Placeholder header}{Text >} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText line}{HorizontalSpace  }{Placeholder number} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText line}{HorizontalSpace  }{Placeholder number}{HorizontalSpace  }{Text "}{Placeholder filename}{Text "} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText pragma}{HorizontalSpace  }{Placeholder arguments} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText undef}{HorizontalSpace  }{Placeholder macro} (30)
+// CHECK-CC2-NEXT: NotImplemented:{TypedText warning}{HorizontalSpace  }{Placeholder message} (30)
+// RUN: c-index-test -code-completion-at=%s:9:8 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: NotImplemented:{TypedText BAR} (30)
+// CHECK-CC3: NotImplemented:{TypedText FOO} (30)
+// RUN: c-index-test -code-completion-at=%s:11:12 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: c-index-test -code-completion-at=%s:11:13 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: c-index-test -code-completion-at=%s:11:5 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: macro definition:{TypedText BAR} (70)
+// CHECK-CC4: macro definition:{TypedText FOO}{LeftParen (}{Placeholder a}{Comma , }{Placeholder b}{RightParen )} (70)
+// RUN: c-index-test -code-completion-at=%s:14:5 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: NotImplemented:{TypedText const} (65)
+// CHECK-CC5: NotImplemented:{TypedText double} (65)
+// CHECK-CC5: NotImplemented:{TypedText enum} (65)
+// CHECK-CC5: NotImplemented:{TypedText extern} (30)
+// CHECK-CC5: NotImplemented:{TypedText float} (65)
+// CHECK-CC5: macro definition:{TypedText FOO}{LeftParen (}{Placeholder a}{Comma , }{Placeholder b}{RightParen )} (70)
+// CHECK-CC5: TypedefDecl:{TypedText id} (65)
+// CHECK-CC5: NotImplemented:{TypedText inline} (30)
+// CHECK-CC5: NotImplemented:{TypedText int} (65)
+// CHECK-CC5: NotImplemented:{TypedText long} (65)
+
+// Same tests as above, but with completion caching.
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:4:2 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:5:2 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:9:8 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:11:5 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:14:5 %s | FileCheck -check-prefix=CHECK-CC5 %s
diff --git a/test/Index/complete-recovery.m b/test/Index/complete-recovery.m
new file mode 100644
index 0000000..e03834e
--- /dev/null
+++ b/test/Index/complete-recovery.m
@@ -0,0 +1,25 @@
+/* Run lines are at the end, since line/column matter in this test. */
+
+@interface A
+- (void)method:(int)x;
+@end
+
+@implementation A
+- (void)method:(int)x {
+  A *a = [A method:1];
+  blarg * blah = wibble
+}
+@end
+
+// RUN: c-index-test -code-completion-at=%s:9:20 -Xclang -code-completion-patterns %s 2>%t | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: not grep error %t
+// CHECK-CC1: NotImplemented:{TypedText @encode}{LeftParen (}{Placeholder type-name}{RightParen )}
+// CHECK-CC1-NOT: NotImplemented:{TypedText _Bool}
+// CHECK-CC1: VarDecl:{ResultType A *}{TypedText a}
+// CHECK-CC1: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )}
+
+// RUN: c-index-test -code-completion-at=%s:10:24 -Xclang -code-completion-patterns %s 2>%t | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: NotImplemented:{TypedText @encode}{LeftParen (}{Placeholder type-name}{RightParen )}
+// CHECK-CC2: NotImplemented:{TypedText _Bool}
+// CHECK-CC2: VarDecl:{ResultType A *}{TypedText a}
+// CHECK-CC2: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )}
diff --git a/test/Index/complete-super.cpp b/test/Index/complete-super.cpp
new file mode 100644
index 0000000..a10cafc
--- /dev/null
+++ b/test/Index/complete-super.cpp
@@ -0,0 +1,33 @@
+// The run lines are below, because this test is line- and
+// column-number sensitive.
+
+struct A {
+  virtual void foo(int x, int y);
+  virtual void bar(double x);
+  virtual void bar(float x);
+};
+
+struct B : A {
+  void foo(int a, int b);
+  void bar(float real);
+};
+
+void B::foo(int a, int b) {
+  A::foo(a, b);
+}
+
+void B::bar(float real) {
+  A::bar(real);
+}
+
+// RUN: c-index-test -code-completion-at=%s:16:3 %s | FileCheck -check-prefix=CHECK-FOO-UNQUAL %s
+// CHECK-FOO-UNQUAL: CXXMethod:{Text A::}{TypedText foo}{LeftParen (}{Placeholder a}{Comma , }{Placeholder b}{RightParen )} (8)
+
+// RUN: c-index-test -code-completion-at=%s:20:3 %s | FileCheck -check-prefix=CHECK-BAR-UNQUAL %s
+// CHECK-BAR-UNQUAL: CXXMethod:{Text A::}{TypedText bar}{LeftParen (}{Placeholder real}{RightParen )} (8)
+// CHECK-BAR-UNQUAL: FunctionDecl:{ResultType void}{TypedText bar}{LeftParen (}{Placeholder float real}{RightParen )} (14)
+// CHECK-BAR-UNQUAL: FunctionDecl:{ResultType void}{Text A::}{TypedText bar}{LeftParen (}{Placeholder double x}{RightParen )} (16)
+
+// RUN: c-index-test -code-completion-at=%s:16:6 %s | FileCheck -check-prefix=CHECK-FOO-QUAL %s
+// CHECK-FOO-QUAL: CXXMethod:{TypedText foo}{LeftParen (}{Placeholder a}{Comma , }{Placeholder b}{RightParen )} (8)
+
diff --git a/test/Index/complete-super.m b/test/Index/complete-super.m
new file mode 100644
index 0000000..fc60c6c
--- /dev/null
+++ b/test/Index/complete-super.m
@@ -0,0 +1,55 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+typedef int Bool;
+
+@interface A
+- (void)add:(int)x to:(int)y;
++ (void)select:(Bool)condition first:(int)x second:(int)y;
+- (void)last;
++ (void)last;
+@end
+
+@interface B : A
+- (void)add:(int)x to:(int)y;
++ (void)select:(Bool)condition first:(int)x second:(int)y;
+@end
+
+@implementation B
+- (void)add:(int)a to:(int)b {
+  [super add:a to:b];
+}
+
++ (void)select:(Bool)condition first:(int)a second:(int)b {
+  [super selector:condition first:a second:b];
+}
+@end
+
+// Check "super" completion as a message receiver.
+// RUN: c-index-test -code-completion-at=%s:20:4 %s | FileCheck -check-prefix=CHECK-ADD-RECEIVER %s
+// CHECK-ADD-RECEIVER: ObjCInstanceMethodDecl:{ResultType void}{TypedText super}{HorizontalSpace  }{Text add:}{Placeholder a}{HorizontalSpace  }{Text to:}{Placeholder b} (8)
+
+// RUN: c-index-test -code-completion-at=%s:24:4 %s | FileCheck -check-prefix=CHECK-SELECT-RECEIVER %s
+// CHECK-SELECT-RECEIVER: ObjCClassMethodDecl:{ResultType void}{TypedText super}{HorizontalSpace  }{Text select:}{Placeholder condition}{HorizontalSpace  }{Text first:}{Placeholder a}{HorizontalSpace  }{Text second:}{Placeholder b} (8)
+
+// Check "super" completion at the first identifier
+// RUN: c-index-test -code-completion-at=%s:20:10 %s | FileCheck -check-prefix=CHECK-ADD-ADD %s
+// CHECK-ADD-ADD: ObjCInstanceMethodDecl:{ResultType void}{TypedText add:}{Placeholder a}{HorizontalSpace  }{Text to:}{Placeholder b} (8)
+// CHECK-ADD-ADD-NOT: add
+// CHECK-ADD-ADD: ObjCInstanceMethodDecl:{ResultType void}{TypedText last} (20)
+
+// RUN: c-index-test -code-completion-at=%s:24:10 %s | FileCheck -check-prefix=CHECK-SELECTOR-SELECTOR %s
+// CHECK-SELECTOR-SELECTOR-NOT: x
+// CHECK-SELECTOR-SELECTOR: ObjCClassMethodDecl:{ResultType void}{TypedText last} (20)
+// CHECK-SELECTOR-SELECTOR: ObjCClassMethodDecl:{ResultType void}{TypedText select:}{Placeholder condition}{HorizontalSpace  }{Text first:}{Placeholder a}{HorizontalSpace  }{Text second:}{Placeholder b} (8)
+
+// Check "super" completion at the second identifier
+// RUN: c-index-test -code-completion-at=%s:20:16 %s | FileCheck -check-prefix=CHECK-ADD-TO %s
+// CHECK-ADD-TO: ObjCInstanceMethodDecl:{ResultType void}{Informative add:}{TypedText to:}{Placeholder b} (8)
+
+// RUN: c-index-test -code-completion-at=%s:24:28 %s | FileCheck -check-prefix=CHECK-SELECTOR-FIRST %s
+// CHECK-SELECTOR-FIRST: ObjCClassMethodDecl:{ResultType void}{Informative select:}{TypedText first:}{Placeholder a}{HorizontalSpace  }{Text second:}{Placeholder b} (8)
+
+// Check "super" completion at the third identifier
+// RUN: c-index-test -code-completion-at=%s:24:37 %s | FileCheck -check-prefix=CHECK-SELECTOR-SECOND %s
+// CHECK-SELECTOR-SECOND: ObjCClassMethodDecl:{ResultType void}{Informative select:}{Informative first:}{TypedText second:}{Placeholder b} (8)
diff --git a/test/Index/complete-type-factors.m b/test/Index/complete-type-factors.m
new file mode 100644
index 0000000..2048cd3
--- /dev/null
+++ b/test/Index/complete-type-factors.m
@@ -0,0 +1,107 @@
+/* Run lines are at the end, since line/column matter in this test. */
+
+enum Color {
+  Red, Green, Blue
+};
+
+enum Priority {
+  Low,
+  High
+};
+
+int func1(enum Color);
+enum Priority func2(int);
+void func3(float);
+enum Priority test1(enum Priority priority, enum Color color, int integer) {
+  int i = integer;
+  enum Color c = color;
+  return priority;
+  func1(c);
+  void (^block)(enum Color, int);
+  block(c, 17);
+  c = color;
+}
+
+// FIXME: It would be great for message sends to have the same
+// benefits as function calls, but we don't quite have the
+// infrastructure yet.
+
+// RUN: c-index-test -code-completion-at=%s:16:11 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: EnumConstantDecl:{ResultType enum Color}{TypedText Blue} (30)
+// CHECK-CC1: ParmDecl:{ResultType enum Color}{TypedText color} (4)
+// CHECK-CC1: FunctionDecl:{ResultType int}{TypedText func1}{LeftParen (}{Placeholder enum Color}{RightParen )} (12)
+// CHECK-CC1: FunctionDecl:{ResultType enum Priority}{TypedText func2}{LeftParen (}{Placeholder int}{RightParen )} (25)
+// CHECK-CC1: EnumConstantDecl:{ResultType enum Color}{TypedText Green} (30)
+// CHECK-CC1: EnumConstantDecl:{ResultType enum Priority}{TypedText High} (30)
+// CHECK-CC1: VarDecl:{ResultType int}{TypedText i} (2)
+// CHECK-CC1: ParmDecl:{ResultType int}{TypedText integer} (2)
+// CHECK-CC1: EnumConstantDecl:{ResultType enum Priority}{TypedText Low} (30)
+// CHECK-CC1: ParmDecl:{ResultType enum Priority}{TypedText priority} (4)
+// CHECK-CC1: EnumConstantDecl:{ResultType enum Color}{TypedText Red} (30)
+// CHECK-CC1: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
+// CHECK-CC1: FunctionDecl:{ResultType enum Priority}{TypedText test1}{LeftParen (}{Placeholder enum Priority priority}{Comma , }{Placeholder enum Color color}{Comma , }{Placeholder int integer}{RightParen )} (25)
+// RUN: c-index-test -code-completion-at=%s:17:18 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: EnumConstantDecl:{ResultType enum Color}{TypedText Blue} (15)
+// CHECK-CC2: VarDecl:{ResultType enum Color}{TypedText c} (2)
+// CHECK-CC2: ParmDecl:{ResultType enum Color}{TypedText color} (2)
+// CHECK-CC2: FunctionDecl:{ResultType int}{TypedText func1}{LeftParen (}{Placeholder enum Color}{RightParen )} (25)
+// CHECK-CC2: FunctionDecl:{ResultType enum Priority}{TypedText func2}{LeftParen (}{Placeholder int}{RightParen )} (50)
+// CHECK-CC2: EnumConstantDecl:{ResultType enum Color}{TypedText Green} (15)
+// CHECK-CC2: EnumConstantDecl:{ResultType enum Priority}{TypedText High} (60)
+// CHECK-CC2: VarDecl:{ResultType int}{TypedText i} (4)
+// CHECK-CC2: ParmDecl:{ResultType int}{TypedText integer} (4)
+// CHECK-CC2: EnumConstantDecl:{ResultType enum Priority}{TypedText Low} (60)
+// CHECK-CC2: ParmDecl:{ResultType enum Priority}{TypedText priority} (8)
+// CHECK-CC2: EnumConstantDecl:{ResultType enum Color}{TypedText Red} (15)
+// CHECK-CC2: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
+// CHECK-CC2: FunctionDecl:{ResultType enum Priority}{TypedText test1}{LeftParen (}{Placeholder enum Priority priority}{Comma , }{Placeholder enum Color color}{Comma , }{Placeholder int integer}{RightParen )} (50)
+// RUN: c-index-test -code-completion-at=%s:18:10 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: EnumConstantDecl:{ResultType enum Color}{TypedText Blue} (60)
+// CHECK-CC3: VarDecl:{ResultType enum Color}{TypedText c} (8)
+// CHECK-CC3: ParmDecl:{ResultType enum Color}{TypedText color} (8)
+// CHECK-CC3: FunctionDecl:{ResultType int}{TypedText func1}{LeftParen (}{Placeholder enum Color}{RightParen )} (25)
+// CHECK-CC3: FunctionDecl:{ResultType enum Priority}{TypedText func2}{LeftParen (}{Placeholder int}{RightParen )} (12)
+// CHECK-CC3: FunctionDecl:{ResultType void}{TypedText func3}{LeftParen (}{Placeholder float}{RightParen )} (50)
+// CHECK-CC3: EnumConstantDecl:{ResultType enum Color}{TypedText Green} (60)
+// CHECK-CC3: EnumConstantDecl:{ResultType enum Priority}{TypedText High} (15)
+// CHECK-CC3: VarDecl:{ResultType int}{TypedText i} (4)
+// CHECK-CC3: ParmDecl:{ResultType int}{TypedText integer} (4)
+// CHECK-CC3: EnumConstantDecl:{ResultType enum Priority}{TypedText Low} (15)
+// CHECK-CC3: ParmDecl:{ResultType enum Priority}{TypedText priority} (2)
+// CHECK-CC3: EnumConstantDecl:{ResultType enum Color}{TypedText Red} (60)
+// CHECK-CC3: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
+// CHECK-CC3: FunctionDecl:{ResultType enum Priority}{TypedText test1}{LeftParen (}{Placeholder enum Priority priority}{Comma , }{Placeholder enum Color color}{Comma , }{Placeholder int integer}{RightParen )} (12)
+// RUN: c-index-test -code-completion-at=%s:19:9 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: EnumConstantDecl:{ResultType enum Color}{TypedText Blue} (15)
+// CHECK-CC4: VarDecl:{ResultType enum Color}{TypedText c} (2)
+// CHECK-CC4: ParmDecl:{ResultType enum Color}{TypedText color} (2)
+// CHECK-CC4: FunctionDecl:{ResultType int}{TypedText func1}{LeftParen (}{Placeholder enum Color}{RightParen )} (25)
+// CHECK-CC4: FunctionDecl:{ResultType enum Priority}{TypedText func2}{LeftParen (}{Placeholder int}{RightParen )} (50)
+// CHECK-CC4: FunctionDecl:{ResultType void}{TypedText func3}{LeftParen (}{Placeholder float}{RightParen )} (50)
+// CHECK-CC4: EnumConstantDecl:{ResultType enum Color}{TypedText Green} (15)
+// CHECK-CC4: EnumConstantDecl:{ResultType enum Priority}{TypedText High} (60)
+// CHECK-CC4: VarDecl:{ResultType int}{TypedText i} (4)
+// CHECK-CC4: ParmDecl:{ResultType int}{TypedText integer} (4)
+// CHECK-CC4: EnumConstantDecl:{ResultType enum Priority}{TypedText Low} (60)
+// CHECK-CC4: ParmDecl:{ResultType enum Priority}{TypedText priority} (8)
+// CHECK-CC4: EnumConstantDecl:{ResultType enum Color}{TypedText Red} (15)
+// CHECK-CC4: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
+// CHECK-CC4: FunctionDecl:{ResultType enum Priority}{TypedText test1}{LeftParen (}{Placeholder enum Priority priority}{Comma , }{Placeholder enum Color color}{Comma , }{Placeholder int integer}{RightParen )} (50)
+// RUN: c-index-test -code-completion-at=%s:21:9 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC4 %s
+// RUN: c-index-test -code-completion-at=%s:22:7 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC6 %s
+// CHECK-CC6: VarDecl:{ResultType void (^)(enum Color, int)}{TypedText block} (8)
+// CHECK-CC6: EnumConstantDecl:{ResultType enum Color}{TypedText Blue} (15)
+// CHECK-CC6: VarDecl:{ResultType enum Color}{TypedText c} (2)
+// CHECK-CC6: ParmDecl:{ResultType enum Color}{TypedText color} (2)
+// CHECK-CC6: FunctionDecl:{ResultType int}{TypedText func1}{LeftParen (}{Placeholder enum Color}{RightParen )} (25)
+// CHECK-CC6: FunctionDecl:{ResultType enum Priority}{TypedText func2}{LeftParen (}{Placeholder int}{RightParen )} (50)
+// CHECK-CC6: FunctionDecl:{ResultType void}{TypedText func3}{LeftParen (}{Placeholder float}{RightParen )} (50)
+// CHECK-CC6: EnumConstantDecl:{ResultType enum Color}{TypedText Green} (15)
+// CHECK-CC6: EnumConstantDecl:{ResultType enum Priority}{TypedText High} (60)
+// CHECK-CC6: VarDecl:{ResultType int}{TypedText i} (4)
+// CHECK-CC6: ParmDecl:{ResultType int}{TypedText integer} (4)
+// CHECK-CC6: EnumConstantDecl:{ResultType enum Priority}{TypedText Low} (60)
+// CHECK-CC6: ParmDecl:{ResultType enum Priority}{TypedText priority} (8)
+// CHECK-CC6: EnumConstantDecl:{ResultType enum Color}{TypedText Red} (15)
+// CHECK-CC6: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
+// CHECK-CC6: FunctionDecl:{ResultType enum Priority}{TypedText test1}{LeftParen (}{Placeholder enum Priority priority}{Comma , }{Placeholder enum Color color}{Comma , }{Placeholder int integer}{RightParen )} (50)
diff --git a/test/Index/complete-unterminated.c b/test/Index/complete-unterminated.c
new file mode 100644
index 0000000..56e6ae1
--- /dev/null
+++ b/test/Index/complete-unterminated.c
@@ -0,0 +1,30 @@
+typedef int Integer;
+
+#if 0
+
+
+#endif
+
+/* blah */
+
+void f0(const char*);
+void f1(char);
+
+const char *hello = "Hello, world";
+const char a = 'a';
+
+#define FOO(a, b) a b
+
+FOO(int, x);
+
+// RUN: c-index-test -code-completion-at=%s:5:1 -pedantic %s 2> %t.err | FileCheck %s
+// RUN: not grep error %t.err
+// CHECK: {TypedText Integer}
+// RUN: c-index-test -code-completion-at=%s:8:6 -pedantic %s 2> %t.err
+// RUN: not grep error %t.err
+// RUN: c-index-test -code-completion-at=%s:10:28 -pedantic %s 2> %t.err
+// RUN: not grep unterminated %t.err
+// RUN: c-index-test -code-completion-at=%s:11:17 -pedantic %s 2> %t.err
+// RUN: not grep unterminated %t.err
+// RUN: c-index-test -code-completion-at=%s:18:10 -pedantic %s 2> %t.err
+// RUN: not grep unterminated %t.err
diff --git a/test/Index/crash-recovery-code-complete.c b/test/Index/crash-recovery-code-complete.c
new file mode 100644
index 0000000..a80bdc2
--- /dev/null
+++ b/test/Index/crash-recovery-code-complete.c
@@ -0,0 +1,10 @@
+// RUN: env CINDEXTEST_EDITING=1 \
+// RUN:   not c-index-test -code-completion-at=%s:20:1 \
+// RUN:   "-remap-file=%s;%S/Inputs/crash-recovery-code-complete-remap.c" \
+// RUN:   %s 2> %t.err
+// RUN: FileCheck < %t.err -check-prefix=CHECK-CODE-COMPLETE-CRASH %s
+// CHECK-CODE-COMPLETE-CRASH: Unable to perform code completion!
+//
+// REQUIRES: crash-recovery
+
+#warning parsing original file
diff --git a/test/Index/crash-recovery-reparse.c b/test/Index/crash-recovery-reparse.c
new file mode 100644
index 0000000..e394bd1
--- /dev/null
+++ b/test/Index/crash-recovery-reparse.c
@@ -0,0 +1,10 @@
+// RUN: env CINDEXTEST_EDITING=1 \
+// RUN:   not c-index-test -test-load-source-reparse 1 local \
+// RUN:   -remap-file="%s;%S/Inputs/crash-recovery-reparse-remap.c" \
+// RUN:   %s 2> %t.err
+// RUN: FileCheck < %t.err -check-prefix=CHECK-REPARSE-SOURCE-CRASH %s
+// CHECK-REPARSE-SOURCE-CRASH: Unable to reparse translation unit
+//
+// REQUIRES: crash-recovery
+
+#warning parsing original file
diff --git a/test/Index/crash-recovery.c b/test/Index/crash-recovery.c
new file mode 100644
index 0000000..b7f6e0b
--- /dev/null
+++ b/test/Index/crash-recovery.c
@@ -0,0 +1,7 @@
+// RUN: not c-index-test -test-load-source all %s 2> %t.err
+// RUN: FileCheck < %t.err -check-prefix=CHECK-LOAD-SOURCE-CRASH %s
+// CHECK-LOAD-SOURCE-CRASH: Unable to load translation unit
+//
+// REQUIRES: crash-recovery
+
+#pragma clang __debug crash
diff --git a/test/Index/invalid-rdar-8236270.cpp b/test/Index/invalid-rdar-8236270.cpp
new file mode 100644
index 0000000..6fd088d
--- /dev/null
+++ b/test/Index/invalid-rdar-8236270.cpp
@@ -0,0 +1,11 @@
+// RUN: c-index-test -test-load-source all %s 2>&1 | FileCheck %s
+
+// This test case previously just crashed the frontend.
+
+struct abc *P;
+int main(
+
+// CHECK: StructDecl=abc:5:8 Extent=[5:1 - 5:11]
+// CHECK: VarDecl=P:5:13 (Definition) Extent=[5:8 - 5:14]
+// CHECK: VarDecl=main:6:5 (Definition) Extent=[6:1 - 6:9]
+
diff --git a/test/Index/load-stmts.cpp b/test/Index/load-stmts.cpp
index fdfedfb..efde248 100644
--- a/test/Index/load-stmts.cpp
+++ b/test/Index/load-stmts.cpp
@@ -10,9 +10,31 @@
   }
 }
 
+// Test handling of C++ base specifiers.
+class A {
+  void doA();
+};
+
+class B {
+  void doB();
+};
+
+class C : public A, private B {
+  void doC();
+};
+
+class D : virtual public C, virtual private A {};
+
 // 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:1:13: TypedefDecl=T:1:13 (Definition) Extent=[1:13 - 1:14]
+// CHECK: load-stmts.cpp:2:8: StructDecl=X:2:8 (Definition) Extent=[2:1 - 2:23]
+// CHECK: load-stmts.cpp:2:16: FieldDecl=a:2:16 (Definition) Extent=[2:16 - 2:17]
+// CHECK: load-stmts.cpp:2:19: FieldDecl=b:2:19 (Definition) Extent=[2:19 - 2:20]
+// CHECK: load-stmts.cpp:3:6: FunctionDecl=f:3:6 (Definition) Extent=[3:6 - 11:2]
+// CHECK: load-stmts.cpp:3:12: ParmDecl=x:3:12 (Definition) Extent=[3:8 - 3:13]
+// CHECK: <invalid loc>:0:0: UnexposedStmt= Extent=[3:15 - 11:2]
+// CHECK: <invalid loc>:0:0: UnexposedStmt= Extent=[4:3 - 5:4]
+// CHECK: <invalid loc>:0:0: 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]
@@ -23,29 +45,41 @@
 // 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: <invalid loc>:0:0: UnexposedStmt= Extent=[4:31 - 5:4]
+// CHECK: <invalid loc>:0:0: 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: <invalid loc>:0:0: UnexposedStmt= Extent=[6:19 - 6:22]
+// CHECK: <invalid loc>:0:0: 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: <invalid loc>:0:0: UnexposedStmt= Extent=[7:22 - 7:25]
+// CHECK: <invalid loc>:0:0: 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: <invalid loc>:0:0: UnexposedStmt= Extent=[8:21 - 10:4]
+// CHECK: <invalid loc>:0:0: UnexposedStmt= Extent=[9:3 - 9:17]
 // CHECK: load-stmts.cpp:9:8: UnexposedExpr= Extent=[9:8 - 9:10]
+// CHECK: <invalid loc>:0:0: UnexposedStmt= Extent=[9:12 - 9:17]
+// CHECK: load-stmts.cpp:14:7: ClassDecl=A:14:7 (Definition) Extent=[14:1 - 16:2]
+// CHECK: load-stmts.cpp:15:8: CXXMethod=doA:15:8 Extent=[15:8 - 15:13]
+// CHECK: load-stmts.cpp:18:7: ClassDecl=B:18:7 (Definition) Extent=[18:1 - 20:2]
+// CHECK: load-stmts.cpp:19:8: CXXMethod=doB:19:8 Extent=[19:8 - 19:13]
+// CHECK: load-stmts.cpp:22:7: ClassDecl=C:22:7 (Definition) Extent=[22:1 - 24:2]
+// CHECK: <invalid loc>:0:0: C++ base class specifier=class A:14:7 [access=public isVirtual=false]
+// CHECK: <invalid loc>:0:0: C++ base class specifier=class B:18:7 [access=private isVirtual=false]
+// CHECK: load-stmts.cpp:23:8: CXXMethod=doC:23:8 Extent=[23:8 - 23:13]
+// CHECK: load-stmts.cpp:26:7: ClassDecl=D:26:7 (Definition) Extent=[26:1 - 26:49]
+// CHECK: <invalid loc>:0:0: C++ base class specifier=class C:22:7 [access=public isVirtual=true]
+// CHECK: <invalid loc>:0:0: C++ base class specifier=class A:14:7 [access=private isVirtual=true]
+
diff --git a/test/Index/local-symbols.m b/test/Index/local-symbols.m
new file mode 100644
index 0000000..8557e7f
--- /dev/null
+++ b/test/Index/local-symbols.m
@@ -0,0 +1,26 @@
+// RUN: c-index-test -test-load-source local %s | FileCheck %s
+
+// From: <rdar://problem/7568881>
+// The method 'bar' was also being reported outside the @implementation
+
+@interface Foo {
+  id x;
+}
+- (id) bar;
+@end
+
+@implementation Foo
+- (id) bar {
+  return 0;
+}
+@end
+
+// CHECK: local-symbols.m:6:12: ObjCInterfaceDecl=Foo:6:12 Extent=[6:1 - 10:5]
+// CHECK: local-symbols.m:7:6: ObjCIvarDecl=x:7:6 (Definition) Extent=[7:6 - 7:7]
+// CHECK: local-symbols.m:7:3: TypeRef=id:0:0 Extent=[7:3 - 7:5]
+// CHECK: local-symbols.m:9:1: ObjCInstanceMethodDecl=bar:9:1 Extent=[9:1 - 9:12]
+// CHECK: local-symbols.m:9:4: TypeRef=id:0:0 Extent=[9:4 - 9:6]
+// CHECK: local-symbols.m:12:1: ObjCImplementationDecl=Foo:12:1 (Definition) Extent=[12:1 - 16:2]
+// CHECK: local-symbols.m:13:1: ObjCInstanceMethodDecl=bar:13:1 (Definition) Extent=[13:1 - 15:2]
+// CHECK: local-symbols.m:13:4: TypeRef=id:0:0 Extent=[13:4 - 13:6]
+
diff --git a/test/Index/preamble-reparse.c b/test/Index/preamble-reparse.c
new file mode 100644
index 0000000..5bd03b3
--- /dev/null
+++ b/test/Index/preamble-reparse.c
@@ -0,0 +1,2 @@
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 local "-remap-file=%S/Inputs/preamble-reparse-1.c;%S/Inputs/preamble-reparse-2.c" %S/Inputs/preamble-reparse-1.c | FileCheck %s
+// CHECK: preamble-reparse-1.c:1:5: VarDecl=x:1:5 Extent=[1:1 - 1:6]
diff --git a/test/Index/preamble.c b/test/Index/preamble.c
new file mode 100644
index 0000000..54abf99
--- /dev/null
+++ b/test/Index/preamble.c
@@ -0,0 +1,28 @@
+#include "prefix.h"
+#include "preamble.h"
+int wibble(int);
+
+void f(int x) {
+  
+}
+// RUN: c-index-test -write-pch %t.pch -x c-header %S/Inputs/prefix.h
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 local -I %S/Inputs -include %t %s 2> %t.stderr.txt | FileCheck %s
+// RUN: FileCheck -check-prefix CHECK-DIAG %s < %t.stderr.txt
+// CHECK: preamble.h:1:12: FunctionDecl=bar:1:12 (Definition) Extent=[1:12 - 6:2]
+// CHECK: <invalid loc>:0:0: UnexposedStmt= Extent=[1:23 - 6:2]
+// CHECK: <invalid loc>:0:0: UnexposedStmt= Extent=[2:3 - 2:16]
+// CHECK: <invalid loc>:0:0: UnexposedStmt= Extent=[3:3 - 3:15]
+// CHECK: preamble.h:4:3: UnexposedExpr= Extent=[4:3 - 4:13]
+// CHECK: preamble.h:4:3: DeclRefExpr=ptr:2:8 Extent=[4:3 - 4:6]
+// CHECK: preamble.h:4:9: UnexposedExpr=ptr1:3:10 Extent=[4:9 - 4:13]
+// CHECK: preamble.h:4:9: DeclRefExpr=ptr1:3:10 Extent=[4:9 - 4:13]
+// CHECK: <invalid loc>:0:0: UnexposedStmt= Extent=[5:3 - 5:11]
+// CHECK: preamble.h:5:10: UnexposedExpr= Extent=[5:10 - 5:11]
+// CHECK: preamble.c:3:5: FunctionDecl=wibble:3:5 Extent=[3:5 - 3:16]
+// CHECK: preamble.c:3:15: ParmDecl=:3:15 (Definition) Extent=[3:12 - 3:16]
+// CHECK-DIAG: preamble.h:4:7:{4:9-4:13}: warning: incompatible pointer types assigning to 'int *' from 'float *'
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:6:1 -I %S/Inputs -include %t %s 2> %t.stderr.txt | FileCheck -check-prefix CHECK-CC %s
+// CHECK-CC: FunctionDecl:{ResultType int}{TypedText bar}{LeftParen (}{Placeholder int i}{RightParen )} (50)
+// CHECK-CC: FunctionDecl:{ResultType void}{TypedText f}{LeftParen (}{Placeholder int x}{RightParen )} (45)
+// CHECK-CC: FunctionDecl:{ResultType int}{TypedText foo}{LeftParen (}{Placeholder int}{RightParen )} (50)
+// CHECK-CC: FunctionDecl:{ResultType int}{TypedText wibble}{LeftParen (}{Placeholder int}{RightParen )} (50)
diff --git a/test/Index/print-typekind.c b/test/Index/print-typekind.c
new file mode 100644
index 0000000..18189c3
--- /dev/null
+++ b/test/Index/print-typekind.c
@@ -0,0 +1,25 @@
+typedef int FooType;
+int *p;
+int *f(int *p, char *x, FooType z) {
+  FooType w = z;
+  return p + z;
+}
+
+// RUN: c-index-test -test-print-typekind %s | FileCheck %s
+// CHECK: TypedefDecl=FooType:1:13 (Definition) typekind=Typedef [canonical=Int] [isPOD=1]
+// CHECK: VarDecl=p:2:6 typekind=Pointer [isPOD=1]
+// CHECK: FunctionDecl=f:3:6 (Definition) typekind=FunctionProto [canonical=FunctionProto] [result=Pointer] [isPOD=0]
+// CHECK: ParmDecl=p:3:13 (Definition) typekind=Pointer [isPOD=1]
+// CHECK: ParmDecl=x:3:22 (Definition) typekind=Pointer [isPOD=1]
+// CHECK: ParmDecl=z:3:33 (Definition) typekind=Typedef [canonical=Int] [isPOD=1]
+// CHECK: TypeRef=FooType:1:13 typekind=Invalid [isPOD=0]
+// CHECK: UnexposedStmt= typekind=Invalid [isPOD=0]
+// CHECK: UnexposedStmt= typekind=Invalid [isPOD=0]
+// CHECK: VarDecl=w:4:11 (Definition) typekind=Typedef [canonical=Int] [isPOD=1]
+// CHECK: TypeRef=FooType:1:13 typekind=Invalid [isPOD=0]
+// CHECK: DeclRefExpr=z:3:33 typekind=Typedef [canonical=Int] [isPOD=1]
+// CHECK: UnexposedStmt= typekind=Invalid [isPOD=0]
+// CHECK: UnexposedExpr= typekind=Pointer [isPOD=1]
+// CHECK: DeclRefExpr=p:3:13 typekind=Pointer [isPOD=1]
+// CHECK: DeclRefExpr=z:3:33 typekind=Typedef [canonical=Int] [isPOD=1]
+
diff --git a/test/Index/print-typekind.m b/test/Index/print-typekind.m
new file mode 100644
index 0000000..68827fb
--- /dev/null
+++ b/test/Index/print-typekind.m
@@ -0,0 +1,10 @@
+@interface Foo
+@property (readonly) id x;
+-(int) mymethod;
+@end
+
+// RUN: c-index-test -test-print-typekind %s | FileCheck %s
+// CHECK: ObjCPropertyDecl=x:2:25 typekind=Typedef [canonical=ObjCObjectPointer]
+// CHECK: ObjCInstanceMethodDecl=mymethod:3:1 typekind=Invalid [result=Int]
+
+
diff --git a/test/Index/properties-class-extensions.m b/test/Index/properties-class-extensions.m
new file mode 100644
index 0000000..8bca37e
--- /dev/null
+++ b/test/Index/properties-class-extensions.m
@@ -0,0 +1,28 @@
+// Test that @properties within class extensions are visited by
+// clang_visitChildren only in the class extension, not the original
+// @interface (where we have a duplicate declaration - to be removed).
+@interface Foo {} @end
+@interface Foo (Cat)
+  @property int a;
+@end
+@interface Foo ()
+  @property int b;
+  - (void) bar;
+@end
+
+// RUN: c-index-test -test-load-source local %s | FileCheck %s
+// CHECK: properties-class-extensions.m:4:12: ObjCInterfaceDecl=Foo:4:12 Extent=[4:1 - 4:23]
+// CHECK: properties-class-extensions.m:5:12: ObjCCategoryDecl=Cat:5:12 Extent=[5:1 - 7:5]
+// CHECK: properties-class-extensions.m:5:12: ObjCClassRef=Foo:4:12 Extent=[5:12 - 5:15]
+// CHECK: properties-class-extensions.m:6:17: ObjCPropertyDecl=a:6:17 Extent=[6:17 - 6:18]
+// CHECK: properties-class-extensions.m:6:17: ObjCInstanceMethodDecl=a:6:17 Extent=[6:17 - 6:18]
+// CHECK: properties-class-extensions.m:6:17: ObjCInstanceMethodDecl=setA::6:17 Extent=[6:17 - 6:18]
+// CHECK: properties-class-extensions.m:6:17: ParmDecl=a:6:17 (Definition) Extent=[6:17 - 6:18]
+// CHECK: properties-class-extensions.m:8:12: ObjCCategoryDecl=:8:12 Extent=[8:1 - 11:5]
+// CHECK: properties-class-extensions.m:8:12: ObjCClassRef=Foo:4:12 Extent=[8:12 - 8:15]
+// CHECK: properties-class-extensions.m:9:17: ObjCPropertyDecl=b:9:17 Extent=[9:17 - 9:18]
+// CHECK: properties-class-extensions.m:9:17: ObjCInstanceMethodDecl=b:9:17 Extent=[9:17 - 9:18]
+// CHECK: properties-class-extensions.m:9:17: ObjCInstanceMethodDecl=setB::9:17 Extent=[9:17 - 9:18]
+// CHECK: properties-class-extensions.m:9:17: ParmDecl=b:9:17 (Definition) Extent=[9:17 - 9:18]
+// CHECK: properties-class-extensions.m:10:3: ObjCInstanceMethodDecl=bar:10:3 Extent=[10:3 - 10:16]
+
diff --git a/test/Index/rdar-8288645-invalid-code.mm b/test/Index/rdar-8288645-invalid-code.mm
new file mode 100644
index 0000000..3405f0a
--- /dev/null
+++ b/test/Index/rdar-8288645-invalid-code.mm
@@ -0,0 +1,8 @@
+// RUN: c-index-test -test-load-source all %s 2>&1 | FileCheck %s
+
+// This test case previously crashed Sema.
+
+extern "C" { @implementation Foo  - (id)initWithBar:(Baz<WozBar>)pepper {
+
+// CHECK: warning: cannot find interface declaration for 'Foo'
+// CHECK: warning: '@end' is missing in implementation context
diff --git a/test/Index/remap-load.c b/test/Index/remap-load.c
index b8415e6..d9634a4 100644
--- a/test/Index/remap-load.c
+++ b/test/Index/remap-load.c
@@ -5,8 +5,8 @@
 // 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: <invalid loc>:0:0: UnexposedStmt= Extent=[1:33 - 3:2]
+// CHECK: <invalid loc>:0:0: 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]
diff --git a/test/Index/usrs.cpp b/test/Index/usrs.cpp
new file mode 100644
index 0000000..833e312
--- /dev/null
+++ b/test/Index/usrs.cpp
@@ -0,0 +1,110 @@
+namespace foo {
+  int x;
+  void bar(int z);
+}
+namespace bar {
+  typedef int QType;
+  void bar(QType z);
+}
+
+class ClsA {
+public:
+  int a, b;
+  ClsA(int A, int B) : a(A), b(B) {}
+};
+
+namespace foo {
+  class ClsB : public ClsA {
+  public:
+    ClsB() : ClsA(1, 2) {}
+    int result() const;
+  };
+}
+
+int foo::ClsB::result() const {
+  return a + b;
+}
+
+namespace {
+  class ClsC : public foo::ClsB {};
+  int w;
+}
+
+int z;
+
+namespace foo { namespace taz {
+  int x;
+  static inline int add(int a, int b) { return a + b; }
+  void sub(int a, int b);
+}
+}
+
+namespace foo { namespace taz {
+  class ClsD : public foo::ClsB {
+  public:
+    ClsD& operator=(int x) { a = x; return *this; }
+    ClsD& operator=(double x) { a = (int) x; return *this; }
+    ClsD& operator=(const ClsD &x) { a = x.a; return *this; }
+    static int qux();
+    static int uz(int z, ...);
+    bool operator==(const ClsD &x) const { return a == x.a; }
+  };
+}}
+
+extern "C" {
+  void rez(int a, int b);
+}
+
+// RUN: c-index-test -test-load-source-usrs all %s | FileCheck %s
+// CHECK: usrs.cpp c:@N@foo Extent=[1:11 - 4:2]
+// CHECK: usrs.cpp c:@N@foo@x Extent=[2:3 - 2:8]
+// CHECK: usrs.cpp c:@N@foo@F@bar#I# Extent=[3:8 - 3:18]
+// CHECK: usrs.cpp c:usrs.cpp@36@N@foo@F@bar#I#@z Extent=[3:12 - 3:17]
+// CHECK: usrs.cpp c:@N@bar Extent=[5:11 - 8:2]
+// CHECK: usrs.cpp c:usrs.cpp@76@N@bar@T@QType Extent=[6:15 - 6:20]
+// CHECK: usrs.cpp c:@N@bar@F@bar#I# Extent=[7:8 - 7:20]
+// CHECK: usrs.cpp c:usrs.cpp@94@N@bar@F@bar#I#@z Extent=[7:12 - 7:19]
+// CHECK: usrs.cpp c:@C@ClsA Extent=[10:1 - 14:2]
+// CHECK: usrs.cpp c: Extent=[11:1 - 11:8]
+// CHECK: usrs.cpp c:@C@ClsA@FI@a Extent=[12:7 - 12:8]
+// CHECK: usrs.cpp c:@C@ClsA@FI@b Extent=[12:10 - 12:11]
+// CHECK: usrs.cpp c:@C@ClsA@F@ClsA#I#I# Extent=[13:3 - 13:37]
+// CHECK: usrs.cpp c:usrs.cpp@147@C@ClsA@F@ClsA#I#I#@A Extent=[13:8 - 13:13]
+// CHECK: usrs.cpp c:usrs.cpp@154@C@ClsA@F@ClsA#I#I#@B Extent=[13:15 - 13:20]
+// CHECK: usrs.cpp c:@N@foo Extent=[16:11 - 22:2]
+// CHECK: usrs.cpp c:@N@foo@C@ClsB Extent=[17:3 - 21:4]
+// CHECK: usrs.cpp c: Extent=[18:3 - 18:10]
+// CHECK: usrs.cpp c:@N@foo@C@ClsB@F@ClsB# Extent=[19:5 - 19:27]
+// CHECK: usrs.cpp c:@N@foo@C@ClsB@F@result#1 Extent=[20:9 - 20:17]
+// CHECK: usrs.cpp c:@N@foo@C@ClsB@F@result#1 Extent=[24:16 - 26:2]
+// CHECK: usrs.cpp c:@aN@C@ClsC Extent=[29:3 - 29:35]
+// CHECK: usrs.cpp c:@aN@w Extent=[30:3 - 30:8]
+// CHECK: usrs.cpp c:@z Extent=[33:1 - 33:6]
+// CHECK: usrs.cpp c:@N@foo Extent=[35:11 - 40:2]
+// CHECK: usrs.cpp c:@N@foo@N@taz Extent=[35:27 - 39:2]
+// CHECK: usrs.cpp c:@N@foo@N@taz@x Extent=[36:3 - 36:8]
+// CHECK: usrs.cpp c:usrs.cpp@475@N@foo@N@taz@F@add#I#I# Extent=[37:21 - 37:56]
+// CHECK: usrs.cpp c:usrs.cpp@479@N@foo@N@taz@F@add#I#I#@a Extent=[37:25 - 37:30]
+// CHECK: usrs.cpp c:usrs.cpp@486@N@foo@N@taz@F@add#I#I#@b Extent=[37:32 - 37:37]
+// CHECK: usrs.cpp c:@N@foo@N@taz@F@sub#I#I# Extent=[38:8 - 38:25]
+// CHECK: usrs.cpp c:usrs.cpp@522@N@foo@N@taz@F@sub#I#I#@a Extent=[38:12 - 38:17]
+// CHECK: usrs.cpp c:usrs.cpp@529@N@foo@N@taz@F@sub#I#I#@b Extent=[38:19 - 38:24]
+// CHECK: usrs.cpp c:@N@foo Extent=[42:11 - 52:3]
+// CHECK: usrs.cpp c:@N@foo@N@taz Extent=[42:27 - 52:2]
+// CHECK: usrs.cpp c:@N@foo@N@taz@C@ClsD Extent=[43:3 - 51:4]
+// CHECK: usrs.cpp c: Extent=[44:3 - 44:10]
+// CHECK: usrs.cpp c:@N@foo@N@taz@C@ClsD@F@operator=#I# Extent=[45:11 - 45:52]
+// CHECK: usrs.cpp c:usrs.cpp@638@N@foo@N@taz@C@ClsD@F@operator=#I#@x Extent=[45:21 - 45:26]
+// CHECK: usrs.cpp c:@N@foo@N@taz@C@ClsD@F@operator=#d# Extent=[46:11 - 46:61]
+// CHECK: usrs.cpp c:usrs.cpp@690@N@foo@N@taz@C@ClsD@F@operator=#d#@x Extent=[46:21 - 46:29]
+// CHECK: usrs.cpp c:@N@foo@N@taz@C@ClsD@F@operator=#&1$@N@foo@N@taz@C@ClsD# Extent=[47:11 - 47:62]
+// CHECK: usrs.cpp c:usrs.cpp@757@N@foo@N@taz@C@ClsD@F@operator=#&1$@N@foo@N@taz@C@ClsD#@x Extent=[47:27 - 47:34]
+// CHECK: usrs.cpp c:@N@foo@N@taz@C@ClsD@F@qux#S Extent=[48:16 - 48:21]
+// CHECK: usrs.cpp c:@N@foo@N@taz@C@ClsD@F@uz#I.#S Extent=[49:16 - 49:30]
+// CHECK: usrs.cpp c:usrs.cpp@833@N@foo@N@taz@C@ClsD@F@uz#I.#S@z Extent=[49:19 - 49:24]
+// CHECK: usrs.cpp c:@N@foo@N@taz@C@ClsD@F@operator==#&1$@N@foo@N@taz@C@ClsD#1 Extent=[50:10 - 50:62]
+// CHECK: usrs.cpp c:usrs.cpp@872@N@foo@N@taz@C@ClsD@F@operator==#&1$@N@foo@N@taz@C@ClsD#1@x Extent=[50:27 - 50:34]
+// CHECK: usrs.cpp c:@F@rez Extent=[55:8 - 55:25]
+// CHECK: usrs.cpp c:usrs.cpp@941@F@rez@a Extent=[55:12 - 55:17]
+// CHECK: usrs.cpp c:usrs.cpp@948@F@rez@b Extent=[55:19 - 55:24]
+
diff --git a/test/Index/usrs.m b/test/Index/usrs.m
index 28771ae..4b3de5c 100644
--- a/test/Index/usrs.m
+++ b/test/Index/usrs.m
@@ -1,5 +1,7 @@
 // RUN: c-index-test -test-load-source-usrs all %s | FileCheck %s
 
+static inline int my_helper(int x, int y) { return x + y; }
+
 enum {
   ABA,
   CADABA
@@ -36,6 +38,7 @@
   return 0;
 }
 + (id) kingkong {
+  int local_var;
   return 0;
 }
 @synthesize d1;
@@ -43,32 +46,77 @@
 
 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]
+static int local_func(int x) { return x; }
+
+@interface CWithExt
+- (id) meth1;
+@end
+@interface CWithExt ()
+- (id) meth2;
+@end
+@interface CWithExt ()
+- (id) meth3;
+@end
+@interface CWithExt (Bar)
+- (id) meth4;
+@end
+@implementation CWithExt
+- (id) meth1 { return 0; }
+- (id) meth2 { return 0; }
+- (id) meth3 { return 0; }
+@end
+@implementation CWithExt (Bar)
+- (id) meth4 { return 0; }
+@end
+
+// CHECK: usrs.m c:usrs.m@85@F@my_helper Extent=[3:19 - 3:60]
+// CHECK: usrs.m c:usrs.m@95@F@my_helper@x Extent=[3:29 - 3:34]
+// CHECK: usrs.m c:usrs.m@102@F@my_helper@y Extent=[3:36 - 3:41]
+// CHECK: usrs.m c:usrs.m@128@Ea Extent=[5:1 - 8:2]
+// CHECK: usrs.m c:usrs.m@128@Ea@ABA Extent=[6:3 - 6:6]
+// CHECK: usrs.m c:usrs.m@128@Ea@CADABA Extent=[7:3 - 7:9]
+// CHECK: usrs.m c:usrs.m@155@Ea Extent=[10:1 - 13:2]
+// CHECK: usrs.m c:usrs.m@155@Ea@FOO Extent=[11:3 - 11:6]
+// CHECK: usrs.m c:usrs.m@155@Ea@BAR Extent=[12:3 - 12:6]
+// CHECK: usrs.m c:@SA@MyStruct Extent=[15:9 - 18:2]
+// CHECK: usrs.m c:@SA@MyStruct@FI@wa Extent=[16:7 - 16:9]
+// CHECK: usrs.m c:@SA@MyStruct@FI@moo Extent=[17:7 - 17:10]
+// CHECK: usrs.m c:usrs.m@219@T@MyStruct Extent=[18:3 - 18:11]
+// CHECK: usrs.m c:@E@Pizza Extent=[20:1 - 23:2]
+// CHECK: usrs.m c:@E@Pizza@CHEESE Extent=[21:3 - 21:9]
+// CHECK: usrs.m c:@E@Pizza@MUSHROOMS Extent=[22:3 - 22:12]
+// CHECK: usrs.m c:objc(cs)Foo Extent=[25:1 - 32:5]
+// CHECK: usrs.m c:objc(cs)Foo@x Extent=[26:6 - 26:7]
+// CHECK: usrs.m c:objc(cs)Foo@y Extent=[27:6 - 27:7]
+// CHECK: usrs.m c:objc(cs)Foo(py)d1 Extent=[31:15 - 31:17]
+// CHECK: usrs.m c:objc(cs)Foo(im)godzilla Extent=[29:1 - 29:17]
+// CHECK: usrs.m c:objc(cs)Foo(cm)kingkong Extent=[30:1 - 30:17]
+// CHECK: usrs.m c:objc(cs)Foo(im)d1 Extent=[31:15 - 31:17]
+// CHECK: usrs.m c:objc(cs)Foo(im)setD1: Extent=[31:15 - 31:17]
+// CHECK: usrs.m c:usrs.m@352objc(cs)Foo(im)setD1:@d1 Extent=[31:15 - 31:17]
+// CHECK: usrs.m c:objc(cs)Foo Extent=[34:1 - 45:2]
+// CHECK: usrs.m c:objc(cs)Foo(im)godzilla Extent=[35:1 - 39:2]
+// CHECK: usrs.m c:usrs.m@409objc(cs)Foo(im)godzilla@a Extent=[36:10 - 36:19]
+// CHECK: usrs.m c:objc(cs)Foo(im)godzilla@z Extent=[37:10 - 37:15]
+// CHECK: usrs.m c:objc(cs)Foo(cm)kingkong Extent=[40:1 - 43:2]
+// CHECK: usrs.m c:usrs.m@470objc(cs)Foo(cm)kingkong@local_var Extent=[41:3 - 41:16]
+// CHECK: usrs.m c:objc(cs)Foo@d1 Extent=[44:13 - 44:15]
+// CHECK: usrs.m c:objc(cs)Foo(py)d1 Extent=[44:1 - 44:15]
+// CHECK: usrs.m c:@z Extent=[47:1 - 47:6]
+// CHECK: usrs.m c:usrs.m@540@F@local_func Extent=[49:12 - 49:43]
+// CHECK: usrs.m c:usrs.m@551@F@local_func@x Extent=[49:23 - 49:28]
+// CHECK: usrs.m c:objc(cs)CWithExt Extent=[51:1 - 53:5]
+// CHECK: usrs.m c:objc(cs)CWithExt(im)meth1 Extent=[52:1 - 52:14]
+// CHECK: usrs.m c:objc(ext)CWithExt@usrs.m@612 Extent=[54:1 - 56:5]
+// CHECK: usrs.m c:objc(cs)CWithExt(im)meth2 Extent=[55:1 - 55:14]
+// CHECK: usrs.m c:objc(ext)CWithExt@usrs.m@654 Extent=[57:1 - 59:5]
+// CHECK: usrs.m c:objc(cs)CWithExt(im)meth3 Extent=[58:1 - 58:14]
+// CHECK: usrs.m c:objc(cy)CWithExt@Bar Extent=[60:1 - 62:5]
+// CHECK: usrs.m c:objc(cy)CWithExt@Bar(im)meth4 Extent=[61:1 - 61:14]
+// CHECK: usrs.m c:objc(cs)CWithExt Extent=[63:1 - 67:2]
+// CHECK: usrs.m c:objc(cs)CWithExt(im)meth1 Extent=[64:1 - 64:27]
+// CHECK: usrs.m c:objc(cs)CWithExt(im)meth2 Extent=[65:1 - 65:27]
+// CHECK: usrs.m c:objc(cs)CWithExt(im)meth3 Extent=[66:1 - 66:27]
+// CHECK: usrs.m c:objc(cy)CWithExt@Bar Extent=[68:1 - 70:2]
+// CHECK: usrs.m c:objc(cy)CWithExt@Bar(im)meth4 Extent=[69:1 - 69:27]
 
diff --git a/test/Lexer/block_cmt_end.c b/test/Lexer/block_cmt_end.c
index 72bc836..b03fb23 100644
--- a/test/Lexer/block_cmt_end.c
+++ b/test/Lexer/block_cmt_end.c
@@ -17,7 +17,7 @@
 /* expected-warning {{escaped newline}} expected-warning {{backslash and newline}}  *\  
 /
 
-int bar /* expected-error {{invalid token after top level declarator}} */
+int bar /* expected-error {{expected ';' after top level declarator}} */
 
 /* xyz
 
diff --git a/test/Lexer/c90.c b/test/Lexer/c90.c
index 6293d42..f191397 100644
--- a/test/Lexer/c90.c
+++ b/test/Lexer/c90.c
@@ -11,3 +11,19 @@
 
 // comment accepted as extension    /* expected-error {{// comments are not allowed in this language}}
 
+void test2() {
+  const char * str =
+    "sdjflksdjf lksdjf skldfjsdkljflksdjf kldsjflkdsj fldks jflsdkjfds" // expected-error{{string literal of length 845 exceeds maximum length 509 that C90 compilers are required to support}}
+    "sdjflksdjf lksdjf skldfjsdkljflksdjf kldsjflkdsj fldks jflsdkjfds"
+    "sdjflksdjf lksdjf skldfjsdkljflksdjf kldsjflkdsj fldks jflsdkjfds"
+    "sdjflksdjf lksdjf skldfjsdkljflksdjf kldsjflkdsj fldks jflsdkjfds"
+    "sdjflksdjf lksdjf skldfjsdkljflksdjf kldsjflkdsj fldks jflsdkjfds"
+    "sdjflksdjf lksdjf skldfjsdkljflksdjf kldsjflkdsj fldks jflsdkjfds"
+    "sdjflksdjf lksdjf skldfjsdkljflksdjf kldsjflkdsj fldks jflsdkjfds"
+    "sdjflksdjf lksdjf skldfjsdkljflksdjf kldsjflkdsj fldks jflsdkjfds"
+    "sdjflksdjf lksdjf skldfjsdkljflksdjf kldsjflkdsj fldks jflsdkjfds"
+    "sdjflksdjf lksdjf skldfjsdkljflksdjf kldsjflkdsj fldks jflsdkjfds"
+    "sdjflksdjf lksdjf skldfjsdkljflksdjf kldsjflkdsj fldks jflsdkjfds"
+    "sdjflksdjf lksdjf skldfjsdkljflksdjf kldsjflkdsj fldks jflsdkjfds"
+    "sdjflksdjf lksdjf skldfjsdkljflksdjf kldsjflkdsj fldks jflsdkjfds";
+}
diff --git a/test/Lexer/conflict-marker.c b/test/Lexer/conflict-marker.c
index f86111c..45efdec 100644
--- a/test/Lexer/conflict-marker.c
+++ b/test/Lexer/conflict-marker.c
@@ -4,7 +4,7 @@
 // PR5238
 
 // diff3 style
-<<<<<<< .mine             // expected-error {{version control conflict marker in file}}
+<<<<<<< .mine      // expected-error {{version control conflict marker in file}}
 int x = 4;
 |||||||
 int x = 123;
@@ -13,7 +13,7 @@
 >>>>>>> .r91107
 
 // normal style.
-<<<<<<< .mine             // expected-error {{version control conflict marker in file}}
+<<<<<<< .mine     // expected-error {{version control conflict marker in file}}
 typedef int y;
 =======
 typedef struct foo *y;
@@ -22,6 +22,7 @@
 ;
 y b;
 
+
 int foo() {
   y a = x;
   return x + a;
diff --git a/test/Lexer/constants.c b/test/Lexer/constants.c
index b833e7b..de0962e 100644
--- a/test/Lexer/constants.c
+++ b/test/Lexer/constants.c
@@ -24,6 +24,13 @@
   'abcd'  // expected-warning {{multi-character character constant}}
 };
 
+//  PR4499
+int m0 = '0';
+int m1 = '\\\''; // expected-warning {{multi-character character constant}}
+int m2 = '\\\\'; // expected-warning {{multi-character character constant}}
+int m3 = '\\\
+';
+
 
 #pragma clang diagnostic ignored "-Wmultichar"
 
@@ -55,3 +62,6 @@
   -1.9e500,  // expected-warning {{too large}}
   -1.9e-500  // expected-warning {{too small}}
 };
+
+// PR7888
+double g = 1e100000000; // expected-warning {{too large}}
diff --git a/test/Lexer/gnu_keywords.c b/test/Lexer/gnu_keywords.c
index 3234f58..c4bd9b3 100644
--- a/test/Lexer/gnu_keywords.c
+++ b/test/Lexer/gnu_keywords.c
@@ -1,7 +1,7 @@
-// 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
+// RUN: %clang_cc1 -DGNU_KEYWORDS -std=gnu89 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -DGNU_KEYWORDS -std=c99 -fgnu-keywords -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=gnu89 -fno-gnu-keywords -fsyntax-only -verify %s
 
 void f() {
 #ifdef GNU_KEYWORDS
diff --git a/test/Lexer/has_feature_cxx0x.cpp b/test/Lexer/has_feature_cxx0x.cpp
index 7ea4c2c..650e577 100644
--- a/test/Lexer/has_feature_cxx0x.cpp
+++ b/test/Lexer/has_feature_cxx0x.cpp
@@ -1,5 +1,5 @@
-// 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
+// RUN: %clang_cc1 -E -std=c++0x %s -o - | FileCheck --check-prefix=CHECK-0X %s
+// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-0X %s
 
 #if __has_feature(cxx_lambdas)
 int lambdas();
diff --git a/test/Lexer/has_feature_exceptions.cpp b/test/Lexer/has_feature_exceptions.cpp
index cfd1efb..bb5dc0c 100644
--- a/test/Lexer/has_feature_exceptions.cpp
+++ b/test/Lexer/has_feature_exceptions.cpp
@@ -1,5 +1,5 @@
-// 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
+// RUN: %clang_cc1 -E -fexceptions %s -o - | FileCheck --check-prefix=CHECK-EXCEPTIONS %s
+// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-EXCEPTIONS %s
 
 #if __has_feature(cxx_exceptions)
 int foo();
diff --git a/test/Lexer/has_feature_rtti.cpp b/test/Lexer/has_feature_rtti.cpp
index 690906c..4bfeead 100644
--- a/test/Lexer/has_feature_rtti.cpp
+++ b/test/Lexer/has_feature_rtti.cpp
@@ -1,5 +1,5 @@
-// 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
+// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-RTTI %s
+// RUN: %clang_cc1 -E -fno-rtti %s -o - | FileCheck --check-prefix=CHECK-NO-RTTI %s
 
 #if __has_feature(cxx_rtti)
 int foo();
diff --git a/test/Lexer/hexfloat.cpp b/test/Lexer/hexfloat.cpp
index 5a62556..493b64e 100644
--- a/test/Lexer/hexfloat.cpp
+++ b/test/Lexer/hexfloat.cpp
@@ -1,5 +1,6 @@
-//RUN: %clang_cc1 -fsyntax-only -verify
-//RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// XFAIL: *
 
 #ifndef __GXX_EXPERIMENTAL_CXX0X__
 float f = 0x1p+1; // expected-warning {{incompatible with C++0x}}
diff --git a/test/Lexer/constants-ms.c b/test/Lexer/ms-extensions.c
similarity index 100%
rename from test/Lexer/constants-ms.c
rename to test/Lexer/ms-extensions.c
diff --git a/test/Lexer/preamble.c b/test/Lexer/preamble.c
new file mode 100644
index 0000000..69cdbb7
--- /dev/null
+++ b/test/Lexer/preamble.c
@@ -0,0 +1,37 @@
+// Preamble detection test: see below for comments and test commands.
+//
+#include <blah>
+#ifndef FOO
+#else
+#ifdef BAR
+#elif WIBBLE
+#endif
+#pragma unknown
+#endif
+#ifdef WIBBLE
+#include "honk"
+#else
+int foo();
+#endif
+
+// This test checks for detection of the preamble of a file, which
+// includes all of the starting comments and #includes. Note that any
+// changes to the preamble part of this file must be mirrored in
+// Inputs/preamble.txt, since we diff against it.
+
+// RUN: %clang_cc1 -print-preamble %s > %t
+// RUN: echo END. >> %t
+// RUN: FileCheck < %t %s
+// XFAIL: win32
+
+// CHECK: // Preamble detection test: see below for comments and test commands.
+// CHECK-NEXT: //
+// CHECK-NEXT: #include <blah>
+// CHECK-NEXT: #ifndef FOO
+// CHECK-NEXT: #else
+// CHECK-NEXT: #ifdef BAR
+// CHECK-NEXT: #elif WIBBLE
+// CHECK-NEXT: #endif
+// CHECK-NEXT: #pragma unknown
+// CHECK-NEXT: #endif
+// CHECK-NEXT: END.
diff --git a/test/Makefile b/test/Makefile
index e9d8945..5bb50c6 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,5 +1,5 @@
-LEVEL = ../../..
-include $(LEVEL)/Makefile.common
+CLANG_LEVEL := ..
+include $(CLANG_LEVEL)/Makefile
 
 # Test in all immediate subdirectories if unset.
 ifdef TESTSUITE
@@ -18,7 +18,7 @@
 ifdef VERBOSE
 TESTARGS = -v
 else
-TESTARGS = -s -v
+TESTARGS = -s -v 
 endif
 endif
 
diff --git a/test/Misc/diag-aka-types.cpp b/test/Misc/diag-aka-types.cpp
new file mode 100644
index 0000000..7233c4e
--- /dev/null
+++ b/test/Misc/diag-aka-types.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+struct X {};
+typedef X foo_t;
+
+foo_t *ptr;
+char c1 = ptr; // expected-error{{'foo_t *' (aka 'X *')}}
+
+const foo_t &ref = foo_t();
+char c2 = ref; // expected-error{{'foo_t const' (aka 'X const')}}
diff --git a/test/Misc/macro-backtrace-limit.c b/test/Misc/macro-backtrace-limit.c
new file mode 100644
index 0000000..1e512fe
--- /dev/null
+++ b/test/Misc/macro-backtrace-limit.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -fmacro-backtrace-limit 5 %s > %t 2>&1 
+// RUN: FileCheck %s < %t
+
+#define M1(A, B) ((A) < (B))
+#define M2(A, B) M1(A, B)
+#define M3(A, B) M2(A, B)
+#define M4(A, B) M3(A, B)
+#define M5(A, B) M4(A, B)
+#define M6(A, B) M5(A, B)
+#define M7(A, B) M6(A, B)
+#define M8(A, B) M7(A, B)
+#define M9(A, B) M8(A, B)
+#define M10(A, B) M9(A, B)
+#define M11(A, B) M10(A, B)
+#define M12(A, B) M11(A, B)
+
+void f(int *ip, float *fp) {
+  // CHECK: macro-backtrace-limit.c:31:7: warning: comparison of distinct pointer types ('int *' and 'float *')
+  // CHECK: if (M12(ip, fp)) { }
+  // CHECK: macro-backtrace-limit.c:15:19: note: instantiated from:
+  // CHECK: #define M12(A, B) M11(A, B)
+  // CHECK: macro-backtrace-limit.c:14:19: note: instantiated from:
+  // CHECK: #define M11(A, B) M10(A, B)
+  // CHECK: note: (skipping 7 contexts in backtrace; use -fmacro-backtrace-limit=0 to see all)
+  // CHECK: macro-backtrace-limit.c:6:18: note: instantiated from:
+  // CHECK: #define M3(A, B) M2(A, B)
+  // CHECK: macro-backtrace-limit.c:5:18: note: instantiated from:
+  // CHECK: #define M2(A, B) M1(A, B)
+  // CHECK: macro-backtrace-limit.c:4:23: note: instantiated from:
+  // CHECK: #define M1(A, B) ((A) < (B))
+  if (M12(ip, fp)) { }
+}
diff --git a/test/Misc/verify.c b/test/Misc/verify.c
new file mode 100644
index 0000000..85b034e
--- /dev/null
+++ b/test/Misc/verify.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct s; // expected-note 7 {{forward declaration of 'struct s'}}
+
+// standard string matching
+struct s s1; // expected-error {{tentative definition has type 'struct s' that is never completed}}
+struct s s2; // expected-error {{tentative definition has type}}
+
+// regex matching
+struct s r1; // expected-error-re {{tentative definition has type 'struct s' that is never completed}}
+struct s r2; // expected-error-re {{tentative definition has type '.*[[:space:]]*.*' that is never completed}}
+struct s r3; // expected-error-re {{tentative definition has type '(.*)[[:space:]]*(.*)' that is never completed}}
+struct s r4; // expected-error-re {{^tentative}}
+struct s r5; // expected-error-re {{completed$}}
diff --git a/test/PCH/Inputs/chain-cxx1.h b/test/PCH/Inputs/chain-cxx1.h
new file mode 100644
index 0000000..7ea3ffb
--- /dev/null
+++ b/test/PCH/Inputs/chain-cxx1.h
@@ -0,0 +1,19 @@
+// Primary header for C++ chained PCH test
+
+void f();
+
+// Name not appearing in dependent
+void pf();
+
+namespace ns {
+  void g();
+
+  void pg();
+}
+
+template <typename T>
+struct S { typedef int G; };
+
+// Partially specialize
+template <typename T>
+struct S<T *> { typedef int H; };
diff --git a/test/PCH/Inputs/chain-cxx2.h b/test/PCH/Inputs/chain-cxx2.h
new file mode 100644
index 0000000..adc10fd
--- /dev/null
+++ b/test/PCH/Inputs/chain-cxx2.h
@@ -0,0 +1,32 @@
+// Dependent header for C++ chained PCH test
+
+// Overload function from primary
+void f(int);
+
+// Add function with different name
+void f2();
+
+// Reopen namespace
+namespace ns {
+  // Overload function from primary
+  void g(int);
+
+  // Add different name
+  void g2();
+}
+
+// Specialize template from primary
+template <>
+struct S<int> { typedef int I; };
+
+// Partially specialize
+template <typename T>
+struct S<T &> { typedef int J; };
+
+// Specialize previous partial specialization
+template <>
+struct S<int *> { typedef int K; };
+
+// Specialize the partial specialization from this file
+template <>
+struct S<int &> { typedef int L; };
diff --git a/test/PCH/Inputs/chain-decls1.h b/test/PCH/Inputs/chain-decls1.h
new file mode 100644
index 0000000..9de4461
--- /dev/null
+++ b/test/PCH/Inputs/chain-decls1.h
@@ -0,0 +1,11 @@
+void f();
+
+struct one {};
+void two();
+
+void many(int i);
+struct many;
+void many(int j);
+struct many;
+
+void noret();
diff --git a/test/PCH/Inputs/chain-decls2.h b/test/PCH/Inputs/chain-decls2.h
new file mode 100644
index 0000000..b8b7d04
--- /dev/null
+++ b/test/PCH/Inputs/chain-decls2.h
@@ -0,0 +1,12 @@
+void g();
+
+struct two {};
+void one();
+struct three {}; // for verification
+
+void many(int k);
+struct many;
+void many(int l);
+struct many {};
+
+void noret() __attribute__((noreturn));
diff --git a/test/PCH/Inputs/chain-ext_vector1.h b/test/PCH/Inputs/chain-ext_vector1.h
new file mode 100644
index 0000000..5109336
--- /dev/null
+++ b/test/PCH/Inputs/chain-ext_vector1.h
@@ -0,0 +1,3 @@
+// First header file for chain-ext_vector.c PCH test
+
+typedef __attribute__((ext_vector_type(2))) float float2;
diff --git a/test/PCH/Inputs/chain-ext_vector2.h b/test/PCH/Inputs/chain-ext_vector2.h
new file mode 100644
index 0000000..bdaeccc
--- /dev/null
+++ b/test/PCH/Inputs/chain-ext_vector2.h
@@ -0,0 +1,3 @@
+// Second header file for chain-ext_vector.c PCH test
+
+typedef __attribute__((ext_vector_type(4))) float float4;
diff --git a/test/PCH/Inputs/chain-external-defs1.h b/test/PCH/Inputs/chain-external-defs1.h
new file mode 100644
index 0000000..36a2653
--- /dev/null
+++ b/test/PCH/Inputs/chain-external-defs1.h
@@ -0,0 +1,13 @@
+// Helper 1 for chain-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/Inputs/chain-external-defs2.h b/test/PCH/Inputs/chain-external-defs2.h
new file mode 100644
index 0000000..72af92f
--- /dev/null
+++ b/test/PCH/Inputs/chain-external-defs2.h
@@ -0,0 +1,11 @@
+// Helper 2 for chain-external-defs.c test
+
+// Tentative definitions
+int y;
+int y2;
+
+// Should still not show up
+static int z;
+
+int incomplete_array[];
+int incomplete_array3[];
diff --git a/test/PCH/Inputs/chain-macro-override1.h b/test/PCH/Inputs/chain-macro-override1.h
new file mode 100644
index 0000000..4f9321d
--- /dev/null
+++ b/test/PCH/Inputs/chain-macro-override1.h
@@ -0,0 +1,4 @@
+void f() __attribute__((unavailable));
+void g();
+#define g() f()
+#define h() f()
diff --git a/test/PCH/Inputs/chain-macro-override2.h b/test/PCH/Inputs/chain-macro-override2.h
new file mode 100644
index 0000000..f279e2a
--- /dev/null
+++ b/test/PCH/Inputs/chain-macro-override2.h
@@ -0,0 +1,4 @@
+#define f() g()
+#undef g
+#undef h
+#define h() g()
diff --git a/test/PCH/Inputs/chain-macro1.h b/test/PCH/Inputs/chain-macro1.h
new file mode 100644
index 0000000..2e80e47
--- /dev/null
+++ b/test/PCH/Inputs/chain-macro1.h
@@ -0,0 +1 @@
+#define FOOBAR void f();
diff --git a/test/PCH/Inputs/chain-macro2.h b/test/PCH/Inputs/chain-macro2.h
new file mode 100644
index 0000000..e888228
--- /dev/null
+++ b/test/PCH/Inputs/chain-macro2.h
@@ -0,0 +1 @@
+#define BARFOO void g();
diff --git a/test/PCH/Inputs/chain-selectors1.h b/test/PCH/Inputs/chain-selectors1.h
new file mode 100644
index 0000000..37c1c00
--- /dev/null
+++ b/test/PCH/Inputs/chain-selectors1.h
@@ -0,0 +1,12 @@
+@interface X
+  -(void)f;
+  -(void)f2;
+  -(void)g:(int)p;
+  -(void)h:(int)p1 foo:(int)p2;
+@end
+
+void foo1() {
+  // FIXME: Can't verify warnings in headers
+  //(void)@selector(x);
+  (void)@selector(f);
+}
diff --git a/test/PCH/Inputs/chain-selectors2.h b/test/PCH/Inputs/chain-selectors2.h
new file mode 100644
index 0000000..4d6b556
--- /dev/null
+++ b/test/PCH/Inputs/chain-selectors2.h
@@ -0,0 +1,11 @@
+@interface Y
+  -(void)f;
+  -(double)f2;
+  -(void)e;
+@end
+
+void foo2() {
+  // FIXME: Can't verify warnings in headers
+  //(void)@selector(y);
+  //(void)@selector(e);
+}
diff --git a/test/PCH/Inputs/chain-trivial1.h b/test/PCH/Inputs/chain-trivial1.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/PCH/Inputs/chain-trivial1.h
diff --git a/test/PCH/Inputs/chain-trivial2.h b/test/PCH/Inputs/chain-trivial2.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/PCH/Inputs/chain-trivial2.h
diff --git a/test/PCH/Inputs/namespaces.h b/test/PCH/Inputs/namespaces.h
index 1bab746..553aadd 100644
--- a/test/PCH/Inputs/namespaces.h
+++ b/test/PCH/Inputs/namespaces.h
@@ -6,8 +6,35 @@
 
 namespace N1 {
   typedef int t2;
+
+  void used_func();
+
+  struct used_cls { };
 }
 
 namespace N2 {
   typedef float t1;
+
+  namespace Inner {
+    typedef int t3;
+  };
+}
+
+namespace {
+  void anon() { }
+  class C;
+}
+
+namespace N3 {
+  namespace {
+    class C;
+  }
+}
+
+namespace Alias1 = N2::Inner;
+
+using namespace N2::Inner;
+
+extern "C" {
+  void ext();
 }
diff --git a/test/PCH/Inputs/preamble.h b/test/PCH/Inputs/preamble.h
new file mode 100644
index 0000000..aee330a
--- /dev/null
+++ b/test/PCH/Inputs/preamble.h
@@ -0,0 +1 @@
+int f(int);
diff --git a/test/PCH/attrs.h b/test/PCH/attrs.h
index 0d01565..58f0589 100644
--- a/test/PCH/attrs.h
+++ b/test/PCH/attrs.h
@@ -4,4 +4,4 @@
 
 
 
-int f(int) __attribute__((overloadable));
+int f(int) __attribute__((visibility("default"), overloadable));
diff --git a/test/PCH/chain-cxx.cpp b/test/PCH/chain-cxx.cpp
new file mode 100644
index 0000000..3e46214
--- /dev/null
+++ b/test/PCH/chain-cxx.cpp
@@ -0,0 +1,28 @@
+// Test C++ chained PCH functionality
+
+// Without PCH
+// RUN: %clang_cc1 -fsyntax-only -verify -include %S/Inputs/chain-cxx1.h -include %S/Inputs/chain-cxx2.h %s
+
+// With PCH
+// RUN: %clang_cc1 -x c++ -emit-pch -o %t1 %S/Inputs/chain-cxx1.h
+// RUN: %clang_cc1 -x c++ -emit-pch -o %t2 %S/Inputs/chain-cxx2.h -include-pch %t1 -chained-pch
+// RUN: %clang_cc1 -fsyntax-only -verify -include-pch %t2 %s
+
+void test() {
+  f();
+  f(1);
+  pf();
+  f2();
+
+  ns::g();
+  ns::g(1);
+  ns::pg();
+  ns::g2();
+
+  typedef S<double>::G T1;
+  typedef S<double *>::H T2;
+  typedef S<int>::I T3;
+  typedef S<double &>::J T4;
+  typedef S<int *>::K T5;
+  typedef S<int &>::L T6;
+}
diff --git a/test/PCH/chain-decls.c b/test/PCH/chain-decls.c
new file mode 100644
index 0000000..b3daa4a
--- /dev/null
+++ b/test/PCH/chain-decls.c
@@ -0,0 +1,27 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/Inputs/chain-decls1.h -include %S/Inputs/chain-decls2.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t1 %S/Inputs/chain-decls1.h
+// RUN: %clang_cc1 -emit-pch -o %t2 %S/Inputs/chain-decls2.h -include-pch %t1 -chained-pch
+// RUN: %clang_cc1 -include-pch %t2 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -ast-print -include-pch %t2 %s | FileCheck %s
+
+// CHECK: void f();
+// CHECK: void g();
+
+int h() {
+  f();
+  g();
+
+  struct one x;
+  one();
+  struct two y;
+  two();
+  struct three z;
+
+  many(0);
+  struct many m;
+
+  noret();
+}
diff --git a/test/PCH/chain-ext_vector.c b/test/PCH/chain-ext_vector.c
new file mode 100644
index 0000000..2635070
--- /dev/null
+++ b/test/PCH/chain-ext_vector.c
@@ -0,0 +1,11 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/Inputs/chain-ext_vector1.h -include %S/Inputs/chain-ext_vector2.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t1 %S/Inputs/chain-ext_vector1.h
+// RUN: %clang_cc1 -emit-pch -o %t2 %S/Inputs/chain-ext_vector2.h -include-pch %t1 -chained-pch
+// RUN: %clang_cc1 -include-pch %t2 -fsyntax-only -verify %s
+
+int test(float4 f4) {
+  return f4.xy; // expected-error{{float2}}
+}
diff --git a/test/PCH/chain-external-defs.c b/test/PCH/chain-external-defs.c
new file mode 100644
index 0000000..dd92d8e
--- /dev/null
+++ b/test/PCH/chain-external-defs.c
@@ -0,0 +1,54 @@
+// Test with pch.
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-pch -o %t1.pch %S/Inputs/chain-external-defs1.h
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-pch -o %t2.pch %S/Inputs/chain-external-defs2.h -include-pch %t1.pch -chained-pch
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -include-pch %t2.pch -emit-llvm -o %t %s
+// RUN: echo FINI >> %t
+// RUN: FileCheck -input-file=%t -check-prefix=Z %s
+// RUN: FileCheck -input-file=%t -check-prefix=XA %s
+// RUN: FileCheck -input-file=%t -check-prefix=YA %s
+// RUN: FileCheck -input-file=%t -check-prefix=XB %s
+// RUN: FileCheck -input-file=%t -check-prefix=YB %s
+// RUN: FileCheck -input-file=%t -check-prefix=AA %s
+// RUN: FileCheck -input-file=%t -check-prefix=AB %s
+// RUN: FileCheck -input-file=%t -check-prefix=AC %s
+// RUN: FileCheck -input-file=%t -check-prefix=S %s
+
+// Z-NOT: @z
+
+// XA: @x = common global i32 0
+// XA-NOT: @x = common global i32 0
+
+// YA: @y = common global i32 0
+// YA-NOT: @y = common global i32 0
+
+// XB: @x2 = global i32 19
+// XB-NOT: @x2 = global i32 19
+int x2 = 19;
+// YB: @y2 = global i32 18
+// YB-NOT: @y2 = global i32 18
+int y2 = 18;
+
+// AA: @incomplete_array = common global [1 x i32]
+// AA-NOT: @incomplete_array = common global [1 x i32]
+// AB: @incomplete_array2 = common global [17 x i32]
+// AB-NOT: @incomplete_array2 = common global [17 x i32]
+int incomplete_array2[17];
+// AC: @incomplete_array3 = common global [1 x i32]
+// AC-NOT: @incomplete_array3 = common global [1 x i32]
+int incomplete_array3[];
+
+// S: @s = common global %struct.S
+// S-NOT: @s = common global %struct.S
+struct S {
+  int x, y;
+};
+
+// Z: FINI
+// XA: FINI
+// YA: FINI
+// XB: FINI
+// YB: FINI
+// AA: FINI
+// AB: FINI
+// AC: FINI
+// S: FINI
diff --git a/test/PCH/chain-macro-override.c b/test/PCH/chain-macro-override.c
new file mode 100644
index 0000000..14478af
--- /dev/null
+++ b/test/PCH/chain-macro-override.c
@@ -0,0 +1,13 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/Inputs/chain-macro-override1.h -include %S/Inputs/chain-macro-override2.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t1 %S/Inputs/chain-macro-override1.h
+// RUN: %clang_cc1 -emit-pch -o %t2 %S/Inputs/chain-macro-override2.h -include-pch %t1 -chained-pch
+// RUN: %clang_cc1 -include-pch %t2 -fsyntax-only -verify %s
+
+void foo() {
+  f();
+  g();
+  h();
+}
diff --git a/test/PCH/chain-macro.c b/test/PCH/chain-macro.c
new file mode 100644
index 0000000..b4dcdfe
--- /dev/null
+++ b/test/PCH/chain-macro.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-pch -o %t1 %S/Inputs/chain-macro1.h
+// RUN: %clang_cc1 -emit-pch -o %t2 %S/Inputs/chain-macro2.h -include-pch %t1 -chained-pch
+// RUN: %clang_cc1 -fsyntax-only -verify -include-pch %t2 %s
+// RUN: %clang_cc1 -ast-print -include-pch %t2 %s | FileCheck %s
+
+// CHECK: void f();
+FOOBAR
+// CHECK: void g();
+BARFOO
diff --git a/test/PCH/chain-predecl.h b/test/PCH/chain-predecl.h
new file mode 100644
index 0000000..bd332ff
--- /dev/null
+++ b/test/PCH/chain-predecl.h
@@ -0,0 +1,3 @@
+// First header for chain-predecl.m
+@class Foo;
+@protocol Pro;
diff --git a/test/PCH/chain-predecl.m b/test/PCH/chain-predecl.m
new file mode 100644
index 0000000..2b0444e
--- /dev/null
+++ b/test/PCH/chain-predecl.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-pch -o %t1 %S/chain-predecl.h -x objective-c
+// RUN: %clang_cc1 -emit-pch -o %t2 %s -x objective-c -include-pch %t1 -chained-pch
+
+// Test predeclarations across chained PCH.
+@interface Foo
+-(void)bar;
+@end
+@interface Boom
+-(void)bar;
+@end
+@protocol Pro
+-(void)baz;
+@end
+@protocol Kaboom
+-(void)baz;
+@end
diff --git a/test/PCH/chain-selectors.m b/test/PCH/chain-selectors.m
new file mode 100644
index 0000000..60db3f9
--- /dev/null
+++ b/test/PCH/chain-selectors.m
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wselector -include %S/Inputs/chain-selectors1.h -include %S/Inputs/chain-selectors2.h
+
+// RUN: %clang_cc1 -x objective-c -emit-pch -o %t1 %S/Inputs/chain-selectors1.h
+// RUN: %clang_cc1 -x objective-c -emit-pch -o %t2 %S/Inputs/chain-selectors2.h -include-pch %t1 -chained-pch
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wselector -include-pch %t2
+
+@implementation X
+-(void)f {}
+-(void)f2 {}
+-(void)g: (int)p {}
+-(void)h: (int)p1 foo: (int)p2 {}
+@end
+
+void bar() {
+  id a = 0;
+  [a nothing]; // expected-warning {{method '-nothing' not found}}
+  [a f];
+  // FIXME: Can't verify notes in headers
+  //[a f2];
+
+  (void)@selector(x); // expected-warning {{unimplemented selector}}
+  (void)@selector(y); // expected-warning {{unimplemented selector}}
+  (void)@selector(e); // expected-warning {{unimplemented selector}}
+}
diff --git a/test/PCH/chain-trivial.c b/test/PCH/chain-trivial.c
new file mode 100644
index 0000000..c78b0e4
--- /dev/null
+++ b/test/PCH/chain-trivial.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-pch -o %t1 %S/Inputs/chain-trivial1.h
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-pch -o %t2 -include-pch %t1 -chained-pch %S/Inputs/chain-trivial2.h
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-print -include-pch %t2 %s | FileCheck %s
+// CHECK: struct __va_list_tag {
diff --git a/test/PCH/cxx-friends.cpp b/test/PCH/cxx-friends.cpp
new file mode 100644
index 0000000..a8d7558
--- /dev/null
+++ b/test/PCH/cxx-friends.cpp
@@ -0,0 +1,13 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/cxx-friends.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-friends.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+class F {
+  void m() {
+    A* a;
+    a->x = 0;
+  }
+};
diff --git a/test/PCH/cxx-friends.h b/test/PCH/cxx-friends.h
new file mode 100644
index 0000000..2a33f15
--- /dev/null
+++ b/test/PCH/cxx-friends.h
@@ -0,0 +1,6 @@
+// Header for PCH test cxx-friends.cpp
+
+class A {
+  int x;
+  friend class F;
+};
diff --git a/test/PCH/cxx-namespaces.cpp b/test/PCH/cxx-namespaces.cpp
new file mode 100644
index 0000000..0fd3de7
--- /dev/null
+++ b/test/PCH/cxx-namespaces.cpp
@@ -0,0 +1,10 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/cxx-namespaces.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-namespaces.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+void m() {
+  N::x = 0;
+}
diff --git a/test/PCH/cxx-namespaces.h b/test/PCH/cxx-namespaces.h
new file mode 100644
index 0000000..f338953
--- /dev/null
+++ b/test/PCH/cxx-namespaces.h
@@ -0,0 +1,7 @@
+// Header for PCH test cxx-namespaces.cpp
+
+namespace N {
+    namespace {
+        int x;
+    }
+}
diff --git a/test/PCH/cxx-offsetof-base.cpp b/test/PCH/cxx-offsetof-base.cpp
new file mode 100644
index 0000000..18265de
--- /dev/null
+++ b/test/PCH/cxx-offsetof-base.cpp
@@ -0,0 +1,2 @@
+// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-offsetof-base.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only %s 
diff --git a/test/PCH/cxx-offsetof-base.h b/test/PCH/cxx-offsetof-base.h
new file mode 100644
index 0000000..7c78101
--- /dev/null
+++ b/test/PCH/cxx-offsetof-base.h
@@ -0,0 +1,5 @@
+// Header for PCH test cxx-offsetof-base.cpp
+
+struct Base { int x; };
+struct Derived : Base { int y; };
+int o = __builtin_offsetof(Derived, x);
diff --git a/test/PCH/cxx-required-decls.cpp b/test/PCH/cxx-required-decls.cpp
new file mode 100644
index 0000000..8c4b11c
--- /dev/null
+++ b/test/PCH/cxx-required-decls.cpp
@@ -0,0 +1,10 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/cxx-required-decls.h %s -emit-llvm -o - | FileCheck %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-required-decls.h
+// RUN: %clang_cc1 -include-pch %t %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: @_ZL5globS = internal global %struct.S zeroinitializer
+// CHECK: @_ZL3bar = internal global i32 0, align 4
+// CHECK: @glob_var = global i32 0
diff --git a/test/PCH/cxx-required-decls.h b/test/PCH/cxx-required-decls.h
new file mode 100644
index 0000000..099d2da
--- /dev/null
+++ b/test/PCH/cxx-required-decls.h
@@ -0,0 +1,12 @@
+// Header for PCH test cxx-required-decls.cpp
+
+struct S {
+  S();
+};
+
+static S globS;
+
+extern int ext_foo;
+static int bar = ++ext_foo;
+
+int glob_var;
diff --git a/test/PCH/cxx-static_assert.cpp b/test/PCH/cxx-static_assert.cpp
new file mode 100644
index 0000000..3440921
--- /dev/null
+++ b/test/PCH/cxx-static_assert.cpp
@@ -0,0 +1,11 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/cxx-static_assert.h -verify -std=c++0x %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x c++-header -std=c++0x -emit-pch -o %t %S/cxx-static_assert.h
+// RUN: %clang_cc1 -include-pch %t -verify -std=c++0x %s 
+
+// 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;
diff --git a/test/PCH/cxx-static_assert.h b/test/PCH/cxx-static_assert.h
new file mode 100644
index 0000000..ba41ab8
--- /dev/null
+++ b/test/PCH/cxx-static_assert.h
@@ -0,0 +1,9 @@
+// Header for PCH test cxx-static_assert.cpp
+
+
+
+
+
+template<int N> struct T {
+    static_assert(N == 2, "N is not 2!");
+};
diff --git a/test/PCH/cxx-templates.cpp b/test/PCH/cxx-templates.cpp
new file mode 100644
index 0000000..a862ea5
--- /dev/null
+++ b/test/PCH/cxx-templates.cpp
@@ -0,0 +1,35 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/cxx-templates.h -verify %s -ast-dump -o -
+// RUN: %clang_cc1 -include %S/cxx-templates.h %s -emit-llvm -o - | FileCheck %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-templates.h
+// RUN: %clang_cc1 -include-pch %t -verify %s -ast-dump  -o -
+// RUN: %clang_cc1 -include-pch %t %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: define weak_odr void @_ZN2S4IiE1mEv
+// CHECK: define linkonce_odr void @_ZN2S3IiE1mEv
+
+struct A {
+  typedef int type;
+  static void my_f();
+  template <typename T>
+  static T my_templf(T x) { return x; }
+};
+
+void test() {
+  int x = templ_f<int, 5>(3);
+  
+  S<char, float>::templ();
+  S<int, char>::partial();
+  S<int, float>::explicit_special();
+  
+  Dep<A>::Ty ty;
+  Dep<A> a;
+  a.f();
+  
+  S3<int> s3;
+  s3.m();
+}
+
+template struct S4<int>;
diff --git a/test/PCH/cxx-templates.h b/test/PCH/cxx-templates.h
new file mode 100644
index 0000000..978d768
--- /dev/null
+++ b/test/PCH/cxx-templates.h
@@ -0,0 +1,137 @@
+// Header for PCH test cxx-templates.cpp
+
+template <typename T1, typename T2>
+struct S;
+
+template <typename T1, typename T2>
+struct S {
+  S() { }
+  static void templ();
+};
+
+template <typename T>
+struct S<int, T> {
+    static void partial();
+};
+
+template <>
+struct S<int, float> {
+    static void explicit_special();
+};
+
+template <int x>
+int tmpl_f2() { return x; }
+
+template <typename T, int y>
+T templ_f(T x) {
+  int z = templ_f<int, 5>(3);
+  z = tmpl_f2<y+2>();
+  T data[y];
+  return x+y;
+}
+
+void govl(int);
+void govl(char);
+
+template <typename T>
+struct Unresolv {
+  void f() {
+    govl(T());
+  }
+};
+
+template <typename T>
+struct Dep {
+  typedef typename T::type Ty;
+  void f() {
+    Ty x = Ty();
+    T::my_f();
+    int y = T::template my_templf<int>(0);
+    ovl(y);
+  }
+  
+  void ovl(int);
+  void ovl(float);
+};
+
+template<typename T, typename A1>
+inline T make_a(const A1& a1) {
+  T::depend_declref();
+  return T(a1);
+}
+
+template <class T> class UseBase {
+  void foo();
+  typedef int bar;
+};
+
+template <class T> class UseA : public UseBase<T> {
+  using UseBase<T>::foo;
+  using typename UseBase<T>::bar; 
+};
+
+template <class T> class Sub : public UseBase<int> { };
+
+template <class _Ret, class _Tp>
+  class mem_fun_t
+  {
+  public:
+    explicit
+    mem_fun_t(_Ret (_Tp::*__pf)())
+     {}
+
+  private:
+    _Ret (_Tp::*_M_f)();
+  };
+
+template<unsigned N>
+bool isInt(int x);
+
+template<> bool isInt<8>(int x) {
+  try { ++x; } catch(...) { --x; }
+  return true;
+}
+
+template<typename _CharT>
+int __copy_streambufs_eof(_CharT);
+
+class basic_streambuf 
+{
+  void m() { }
+  friend int __copy_streambufs_eof<>(int);
+};
+
+// PR 7660
+template<typename T> struct S_PR7660 { void g(void (*)(T)); };
+ template<> void S_PR7660<int>::g(void(*)(int)) {}
+
+// PR 7670
+template<typename> class C_PR7670;
+template<> class C_PR7670<int>;
+template<> class C_PR7670<int>;
+
+template <bool B>
+struct S2 {
+    static bool V;
+};
+
+extern template class S2<true>;
+
+template <typename T>
+struct S3 {
+    void m();
+};
+
+template <typename T>
+inline void S3<T>::m() { }
+
+template <typename T>
+struct S4 {
+    void m() { }
+};
+extern template struct S4<int>;
+
+void S4ImplicitInst() {
+    S4<int> s;
+    s.m();
+}
diff --git a/test/PCH/cxx-traits.cpp b/test/PCH/cxx-traits.cpp
new file mode 100644
index 0000000..69c6475
--- /dev/null
+++ b/test/PCH/cxx-traits.cpp
@@ -0,0 +1,8 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/cxx-traits.h -fsyntax-only -verify %s
+
+// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-traits.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s
+
+bool _Is_pod_comparator = __is_pod<int>::__value;
+bool _Is_empty_check = __is_empty<int>::__value;
diff --git a/test/PCH/cxx-traits.h b/test/PCH/cxx-traits.h
new file mode 100644
index 0000000..62722ab
--- /dev/null
+++ b/test/PCH/cxx-traits.h
@@ -0,0 +1,11 @@
+// Header for PCH test cxx-traits.cpp
+
+template<typename _Tp>
+struct __is_pod {
+  enum { __value };
+};
+
+template<typename _Tp>
+struct __is_empty {
+  enum { __value };
+};
diff --git a/test/PCH/cxx-typeid.cpp b/test/PCH/cxx-typeid.cpp
new file mode 100644
index 0000000..41dd544
--- /dev/null
+++ b/test/PCH/cxx-typeid.cpp
@@ -0,0 +1,9 @@
+// Test this without pch.
+// RUN: %clang -include %S/cxx-typeid.h -fsyntax-only -Xclang -verify %s
+
+// RUN: %clang -ccc-pch-is-pch -x c++-header -o %t.gch %S/cxx-typeid.h
+// RUN: %clang -ccc-pch-is-pch -include %t -fsyntax-only -Xclang -verify %s 
+
+void f() {
+    (void)typeid(int);
+}
diff --git a/test/PCH/cxx-typeid.h b/test/PCH/cxx-typeid.h
new file mode 100644
index 0000000..aa3b16a
--- /dev/null
+++ b/test/PCH/cxx-typeid.h
@@ -0,0 +1,3 @@
+// Header for PCH test cxx-typeid.cpp
+
+#include <typeinfo>
diff --git a/test/PCH/cxx-using.cpp b/test/PCH/cxx-using.cpp
new file mode 100644
index 0000000..2ca7dad
--- /dev/null
+++ b/test/PCH/cxx-using.cpp
@@ -0,0 +1,15 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/cxx-using.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-using.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+void m() {
+    D s;   // expected-note {{candidate function}}
+    s.f(); // expected-error {{no matching member}}
+}
+
+
+
+// expected-note {{candidate function}}
diff --git a/test/PCH/cxx-using.h b/test/PCH/cxx-using.h
new file mode 100644
index 0000000..572cea2
--- /dev/null
+++ b/test/PCH/cxx-using.h
@@ -0,0 +1,16 @@
+// Header for PCH test cxx-using.cpp
+
+
+
+
+
+
+struct B {
+    void f(char c);
+};
+
+struct D : B 
+{
+    using B::f;
+    void f(int);
+};
diff --git a/test/PCH/cxx_exprs.cpp b/test/PCH/cxx_exprs.cpp
index 0f0fe88..2b9a5ab 100644
--- a/test/PCH/cxx_exprs.cpp
+++ b/test/PCH/cxx_exprs.cpp
@@ -1,9 +1,9 @@
 // Test this without pch.
-// RUN: %clang_cc1 -include %S/cxx_exprs.h -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -include %S/cxx_exprs.h -std=c++0x -fsyntax-only -verify %s -ast-dump
 
-// Test with pch.
+// Test with pch. Use '-ast-dump' to force deserialization of function bodies.
 // 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 
+// RUN: %clang_cc1 -std=c++0x -include-pch %t -fsyntax-only -verify %s -ast-dump
 
 int integer;
 double floating;
@@ -33,3 +33,7 @@
 
 // CXXNullPtrLiteralExpr
 cxx_null_ptr_result null_ptr = nullptr;
+
+// CXXTypeidExpr
+typeid_result1 typeid_1 = 0;
+typeid_result2 typeid_2 = 0;
diff --git a/test/PCH/cxx_exprs.h b/test/PCH/cxx_exprs.h
index a871aa2..67ab4a6 100644
--- a/test/PCH/cxx_exprs.h
+++ b/test/PCH/cxx_exprs.h
@@ -1,11 +1,12 @@
 // 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 { };
+struct Base { Base(int); virtual void f(int x = 492); ~Base(); };
+struct Derived : Base { Derived(); void g(); };
 Base *base_ptr;
 typedef __typeof__(dynamic_cast<Derived *>(base_ptr)) dynamic_cast_result;
 
@@ -27,3 +28,56 @@
 
 // CXXNullPtrLiteralExpr
 typedef __typeof__(nullptr) cxx_null_ptr_result;
+
+void foo(Derived *P) {
+  // CXXMemberCallExpr
+  P->f(12);
+}
+
+
+// FIXME: This is a hack until <typeinfo> works completely.
+namespace std {
+  class type_info {};
+}
+
+// CXXTypeidExpr - Both expr and type forms.
+typedef __typeof__(typeid(int))* typeid_result1;
+typedef __typeof__(typeid(2))*   typeid_result2;
+
+Derived foo();
+
+Derived::Derived() : Base(4) {
+}
+
+void Derived::g() {
+  // CXXThisExpr
+  f(2);        // Implicit
+  this->f(1);  // Explicit
+  
+  // CXXThrowExpr
+  throw;
+  throw 42;
+  
+  // CXXDefaultArgExpr
+  f();
+  
+  const Derived &X = foo();
+  
+  // FIXME: How do I make a CXXBindReferenceExpr, CXXConstructExpr? 
+  
+  int A = int(0.5);  // CXXFunctionalCastExpr
+  A = int();         // CXXZeroInitValueExpr
+  
+  Base *b = new Base(4);       // CXXNewExpr
+  delete b;                    // CXXDeleteExpr
+}
+
+
+// FIXME: The comment on CXXTemporaryObjectExpr is broken, this doesn't make
+// one.
+struct CtorStruct { CtorStruct(int, float); };
+
+CtorStruct create_CtorStruct() {
+  return CtorStruct(1, 3.14f); // CXXTemporaryObjectExpr
+};
+
diff --git a/test/PCH/exprs.c b/test/PCH/exprs.c
index 2b588a2..d855def 100644
--- a/test/PCH/exprs.c
+++ b/test/PCH/exprs.c
@@ -5,6 +5,7 @@
 // RUN: %clang_cc1 -emit-pch -fblocks -o %t %S/exprs.h
 // RUN: %clang_cc1 -fblocks -include-pch %t -fsyntax-only -verify %s 
 
+__SIZE_TYPE__ size_type_value;
 int integer;
 long long_integer;
 double floating;
@@ -35,6 +36,9 @@
 // UnaryOperator
 negate_enum *int_ptr4 = &integer;
 
+// OffsetOfExpr
+offsetof_type *offsetof_ptr = &size_type_value;
+
 // SizeOfAlignOfExpr
 typeof(sizeof(float)) size_t_value;
 typeof_sizeof *size_t_ptr = &size_t_value;
@@ -55,6 +59,8 @@
 // CompoundAssignOperator
 addeq_result *int_ptr6 = &integer;
 
+add_result_with_typeinfo *int_typeinfo_ptr6;
+
 // ConditionalOperator
 conditional_operator *double_ptr4 = &floating;
 
diff --git a/test/PCH/exprs.h b/test/PCH/exprs.h
index 7012422..80768f8 100644
--- a/test/PCH/exprs.h
+++ b/test/PCH/exprs.h
@@ -25,6 +25,19 @@
 // UnaryOperator
 typedef typeof(-Enumerator) negate_enum;
 
+// OffsetOfExpr
+struct X {
+  int member;
+};
+struct Y {
+  struct X array[5];
+};
+struct Z {
+  struct Y y;
+};
+typedef typeof(__builtin_offsetof(struct Z, y.array[1 + 2].member)) 
+  offsetof_type;
+
 // SizeOfAlignOfExpr
 typedef typeof(sizeof(int)) typeof_sizeof;
 typedef typeof(sizeof(Enumerator)) typeof_sizeof2;
@@ -59,6 +72,8 @@
 // CompoundLiteral
 typedef typeof((struct S){.x = 3.5}) compound_literal;
 
+typedef typeof(i + sizeof(int[i + Enumerator])) add_result_with_typeinfo;
+
 // ExtVectorElementExpr
 typedef __attribute__(( ext_vector_type(2) )) double double2;
 extern double2 vec2, vec2b;
diff --git a/test/PCH/namespaces.cpp b/test/PCH/namespaces.cpp
index eef9e06..b8a22e5 100644
--- a/test/PCH/namespaces.cpp
+++ b/test/PCH/namespaces.cpp
@@ -8,7 +8,35 @@
 int int_val;
 N1::t1 *ip1 = &int_val;
 N1::t2 *ip2 = &int_val;
+N2::Inner::t3 *ip3 = &int_val;
 
 float float_val;
 namespace N2 { }
 N2::t1 *fp1 = &float_val;
+
+Alias1::t3 *ip4 = &int_val;
+t3 *ip5 = &int_val;
+
+void(*funp1)() = anon;
+
+namespace {
+  class C;
+}
+C* cp1;
+
+namespace N3 {
+  namespace {
+    class C;
+  }
+}
+
+N3::C *cp2;
+
+void(*funp2)() = ext;
+
+using N1::used_func;
+void (*pused)() = used_func;
+
+using N1::used_cls;
+used_cls s1;
+used_cls* ps1 = &s1;
diff --git a/test/PCH/objcxx-ivar-class.h b/test/PCH/objcxx-ivar-class.h
new file mode 100644
index 0000000..50ebda7
--- /dev/null
+++ b/test/PCH/objcxx-ivar-class.h
@@ -0,0 +1,15 @@
+struct S {
+    S();
+    S(const S&);
+    S& operator= (const S&);
+};
+
+@interface C {
+    S position;
+}
+@property(assign, nonatomic) S position;
+@end
+
+@implementation C
+    @synthesize position;
+@end
diff --git a/test/PCH/objcxx-ivar-class.mm b/test/PCH/objcxx-ivar-class.mm
new file mode 100644
index 0000000..89d3e08
--- /dev/null
+++ b/test/PCH/objcxx-ivar-class.mm
@@ -0,0 +1,15 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/objcxx-ivar-class.h -verify %s -emit-llvm -o - | FileCheck %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x objective-c++-header -emit-pch -o %t %S/objcxx-ivar-class.h
+// RUN: %clang_cc1 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: [C position]
+// CHECK: call void @_ZN1SC1ERKS_
+
+// CHECK: [C setPosition:]
+// CHECK: call %struct.S* @_ZN1SaSERKS_
+
+// CHECK: [C .cxx_destruct]
+// CHECK: [C .cxx_construct]
diff --git a/test/PCH/pchpch.c b/test/PCH/pchpch.c
new file mode 100644
index 0000000..d68a6ad
--- /dev/null
+++ b/test/PCH/pchpch.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-pch -o %t1 %S/pchpch1.h
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-pch -o %t2 %S/pchpch2.h -include-pch %t1
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fsyntax-only %s -include-pch %t2
+
+// The purpose of this test is to make sure that a PCH created while including
+// an existing PCH can be loaded.
diff --git a/test/PCH/pchpch1.h b/test/PCH/pchpch1.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/PCH/pchpch1.h
diff --git a/test/PCH/pchpch2.h b/test/PCH/pchpch2.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/PCH/pchpch2.h
diff --git a/test/PCH/pragma-weak.c b/test/PCH/pragma-weak.c
new file mode 100644
index 0000000..18b45c8
--- /dev/null
+++ b/test/PCH/pragma-weak.c
@@ -0,0 +1,10 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/pragma-weak.h %s -verify -emit-llvm -o - | FileCheck %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x c-header -emit-pch -o %t %S/pragma-weak.h
+// RUN: %clang_cc1 -include-pch %t %s -verify -emit-llvm -o - | FileCheck %s
+
+// CHECK: @weakvar = weak global i32 0
+int weakvar;
+// expected-warning {{weak identifier 'undeclaredvar' never declared}}
diff --git a/test/PCH/pragma-weak.h b/test/PCH/pragma-weak.h
new file mode 100644
index 0000000..42ecd50
--- /dev/null
+++ b/test/PCH/pragma-weak.h
@@ -0,0 +1,10 @@
+// Header for PCH test pragma-weak.c
+
+#pragma weak weakvar
+
+
+
+
+
+
+#pragma weak undeclaredvar
diff --git a/test/PCH/preamble.c b/test/PCH/preamble.c
new file mode 100644
index 0000000..bdc0aea
--- /dev/null
+++ b/test/PCH/preamble.c
@@ -0,0 +1,21 @@
+// Check that using the preamble option actually skips the preamble.
+
+// RUN: %clang_cc1 -emit-pch -o %t %S/Inputs/preamble.h
+// RUN: %clang_cc1 -include-pch %t -preamble-bytes=278,1 -DFOO=f -verify %s
+
+float f(int); // Not an error, because we skip this via the preamble!
+
+
+
+
+
+
+
+
+
+
+
+
+int g(int x) {
+  return FOO(x);
+}
diff --git a/test/PCH/pth.c b/test/PCH/pth.c
new file mode 100644
index 0000000..1262f8a
--- /dev/null
+++ b/test/PCH/pth.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-pth -o %t %S/pth.h
+// RUN: %clang_cc1 -triple i386-unknown-unknown -include-pth %t -fsyntax-only %s 2>&1 | FileCheck %s
+
+#error This is the only diagnostic
+
+// CHECK: This is the only diagnostic
+// CHECK: 1 error generated.
\ No newline at end of file
diff --git a/test/PCH/pth.h b/test/PCH/pth.h
new file mode 100644
index 0000000..9ae7021
--- /dev/null
+++ b/test/PCH/pth.h
@@ -0,0 +1,12 @@
+// This case came up when using PTH with Boost (<rdar://problem/8227989>).
+
+# ifndef R8227989_PREPROCESSOR_CONFIG_CONFIG_HPP
+# ifndef R8227989_PP_CONFIG_FLAGS
+# endif
+#
+# ifndef R8227989_PP_CONFIG_ERRORS
+#    ifdef NDEBUG
+#    endif
+# endif
+# endif
+
diff --git a/test/PCH/reinclude.cpp b/test/PCH/reinclude.cpp
new file mode 100644
index 0000000..6ab1002
--- /dev/null
+++ b/test/PCH/reinclude.cpp
@@ -0,0 +1,8 @@
+// Test without PCH
+// RUN: %clang_cc1 %s -include %S/reinclude1.h -include %S/reinclude2.h -fsyntax-only -verify
+
+// RUN: %clang_cc1 -x c++-header %S/reinclude1.h -emit-pch -o %t1
+// RUN: %clang_cc1 -x c++-header %S/reinclude2.h -include-pch %t1 -emit-pch -o %t2
+// RUN: %clang_cc1 %s -include-pch %t2 -fsyntax-only -verify
+
+int q2 = A::y;
diff --git a/test/PCH/reinclude1.h b/test/PCH/reinclude1.h
new file mode 100644
index 0000000..4c8ccae
--- /dev/null
+++ b/test/PCH/reinclude1.h
@@ -0,0 +1,4 @@
+namespace A {
+  int x;
+  int y;
+}
diff --git a/test/PCH/reinclude2.h b/test/PCH/reinclude2.h
new file mode 100644
index 0000000..2aa6d31
--- /dev/null
+++ b/test/PCH/reinclude2.h
@@ -0,0 +1 @@
+int q1 = A::x;
diff --git a/test/PCH/selector-warning.h b/test/PCH/selector-warning.h
new file mode 100644
index 0000000..bd41929
--- /dev/null
+++ b/test/PCH/selector-warning.h
@@ -0,0 +1,24 @@
+typedef struct objc_selector    *SEL;
+
+@interface Foo 
+- (void) NotOK;
+@end
+
+@implementation Foo
+- (void) foo
+{
+  SEL a = @selector(b1ar); 
+  a = @selector(b1ar); 
+  a = @selector(bar);
+  a = @selector(ok);	// expected-warning {{unimplemented selector 'ok'}}
+  a = @selector(ok);
+  a = @selector(NotOK);	// expected-warning {{unimplemented selector 'NotOK'}}
+  a = @selector(NotOK);
+
+  a = @selector(clNotOk);	// expected-warning {{unimplemented selector 'clNotOk'}}
+
+  a = @selector (cl1);
+  a = @selector (cl2);
+  a = @selector (instNotOk);	// expected-warning {{unimplemented selector 'instNotOk'}}
+}
+@end
diff --git a/test/PCH/selector-warning.m b/test/PCH/selector-warning.m
new file mode 100644
index 0000000..413f64f
--- /dev/null
+++ b/test/PCH/selector-warning.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -x objective-c -emit-pch -o %t.h.pch %S/selector-warning.h
+// RUN: %clang_cc1 -include-pch %t.h.pch %s
+
+@interface Bar 
++ (void) clNotOk;
+- (void) instNotOk;
++ (void) cl1;
+@end
+
+@implementation Bar
+- (void) bar {}
++ (void) cl1 {}
++ (void) cl2 {}
+@end
+
+@implementation Bar(CAT)
+- (void) b1ar {}
+@end
+
diff --git a/test/PCH/types.c b/test/PCH/types.c
index c21b33a..73a2205 100644
--- a/test/PCH/types.c
+++ b/test/PCH/types.c
@@ -3,7 +3,7 @@
 
 // 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 
+// RUN: %clang_cc1 -fblocks -include-pch %t -fsyntax-only -verify %s -ast-print
 
 typedef int INT;
 INT int_value;
diff --git a/test/PCH/types.h b/test/PCH/types.h
index df9f5c8..ab42331 100644
--- a/test/PCH/types.h
+++ b/test/PCH/types.h
@@ -42,3 +42,8 @@
 
 // TYPE_TYPEOF
 typedef typeof(int_ptr *) int_ptr_ptr2;
+
+struct S2;
+struct S2 {};
+enum E;
+enum E { myenum };
diff --git a/test/Parser/2008-10-31-parse-noop-failure.c b/test/Parser/2008-10-31-parse-noop-failure.c
deleted file mode 100755
index 6df508e..0000000
--- a/test/Parser/2008-10-31-parse-noop-failure.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: %clang_cc1 -verify -parse-noop %s
-
-void add_attribute(id) int id; {}
-
diff --git a/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c
index 0b2733e..ec272cd 100644
--- a/test/Parser/MicrosoftExtensions.c
+++ b/test/Parser/MicrosoftExtensions.c
@@ -1,8 +1,9 @@
-// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify -fms-extensions -x objective-c++ %s
+// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify -fms-extensions -Wno-missing-declarations -x objective-c++ %s
 __stdcall int func0();
 int __stdcall func();
 typedef int (__cdecl *tptr)();
 void (*__fastcall fastpfunc)();
+struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {};
 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 );
@@ -34,3 +35,4 @@
 #define FOO(x) #@x
 char x = FOO(a);
 
+typedef enum E { e1 };
diff --git a/test/Parser/altivec.c b/test/Parser/altivec.c
index ed14457..92ec688 100644
--- a/test/Parser/altivec.c
+++ b/test/Parser/altivec.c
@@ -13,7 +13,9 @@
 __vector signed int vv_sint;
 __vector unsigned int vv_ui;
 __vector float vv_f;
-__vector bool vv_b;
+__vector bool char vv_bc;
+__vector bool short vv_bs;
+__vector bool int vv_bi;
 __vector __pixel vv_p;
 __vector pixel vv__p;
 __vector int vf__r();
@@ -33,7 +35,9 @@
 vector signed int v_sint;
 vector unsigned int v_ui;
 vector float v_f;
-vector bool v_b;
+vector bool char v_bc;
+vector bool short v_bs;
+vector bool int v_bi;
 vector __pixel v_p;
 vector pixel v__p;
 vector int f__r();
@@ -57,14 +61,20 @@
 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'}}
+vector bool v_b;                    // expected-warning {{type specifier missing, defaults to 'int'}}
 
 // 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'}}
+__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'}}
+vector bool float v_bf;              // expected-error {{cannot use 'float' with '__vector bool'}}
+vector bool double v_bd;             // expected-error {{cannot use 'double' with '__vector bool'}}
+vector bool pixel v_bp;              // expected-error {{cannot use '__pixel' with '__vector bool'}}
+vector bool signed char v_bsc;       // expected-error {{cannot use 'signed' with '__vector bool'}}
+vector bool unsigned int v_bsc2;     // expected-error {{cannot use 'unsigned' with '__vector bool'}}
+vector bool long v_bl;               // expected-error {{cannot use 'long' with '__vector bool'}}
+vector bool long long v_bll;         // expected-error {{cannot use 'long long' with '__vector bool'}}
 
 void f() {
   __vector unsigned int v = {0,0,0,0};
@@ -91,3 +101,11 @@
   gccv = v;
   gccvector unsigned int tgv = v;
 }
+
+// bug 6895 - Vectorl literal casting confusion.
+vector char v1 = (vector char)((vector int)(1, 2, 3, 4));

+vector char v2 = (vector char)((vector float)(1.0f, 2.0f, 3.0f, 4.0f));

+vector char v3 = (vector char)((vector int)('a', 'b', 'c', 'd'));

+vector int v4 = (vector int)(1, 2, 3, 4);

+vector float v5 = (vector float)(1.0f, 2.0f, 3.0f, 4.0f);
+vector char v6 = (vector char)((vector int)(1+2, -2, (int)(2.0 * 3), -(5-3)));
diff --git a/test/Parser/asm-constraints-pr7869.c b/test/Parser/asm-constraints-pr7869.c
new file mode 100644
index 0000000..d6f1725
--- /dev/null
+++ b/test/Parser/asm-constraints-pr7869.c
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void
+f1 (void)
+{
+  __asm__ volatile (""
+            : [a] "+r" (a), [b] "+r" (b), [c] "+r" (c), [d] "+r" (d),
+              [e] "+r" (e), [f] "+r" (f), [g] "+r" (g), [h] "+r" (h),
+              [i] "+r" (i), [j] "+r" (j), [k] "+r" (k), [l] "+r" (l));
+}
+
+void
+f2 (void)
+{
+  __asm__ volatile (""
+            : [a] "+r,m" (a), [b] "+r,m" (b), [c] "+r,m" (c), [d] "+r,m" (d),
+              [e] "+r,m" (e), [f] "+r,m" (f), [g] "+r,m" (g), [h] "+r,m" (h),
+              [i] "+r,m" (i), [j] "+r,m" (j), [k] "+r,m" (k), [l] "+r,m" (l));
+}
+
+void
+f3 (void)
+{
+  __asm__ volatile (""
+            : [a] "=r" (a), [b] "=r" (b), [c] "=r" (c), [d] "=r" (d),
+              [e] "=r" (e), [f] "=r" (f), [g] "=r" (g), [h] "=r" (h),
+              [i] "=r" (i), [j] "=r" (j), [k] "=r" (k), [l] "=r" (l)
+            : "[a]" (a), "[b]" (b), "[c]" (c), "[d]" (d),
+              "[e]" (e), "[f]" (f), "[g]" (g), "[h]" (h),
+              "[i]" (i), "[j]" (j), "[k]" (k), "[l]" (l));
+}
+
+void
+f4 (void)
+{
+  __asm__ volatile (""
+            : [a] "=r,m" (a), [b] "=r,m" (b), [c] "=r,m" (c), [d] "=r,m" (d),
+              [e] "=r,m" (e), [f] "=r,m" (f), [g] "=r,m" (g), [h] "=r,m" (h),
+              [i] "=r,m" (i), [j] "=r,m" (j), [k] "=r,m" (k), [l] "=r,m" (l)
+            : "[a],m" (a), "[b],m" (b), "[c],m" (c), "[d],m" (d),
+              "[e],m" (e), "[f],m" (f), "[g],m" (g), "[h],m" (h),
+              "[i],m" (i), "[j],m" (j), "[k],m" (k), "[l],m" (l));
+}
diff --git a/test/Parser/asm.c b/test/Parser/asm.c
index df2e16f..9081826 100644
--- a/test/Parser/asm.c
+++ b/test/Parser/asm.c
@@ -1,7 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
 void f1() {
-  asm ("ret" : : :); // expected-error {{expected string literal}}
+  // PR7673: Some versions of GCC support an empty clobbers section.
+  asm ("ret" : : :);
 }
 
 void f2() {
diff --git a/test/Parser/backtrack-crash.cpp b/test/Parser/backtrack-crash.cpp
new file mode 100644
index 0000000..cc26873
--- /dev/null
+++ b/test/Parser/backtrack-crash.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic
+// PR7072
+()( // expected-error {{expected unqualified-id}}
+
diff --git a/test/Parser/block-block-storageclass.c b/test/Parser/block-block-storageclass.c
index a4efc44..97ba113 100644
--- a/test/Parser/block-block-storageclass.c
+++ b/test/Parser/block-block-storageclass.c
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -parse-noop %s
-#if 0
+// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
 int printf(const char *, ...);
 void _Block_byref_release(void*src){}
 
@@ -16,4 +15,3 @@
 
    return X;
 }
-#endif
diff --git a/test/Parser/block-pointer-decl.c b/test/Parser/block-pointer-decl.c
index 2979b01..a8cc258 100644
--- a/test/Parser/block-pointer-decl.c
+++ b/test/Parser/block-pointer-decl.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -parse-noop -fblocks %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s
+
+int printf(char const *, ...);
 
 struct blockStruct {
   int (^a)(float, int);
diff --git a/test/Parser/bracket-crash.cpp b/test/Parser/bracket-crash.cpp
new file mode 100644
index 0000000..fd18e0e
--- /dev/null
+++ b/test/Parser/bracket-crash.cpp
@@ -0,0 +1,6 @@
+// RUN: not %clang_cc1 -fsyntax-only %s
+// PR7481
+struct{
+  a
+}
+
diff --git a/test/Parser/cxx-altivec.cpp b/test/Parser/cxx-altivec.cpp
index 66d4f32..8f46330 100644
--- a/test/Parser/cxx-altivec.cpp
+++ b/test/Parser/cxx-altivec.cpp
@@ -1,5 +1,4 @@
 // 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;
@@ -14,7 +13,9 @@
 __vector signed int vv_sint;
 __vector unsigned int vv_ui;
 __vector float vv_f;
-__vector bool vv_b;
+__vector bool char vv_bc;
+__vector bool short vv_bs;
+__vector bool int vv_bi;
 __vector __pixel vv_p;
 __vector pixel vv__p;
 __vector int vf__r();
@@ -34,7 +35,9 @@
 vector signed int v_sint;
 vector unsigned int v_ui;
 vector float v_f;
-vector bool v_b;
+vector bool char v_bc;
+vector bool short v_bs;
+vector bool int v_bi;
 vector __pixel v_p;
 vector pixel v__p;
 vector int f__r();
@@ -64,6 +67,14 @@
 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'}}
+vector bool v_b;                     // expected-error {{error: C++ requires a type specifier for all declarations}}
+vector bool float v_bf;              // expected-error {{cannot use 'float' with '__vector bool'}}
+vector bool double v_bd;             // expected-error {{cannot use 'double' with '__vector bool'}}
+vector bool pixel v_bp;              // expected-error {{cannot use '__pixel' with '__vector bool'}}
+vector bool signed char v_bsc;       // expected-error {{cannot use 'signed' with '__vector bool'}}
+vector bool unsigned int v_bsc2;      // expected-error {{cannot use 'unsigned' with '__vector bool'}}
+vector bool long v_bl;               // expected-error {{cannot use 'long' with '__vector bool'}}
+vector bool long long v_bll;         // expected-error {{cannot use 'long long' with '__vector bool'}}
 
 void f() {
   __vector unsigned int v = {0,0,0,0};
@@ -107,3 +118,46 @@
   void f__a2(int b, vector int a);
 };
 
+
+// bug 6895 - Vectorl literal casting confusion.
+vector char v1 = (vector char)((vector int)(1, 2, 3, 4));
+vector char v2 = (vector char)((vector float)(1.0f, 2.0f, 3.0f, 4.0f));
+vector char v3 = (vector char)((vector int)('a', 'b', 'c', 'd'));
+vector int v4 = (vector int)(1, 2, 3, 4);
+vector float v5 = (vector float)(1.0f, 2.0f, 3.0f, 4.0f);
+vector char v6 = (vector char)((vector int)(1+2, -2, (int)(2.0 * 3), -(5-3)));
+
+#if 0 // Not ready yet.
+// bug 7553 - Problem with '==' and vectors
+void func() {
+  vector int v10i = (vector int)(1, 2, 3, 4);
+  vector int v11i = (vector int)(1, 2, 3, 4);
+  bool r10ieq = (v10i == v11i);
+  bool r10ine = (v10i != v11i);
+  bool r10igt = (v10i > v11i);
+  bool r10ige = (v10i >= v11i);
+  bool r10ilt = (v10i < v11i);
+  bool r10ile = (v10i <= v11i);
+  vector float v10f = (vector float)(1.0f, 2.0f, 3.0f, 4.0f);
+  vector float v11f = (vector float)(1.0f, 2.0f, 3.0f, 4.0f);
+  bool r10feq = (v10f == v11f);
+  bool r10fne = (v10f != v11f);
+  bool r10fgt = (v10f > v11f);
+  bool r10fge = (v10f >= v11f);
+  bool r10flt = (v10f < v11f);
+  bool r10fle = (v10f <= v11f);
+}
+#endif
+
+// vecreturn attribute test
+struct Vector
+{
+	__vector float xyzw;
+} __attribute__((vecreturn));
+
+Vector Add(Vector lhs, Vector rhs)
+{
+	Vector result;
+	result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
+	return result; // This will (eventually) be returned in a register
+}
diff --git a/test/Parser/cxx-ambig-decl-expr-xfail.cpp b/test/Parser/cxx-ambig-decl-expr-xfail.cpp
new file mode 100644
index 0000000..ac4accb
--- /dev/null
+++ b/test/Parser/cxx-ambig-decl-expr-xfail.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// XFAIL: *
+struct X { 
+  template<typename T> X(T);
+  X(int, int);
+
+  X operator()(int, int) const;
+};
+
+template<typename T, typename U> struct Y { };
+
+X *x;
+void f() {
+  int y = 0;
+  X (*x)(int(y), int(y)) = Y<int, float>(), ++y;
+}
diff --git a/test/Parser/cxx-ambig-decl-expr.cpp b/test/Parser/cxx-ambig-decl-expr.cpp
new file mode 100644
index 0000000..b5ff728
--- /dev/null
+++ b/test/Parser/cxx-ambig-decl-expr.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct X {
+  template<typename T, typename U>
+  static void f(int, int);
+};
+
+void f() {
+  void (*ptr)(int, int) = &X::f<int, int>;
+}
diff --git a/test/Parser/cxx-attributes.cpp b/test/Parser/cxx-attributes.cpp
index 192193a..8603b30 100644
--- a/test/Parser/cxx-attributes.cpp
+++ b/test/Parser/cxx-attributes.cpp
@@ -1,9 +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) )) {}

-};

-

+// 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-casting.cpp b/test/Parser/cxx-casting.cpp
index c8b4716..98d962a 100644
--- a/test/Parser/cxx-casting.cpp
+++ b/test/Parser/cxx-casting.cpp
@@ -5,8 +5,6 @@
   return const_cast<char*>(var);
 }
 
-#if 0
-// FIXME: Uncomment when C++ is supported more.
 struct A {
   virtual ~A() {}
 };
@@ -18,7 +16,6 @@
 {
   return dynamic_cast<struct B*>(a);
 }
-#endif
 
 char *reinterpret_cast_test()
 {
@@ -34,3 +31,9 @@
 {
   return reinterpret_cast<char*>(0xdeadbeef)[0];
 }
+
+// This was being incorrectly tentatively parsed.
+namespace test1 {
+  template <class T> class A {};
+  void foo() { A<int>(*(A<int>*)0); }
+}
diff --git a/test/Parser/cxx-class.cpp b/test/Parser/cxx-class.cpp
index 4abbbc5..57831a4 100644
--- a/test/Parser/cxx-class.cpp
+++ b/test/Parser/cxx-class.cpp
@@ -7,7 +7,7 @@
   static int sf(), u;
 
   struct S {};
-  enum {};
+  enum {}; // expected-warning{{declaration does not declare anything}}
   int; // expected-warning {{declaration does not declare anything}}
   int : 1, : 2;
 
diff --git a/test/Parser/cxx-condition.cpp b/test/Parser/cxx-condition.cpp
index a3991c4..552d823 100644
--- a/test/Parser/cxx-condition.cpp
+++ b/test/Parser/cxx-condition.cpp
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -parse-noop -verify %s
+// RUN: %clang_cc1 -fsyntax-only -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) ;
+  if (const int x = a) ; // expected-warning{{empty body}}
   switch (int x = a+10) {}
   for (; int x = ++a; ) ;
 }
diff --git a/test/Parser/cxx-decl.cpp b/test/Parser/cxx-decl.cpp
index ae004ce..e00ffd0 100644
--- a/test/Parser/cxx-decl.cpp
+++ b/test/Parser/cxx-decl.cpp
@@ -37,6 +37,10 @@
   }
 };
 
+class asm_class_test {
+  void foo() __asm__("baz");
+};
+
 enum { fooenum = 1 };
 
 struct a {
@@ -72,3 +76,10 @@
 }  // no ;
 
 typedef Class1<Class2> Type1; // expected-error {{cannot combine with previous 'class' declaration specifier}}
+
+// rdar : // 8307865
+struct CodeCompleteConsumer {
+};
+
+void CodeCompleteConsumer::() { // expected-error {{xpected unqualified-id}}
+} 
diff --git a/test/Parser/cxx-default-args.cpp b/test/Parser/cxx-default-args.cpp
index a084fb0..7fe8474 100644
--- a/test/Parser/cxx-default-args.cpp
+++ b/test/Parser/cxx-default-args.cpp
@@ -7,3 +7,10 @@
   void m(int x = undecl + 0); // expected-error {{use of undeclared identifier 'undecl'}}
 };
 
+typedef struct Inst {
+  void m(int x=0);
+} *InstPtr;
+
+struct X {
+  void f(int x = 1:); // expected-error {{unexpected end of default argument expression}}
+};
diff --git a/test/Parser/cxx-namespace-alias.cpp b/test/Parser/cxx-namespace-alias.cpp
index 2e4d7af..9b90aab 100644
--- a/test/Parser/cxx-namespace-alias.cpp
+++ b/test/Parser/cxx-namespace-alias.cpp
@@ -1,8 +1,9 @@
-// RUN: %clang_cc1 -parse-noop -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
-namespace A = B;
+namespace A = B; // expected-error{{namespace name}}
 
 namespace A = !; // expected-error {{expected namespace name}}
-namespace A = A::!; // expected-error {{expected namespace name}}
+namespace A = A::!; // expected-error {{expected namespace name}} \
+                    // expected-error{{use of undeclared identifier 'A'}}
 
 
diff --git a/test/Parser/cxx-typeof.cpp b/test/Parser/cxx-typeof.cpp
index 7e89101..4c598e9 100644
--- a/test/Parser/cxx-typeof.cpp
+++ b/test/Parser/cxx-typeof.cpp
@@ -5,3 +5,9 @@
   int x;
   typeof pi[x] y; 
 }
+
+// Part of rdar://problem/8347416;  from the gcc test suite.
+struct S {
+  int i;
+  __typeof(S::i) foo(); // expected-error {{invalid use of nonstatic data member 'i'}}
+};
diff --git a/test/Parser/cxx-undeclared-identifier.cpp b/test/Parser/cxx-undeclared-identifier.cpp
new file mode 100644
index 0000000..f15deab
--- /dev/null
+++ b/test/Parser/cxx-undeclared-identifier.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+// PR7180
+int f(a::b::c); // expected-error {{use of undeclared identifier 'a'}}
+
+class Foo::Bar { // expected-error {{use of undeclared identifier 'Foo'}} \
+                 // expected-note {{to match this '{'}} \
+                 // expected-error {{expected ';' after class}}
+                 // expected-error {{expected '}'}}
diff --git a/test/Parser/declarators.c b/test/Parser/declarators.c
index 31712af..e245adb 100644
--- a/test/Parser/declarators.c
+++ b/test/Parser/declarators.c
@@ -83,3 +83,17 @@
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
+
+// <rdar://problem/8044088>
+struct X<foo::int> { }; // expected-error{{expected identifier or '('}}
+
+
+// PR7617 - error recovery on missing ;.
+
+void test14()  // expected-error {{expected ';' after top level declarator}}
+
+void test14a();
+void *test14b = (void*)test14a; // Make sure test14a didn't get skipped.
+
+// rdar://problem/8358508
+long struct X { int x; } test15(); // expected-error {{'long struct' is invalid}}
diff --git a/test/Parser/expressions.c b/test/Parser/expressions.c
index 44ebe66..ffc5c83 100644
--- a/test/Parser/expressions.c
+++ b/test/Parser/expressions.c
@@ -1,19 +1,17 @@
-// RUN: %clang_cc1 -parse-noop -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 void test1() {
-  if (sizeof (int){ 1});   // sizeof compound literal
-  if (sizeof (int));       // sizeof type
+  if (sizeof (int){ 1}) {}   // sizeof compound literal
+  if (sizeof (int)) {}       // sizeof type
 
-  (int)4;   // cast.
-  (int){4}; // compound literal.
+  (void)(int)4;   // cast.
+  (void)(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 A = (struct{ int a;}){ 1}.a;
 }
 
 int test2(int a, int b) {
-  return a ? a,b : a;
+  return a ? (void)a,b : a;
 }
 
 int test3(int a, int b, int c) {
@@ -22,23 +20,27 @@
 
 int test4() {
   test4();
+  return 0;
 }
 
+struct X0 { struct { struct { int c[10][9]; } b; } a; };
+
 int test_offsetof() {
-  // FIXME: change into something that is semantically correct.
-  __builtin_offsetof(int, a.b.c[4][5]);
+  (void)__builtin_offsetof(struct X0, a.b.c[4][5]);
+  return 0;
 }
 
 void test_sizeof(){
         int arr[10];
-        sizeof arr[0];
-        sizeof(arr[0]);
-        sizeof(arr)[0];
+        (void)sizeof arr[0];
+        (void)sizeof(arr[0]);
+        (void)sizeof(arr)[0];
 }
 
 // PR3418
 int test_leading_extension() {
   __extension__ (*(char*)0) = 1;
+  return 0;
 }
 
 // PR3972
diff --git a/test/Parser/expressions.m b/test/Parser/expressions.m
index e27f405..1f1005a 100644
--- a/test/Parser/expressions.m
+++ b/test/Parser/expressions.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -parse-noop %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 void test1() {
   @"s";            // expected-warning {{expression result unused}}
diff --git a/test/Parser/method-prototype-1.m b/test/Parser/method-prototype-1.m
index d2d9563..a32bc2e 100644
--- a/test/Parser/method-prototype-1.m
+++ b/test/Parser/method-prototype-1.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -parse-noop
+// RUN: %clang_cc1 %s -fsyntax-only
 @interface MyObject 
 - (void) bycopy  : (int) woodo, ... ;
 - (void) break  : (int) woodo, ... ;
diff --git a/test/Parser/namespaces.cpp b/test/Parser/namespaces.cpp
new file mode 100644
index 0000000..b8c7819
--- /dev/null
+++ b/test/Parser/namespaces.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR6596
+namespace g { enum { o = 0 }; }
+
+void foo() {
+  namespace a { typedef g::o o; } // expected-error{{namespaces can only be defined in global or namespace scope}}
+}
diff --git a/test/Parser/objc-messaging-1.m b/test/Parser/objc-messaging-1.m
index 511290e..82450df 100644
--- a/test/Parser/objc-messaging-1.m
+++ b/test/Parser/objc-messaging-1.m
@@ -1,19 +1,26 @@
-// RUN: %clang_cc1 %s -parse-noop
+// RUN: %clang_cc1 %s -fsyntax-only -verify
 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];
+	[a ii]; // expected-warning{{not found}}
+	[a if: 1 :2]; // expected-warning{{not found}}
+	[a inout: 1 :2 another:(2,3,4)]; // expected-warning{{not found}} \
+           // expected-warning 2{{expression result unused}}
+	[a inout: 1 :2 another:(2,3,4), 6,6,8]; // expected-warning{{not found}} \
+           // expected-warning 2{{expression result unused}}
+	[a inout: 1 :2 another:(2,3,4), (6,4,5),6,8]; // expected-warning{{not found}} \
+           // expected-warning 4{{expression result unused}}
+	[a inout: 1 :2 another:(i+10), (i,j-1,5),6,8]; // expected-warning{{not found}} \
+           // expected-warning 2{{expression result unused}}
+	[a long: 1 :2 another:(i+10), (i,j-1,5),6,8]; // expected-warning{{not found}} \
+           // expected-warning 2{{expression result unused}}
+	[a : "Hello\n" :2 another:(i+10), (i,j-1,5),6,8]; // expected-warning{{not found}} \
+           // expected-warning 2{{expression result unused}}
 
 	// Comma expression as receiver (rdar://6222856)
-	[a, b, c foo];
+	[a, b, c foo]; // expected-warning{{not found}} \
+           // expected-warning 2{{expression result unused}}
 
 }
diff --git a/test/Parser/objc-try-catch-1.m b/test/Parser/objc-try-catch-1.m
index 1934cbd..7193691 100644
--- a/test/Parser/objc-try-catch-1.m
+++ b/test/Parser/objc-try-catch-1.m
@@ -27,13 +27,15 @@
       return proc();
     }
     @catch (Frob* ex) {
-      @throw 1,2; // expected-error {{@throw requires an Objective-C object type ('int' invalid)}}
+      @throw 1,2; // expected-error {{@throw requires an Objective-C object type ('int' invalid)}} \
+				  // expected-warning {{expression result unused}}
     }
     @catch (float x) {  // expected-error {{@catch parameter is not a pointer to an interface type}}
       
     }
     @catch(...) {
-      @throw (4,3,proc());
+      @throw (4,3,proc()); // expected-warning {{expression result unused}} \
+						   // expected-warning {{expression result unused}}
     }
   }
 
diff --git a/test/Parser/pragma-options.c b/test/Parser/pragma-options.c
new file mode 100644
index 0000000..7844e71
--- /dev/null
+++ b/test/Parser/pragma-options.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
+
+/* expected-warning {{expected 'align' following '#pragma options'}} */ #pragma options
+/* expected-warning {{expected '=' following '#pragma options align'}} */ #pragma options align
+/* expected-warning {{expected identifier in '#pragma options'}} */ #pragma options align =
+/* expected-warning {{invalid alignment option in '#pragma options align'}} */ #pragma options align = foo
+/* expected-warning {{extra tokens at end of '#pragma options'}} */ #pragma options align = reset foo
+
+#pragma options align=natural
+#pragma options align=reset
+#pragma options align=mac68k
+#pragma options align=power
+
+/* expected-warning {{expected '=' following '#pragma align'}} */ #pragma align
+/* expected-warning {{expected identifier in '#pragma align'}} */ #pragma align =
+/* expected-warning {{invalid alignment option in '#pragma align'}} */ #pragma align = foo
+/* expected-warning {{extra tokens at end of '#pragma align'}} */ #pragma align = reset foo
+
+#pragma align=natural
+#pragma align=reset
+#pragma align=mac68k
+#pragma align=power
diff --git a/test/Parser/pragma-visibility.c b/test/Parser/pragma-visibility.c
new file mode 100644
index 0000000..cfc3d9e
--- /dev/null
+++ b/test/Parser/pragma-visibility.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#pragma GCC visibility foo // expected-warning{{expected identifier in '#pragma visibility' - ignored}}
+#pragma GCC visibility pop foo // expected-warning{{extra tokens at end of '#pragma visibility' - ignored}}
+#pragma GCC visibility push // expected-warning{{missing '(' after '#pragma visibility'}}
+#pragma GCC visibility push( // expected-warning{{expected identifier in '#pragma visibility' - ignored}}
+#pragma GCC visibility push(hidden // expected-warning{{missing ')' after '#pragma visibility' - ignoring}}
+#pragma GCC visibility push(hidden)
+#pragma GCC visibility pop
diff --git a/test/Parser/recovery.c b/test/Parser/recovery.c
index 8e7181e..6cd95da 100644
--- a/test/Parser/recovery.c
+++ b/test/Parser/recovery.c
@@ -73,3 +73,8 @@
   int X;
   X = 4 // expected-error{{expected ';' after expression}}
 }
+
+
+// rdar://7980651
+typedef int intptr_t;  // expected-note {{'intptr_t' declared here}}
+void bar(intptr y);     // expected-error {{unknown type name 'intptr'; did you mean 'intptr_t'?}}
diff --git a/test/Parser/selector-1.m b/test/Parser/selector-1.m
index 1f9cad6..0f35ce7 100644
--- a/test/Parser/selector-1.m
+++ b/test/Parser/selector-1.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -parse-noop %s 
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
 
 int main() {
  SEL s = @selector(retain);
diff --git a/test/Parser/switch-recovery.cpp b/test/Parser/switch-recovery.cpp
new file mode 100644
index 0000000..8eb4cff
--- /dev/null
+++ b/test/Parser/switch-recovery.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// <rdar://problem/7971948>
+struct A {};
+struct B {
+  void foo() {
+    switch (a) { // expected-error{{use of undeclared identifier 'a'}}
+    default:
+      return;
+    }
+  }
+};
diff --git a/test/Parser/typeof.c b/test/Parser/typeof.c
index cf0e47a..7953a69 100644
--- a/test/Parser/typeof.c
+++ b/test/Parser/typeof.c
@@ -17,3 +17,10 @@
   int xx;
   int *i;
 }
+
+// <rdar://problem/8237491>
+void test2() {
+    int a;
+    short b;
+    __typeof__(a) (*f)(__typeof__(b));    
+}
diff --git a/test/Parser/types.c b/test/Parser/types.c
index 0e8a63d..53b9dd5 100644
--- a/test/Parser/types.c
+++ b/test/Parser/types.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -parse-noop
+// RUN: %clang_cc1 %s -fsyntax-only -verify
 
 // Test the X can be overloaded inside the struct.
 typedef int X; 
diff --git a/test/Preprocessor/dump-macros-undef.c b/test/Preprocessor/dump-macros-undef.c
new file mode 100644
index 0000000..358fd17
--- /dev/null
+++ b/test/Preprocessor/dump-macros-undef.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -E -dD %s | FileCheck %s
+// PR7818
+
+// CHECK: # 1 "{{.+}}.c"
+#define X 3
+// CHECK: #define X 3
+#undef X
+// CHECK: #undef X
diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c
index 4ef460b..6c27a6c 100644
--- a/test/Preprocessor/init.c
+++ b/test/Preprocessor/init.c
@@ -14,6 +14,7 @@
 // CXX0X:#define __DEPRECATED 1
 // CXX0X:#define __GNUG__
 // CXX0X:#define __GXX_EXPERIMENTAL_CXX0X__ 1
+// CXX0X:#define __GXX_RTTI 1
 // CXX0X:#define __GXX_WEAK__ 1
 // CXX0X:#define __cplusplus 199711L
 // CXX0X:#define __private_extern__ extern
@@ -23,6 +24,7 @@
 // 
 // CXX98:#define __DEPRECATED 1
 // CXX98:#define __GNUG__
+// CXX98:#define __GXX_RTTI 1
 // CXX98:#define __GXX_WEAK__ 1
 // CXX98:#define __cplusplus 199711L
 // CXX98:#define __private_extern__ extern
@@ -48,6 +50,10 @@
 // COMMON:#define __STDC__ 1
 // COMMON:#define __VERSION__
 // COMMON:#define __clang__ 1
+// COMMON:#define __clang_major__ {{[0-9]+}}
+// COMMON:#define __clang_minor__ {{[0-9]+}}
+// COMMON:#define __clang_patchlevel__ {{[0-9]+}}
+// COMMON:#define __clang_version__
 // COMMON:#define __llvm__ 1
 //
 // 
@@ -68,9 +74,10 @@
 // C94:#define __STDC_VERSION__ 199409L
 //
 // 
-// RUN: %clang_cc1 -fms-extensions -E -dM < /dev/null | FileCheck -check-prefix MSEXT %s
+// RUN: %clang_cc1 -fms-extensions -triple i686-pc-win32 -E -dM < /dev/null | FileCheck -check-prefix MSEXT %s
 //
 // MSEXT-NOT:#define __STDC__
+// MSEXT:#define _INTEGRAL_MAX_BITS 64
 // MSEXT:#define __int16 __INT16_TYPE__
 // MSEXT:#define __int32 __INT32_TYPE__
 // MSEXT:#define __int64 __INT64_TYPE__
@@ -111,11 +118,20 @@
 // SCHAR-NOT:#define __UNSIGNED_CHAR__
 // SCHAR:#define __clang__ 1
 //
+// RUN: %clang_cc1 -E -dM -fshort-wchar < /dev/null | FileCheck -check-prefix SHORTWCHAR %s
+//
+// SHORTWCHAR: #define __SIZEOF_WCHAR_T__ 2
+// SHORTWCHAR: #define __WCHAR_MAX__ 65535U
+// SHORTWCHAR: #define __WCHAR_TYPE__ unsigned short
+// SHORTWCHAR: #define __WCHAR_WIDTH__ 16
+//
 // 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 __CHAR16_TYPE__ unsigned short
+// ARM:#define __CHAR32_TYPE__ unsigned int
 // ARM:#define __CHAR_BIT__ 8
 // ARM:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
 // ARM:#define __DBL_DIG__ 15
@@ -181,6 +197,18 @@
 // ARM:#define __SCHAR_MAX__ 127
 // ARM:#define __SHRT_MAX__ 32767
 // ARM:#define __SIG_ATOMIC_WIDTH__ 32
+// ARM:#define __SIZEOF_DOUBLE__ 8
+// ARM:#define __SIZEOF_FLOAT__ 4
+// ARM:#define __SIZEOF_INT__ 4
+// ARM:#define __SIZEOF_LONG_DOUBLE__ 8
+// ARM:#define __SIZEOF_LONG_LONG__ 8
+// ARM:#define __SIZEOF_LONG__ 4
+// ARM:#define __SIZEOF_POINTER__ 4
+// ARM:#define __SIZEOF_PTRDIFF_T__ 4
+// ARM:#define __SIZEOF_SHORT__ 2
+// ARM:#define __SIZEOF_SIZE_T__ 4
+// ARM:#define __SIZEOF_WCHAR_T__ 4
+// ARM:#define __SIZEOF_WINT_T__ 4
 // ARM:#define __SIZE_TYPE__ unsigned int
 // ARM:#define __SIZE_WIDTH__ 32
 // ARM:#define __THUMB_INTERWORK__ 1
@@ -201,6 +229,8 @@
 // BFIN:#define __ADSPLPBLACKFIN__ 1
 // BFIN:#define __BFIN 1
 // BFIN:#define __BFIN__ 1
+// BFIN:#define __CHAR16_TYPE__ unsigned short
+// BFIN:#define __CHAR32_TYPE__ unsigned int
 // BFIN:#define __CHAR_BIT__ 8
 // BFIN:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
 // BFIN:#define __DBL_DIG__ 15
@@ -264,6 +294,18 @@
 // BFIN:#define __SCHAR_MAX__ 127
 // BFIN:#define __SHRT_MAX__ 32767
 // BFIN:#define __SIG_ATOMIC_WIDTH__ 32
+// BFIN:#define __SIZEOF_DOUBLE__ 8
+// BFIN:#define __SIZEOF_FLOAT__ 4
+// BFIN:#define __SIZEOF_INT__ 4
+// BFIN:#define __SIZEOF_LONG_DOUBLE__ 8
+// BFIN:#define __SIZEOF_LONG_LONG__ 8
+// BFIN:#define __SIZEOF_LONG__ 4
+// BFIN:#define __SIZEOF_POINTER__ 4
+// BFIN:#define __SIZEOF_PTRDIFF_T__ 4
+// BFIN:#define __SIZEOF_SHORT__ 2
+// BFIN:#define __SIZEOF_SIZE_T__ 4
+// BFIN:#define __SIZEOF_WCHAR_T__ 4
+// BFIN:#define __SIZEOF_WINT_T__ 4
 // BFIN:#define __SIZE_TYPE__ long unsigned int
 // BFIN:#define __SIZE_WIDTH__ 32
 // BFIN:#define __UINTMAX_TYPE__ long long unsigned int
@@ -279,6 +321,8 @@
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-none-none < /dev/null | FileCheck -check-prefix I386 %s
 //
+// I386:#define __CHAR16_TYPE__ unsigned short
+// I386:#define __CHAR32_TYPE__ unsigned int
 // I386:#define __CHAR_BIT__ 8
 // I386:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
 // I386:#define __DBL_DIG__ 15
@@ -345,6 +389,18 @@
 // I386:#define __SCHAR_MAX__ 127
 // I386:#define __SHRT_MAX__ 32767
 // I386:#define __SIG_ATOMIC_WIDTH__ 32
+// I386:#define __SIZEOF_DOUBLE__ 8
+// I386:#define __SIZEOF_FLOAT__ 4
+// I386:#define __SIZEOF_INT__ 4
+// I386:#define __SIZEOF_LONG_DOUBLE__ 12
+// I386:#define __SIZEOF_LONG_LONG__ 8
+// I386:#define __SIZEOF_LONG__ 4
+// I386:#define __SIZEOF_POINTER__ 4
+// I386:#define __SIZEOF_PTRDIFF_T__ 4
+// I386:#define __SIZEOF_SHORT__ 2
+// I386:#define __SIZEOF_SIZE_T__ 4
+// I386:#define __SIZEOF_WCHAR_T__ 4
+// I386:#define __SIZEOF_WINT_T__ 4
 // I386:#define __SIZE_TYPE__ unsigned int
 // I386:#define __SIZE_WIDTH__ 32
 // I386:#define __UINTMAX_TYPE__ long long unsigned int
@@ -364,6 +420,8 @@
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=msp430-none-none < /dev/null | FileCheck -check-prefix MSP430 %s
 //
 // MSP430:#define MSP430 1
+// MSP430:#define __CHAR16_TYPE__ unsigned short
+// MSP430:#define __CHAR32_TYPE__ unsigned int
 // MSP430:#define __CHAR_BIT__ 8
 // MSP430:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
 // MSP430:#define __DBL_DIG__ 15
@@ -427,6 +485,18 @@
 // MSP430:#define __SCHAR_MAX__ 127
 // MSP430:#define __SHRT_MAX__ 32767
 // MSP430:#define __SIG_ATOMIC_WIDTH__ 32
+// MSP430:#define __SIZEOF_DOUBLE__ 8
+// MSP430:#define __SIZEOF_FLOAT__ 4
+// MSP430:#define __SIZEOF_INT__ 2
+// MSP430:#define __SIZEOF_LONG_DOUBLE__ 8
+// MSP430:#define __SIZEOF_LONG_LONG__ 8
+// MSP430:#define __SIZEOF_LONG__ 4
+// MSP430:#define __SIZEOF_POINTER__ 2
+// MSP430:#define __SIZEOF_PTRDIFF_T__ 2
+// MSP430:#define __SIZEOF_SHORT__ 2
+// MSP430:#define __SIZEOF_SIZE_T__ 2
+// MSP430:#define __SIZEOF_WCHAR_T__ 2
+// MSP430:#define __SIZEOF_WINT_T__ 2
 // MSP430:#define __SIZE_TYPE__ unsigned int
 // MSP430:#define __SIZE_WIDTH__ 16
 // MSP430:#define __UINTMAX_TYPE__ long unsigned int
@@ -440,6 +510,8 @@
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=pic16-none-none < /dev/null | FileCheck -check-prefix PIC16 %s
 //
+// PIC16:#define __CHAR16_TYPE__ unsigned short
+// PIC16:#define __CHAR32_TYPE__ unsigned int
 // PIC16:#define __CHAR_BIT__ 8
 // PIC16:#define __DBL_DENORM_MIN__ 1.40129846e-45F
 // PIC16:#define __DBL_DIG__ 6
@@ -503,6 +575,18 @@
 // PIC16:#define __SCHAR_MAX__ 127
 // PIC16:#define __SHRT_MAX__ 32767
 // PIC16:#define __SIG_ATOMIC_WIDTH__ 32
+// PIC16:#define __SIZEOF_DOUBLE__ 4
+// PIC16:#define __SIZEOF_FLOAT__ 4
+// PIC16:#define __SIZEOF_INT__ 2
+// PIC16:#define __SIZEOF_LONG_DOUBLE__ 4
+// PIC16:#define __SIZEOF_LONG_LONG__ 4
+// PIC16:#define __SIZEOF_LONG__ 4
+// PIC16:#define __SIZEOF_POINTER__ 2
+// PIC16:#define __SIZEOF_PTRDIFF_T__ 2
+// PIC16:#define __SIZEOF_SHORT__ 2
+// PIC16:#define __SIZEOF_SIZE_T__ 2
+// PIC16:#define __SIZEOF_WCHAR_T__ 2
+// PIC16:#define __SIZEOF_WINT_T__ 2
 // PIC16:#define __SIZE_TYPE__ unsigned int
 // PIC16:#define __SIZE_WIDTH__ 16
 // PIC16:#define __UINTMAX_TYPE__ long unsigned int
@@ -531,6 +615,8 @@
 // PPC64:#define _BIG_ENDIAN 1
 // PPC64:#define _LP64 1
 // PPC64:#define __BIG_ENDIAN__ 1
+// PPC64:#define __CHAR16_TYPE__ unsigned short
+// PPC64:#define __CHAR32_TYPE__ unsigned int
 // PPC64:#define __CHAR_BIT__ 8
 // PPC64:#define __CHAR_UNSIGNED__ 1
 // PPC64:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
@@ -600,6 +686,18 @@
 // PPC64:#define __SCHAR_MAX__ 127
 // PPC64:#define __SHRT_MAX__ 32767
 // PPC64:#define __SIG_ATOMIC_WIDTH__ 32
+// PPC64:#define __SIZEOF_DOUBLE__ 8
+// PPC64:#define __SIZEOF_FLOAT__ 4
+// PPC64:#define __SIZEOF_INT__ 4
+// PPC64:#define __SIZEOF_LONG_DOUBLE__ 8
+// PPC64:#define __SIZEOF_LONG_LONG__ 8
+// PPC64:#define __SIZEOF_LONG__ 8
+// PPC64:#define __SIZEOF_POINTER__ 8
+// PPC64:#define __SIZEOF_PTRDIFF_T__ 8
+// PPC64:#define __SIZEOF_SHORT__ 2
+// PPC64:#define __SIZEOF_SIZE_T__ 8
+// PPC64:#define __SIZEOF_WCHAR_T__ 4
+// PPC64:#define __SIZEOF_WINT_T__ 4
 // PPC64:#define __SIZE_TYPE__ long unsigned int
 // PPC64:#define __SIZE_WIDTH__ 64
 // PPC64:#define __UINTMAX_TYPE__ long unsigned int
@@ -617,6 +715,8 @@
 // PPC:#define _ARCH_PPC 1
 // PPC:#define _BIG_ENDIAN 1
 // PPC:#define __BIG_ENDIAN__ 1
+// PPC:#define __CHAR16_TYPE__ unsigned short
+// PPC:#define __CHAR32_TYPE__ unsigned int
 // PPC:#define __CHAR_BIT__ 8
 // PPC:#define __CHAR_UNSIGNED__ 1
 // PPC:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
@@ -685,6 +785,18 @@
 // PPC:#define __SCHAR_MAX__ 127
 // PPC:#define __SHRT_MAX__ 32767
 // PPC:#define __SIG_ATOMIC_WIDTH__ 32
+// PPC:#define __SIZEOF_DOUBLE__ 8
+// PPC:#define __SIZEOF_FLOAT__ 4
+// PPC:#define __SIZEOF_INT__ 4
+// PPC:#define __SIZEOF_LONG_DOUBLE__ 8
+// PPC:#define __SIZEOF_LONG_LONG__ 8
+// PPC:#define __SIZEOF_LONG__ 4
+// PPC:#define __SIZEOF_POINTER__ 4
+// PPC:#define __SIZEOF_PTRDIFF_T__ 4
+// PPC:#define __SIZEOF_SHORT__ 2
+// PPC:#define __SIZEOF_SIZE_T__ 4
+// PPC:#define __SIZEOF_WCHAR_T__ 4
+// PPC:#define __SIZEOF_WINT_T__ 4
 // PPC:#define __SIZE_TYPE__ long unsigned int
 // PPC:#define __SIZE_WIDTH__ 32
 // PPC:#define __UINTMAX_TYPE__ long long unsigned int
@@ -698,6 +810,8 @@
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=s390x-none-none -fno-signed-char < /dev/null | FileCheck -check-prefix S390X %s
 //
+// S390X:#define __CHAR16_TYPE__ unsigned short
+// S390X:#define __CHAR32_TYPE__ unsigned int
 // S390X:#define __CHAR_BIT__ 8
 // S390X:#define __CHAR_UNSIGNED__ 1
 // S390X:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
@@ -732,7 +846,7 @@
 // S390X:#define __INT16_TYPE__ short
 // S390X:#define __INT32_TYPE__ int
 // S390X:#define __INT64_C_SUFFIX__ L
-// S390X:#define __INT64_TYPE__ long int
+// S390X:#define __INT64_TYPE__ long long int
 // S390X:#define __INT8_TYPE__ char
 // S390X:#define __INTMAX_MAX__ 9223372036854775807LL
 // S390X:#define __INTMAX_TYPE__ long long int
@@ -762,6 +876,18 @@
 // S390X:#define __SCHAR_MAX__ 127
 // S390X:#define __SHRT_MAX__ 32767
 // S390X:#define __SIG_ATOMIC_WIDTH__ 32
+// S390X:#define __SIZEOF_DOUBLE__ 8
+// S390X:#define __SIZEOF_FLOAT__ 4
+// S390X:#define __SIZEOF_INT__ 4
+// S390X:#define __SIZEOF_LONG_DOUBLE__ 8
+// S390X:#define __SIZEOF_LONG_LONG__ 8
+// S390X:#define __SIZEOF_LONG__ 8
+// S390X:#define __SIZEOF_POINTER__ 8
+// S390X:#define __SIZEOF_PTRDIFF_T__ 8
+// S390X:#define __SIZEOF_SHORT__ 2
+// S390X:#define __SIZEOF_SIZE_T__ 8
+// S390X:#define __SIZEOF_WCHAR_T__ 4
+// S390X:#define __SIZEOF_WINT_T__ 4
 // S390X:#define __SIZE_TYPE__ long unsigned int
 // S390X:#define __SIZE_WIDTH__ 64
 // S390X:#define __UINTMAX_TYPE__ long long unsigned int
@@ -776,6 +902,8 @@
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=sparc-none-none < /dev/null | FileCheck -check-prefix SPARC %s
 //
+// SPARC:#define __CHAR16_TYPE__ unsigned short
+// SPARC:#define __CHAR32_TYPE__ unsigned int
 // SPARC:#define __CHAR_BIT__ 8
 // SPARC:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
 // SPARC:#define __DBL_DIG__ 15
@@ -840,6 +968,18 @@
 // SPARC:#define __SCHAR_MAX__ 127
 // SPARC:#define __SHRT_MAX__ 32767
 // SPARC:#define __SIG_ATOMIC_WIDTH__ 32
+// SPARC:#define __SIZEOF_DOUBLE__ 8
+// SPARC:#define __SIZEOF_FLOAT__ 4
+// SPARC:#define __SIZEOF_INT__ 4
+// SPARC:#define __SIZEOF_LONG_DOUBLE__ 8
+// SPARC:#define __SIZEOF_LONG_LONG__ 8
+// SPARC:#define __SIZEOF_LONG__ 4
+// SPARC:#define __SIZEOF_POINTER__ 4
+// SPARC:#define __SIZEOF_PTRDIFF_T__ 4
+// SPARC:#define __SIZEOF_SHORT__ 2
+// SPARC:#define __SIZEOF_SIZE_T__ 4
+// SPARC:#define __SIZEOF_WCHAR_T__ 4
+// SPARC:#define __SIZEOF_WINT_T__ 4
 // SPARC:#define __SIZE_TYPE__ long unsigned int
 // SPARC:#define __SIZE_WIDTH__ 32
 // SPARC:#define __UINTMAX_TYPE__ long long unsigned int
@@ -857,6 +997,8 @@
 // 
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=tce-none-none < /dev/null | FileCheck -check-prefix TCE %s
 //
+// TCE:#define __CHAR16_TYPE__ unsigned short
+// TCE:#define __CHAR32_TYPE__ unsigned int
 // TCE:#define __CHAR_BIT__ 8
 // TCE:#define __DBL_DENORM_MIN__ 1.40129846e-45F
 // TCE:#define __DBL_DIG__ 6
@@ -918,6 +1060,18 @@
 // TCE:#define __SCHAR_MAX__ 127
 // TCE:#define __SHRT_MAX__ 32767
 // TCE:#define __SIG_ATOMIC_WIDTH__ 32
+// TCE:#define __SIZEOF_DOUBLE__ 4
+// TCE:#define __SIZEOF_FLOAT__ 4
+// TCE:#define __SIZEOF_INT__ 4
+// TCE:#define __SIZEOF_LONG_DOUBLE__ 4
+// TCE:#define __SIZEOF_LONG_LONG__ 4
+// TCE:#define __SIZEOF_LONG__ 4
+// TCE:#define __SIZEOF_POINTER__ 4
+// TCE:#define __SIZEOF_PTRDIFF_T__ 4
+// TCE:#define __SIZEOF_SHORT__ 2
+// TCE:#define __SIZEOF_SIZE_T__ 4
+// TCE:#define __SIZEOF_WCHAR_T__ 4
+// TCE:#define __SIZEOF_WINT_T__ 4
 // TCE:#define __SIZE_TYPE__ unsigned int
 // TCE:#define __SIZE_WIDTH__ 32
 // TCE:#define __TCE_V1__ 1
@@ -936,6 +1090,8 @@
 // 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 __CHAR16_TYPE__ unsigned short
+// X86_64:#define __CHAR32_TYPE__ unsigned int
 // X86_64:#define __CHAR_BIT__ 8
 // X86_64:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
 // X86_64:#define __DBL_DIG__ 15
@@ -1004,6 +1160,18 @@
 // X86_64:#define __SCHAR_MAX__ 127
 // X86_64:#define __SHRT_MAX__ 32767
 // X86_64:#define __SIG_ATOMIC_WIDTH__ 32
+// X86_64:#define __SIZEOF_DOUBLE__ 8
+// X86_64:#define __SIZEOF_FLOAT__ 4
+// X86_64:#define __SIZEOF_INT__ 4
+// X86_64:#define __SIZEOF_LONG_DOUBLE__ 16
+// X86_64:#define __SIZEOF_LONG_LONG__ 8
+// X86_64:#define __SIZEOF_LONG__ 8
+// X86_64:#define __SIZEOF_POINTER__ 8
+// X86_64:#define __SIZEOF_PTRDIFF_T__ 8
+// X86_64:#define __SIZEOF_SHORT__ 2
+// X86_64:#define __SIZEOF_SIZE_T__ 8
+// X86_64:#define __SIZEOF_WCHAR_T__ 4
+// X86_64:#define __SIZEOF_WINT_T__ 4
 // X86_64:#define __SIZE_TYPE__ long unsigned int
 // X86_64:#define __SIZE_WIDTH__ 64
 // X86_64:#define __SSE2_MATH__ 1
@@ -1028,3 +1196,7 @@
 // RUN: %clang_cc1 -x c++ -triple i686-pc-linux-gnu -E -dM < /dev/null | FileCheck -check-prefix GNUSOURCE %s
 // GNUSOURCE:#define _GNU_SOURCE 1
 // 
+// RUN: %clang_cc1 -x c++ -std=c++98 -fno-rtti -E -dM < /dev/null | FileCheck -check-prefix NORTTI %s
+// NORTTI: __GXX_ABI_VERSION
+// NORTTI-NOT:#define __GXX_RTTI
+// NORTTI: __STDC__
diff --git a/test/Preprocessor/macro_fn_comma_swallow.c b/test/Preprocessor/macro_fn_comma_swallow.c
index 5742591..726a889 100644
--- a/test/Preprocessor/macro_fn_comma_swallow.c
+++ b/test/Preprocessor/macro_fn_comma_swallow.c
@@ -1,21 +1,28 @@
 // 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}'
+// RUN: %clang_cc1 %s -E | FileCheck -strict-whitespace %s
 
+// CHECK: 1: foo{A, }
 #define X(Y) foo{A, Y}
-X()
+1: X()
 
+
+// CHECK: 2: fo2{A,}
 #define X2(Y) fo2{A,##Y}
-X2()
+2: X2()
 
 // should eat the comma.
+// CHECK: 3: {foo}
 #define X3(b, ...) {b, ## __VA_ARGS__}
-X3(foo)
+3: X3(foo)
 
 
 
-// RUN: %clang_cc1 %s -E | grep 'AA BB'
 // PR3880
+// CHECK: 4: AA BB
 #define X4(...)  AA , ## __VA_ARGS__ BB
-X4()
+4: X4()
+
+// PR7943
+// CHECK: 5: 1
+#define X5(x,...) x##,##__VA_ARGS__
+5: X5(1)
diff --git a/test/Preprocessor/macro_paste_mscomment.c b/test/Preprocessor/macro_paste_mscomment.c
deleted file mode 100644
index 7132406..0000000
--- a/test/Preprocessor/macro_paste_mscomment.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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_msextensions.c b/test/Preprocessor/macro_paste_msextensions.c
new file mode 100644
index 0000000..c5b4213
--- /dev/null
+++ b/test/Preprocessor/macro_paste_msextensions.c
@@ -0,0 +1,34 @@
+// 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: ;
+
+
+// rdar://8197149 - VC++ allows invalid token pastes: (##baz
+#define foo(x) abc(x)
+#define bar(y) foo(##baz(y))
+bar(q)
+
+// CHECK: abc(baz(q))
diff --git a/test/Preprocessor/non_fragile_feature.m b/test/Preprocessor/non_fragile_feature.m
index 552209d..1f67ed3 100644
--- a/test/Preprocessor/non_fragile_feature.m
+++ b/test/Preprocessor/non_fragile_feature.m
@@ -6,3 +6,7 @@
 #if !__has_feature(objc_nonfragile_abi)
 #error Non-fragile ABI used for compilation but feature macro not set.
 #endif
+
+#if !__has_feature(objc_weak_class)
+#error objc_weak_class should be enabled with nonfragile abi
+#endif
diff --git a/test/Preprocessor/pragma-pushpop-macro.c b/test/Preprocessor/pragma-pushpop-macro.c
new file mode 100644
index 0000000..87cceaa
--- /dev/null
+++ b/test/Preprocessor/pragma-pushpop-macro.c
@@ -0,0 +1,33 @@
+/* Test pragma pop_macro and push_macro directives from
+   http://msdn.microsoft.com/en-us/library/hsttss76.aspx */
+
+// pop_macro: Sets the value of the macro_name macro to the value on the top of
+// the stack for this macro.
+// #pragma pop_macro("macro_name")
+// push_macro: Saves the value of the macro_name macro on the top of the stack
+// for this macro.
+// #pragma push_macro("macro_name")
+//
+// RUN: %clang_cc1 -fms-extensions -E %s -o - | FileCheck %s
+
+#define X 1
+#define Y 2
+int pmx0 = X;
+int pmy0 = Y;
+#define Y 3
+#pragma push_macro("Y")
+#pragma push_macro("X")
+int pmx1 = X;
+#define X 2
+int pmx2 = X;
+#pragma pop_macro("X")
+int pmx3 = X;
+#pragma pop_macro("Y")
+int pmy1 = Y;
+
+// CHECK: int pmx0 = 1
+// CHECK: int pmy0 = 2
+// CHECK: int pmx1 = 1
+// CHECK: int pmx2 = 2
+// CHECK: int pmx3 = 1
+// CHECK: int pmy1 = 3
diff --git a/test/Preprocessor/print_line_track.c b/test/Preprocessor/print_line_track.c
index c87fe00..fb2ccf2 100644
--- a/test/Preprocessor/print_line_track.c
+++ b/test/Preprocessor/print_line_track.c
@@ -3,8 +3,8 @@
  * 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
+ * RUN: %clang_cc1 -E -P %s | count 4
+ * PR1848 PR3437 PR7360
 */
 
 #define t(x) x
diff --git a/test/Preprocessor/stdint.c b/test/Preprocessor/stdint.c
index e701494..f8bb921 100644
--- a/test/Preprocessor/stdint.c
+++ b/test/Preprocessor/stdint.c
@@ -31,8 +31,8 @@
 // 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:typedef long long int intmax_t;
+// ARM:typedef long long unsigned int uintmax_t;
 //
 // ARM:INT8_MAX_ 127
 // ARM:INT8_MIN_ (-127 -1)
@@ -139,8 +139,8 @@
 // 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:typedef long long int intmax_t;
+// BFIN:typedef long long unsigned int uintmax_t;
 //
 // BFIN:INT8_MAX_ 127
 // BFIN:INT8_MIN_ (-127 -1)
@@ -247,8 +247,8 @@
 // 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:typedef long long int intmax_t;
+// I386:typedef long long unsigned int uintmax_t;
 //
 // I386:INT8_MAX_ 127
 // I386:INT8_MIN_ (-127 -1)
@@ -347,8 +347,8 @@
 // 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:typedef long int intmax_t;
+// MSP430:typedef long unsigned int uintmax_t;
 //
 // MSP430:INT8_MAX_ 127
 // MSP430:INT8_MIN_ (-127 -1)
@@ -447,8 +447,8 @@
 // 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:typedef long int intmax_t;
+// PIC16:typedef long unsigned int uintmax_t;
 //
 // PIC16:INT8_MAX_ 127
 // PIC16:INT8_MIN_ (-127 -1)
@@ -554,8 +554,8 @@
 // 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:typedef long int intmax_t;
+// PPC64:typedef long unsigned int uintmax_t;
 //
 // PPC64:INT8_MAX_ 127
 // PPC64:INT8_MIN_ (-127 -1)
@@ -662,8 +662,8 @@
 // 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:typedef long long int intmax_t;
+// PPC:typedef long long unsigned int uintmax_t;
 //
 // PPC:INT8_MAX_ 127
 // PPC:INT8_MIN_ (-127 -1)
@@ -738,8 +738,8 @@
 //
 // 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 signed long long int int64_t;
+// S390X:typedef unsigned long 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;
@@ -769,8 +769,8 @@
 // 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:typedef long long int intmax_t;
+// S390X:typedef long long unsigned int uintmax_t;
 //
 // S390X:INT8_MAX_ 127
 // S390X:INT8_MIN_ (-127 -1)
@@ -803,23 +803,23 @@
 // S390X:UINT_FAST32_MAX_ 4294967295U
 //
 // S390X:INT64_MAX_ 9223372036854775807L
-// S390X:INT64_MIN_ (-9223372036854775807L -1)
+// S390X:INT64_MIN_ (-9223372036854775807LL -1)
 // S390X:UINT64_MAX_ 18446744073709551615UL
-// S390X:INT_LEAST64_MIN_ (-9223372036854775807L -1)
+// S390X:INT_LEAST64_MIN_ (-9223372036854775807LL -1)
 // S390X:INT_LEAST64_MAX_ 9223372036854775807L
 // S390X:UINT_LEAST64_MAX_ 18446744073709551615UL
-// S390X:INT_FAST64_MIN_ (-9223372036854775807L -1)
+// S390X:INT_FAST64_MIN_ (-9223372036854775807LL -1)
 // S390X:INT_FAST64_MAX_ 9223372036854775807L
 // S390X:UINT_FAST64_MAX_ 18446744073709551615UL
 //
-// S390X:INTPTR_MIN_ (-9223372036854775807L -1)
+// S390X:INTPTR_MIN_ (-9223372036854775807LL -1)
 // S390X:INTPTR_MAX_ 9223372036854775807L
 // S390X:UINTPTR_MAX_ 18446744073709551615UL
-// S390X:PTRDIFF_MIN_ (-9223372036854775807L -1)
+// S390X:PTRDIFF_MIN_ (-9223372036854775807LL -1)
 // S390X:PTRDIFF_MAX_ 9223372036854775807L
 // S390X:SIZE_MAX_ 18446744073709551615UL
 //
-// S390X:INTMAX_MIN_ (-9223372036854775807L -1)
+// S390X:INTMAX_MIN_ (-9223372036854775807LL -1)
 // S390X:INTMAX_MAX_ 9223372036854775807L
 // S390X:UINTMAX_MAX_ 18446744073709551615UL
 //
@@ -876,8 +876,8 @@
 // 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:typedef long long int intmax_t;
+// SPARC:typedef long long unsigned int uintmax_t;
 //
 // SPARC:INT8_MAX_ 127
 // SPARC:INT8_MIN_ (-127 -1)
@@ -976,8 +976,8 @@
 // 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:typedef long int intmax_t;
+// TCE:typedef long unsigned int uintmax_t;
 //
 // TCE:INT8_MAX_ 127
 // TCE:INT8_MIN_ (-127 -1)
@@ -1084,8 +1084,8 @@
 // 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:typedef long int intmax_t;
+// X86_64:typedef long unsigned int uintmax_t;
 //
 // X86_64:INT8_MAX_ 127
 // X86_64:INT8_MIN_ (-127 -1)
@@ -1165,11 +1165,11 @@
 // 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
+// RUN: %clang_cc1 -E -ffreestanding -U__UINTMAX_TYPE__ -U__INTMAX_TYPE__ -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:typedef __INTMAX_TYPE__ intmax_t;
+// JOIN:typedef __UINTMAX_TYPE__ uintmax_t;
 // JOIN:INTPTR_MIN_ (-2147483647 -1)
 // JOIN:INTPTR_MAX_ 2147483647
 // JOIN:UINTPTR_MAX_ 4294967295U
diff --git a/test/Rewriter/dllimport-typedef.c b/test/Rewriter/dllimport-typedef.c
index b86fa4a..441f498 100644
--- a/test/Rewriter/dllimport-typedef.c
+++ b/test/Rewriter/dllimport-typedef.c
@@ -9,9 +9,9 @@
 // diagnostics we expect.
 void bar() { return 1; }
 
-// CHECK-NEG: warning: void function 'bar' should not return a value
-// CHECK-NEG: 1 warning generated
+// CHECK-NEG: error: void function 'bar' should not return a value
+// CHECK-NEG: 1 error 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
+// CHECK-POS: error: void function 'bar' should not return a value
+// CHECK-POS: 1 warning and 1 error generated
 
diff --git a/test/Rewriter/missing-dllimport.c b/test/Rewriter/missing-dllimport.c
index c060379..1dfc04c 100644
--- a/test/Rewriter/missing-dllimport.c
+++ b/test/Rewriter/missing-dllimport.c
@@ -11,9 +11,9 @@
 // diagnostics we expect.
 void bar() { return 1; }
 
-// CHECK-NEG: warning: void function 'bar' should not return a value
-// CHECK-NEG: 1 warning generated
+// CHECK-NEG: error: void function 'bar' should not return a value
+// CHECK-NEG: 1 error 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
+// CHECK-POS: error: void function 'bar' should not return a value
+// CHECK-POS: 1 warning and 1 error generated
 
diff --git a/test/Rewriter/rewrite-block-argument.m b/test/Rewriter/rewrite-block-argument.m
new file mode 100644
index 0000000..4ebbef9
--- /dev/null
+++ b/test/Rewriter/rewrite-block-argument.m
@@ -0,0 +1,33 @@
+// 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 -Did="void *" -D"SEL=void*" -D"__declspec(X)=" -emit-llvm -o %t %t-rw.cpp
+// radar 7987817
+
+void *sel_registerName(const char *);
+
+@interface Test {
+}
+@end
+
+@implementation Test
+
+- (void)enumerateProvidersWithBlock:(void (^)(void))block {
+    block();
+}
+
+- (void)providerEnumerator {
+    ^(void (^providerBlock)(void)) {
+        [self enumerateProvidersWithBlock:providerBlock];
+    };
+}
+
+- (void)testNilBlock {
+    [self enumerateProvidersWithBlock:0];
+}
+
+@end
+
+
+
+int main(int argc, char *argv[]) {
+    return 0;
+}
diff --git a/test/Rewriter/rewrite-block-consts.mm b/test/Rewriter/rewrite-block-consts.mm
new file mode 100644
index 0000000..c74873f
--- /dev/null
+++ b/test/Rewriter/rewrite-block-consts.mm
@@ -0,0 +1,19 @@
+// 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
+// rdar:// 8243071
+
+void x(int y) {}
+void f() {
+    const int bar = 3;
+    int baz = 4;
+    __block int bab = 4;
+    __block const int bas = 5;
+    void (^b)() = ^{
+        x(bar);
+        x(baz);
+	x(bab);
+	x(bas);
+	b();
+    };    
+    b();
+}
diff --git a/test/Rewriter/rewrite-constructor-init.mm b/test/Rewriter/rewrite-constructor-init.mm
new file mode 100644
index 0000000..534e7fa
--- /dev/null
+++ b/test/Rewriter/rewrite-constructor-init.mm
@@ -0,0 +1,24 @@
+// 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
+// rdar : // 8213998
+
+typedef unsigned int NSUInteger;
+
+typedef struct _NSRange {
+    NSUInteger location;
+    NSUInteger length;
+} NSRange;
+
+static __inline NSRange NSMakeRange(NSUInteger loc, NSUInteger len) {
+    NSRange r;
+    r.location = loc;
+    r.length = len;
+    return r;
+}
+
+void bar() {
+    __block NSRange previousRange = NSMakeRange(0, 0);    
+    void (^blk)() = ^{
+        previousRange = NSMakeRange(1, 0);
+    };
+}
diff --git a/test/Rewriter/rewrite-elaborated-type.mm b/test/Rewriter/rewrite-elaborated-type.mm
new file mode 100644
index 0000000..9867b4d
--- /dev/null
+++ b/test/Rewriter/rewrite-elaborated-type.mm
@@ -0,0 +1,36 @@
+// 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_Bool=bool -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 8143056
+
+typedef struct objc_class *Class;
+typedef unsigned NSPointerFunctionsOptions;
+extern "C" id NSClassFromObject(id object);
+void *sel_registerName(const char *);
+
+struct NSSlice {
+  int i1;
+};
+
+@interface NSConcretePointerFunctions {
+  @public
+    struct NSSlice slice;
+}
+- (bool)initializeSlice:(struct NSSlice *)slicep withOptions:(NSPointerFunctionsOptions)options;
+@end
+
+@implementation NSConcretePointerFunctions
+- (id)initWithOptions:(NSPointerFunctionsOptions)options {
+      if (![NSClassFromObject(self) initializeSlice:&slice withOptions:options])
+        return 0;
+      return self;
+  }
+- (bool)initializeSlice:(struct NSSlice *)slicep withOptions:(NSPointerFunctionsOptions)options {
+    return 0;
+  }
+@end
+
+@implementation I1
++ (struct s1 *) f0 {
+  return 0;
+}
+@end
diff --git a/test/Rewriter/rewrite-local-static-id.mm b/test/Rewriter/rewrite-local-static-id.mm
new file mode 100644
index 0000000..a0b85f4
--- /dev/null
+++ b/test/Rewriter/rewrite-local-static-id.mm
@@ -0,0 +1,24 @@
+// 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 -Did="void *" -D"SEL=void*" -D"__declspec(X)=" -emit-llvm -o %t %t-rw.cpp
+// radar 7946975
+
+void *sel_registerName(const char *);
+
+@interface foo
+@end
+
+@interface foo2 : foo
++ (id)x;
+@end
+
+typedef void (^b_t)(void);
+
+void bar(b_t block);
+
+void f() {
+        static id foo = 0;
+        bar(^{
+                foo = [foo2 x];
+        });
+}
+
diff --git a/test/Rewriter/rewrite-no-nextline.mm b/test/Rewriter/rewrite-no-nextline.mm
new file mode 100644
index 0000000..0c3657c
--- /dev/null
+++ b/test/Rewriter/rewrite-no-nextline.mm
@@ -0,0 +1,10 @@
+// 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 7946975
+
+@interface RootObject {
+}
+@end void doStuff();
+int main(int argc, char *argv[]) {
+    return 0;
+}
diff --git a/test/Sema/address_spaces.c b/test/Sema/address_spaces.c
index 6258114..23c1405 100644
--- a/test/Sema/address_spaces.c
+++ b/test/Sema/address_spaces.c
@@ -36,7 +36,7 @@
 // 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}} \
+  return base[0];  // expected-error {{illegal implicit conversion 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-x86-64.c b/test/Sema/align-x86-64.c
new file mode 100644
index 0000000..6dcf571
--- /dev/null
+++ b/test/Sema/align-x86-64.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %s
+
+// PR5599
+
+void frob(void *);
+
+void foo(void) {
+  float x[4];
+  char y[__alignof__(x) == 16 ? 1 : -1];
+  frob(y);
+}
diff --git a/test/Sema/altivec-init.c b/test/Sema/altivec-init.c
index 57abc93..b5758bc 100644
--- a/test/Sema/altivec-init.c
+++ b/test/Sema/altivec-init.c
@@ -14,3 +14,22 @@
   // FIXME: test that (type)(fn)(args) still works with -faltivec
   // FIXME: test that c++ overloaded commas still work -faltivec
 }
+
+void __attribute__((__overloadable__)) f(v4 a)
+{
+}
+
+void __attribute__((__overloadable__)) f(int a)
+{
+}
+
+void test()
+{
+  v4 vGCC;
+  vector int vAltiVec;
+
+  f(vAltiVec);
+  vGCC = vAltiVec;
+  vGCC = vGCC > vAltiVec;
+  vAltiVec = 0 ? vGCC : vGCC;
+}
diff --git a/test/Sema/array-init.c b/test/Sema/array-init.c
index f93b087..0ee22c0 100644
--- a/test/Sema/array-init.c
+++ b/test/Sema/array-init.c
@@ -210,7 +210,7 @@
 
 // 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}}
+int u2 = {{3}}; //expected-warning{{too many braces around scalar initializer}}
 
 // PR2362
 void varArray() {
@@ -218,7 +218,8 @@
 }
 
 // PR2151
-void emptyInit() {struct {} x[] = {6};} //expected-warning{{empty struct extension}} expected-error{{initializer for aggregate with no elements}}
+void emptyInit() {struct {} x[] = {6};} //expected-warning{{empty struct (accepted as an extension) has size 0 in C, size 1 in C++}} \
+// expected-error{{initializer for aggregate with no elements}}
 
 void noNamedInit() {
   struct {int:5;} x[] = {6}; //expected-error{{initializer for aggregate with no elements}}
@@ -241,7 +242,8 @@
 };
 
 static void sppp_ipv6cp_up();
-const struct {} ipcp = { sppp_ipv6cp_up }; //expected-warning{{empty struct extension}} expected-warning{{excess elements in struct initializer}}
+const struct {} ipcp = { sppp_ipv6cp_up }; //expected-warning{{empty struct (accepted as an extension) has size 0 in C, size 1 in C++}} \
+// 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;
diff --git a/test/Sema/array-size-64.c b/test/Sema/array-size-64.c
new file mode 100644
index 0000000..f22e8e7
--- /dev/null
+++ b/test/Sema/array-size-64.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -verify %s
+
+void f() {
+  int a[2147483647U][2147483647U]; // expected-error{{array is too large}}
+  int b[1073741825U - 1U][2147483647U];
+  int c[18446744073709551615U/sizeof(int)/2];
+}
diff --git a/test/Sema/array-size.c b/test/Sema/array-size.c
new file mode 100644
index 0000000..7580e3e
--- /dev/null
+++ b/test/Sema/array-size.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple i686-apple-darwin -verify %s
+
+void f() {
+  int x0[1073741824]; // expected-error{{array is too large}}
+  int x1[1073741824 + 1]; // expected-error{{array is too large}}
+  int x2[(unsigned)1073741824]; // expected-error{{array is too large}}
+  int x3[(unsigned)1073741824 + 1]; // expected-error{{array is too large}}
+  int x4[1073741824 - 1];
+}
+
diff --git a/test/Sema/attr-deprecated.c b/test/Sema/attr-deprecated.c
index e723255..e7c997f 100644
--- a/test/Sema/attr-deprecated.c
+++ b/test/Sema/attr-deprecated.c
@@ -4,8 +4,6 @@
 void g() __attribute__((deprecated));
 void g();
 
-void z() __attribute__((bogusattr)); // expected-warning {{'bogusattr' attribute ignored}}
-
 extern int var __attribute__((deprecated));
 
 int a() {
@@ -45,7 +43,7 @@
 foo_dep *test2;    // expected-warning {{'foo_dep' is deprecated}}
 
 struct bar_dep __attribute__((deprecated, 
-                              invalid_attribute));  // expected-warning {{'invalid_attribute' attribute ignored}}
+                              invalid_attribute));  // expected-warning {{unknown attribute 'invalid_attribute' ignored}}
 
 struct bar_dep *test3;   // expected-warning {{'bar_dep' is deprecated}}
 
diff --git a/test/Sema/attr-noreturn.c b/test/Sema/attr-noreturn.c
index b17f9fd..927df7f 100644
--- a/test/Sema/attr-noreturn.c
+++ b/test/Sema/attr-noreturn.c
@@ -9,7 +9,7 @@
 } // expected-warning {{function declared 'noreturn' should not return}}
 
 // On K&R
-int f1() __attribute__((noreturn));
+int f1() __attribute__((noreturn)); // expected-warning{{functions declared 'noreturn' should have a 'void' result type}}
 
 int g0 __attribute__((noreturn)); // expected-warning {{'noreturn' only applies to function types; type here is 'int'}}
 
@@ -40,3 +40,5 @@
 __attribute__((noreturn)) void f(__attribute__((noreturn)) void (*x)(void)) {
   x();
 }
+
+typedef void (*Fun)(void) __attribute__ ((noreturn(2))); // expected-error {{attribute requires 0 argument(s)}}
diff --git a/test/Sema/attr-regparm.c b/test/Sema/attr-regparm.c
index 045a413..4049e0e 100644
--- a/test/Sema/attr-regparm.c
+++ b/test/Sema/attr-regparm.c
@@ -1,7 +1,11 @@
 // 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)}}
+__attribute((regparm(2))) int x0(void);
+__attribute((regparm(1.0))) int x1(void); // expected-error{{'regparm' attribute requires integer constant}}
+__attribute((regparm(-1))) int x2(void); // expected-error{{'regparm' parameter must be between 0 and 3 inclusive}}
+__attribute((regparm(5))) int x3(void); // expected-error{{'regparm' parameter must be between 0 and 3 inclusive}}
+__attribute((regparm(5,3))) int x4(void); // expected-error{{attribute requires 1 argument(s)}}
+
+void __attribute__((regparm(3))) x5(int);
+void x5(int); // expected-note{{previous declaration is here}}
+void __attribute__((regparm(2))) x5(int); // expected-error{{function declared with with regparm(2) attribute was previously declared with the regparm(3) attribute}}
diff --git a/test/Sema/attr-sentinel.c b/test/Sema/attr-sentinel.c
index db90d07..5ca6a8d 100644
--- a/test/Sema/attr-sentinel.c
+++ b/test/Sema/attr-sentinel.c
@@ -4,7 +4,7 @@
 
 #define ATTR __attribute__ ((__sentinel__)) 
 
-void foo1 (int x, ...) ATTR; // expected-note {{function has been explicitly marked sentinel here}}
+void foo1 (int x, ...) ATTR; // expected-note 2 {{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}}
@@ -24,6 +24,12 @@
   foo7(1, NULL); // OK
 
   foo12(1); // expected-warning {{not enough variable arguments in 'foo12' declaration to fit a sentinel}}
+
+  // PR 5685
+  struct A {};
+  struct A a, b, c;
+  foo1(3, &a, &b, &c); // expected-warning {{missing sentinel in function call}}
+  foo1(3, &a, &b, &c, (struct A*) 0);
 }
  
 
diff --git a/test/Sema/attr-unknown.c b/test/Sema/attr-unknown.c
new file mode 100644
index 0000000..bec2e29
--- /dev/null
+++ b/test/Sema/attr-unknown.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wunknown-attributes %s
+
+int x __attribute__((foobar)); // expected-warning {{unknown attribute 'foobar' ignored}}
+void z() __attribute__((bogusattr)); // expected-warning {{unknown attribute 'bogusattr' ignored}}
diff --git a/test/Sema/bitfield-layout.c b/test/Sema/bitfield-layout.c
index edc44bd..2655fc7 100644
--- a/test/Sema/bitfield-layout.c
+++ b/test/Sema/bitfield-layout.c
@@ -30,3 +30,13 @@
 struct f {__attribute((aligned(8))) int x : 30, y : 30, z : 30;};
 CHECK_SIZE(struct, f, 24)
 CHECK_ALIGN(struct, f, 8)
+
+// Large structure (overflows i32, in bits).
+struct s0 {
+  char a[0x32100000];
+  int x:30, y:30;
+};
+
+CHECK_SIZE(struct, s0, 0x32100008)
+CHECK_ALIGN(struct, s0, 4)
+
diff --git a/test/Sema/block-call.c b/test/Sema/block-call.c
index 318bc6b..27e4cfc 100644
--- a/test/Sema/block-call.c
+++ b/test/Sema/block-call.c
@@ -17,6 +17,7 @@
 
   const int (^CICC) () = CIC;
 
+
   int * const (^IPCC) () = 0;
 
   int * const (^IPCC1) () = IPCC;
diff --git a/test/Sema/block-misc.c b/test/Sema/block-misc.c
index 92be5b1..ec74a63 100644
--- a/test/Sema/block-misc.c
+++ b/test/Sema/block-misc.c
@@ -221,3 +221,8 @@
     (void)b[1]; // expected-error {{cannot refer to declaration with an array type inside block}}
   }();
 }
+
+// rdar ://8218839
+const char * (^func)(void) = ^{ return __func__; };
+const char * (^function)(void) = ^{ return __FUNCTION__; };
+const char * (^pretty)(void) = ^{ return __PRETTY_FUNCTION__; };
diff --git a/test/Sema/block-return.c b/test/Sema/block-return.c
index 10b3b84..d40cef1 100644
--- a/test/Sema/block-return.c
+++ b/test/Sema/block-return.c
@@ -100,17 +100,19 @@
 int sz8 = sizeof(^int (*[5])(long) {return funcptr3;}); // expected-error {{block declared as returning an array}}
 
 void foo6() {
-  int (^b)(int) __attribute__((noreturn));
+  int (^b)(int) __attribute__((noreturn)); // expected-warning{{blocks declared 'noreturn' should have a 'void' result type}}
   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}}
+  int (^c)(void) __attribute__((noreturn)) = ^ __attribute__((noreturn)) { return 100; }; // expected-error {{block declared 'noreturn' should not return}} expected-warning{{blocks declared 'noreturn' should have a 'void' result type}}
 }
 
 
 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
+
+ const int (^CC) (void)  = ^const int{ const int i = 1; return i; };
+
 
   int i;
   int (^FF) (void)  = ^{ return i; }; // OK
diff --git a/test/Sema/builtins-arm.c b/test/Sema/builtins-arm.c
new file mode 100644
index 0000000..4dd31e7
--- /dev/null
+++ b/test/Sema/builtins-arm.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple armv7 -fsyntax-only -verify -DTEST0 %s
+// RUN: %clang_cc1 -triple armv7 -fsyntax-only -verify -DTEST1 %s
+
+#ifdef TEST0
+void __clear_cache(char*, char*);
+#endif
+
+#ifdef TEST1
+void __clear_cache(void*, void*);
+#endif
+
diff --git a/test/Sema/builtins.c b/test/Sema/builtins.c
index 6fa563b..787630c 100644
--- a/test/Sema/builtins.c
+++ b/test/Sema/builtins.c
@@ -40,7 +40,15 @@
   
   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}}
+  old = __sync_fetch_and_add((unsigned*)0, 42i); // expected-warning {{imaginary constants are an extension}}
+
+  // PR7600: Pointers are implicitly casted to integers and back.
+  void *old_ptr = __sync_val_compare_and_swap((void**)0, 0, 0);
+
+  // Ensure the return type is correct even when implicit casts are stripped
+  // away. This triggers an assertion while checking the comparison otherwise.
+  if (__sync_fetch_and_add(&old, 1) == 1) {
+  }
 }
 
 
@@ -72,3 +80,18 @@
 void test_unknown_builtin(int a, int b) {
   __builtin_foo(a, b); // expected-error{{use of unknown builtin}}
 }
+
+int test13() {
+  __builtin_eh_return(0, 0); // no warning, eh_return never returns.
+}
+
+// <rdar://problem/8228293>
+void test14() {
+  int old;
+  old = __sync_fetch_and_min((volatile int *)&old, 1);
+}
+
+// <rdar://problem/8336581>
+void test15(const char *s) {
+  __builtin_printf("string is %s\n", s);
+}
diff --git a/test/Sema/c89.c b/test/Sema/c89.c
index 8a9e622..038f7e5 100644
--- a/test/Sema/c89.c
+++ b/test/Sema/c89.c
@@ -61,7 +61,7 @@
 void foo(void) {}
 
 /* PR2759 */
-void test10 (int x[*]); /* expected-warning {{use of C99-specific array features}} */
+void test10 (int x[*]); /* expected-warning {{variable length arrays are a C99 feature, accepted as an extension}} */
 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}} */
diff --git a/test/Sema/cast-incomplete.c b/test/Sema/cast-incomplete.c
new file mode 100644
index 0000000..dd10e00
--- /dev/null
+++ b/test/Sema/cast-incomplete.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify
+// PR5692
+
+enum x;            // expected-note   {{forward declaration}}
+extern struct y a; // expected-note   {{forward declaration}}
+extern union z b;  // expected-note 2 {{forward declaration}}
+
+void foo() {
+  (enum x)1;   // expected-error {{cast to incomplete type}}
+  (struct y)a; // expected-error {{cast to incomplete type}}
+  (union z)b;  // expected-error {{cast to incomplete type}}
+  (union z)1;  // expected-error {{cast to incomplete type}}
+}
+
diff --git a/test/Sema/compare.c b/test/Sema/compare.c
index 631b694..b2c3563 100644
--- a/test/Sema/compare.c
+++ b/test/Sema/compare.c
@@ -3,7 +3,7 @@
 int test(char *C) { // nothing here should warn.
   return C != ((void*)0);
   return C != (void*)0;
-  return C != 0;  
+  return C != 0;
   return C != 1;  // expected-warning {{comparison between pointer and integer ('char *' and 'int')}}
 }
 
@@ -23,8 +23,8 @@
          ((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}}
+         ((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) +
@@ -35,8 +35,8 @@
          ((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}}
+         ((short) a < (unsigned short) b) +
+         ((signed char) a < (unsigned char) b) +
 
          // (A,b)
          (A == (unsigned long) b) +
@@ -87,8 +87,8 @@
          ((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}}
+         ((short) a < (unsigned short) B) +
+         ((signed char) a < (unsigned char) B) +
 
          // (C,b)
          (C == (unsigned long) b) +
@@ -139,8 +139,8 @@
          ((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}}
+         ((short) a < (unsigned short) C) +
+         ((signed char) a < (unsigned char) C) +
 
          // (0x80000,b)
          (0x80000 == (unsigned long) b) +
@@ -191,8 +191,8 @@
          ((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}}
+         ((short) a < (unsigned short) 0x80000) +
+         ((signed char) a < (unsigned char) 0x80000) +
 
          // We should be able to avoid warning about this.
          (b != (a < 4 ? 1 : 2)) +
@@ -218,7 +218,7 @@
 
 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 function_pointers > function_pointers; // expected-warning {{self-comparison always evaluates to false}} 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}}
@@ -229,6 +229,7 @@
   return foo == (void*) 1;
 }
 
+
 int test1(int i) {
   enum en { zero };
   return i > zero;
diff --git a/test/Sema/compound-literal.c b/test/Sema/compound-literal.c
index 08c30b3..aade464 100644
--- a/test/Sema/compound-literal.c
+++ b/test/Sema/compound-literal.c
@@ -11,7 +11,7 @@
 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}}
+typedef struct { } cache_t; // -expected-warning{{empty struct (accepted as an extension) has size 0 in C, size 1 in C++}}
 static cache_t clo_I1_cache = ((cache_t) { } ); // -expected-warning{{use of GNU empty initializer extension}}
 
 typedef struct Test {int a;int b;} Test;
diff --git a/test/Sema/conditional-expr.c b/test/Sema/conditional-expr.c
index 5e2c1a4..6e248bc 100644
--- a/test/Sema/conditional-expr.c
+++ b/test/Sema/conditional-expr.c
@@ -52,7 +52,9 @@
   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}}
+  test0 = test0 ? // expected-warning {{operands of ? are integers of different signs}}
+                  (unsigned) EVal
+                : (int) test0;
 }
 
 int Postgresql() {
@@ -68,3 +70,8 @@
   // 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'}}
 }
+
+int f2(int x) {
+  // We can suppress this because the immediate context wants an int.
+  return (x != 0) ? 0U : x;
+}
diff --git a/test/Sema/const-eval.c b/test/Sema/const-eval.c
index 9c53725..42097e7 100644
--- a/test/Sema/const-eval.c
+++ b/test/Sema/const-eval.c
@@ -74,5 +74,9 @@
 EVAL_EXPR(35, constbool)
 EVAL_EXPR(36, constbool)
 
-EVAL_EXPR(37, (1,2.0) == 2.0)
-EVAL_EXPR(38, __builtin_expect(1,1) == 1)
+EVAL_EXPR(37, (1,2.0) == 2.0 ? 1 : -1)
+EVAL_EXPR(38, __builtin_expect(1,1) == 1 ? 1 : -1)
+
+// PR7884
+EVAL_EXPR(39, __real__(1.f) == 1 ? 1 : -1)
+EVAL_EXPR(40, __imag__(1.f) == 0 ? 1 : -1)
diff --git a/test/Sema/conversion-64-32.c b/test/Sema/conversion-64-32.c
index 1043996..aa72829 100644
--- a/test/Sema/conversion-64-32.c
+++ b/test/Sema/conversion-64-32.c
@@ -1,5 +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}}
+  return v; // expected-warning {{implicit conversion loses integer precision}}
 }
diff --git a/test/Sema/conversion.c b/test/Sema/conversion.c
index addedd9..5fbd64d 100644
--- a/test/Sema/conversion.c
+++ b/test/Sema/conversion.c
@@ -6,17 +6,17 @@
 
 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}}
+  c = s; // expected-warning {{implicit conversion loses integer precision}}
+  c = i; // expected-warning {{implicit conversion loses integer precision}}
+  c = l; // expected-warning {{implicit conversion 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}}
+  s = i; // expected-warning {{implicit conversion loses integer precision}}
+  s = l; // expected-warning {{implicit conversion loses integer precision}}
   i = c;
   i = s;
   i = i;
-  i = l; // expected-warning {{implicit cast loses integer precision}}
+  i = l; // expected-warning {{implicit conversion loses integer precision}}
   l = c;
   l = s;
   l = i;
@@ -40,17 +40,17 @@
   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}}
+  c = (short) BIG; // expected-warning {{implicit conversion loses integer precision}}
+  c = (int) BIG; // expected-warning {{implicit conversion loses integer precision}}
+  c = (long) BIG; // expected-warning {{implicit conversion 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}}
+  s = (int) BIG; // expected-warning {{implicit conversion loses integer precision}}
+  s = (long) BIG; // expected-warning {{implicit conversion loses integer precision}}
   i = (char) BIG;
   i = (short) BIG;
   i = (int) BIG;
-  i = (long) BIG; // expected-warning {{implicit cast loses integer precision}}
+  i = (long) BIG; // expected-warning {{implicit conversion loses integer precision}}
   l = (char) BIG;
   l = (short) BIG;
   l = (int) BIG;
@@ -58,39 +58,39 @@
 }
 
 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 (long long) ll; // expected-warning {{implicit conversion loses integer precision}}
+  return (long) ll; // expected-warning {{implicit conversion loses integer precision}}
+  return (int) ll; // expected-warning {{implicit conversion loses integer precision}}
+  return (short) ll; // expected-warning {{implicit conversion 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 (long long) BIG; // expected-warning {{implicit conversion loses integer precision}}
+  return (long) BIG; // expected-warning {{implicit conversion loses integer precision}}
+  return (int) BIG; // expected-warning {{implicit conversion loses integer precision}}
+  return (short) BIG; // expected-warning {{implicit conversion 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 (long long) ll; // expected-warning {{implicit conversion loses integer precision}}
+  return (long) ll; // expected-warning {{implicit conversion loses integer precision}}
+  return (int) ll; // expected-warning {{implicit conversion 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 (long long) BIG;  // expected-warning {{implicit conversion loses integer precision}}
+  return (long) BIG;  // expected-warning {{implicit conversion loses integer precision}}
+  return (int) BIG;  // expected-warning {{implicit conversion 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 (long long) ll;  // expected-warning {{implicit conversion loses integer precision}}
+  return (long) ll;  // expected-warning {{implicit conversion 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 (long long) BIG;  // expected-warning {{implicit conversion loses integer precision}}
+  return (long) BIG; // expected-warning {{implicit conversion loses integer precision}}
   return (int) BIG;
   return (short) BIG;
   return (char) BIG;
@@ -143,7 +143,7 @@
 }
 
 void test7(short v) {
-  takes_char(v); // expected-warning {{implicit cast loses integer precision}}
+  takes_char(v); // expected-warning {{implicit conversion loses integer precision}}
   takes_short(v);
   takes_int(v);
   takes_long(v);
@@ -154,8 +154,8 @@
 }
 
 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_char(v); // expected-warning {{implicit conversion loses integer precision}}
+  takes_short(v); // expected-warning {{implicit conversion loses integer precision}}
   takes_int(v);
   takes_long(v);
   takes_longlong(v);
@@ -165,9 +165,9 @@
 }
 
 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_char(v); // expected-warning {{implicit conversion loses integer precision}}
+  takes_short(v); // expected-warning {{implicit conversion loses integer precision}}
+  takes_int(v); // expected-warning {{implicit conversion loses integer precision}}
   takes_long(v);
   takes_longlong(v);
   takes_float(v);
@@ -176,9 +176,9 @@
 }
 
 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_char(v); // expected-warning {{implicit conversion loses integer precision}}
+  takes_short(v); // expected-warning {{implicit conversion loses integer precision}}
+  takes_int(v); // expected-warning {{implicit conversion loses integer precision}}
   takes_long(v);
   takes_longlong(v);
   takes_float(v);
@@ -187,35 +187,35 @@
 }
 
 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_char(v); // expected-warning {{implicit conversion turns floating-point number into integer}}
+  takes_short(v); // expected-warning {{implicit conversion turns floating-point number into integer}}
+  takes_int(v); // expected-warning {{implicit conversion turns floating-point number into integer}}
+  takes_long(v); // expected-warning {{implicit conversion turns floating-point number into integer}}
+  takes_longlong(v); // expected-warning {{implicit conversion 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_char(v); // expected-warning {{implicit conversion turns floating-point number into integer}}
+  takes_short(v); // expected-warning {{implicit conversion turns floating-point number into integer}}
+  takes_int(v); // expected-warning {{implicit conversion turns floating-point number into integer}}
+  takes_long(v); // expected-warning {{implicit conversion turns floating-point number into integer}}
+  takes_longlong(v); // expected-warning {{implicit conversion turns floating-point number into integer}}
+  takes_float(v); // expected-warning {{implicit conversion 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_char(v); // expected-warning {{implicit conversion turns floating-point number into integer}}
+  takes_short(v); // expected-warning {{implicit conversion turns floating-point number into integer}}
+  takes_int(v); // expected-warning {{implicit conversion turns floating-point number into integer}}
+  takes_long(v); // expected-warning {{implicit conversion turns floating-point number into integer}}
+  takes_longlong(v); // expected-warning {{implicit conversion turns floating-point number into integer}}
+  takes_float(v); // expected-warning {{implicit conversion loses floating-point precision}}
+  takes_double(v); // expected-warning {{implicit conversion loses floating-point precision}}
   takes_longdouble(v);
 }
 
@@ -229,13 +229,13 @@
 
 void test15(char c) {
   c = c + 1 + c * 2;
-  c = (short) c + 1 + c * 2; // expected-warning {{implicit cast loses integer precision}}
+  c = (short) c + 1 + c * 2; // expected-warning {{implicit conversion 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}}
+  int a = (unsigned long) &test16_external; // expected-warning {{implicit conversion loses integer precision}}
 }
 
 // PR 5938
@@ -249,7 +249,7 @@
   unsigned int x;
   x = U.a;
   x = U.b;
-  x = U.c; // expected-warning {{implicit cast loses integer precision}} 
+  x = U.c; // expected-warning {{implicit conversion loses integer precision}} 
 }
 
 // PR 5939
@@ -277,7 +277,7 @@
 // <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'}}
+  char s = LONG_MAX; // expected-warning {{implicit conversion loses integer precision: 'long' to 'char'}}
 }
 
 // <rdar://problem/7676608>: assertion for compound operators with non-integral RHS
@@ -287,3 +287,13 @@
   char c = 5;
   f7676608(c *= q);
 }
+
+// <rdar://problem/7904686>
+void test_7904686(void) {
+  const int i = -1;
+  unsigned u1 = i; // expected-warning {{implicit conversion changes signedness}}  
+  u1 = i; // expected-warning {{implicit conversion changes signedness}}  
+
+  unsigned u2 = -1; // expected-warning {{implicit conversion changes signedness}}  
+  u2 = -1; // expected-warning {{implicit conversion changes signedness}}  
+}
diff --git a/test/Sema/enum-packed.c b/test/Sema/enum-packed.c
new file mode 100644
index 0000000..0eb6c14
--- /dev/null
+++ b/test/Sema/enum-packed.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR7477
+enum __attribute__((packed)) E {
+  Ea, Eb, Ec, Ed
+};
+
+void test_E(enum E e) {
+  switch (e) {
+  case Ea:
+  case Eb:
+  case Ec:
+  case Ed:
+    break;
+  }
+}
diff --git a/test/Sema/enum.c b/test/Sema/enum.c
index ba4e56b..64aa31b 100644
--- a/test/Sema/enum.c
+++ b/test/Sema/enum.c
@@ -51,7 +51,7 @@
 }
 
 // PR2416
-enum someenum {};  // expected-warning {{use of empty enum extension}}
+enum someenum {};  // expected-error {{use of empty enum}}
 
 // <rdar://problem/6093889>
 enum e0 { // expected-note {{previous definition is here}}
@@ -96,3 +96,9 @@
 // PR4515
 enum PR4515 {PR4515a=1u,PR4515b=(PR4515a-2)/2};
 int CheckPR4515[PR4515b==0?1:-1];
+
+// PR7911
+extern enum PR7911T PR7911V; // expected-warning{{ISO C forbids forward references to 'enum' types}}
+void PR7911F() {
+  switch (PR7911V); // expected-error {{statement requires expression of integer type}}
+}
diff --git a/test/Sema/exprs.c b/test/Sema/exprs.c
index dbb6e80..56a52be 100644
--- a/test/Sema/exprs.c
+++ b/test/Sema/exprs.c
@@ -134,3 +134,19 @@
   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}}
 }
+
+// PR7569
+void test19() {
+  *(int*)0 = 0;   // expected-warning {{indirection of non-volatile null pointer}} \
+                  // expected-note {{consider using __builtin_trap}}
+  *(volatile int*)0 = 0;  // Ok.
+}
+
+int test20(int x) {
+  return x && 4; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+
+  return x && sizeof(int) == 4;  // no warning, RHS is logical op.
+  
+  // no warning, this is an idiom for "true" in old C style.
+  return x && (signed char)1;
+}
diff --git a/test/Sema/ext_vector_casts.c b/test/Sema/ext_vector_casts.c
index d297623..75d41ca 100644
--- a/test/Sema/ext_vector_casts.c
+++ b/test/Sema/ext_vector_casts.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fno-lax-vector-conversions %s
 
 typedef __attribute__(( ext_vector_type(2) )) float float2;
 typedef __attribute__(( ext_vector_type(4) )) int int4;
@@ -43,3 +43,10 @@
     ivec4 |= ivec4;
     ivec4 += ptr; // expected-error {{can't convert between vector values of different size ('int4' and 'int *')}}
 }
+
+typedef __attribute__(( ext_vector_type(2) )) float2 vecfloat2; // expected-error{{invalid vector element type 'float2'}}
+
+void inc(float2 f2) {
+  f2++; // expected-error{{cannot increment value of type 'float2'}}
+  __real f2; // expected-error{{invalid type 'float2' to __real operator}}
+}
diff --git a/test/Sema/ext_vector_comparisons.c b/test/Sema/ext_vector_comparisons.c
new file mode 100644
index 0000000..605ba6c
--- /dev/null
+++ b/test/Sema/ext_vector_comparisons.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unreachable-code %s
+
+typedef __attribute__(( ext_vector_type(4) )) int int4;
+
+static int4 test1() {
+  int4 vec, rv;
+
+  // comparisons to self...
+  return vec == vec; // expected-warning{{self-comparison always evaluates to a constant}}
+  return vec != vec; // expected-warning{{self-comparison always evaluates to a constant}}
+  return vec < vec; // expected-warning{{self-comparison always evaluates to a constant}}
+  return vec <= vec; // expected-warning{{self-comparison always evaluates to a constant}}
+  return vec > vec; // expected-warning{{self-comparison always evaluates to a constant}}
+  return vec >= vec; // expected-warning{{self-comparison always evaluates to a constant}}
+}
+
+
+typedef __attribute__(( ext_vector_type(4) )) float float4;
+
+static int4 test2() {
+  float4 vec, rv;
+
+  // comparisons to self.  no warning, they're floats
+  return vec == vec; // no-warning
+  return vec != vec; // no-warning
+  return vec < vec;  // no-warning
+  return vec <= vec; // no-warning
+  return vec > vec;  // no-warning
+  return vec >= vec; // no-warning
+}
diff --git a/test/Sema/extern-redecl.c b/test/Sema/extern-redecl.c
new file mode 100644
index 0000000..067e3c2
--- /dev/null
+++ b/test/Sema/extern-redecl.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+// rdar: // 8125274
+static int a16[];  // expected-warning {{tentative array definition assumed to have one element}}
+
+void f16(void) {
+    extern int a16[];
+}
+
diff --git a/test/Sema/format-strings-fixit.c b/test/Sema/format-strings-fixit.c
new file mode 100644
index 0000000..7cd76c7
--- /dev/null
+++ b/test/Sema/format-strings-fixit.c
@@ -0,0 +1,44 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -pedantic -Wall -fixit %t || true
+// RUN: %clang_cc1 -fsyntax-only -pedantic -Wall -Werror %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. */
+
+int printf(char const *, ...);
+
+void test() {
+  // Basic types
+  printf("%s", (int) 123);
+  printf("abc%0f", "testing testing 123");
+  printf("%u", (long) -12);
+  printf("%p", 123);
+  printf("%c\n", "x");
+  printf("%c\n", 1.23);
+
+  // Larger types
+  printf("%+.2d", (unsigned long long) 123456);
+  printf("%1d", (long double) 1.23);
+
+  // Flag handling
+  printf("%0+s", (unsigned) 31337); // 0 flag should stay
+  printf("%#p", (void *) 0);
+  printf("% +f", 1.23); // + flag should stay
+  printf("%0-f", 1.23); // - flag should stay
+
+  // Positional arguments
+  printf("%1$f:%2$.*3$f:%4$.*3$f\n", 1, 2, 3, 4);
+
+  // Precision
+  printf("%10.5d", 1l); // (bug 7394)
+  printf("%.2c", 'a');
+
+  // Ignored flags
+  printf("%0-f", 1.23);
+
+  // Bad length modifiers
+  printf("%hhs", "foo");
+  printf("%1$zp", (void *)0);
+}
diff --git a/test/Sema/format-strings-scanf.c b/test/Sema/format-strings-scanf.c
new file mode 100644
index 0000000..42b6c03
--- /dev/null
+++ b/test/Sema/format-strings-scanf.c
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral %s
+
+typedef __typeof(sizeof(int)) size_t;
+typedef struct _FILE FILE;
+typedef __WCHAR_TYPE__ wchar_t;
+
+int fscanf(FILE * restrict, const char * restrict, ...) ;
+int scanf(const char * restrict, ...) ;
+int sscanf(const char * restrict, const char * restrict, ...) ;
+
+void test(const char *s, int *i) {
+  scanf(s, i); // expected-warning{{ormat string is not a string literal}}
+  scanf("%0d", i); // expected-warning{{zero field width in scanf format string is unused}}
+  scanf("%00d", i); // expected-warning{{zero field width in scanf format string is unused}}
+  scanf("%d%[asdfasdfd", i, s); // expected-warning{{no closing ']' for '%[' in scanf format string}}
+
+  unsigned short s_x;
+  scanf ("%" "hu" "\n", &s_x); // no-warning
+  scanf("%y", i); // expected-warning{{invalid conversion specifier 'y'}}
+  scanf("%%"); // no-warning
+  scanf("%%%1$d", i); // no-warning
+  scanf("%1$d%%", i); // no-warning
+  scanf("%d", i, i); // expected-warning{{data argument not used by format string}}
+  scanf("%*d", i); // // expected-warning{{data argument not used by format string}}
+  scanf("%*d", i); // // expected-warning{{data argument not used by format string}}
+  scanf("%*d%1$d", i); // no-warning
+}
+
+void bad_length_modifiers(char *s, void *p, wchar_t *ws, long double *ld) {
+  scanf("%hhs", "foo"); // expected-warning{{length modifier 'hh' results in undefined behavior or no effect with 's' conversion specifier}}
+  scanf("%1$zp", p); // expected-warning{{length modifier 'z' results in undefined behavior or no effect with 'p' conversion specifier}}
+  scanf("%ls", ws); // no-warning
+  scanf("%#.2Lf", ld); // expected-warning{{invalid conversion specifier '#'}}
+}
diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c
index bdc2bb0..2325454 100644
--- a/test/Sema/format-strings.c
+++ b/test/Sema/format-strings.c
@@ -172,18 +172,21 @@
   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
+  printf("%c\n", "x"); // expected-warning{{conversion specifies type 'int' but the argument has type 'char *'}}
+  printf("%c\n", 1.23); // expected-warning{{conversion specifies type 'int' but the argument has type 'double'}}
 } 
 
 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("%p", 123); // expected-warning{{conversion specifies type 'void *' but the argument has type 'int'}}
+  printf("%.4p", p); // expected-warning{{precision used with 'p' conversion specifier, resulting in undefined behavior}}
+  printf("%+p", p); // expected-warning{{flag '+' results in undefined behavior with 'p' conversion specifier}}
+  printf("% p", p); // expected-warning{{flag ' ' results in undefined behavior with 'p' conversion specifier}}
+  printf("%0p", p); // expected-warning{{flag '0' results in undefined behavior with '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}}
+  printf("%+s", p); // expected-warning{{flag '+' results in undefined behavior with 's' conversion specifier}}
+  printf("% s", p); // expected-warning{{flag ' ' results in undefined behavior with 's' conversion specifier}}
+  printf("%0s", p); // expected-warning{{flag '0' results in undefined behavior with 's' conversion specifier}}
 }
 
 void test12(char *b) {
@@ -236,6 +239,8 @@
   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}}
+  printf("%%%1$d", (int) 2); // no-warning
+  printf("%1$d%%", (int) 2); // no-warning
 }
 
 // PR 6697 - Handle format strings where the data argument is not adjacent to the format string
@@ -251,3 +256,48 @@
   myprintf_PR_6697("%1$s\n", 1, (int) 0); // expected-warning{{conversion specifies type 'char *' but the argument has type 'int'}}
 }
 
+void rdar8026030(FILE *fp) {
+  fprintf(fp, "\%"); // expected-warning{{incomplete format specifier}}
+}
+
+void bug7377_bad_length_mod_usage() {
+  // Bad length modifiers
+  printf("%hhs", "foo"); // expected-warning{{length modifier 'hh' results in undefined behavior or no effect with 's' conversion specifier}}
+  printf("%1$zp", (void *)0); // expected-warning{{length modifier 'z' results in undefined behavior or no effect with 'p' conversion specifier}}
+  printf("%ls", L"foo"); // no-warning
+  printf("%#.2Lf", (long double)1.234); // no-warning
+
+  // Bad flag usage
+  printf("%#p", (void *) 0); // expected-warning{{flag '#' results in undefined behavior with 'p' conversion specifier}}
+  printf("%0d", -1); // no-warning
+  printf("%#n", (void *) 0); // expected-warning{{flag '#' results in undefined behavior with 'n' conversion specifier}} expected-warning{{use of '%n' in format string discouraged (potentially insecure)}}
+  printf("%-n", (void *) 0); // expected-warning{{flag '-' results in undefined behavior with 'n' conversion specifier}} expected-warning{{use of '%n' in format string discouraged (potentially insecure)}}
+  printf("%-p", (void *) 0); // no-warning
+
+  // Bad optional amount use
+  printf("%.2c", 'a'); // expected-warning{{precision used with 'c' conversion specifier, resulting in undefined behavior}}
+  printf("%1n", (void *) 0); // expected-warning{{field width used with 'n' conversion specifier, resulting in undefined behavior}} expected-warning{{use of '%n' in format string discouraged (potentially insecure)}}
+  printf("%.9n", (void *) 0); // expected-warning{{precision used with 'n' conversion specifier, resulting in undefined behavior}} expected-warning{{use of '%n' in format string discouraged (potentially insecure)}}
+
+  // Ignored flags
+  printf("% +f", 1.23); // expected-warning{{flag ' ' is ignored when flag '+' is present}}
+  printf("%+ f", 1.23); // expected-warning{{flag ' ' is ignored when flag '+' is present}}
+  printf("%0-f", 1.23); // expected-warning{{flag '0' is ignored when flag '-' is present}}
+  printf("%-0f", 1.23); // expected-warning{{flag '0' is ignored when flag '-' is present}}
+  printf("%-+f", 1.23); // no-warning
+}
+
+// PR 7981 - handle '%lc' (wint_t)
+#ifndef wint_t
+typedef int __darwin_wint_t;
+typedef __darwin_wint_t wint_t;
+#endif
+
+void pr7981(wint_t c, wchar_t c2) {
+  printf("%lc", c); // no-warning
+  printf("%lc", 1.0); // expected-warning{{the argument has type 'double'}}
+  printf("%lc", (char) 1); // no-warning
+  printf("%lc", &c); // expected-warning{{the argument has type 'wint_t *' (aka 'int *')}}
+  printf("%lc", c2); // no-warning
+}
+
diff --git a/test/Sema/function-redecl.c b/test/Sema/function-redecl.c
index b8a64af..27ec163 100644
--- a/test/Sema/function-redecl.c
+++ b/test/Sema/function-redecl.c
@@ -120,12 +120,12 @@
 typedef int a();
 typedef int a2(int*);
 a x;
-a2 x2;
+a2 x2; // expected-note{{passing argument to parameter here}}
 void test_x() {
   x(5);
   x2(5); // expected-warning{{incompatible integer to pointer conversion passing 'int' to parameter of type 'int *'}}
 }
 
-enum e0 {}; 
+enum e0 {one}; 
 void f3(); 
 void f3(enum e0 x) {}
diff --git a/test/Sema/function.c b/test/Sema/function.c
index 9a83519..b51c137 100644
--- a/test/Sema/function.c
+++ b/test/Sema/function.c
@@ -34,10 +34,10 @@
 
 // PR2790
 void t13() {
-  return 0; // expected-warning {{void function 't13' should not return a value}}
+  return 0; // expected-error {{void function 't13' should not return a value}}
 }
 int t14() {
-  return; // expected-warning {{non-void function 't14' should return a value}}
+  return; // expected-error {{non-void function 't14' should return a value}}
 }
 
 // <rdar://problem/6097326>
diff --git a/test/Sema/i-c-e.c b/test/Sema/i-c-e.c
index 97d9f43..eb77bbe 100644
--- a/test/Sema/i-c-e.c
+++ b/test/Sema/i-c-e.c
@@ -50,9 +50,11 @@
 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}}
+int comma1[0?1,2:3];  // expected-warning {{expression result unused}}
+int comma2[1||(1,2)]; // expected-warning {{expression result unused}} \
+                      // expected-warning {{use of logical || with constant operand}}
+int comma3[(1,2)]; // expected-warning {{size of static array must be an integer constant expression}} \
+					// expected-warning {{expression result unused}}
 
 // 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}}
diff --git a/test/Sema/implicit-decl.c b/test/Sema/implicit-decl.c
index 830cde9..f455977 100644
--- a/test/Sema/implicit-decl.c
+++ b/test/Sema/implicit-decl.c
@@ -10,7 +10,6 @@
    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/init.c b/test/Sema/init.c
index b9867cf..ac274a4 100644
--- a/test/Sema/init.c
+++ b/test/Sema/init.c
@@ -118,8 +118,6 @@
 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;
@@ -131,3 +129,17 @@
 // PR5447
 const double pr5447 = (0.05 < -1.0) ? -1.0 : 0.0499878;
 
+// PR4386
+
+// None of these are constant initializers, but we implement GCC's old
+// behaviour of accepting bar and zed but not foo. GCC's behaviour was
+// changed in 2007 (rev 122551), so we should be able to change too one
+// day.
+int PR4386_bar();
+int PR4386_foo() __attribute((weak));
+int PR4386_zed();
+
+int PR4386_a = ((void *) PR4386_bar) != 0;
+int PR4386_b = ((void *) PR4386_foo) != 0; // expected-error{{initializer element is not a compile-time constant}}
+int PR4386_c = ((void *) PR4386_zed) != 0;
+int PR4386_zed() __attribute((weak));
diff --git a/test/Sema/knr-def-call.c b/test/Sema/knr-def-call.c
index 8ae0550..66f2ec0 100644
--- a/test/Sema/knr-def-call.c
+++ b/test/Sema/knr-def-call.c
@@ -16,3 +16,14 @@
 
 typedef void (*f3)(void);
 f3 t3(int b) { return b? f0 : f1; } // okay
+
+// <rdar://problem/8193107>
+void f4() {
+    char *rindex();
+}
+
+char *rindex(s, c)
+     register char *s, c; // expected-warning{{promoted type 'char *' of K&R function parameter is not compatible with the parameter type 'char const *' declared in a previous prototype}}
+{
+  return 0;
+}
diff --git a/test/Sema/missing-field-initializers.c b/test/Sema/missing-field-initializers.c
index 8281914..6aa48ba 100644
--- a/test/Sema/missing-field-initializers.c
+++ b/test/Sema/missing-field-initializers.c
@@ -20,6 +20,8 @@
   1
 }; // expected-warning {{missing field 'b' initializer}}
 
+struct Foo bar2[] = { {}, {}, {} };
+
 struct One { int a; int b; };
 struct Two { float c; float d; float e; };
 
diff --git a/test/Sema/offsetof.c b/test/Sema/offsetof.c
index 49d4eb4..5026193 100644
--- a/test/Sema/offsetof.c
+++ b/test/Sema/offsetof.c
@@ -53,4 +53,15 @@
 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'}}
+int test2[__builtin_offsetof(struct incomplete[10], [4].foo)]; // expected-error {{array has incomplete element type 'struct incomplete'}}
+
+// Bitfields
+struct has_bitfields {
+  int i : 7;
+  int j : 12; // expected-note{{bit-field is declared here}}
+};
+
+int test3 = __builtin_offsetof(struct has_bitfields, j); // expected-error{{cannot compute offset of bit-field 'j'}}
+
+typedef struct Array { int array[1]; } Array;
+int test4 = __builtin_offsetof(Array, array);
diff --git a/test/Sema/opencl-init.c b/test/Sema/opencl-init.c
new file mode 100644
index 0000000..3d116bd
--- /dev/null
+++ b/test/Sema/opencl-init.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -x cl -verify -pedantic -fsyntax-only
+
+typedef float float8 __attribute((ext_vector_type(8)));
+
+typedef float float32_t;
+typedef __attribute__(( __vector_size__(16) )) float32_t __neon_float32x4_t;
+typedef struct __simd128_float32_t {
+  __neon_float32x4_t val;
+} float32x4_t;
+
+float8 foo(float8 x) { 
+  float32x4_t lo;
+  float32x4_t hi;
+  return (float8) (lo.val, hi.val);
+}
diff --git a/test/Sema/overloadable.c b/test/Sema/overloadable.c
index 28c3e4c..8fb41a9 100644
--- a/test/Sema/overloadable.c
+++ b/test/Sema/overloadable.c
@@ -41,7 +41,6 @@
 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}}
 
@@ -60,3 +59,13 @@
 double test_p6600(DoubleVec d) {
   return magnitude(d) * magnitude(d);
 }
+
+// PR7738
+extern int __attribute__((overloadable)) f0(); // expected-error{{'overloadable' function 'f0' must have a prototype}}
+typedef int f1_type();
+f1_type __attribute__((overloadable)) f1; // expected-error{{'overloadable' function 'f1' must have a prototype}}
+
+void test() { 
+  f0();
+  f1();
+}
diff --git a/test/Sema/pragma-align-mac68k-unsupported.c b/test/Sema/pragma-align-mac68k-unsupported.c
new file mode 100644
index 0000000..c23c01b
--- /dev/null
+++ b/test/Sema/pragma-align-mac68k-unsupported.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify %s
+
+/* expected-error {{mac68k alignment pragma is not supported}} */ #pragma options align=mac68k
diff --git a/test/Sema/pragma-align-mac68k.c b/test/Sema/pragma-align-mac68k.c
new file mode 100644
index 0000000..fb8da51
--- /dev/null
+++ b/test/Sema/pragma-align-mac68k.c
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
+
+#include <stddef.h>
+
+#pragma options align=mac68k
+
+typedef float __attribute__((vector_size (8))) v2f_t;
+typedef float __attribute__((vector_size (16))) v4f_t;
+
+extern int a0_0[__alignof(v2f_t) == 8 ? 1 : -1];
+extern int a0_1[__alignof(v4f_t) == 16 ? 1 : -1];
+
+struct s1 {
+  char f0;
+  int  f1;
+};
+extern int a1_0[offsetof(struct s1, f0) == 0 ? 1 : -1];
+extern int a1_1[offsetof(struct s1, f1) == 2 ? 1 : -1];
+extern int a1_2[sizeof(struct s1) == 6 ? 1 : -1];
+extern int a1_3[__alignof(struct s1) == 2 ? 1 : -1];
+
+struct s2 {
+  char f0;
+  double f1;
+};
+extern int a2_0[offsetof(struct s2, f0) == 0 ? 1 : -1];
+extern int a2_1[offsetof(struct s2, f1) == 2 ? 1 : -1];
+extern int a2_2[sizeof(struct s2) == 10 ? 1 : -1];
+extern int a2_3[__alignof(struct s2) == 2 ? 1 : -1];
+
+struct s3 {
+  char f0;
+  v4f_t f1;
+};
+extern int a3_0[offsetof(struct s3, f0) == 0 ? 1 : -1];
+extern int a3_1[offsetof(struct s3, f1) == 2 ? 1 : -1];
+extern int a3_2[sizeof(struct s3) == 18 ? 1 : -1];
+extern int a3_3[__alignof(struct s3) == 2 ? 1 : -1];
+
+struct s4 {
+  char f0;
+  char f1;
+};
+extern int a4_0[offsetof(struct s4, f0) == 0 ? 1 : -1];
+extern int a4_1[offsetof(struct s4, f1) == 1 ? 1 : -1];
+extern int a4_2[sizeof(struct s4) == 2 ? 1 : -1];
+extern int a4_3[__alignof(struct s4) == 2 ? 1 : -1];
+
+struct s5 {
+  unsigned f0 : 9;
+  unsigned f1 : 9;
+};
+extern int a5_0[sizeof(struct s5) == 4 ? 1 : -1];
+extern int a5_1[__alignof(struct s5) == 2 ? 1 : -1];
+
+struct s6 {
+  unsigned : 0;
+  unsigned : 0;
+};
+extern int a6_0[sizeof(struct s6) == 0 ? 1 : -1];
+extern int a6_1[__alignof(struct s6) == 2 ? 1 : -1];
+
+struct s7 {
+  char : 1;
+  unsigned : 1;
+};
+extern int a7_0[sizeof(struct s7) == 2 ? 1 : -1];
+extern int a7_1[__alignof(struct s7) == 2 ? 1 : -1];
+
+struct s8 {
+  char f0;
+  unsigned : 1;
+};
+extern int a8_0[sizeof(struct s8) == 2 ? 1 : -1];
+extern int a8_1[__alignof(struct s8) == 2 ? 1 : -1];
+
+struct s9 {
+  char f0[3];
+  unsigned : 0;
+  char f1;
+};
+extern int a9_0[sizeof(struct s9) == 6 ? 1 : -1];
+extern int a9_1[__alignof(struct s9) == 2 ? 1 : -1];
+
+struct s10 {
+  char f0;
+};
+extern int a10_0[sizeof(struct s10) == 2 ? 1 : -1];
+extern int a10_1[__alignof(struct s10) == 2 ? 1 : -1];
+
+struct s11 {
+  char f0;
+  v2f_t f1;
+};
+extern int a11_0[offsetof(struct s11, f0) == 0 ? 1 : -1];
+extern int a11_1[offsetof(struct s11, f1) == 2 ? 1 : -1];
+extern int a11_2[sizeof(struct s11) == 10 ? 1 : -1];
+extern int a11_3[__alignof(struct s11) == 2 ? 1 : -1];
diff --git a/test/Sema/pragma-align-packed.c b/test/Sema/pragma-align-packed.c
new file mode 100644
index 0000000..74fbd13
--- /dev/null
+++ b/test/Sema/pragma-align-packed.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
+
+#pragma pack(push, 1)
+struct s0 {
+  char f0;
+  int  f1 __attribute__((aligned(4)));
+};
+extern int a[sizeof(struct s0) == 5 ? 1 : -1];
+#pragma pack(pop)
+
+struct __attribute__((packed)) s1 {
+  char f0;
+  int  f1 __attribute__((aligned(4)));
+};
+extern int a[sizeof(struct s1) == 8 ? 1 : -1];
+
+#pragma options align=packed
+struct s2 {
+  char f0;
+  int  f1 __attribute__((aligned(4)));
+};
+extern int a[sizeof(struct s2) == 5 ? 1 : -1];
+#pragma options align=reset
+
+#pragma pack(1)
+struct s3_0 { unsigned char f0; unsigned int f1; };
+int t3_0[sizeof(struct s3_0) == 5 ? 1 : -1];
+#pragma options align=reset
+struct s3_1 { unsigned char f0; unsigned int f1; };
+int t3_1[sizeof(struct s3_1) == 8 ? 1 : -1];
diff --git a/test/Sema/pragma-pack-and-options-align.c b/test/Sema/pragma-pack-and-options-align.c
new file mode 100644
index 0000000..ebf1ade
--- /dev/null
+++ b/test/Sema/pragma-pack-and-options-align.c
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple i686-apple-darwin9 %s -fsyntax-only -verify
+
+// Check that #pragma pack and #pragma options share the same stack.
+
+#pragma pack(push, 1)
+struct s0 {
+  char c;
+  int x;
+};
+extern int a[sizeof(struct s0) == 5 ? 1 : -1];
+
+#pragma options align=natural
+struct s1 {
+  char c;
+  int x;
+};
+extern int a[sizeof(struct s1) == 8 ? 1 : -1];
+
+#pragma options align=reset
+#pragma options align=native
+struct s1_1 {
+  char c;
+  int x;
+};
+extern int a[sizeof(struct s1_1) == 8 ? 1 : -1];
+
+#pragma pack(pop)
+struct s2 {
+  char c;
+  int x;
+};
+extern int a[sizeof(struct s2) == 5 ? 1 : -1];
+#pragma pack(pop)
+
+struct s3 {
+  char c;
+  int x;
+};
+extern int a[sizeof(struct s3) == 8 ? 1 : -1];
+
+/* expected-warning {{#pragma options align=reset failed: stack empty}} */ #pragma options align=reset
+/* expected-warning {{#pragma pack(pop, ...) failed: stack empty}} */ #pragma pack(pop)
diff --git a/test/Sema/return-noreturn.c b/test/Sema/return-noreturn.c
index ff43754..a7f4e6f 100644
--- a/test/Sema/return-noreturn.c
+++ b/test/Sema/return-noreturn.c
@@ -20,11 +20,11 @@
 // 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) {
+__attribute__((__noreturn__)) void* test3(int arg) { // expected-warning{{functions declared 'noreturn' should have a 'void' result type}}
   while (1) foo_test_3();
 }
 
-__attribute__((__noreturn__)) void* test3_positive(int arg) {
+__attribute__((__noreturn__)) void* test3_positive(int arg) { // expected-warning{{functions declared 'noreturn' should have a 'void' result type}}
   while (0) foo_test_3();
 } // expected-warning{{function declared 'noreturn' should not return}}
 
diff --git a/test/Sema/return.c b/test/Sema/return.c
index 0d46d98..af78b41 100644
--- a/test/Sema/return.c
+++ b/test/Sema/return.c
@@ -1,4 +1,4 @@
-// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wno-unreachable-code -Wno-unused-value
+// RUN: %clang %s -fsyntax-only -Wignored-qualifiers -Wreturn-type -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 
@@ -60,7 +60,7 @@
   (void)(1 + unknown());
 } // expected-warning {{control reaches end of non-void function}}
 
-int halt3() __attribute__((noreturn));
+int halt3() __attribute__((noreturn)); // expected-warning{{functions declared 'noreturn' should have a 'void' result type}}
 
 int test9() {
   (void)(halt3() + unknown());
@@ -239,3 +239,6 @@
 }
 static inline int si_forward() {} // expected-warning{{control reaches end of non-void function}}
 
+// Test warnings on ignored qualifiers on return types.
+const int ignored_c_quals(); // expected-warning{{'const' type qualifier on return type has no effect}}
+const volatile int ignored_cv_quals(); // expected-warning{{'const volatile' type qualifiers on return type have no effect}}
diff --git a/test/Sema/scope-check.c b/test/Sema/scope-check.c
index 6f86402..4ccb64c 100644
--- a/test/Sema/scope-check.c
+++ b/test/Sema/scope-check.c
@@ -1,7 +1,7 @@
 // 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}}
+  goto L;    // expected-error{{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:
@@ -9,7 +9,7 @@
 }
 
 int test2(int x) {
-  goto L;            // expected-error{{illegal goto into protected scope}}
+  goto L;            // expected-error{{goto into protected scope}}
   typedef int a[x];  // expected-note {{jump bypasses initialization of VLA typedef}}
   L:
   return sizeof(a);
@@ -18,14 +18,14 @@
 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))}}
+  goto L;            // expected-error{{goto into protected scope}}
+int a __attribute((cleanup(test3clean))); // expected-note {{jump bypasses initialization of variable with __attribute__((cleanup))}}
 L:
   return a;
 }
 
 int test4(int x) {
-  goto L;       // expected-error{{illegal goto into protected scope}}
+  goto L;       // expected-error{{goto into protected scope}}
 int a[x];       // expected-note {{jump bypasses initialization of variable length array}}
   test4(x);
 L:
@@ -50,7 +50,7 @@
   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}}
+  case 2:           // expected-error {{switch case is in protected scope}}
     a[1] = 2;
     break;
   }
@@ -58,17 +58,17 @@
 
 int test8(int x) {
   // For statement.
-  goto L2;     // expected-error {{illegal goto into protected scope}}
+  goto L2;     // expected-error {{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}}
+  goto L3;   // expected-error {{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}}
+  goto L4; // expected-error {{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}}
@@ -91,7 +91,7 @@
     int A[x], B = ({ if (x)
                        goto L7;
                      else 
-                       goto L8;  // expected-error {{illegal goto into protected scope}}
+                       goto L8;  // expected-error {{goto into protected scope}}
                      4; }),
         C[x];   // expected-note {{jump bypasses initialization of variable length array}}
   L8:; // bad
@@ -103,7 +103,7 @@
                goto L9;
              else
                // FIXME:
-               goto L10;  // fixme-error {{illegal goto into protected scope}}
+               goto L10;  // fixme-error {{goto into protected scope}}
            4; })];
   L10:; // bad
   }
@@ -123,7 +123,7 @@
   }
   
   // Statement expressions 2.
-  goto L1;     // expected-error {{illegal goto into protected scope}}
+  goto L1;     // expected-error {{goto into protected scope}}
   return x == ({
                  int a[x];   // expected-note {{jump bypasses initialization of variable length array}}  
                L1:
@@ -133,32 +133,32 @@
 void test9(int n, void *P) {
   int Y;
   int Z = 4;
-  goto *P;  // ok.
+  goto *P;  // expected-warning {{indirect goto might cross protected scopes}}
 
 L2: ;
-  int a[n]; // expected-note 2 {{jump bypasses initialization of variable length array}}
+  int a[n]; // expected-note {{jump bypasses initialization of variable length array}}
 
-L3:
+L3:         // expected-note {{possible target of indirect goto}}
 L4:  
-  goto *P;  // expected-warning {{illegal indirect goto in protected scope, unknown effect on scopes}}
+  goto *P;
   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}}
+    &&L2,
+    &&L3
   };
 }
 
 void test10(int n, void *P) {
-  goto L0;     // expected-error {{illegal goto into protected scope}}
+  goto L0;     // expected-error {{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}}
+  goto L1;      // expected-error {{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}}
+  goto L2;     // expected-error {{goto into protected scope}}
   A d[n];      // expected-note {{jump bypasses initialization of variable length array}}
 L2:
   return;
@@ -171,7 +171,7 @@
     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}}
+    case 4:       // expected-error {{switch case is in protected scope}}
       return;
     }
   };
@@ -185,7 +185,7 @@
   L1:
     goto L2;
   L2:
-    goto L3;    // expected-error {{illegal goto into protected scope}}
+    goto L3;    // expected-error {{goto into protected scope}}
     int Arr[n]; // expected-note {{jump bypasses initialization of variable length array}}
   L3:
     goto L4;
@@ -193,3 +193,9 @@
   };
 }
 
+void test13(int n, void *p) {
+  int vla[n];
+  goto *p;
+ a0: ;
+  static void *ps[] = { &&a0 };
+}
diff --git a/test/Sema/self-comparison.c b/test/Sema/self-comparison.c
index 1baba27..c5c0611 100644
--- a/test/Sema/self-comparison.c
+++ b/test/Sema/self-comparison.c
@@ -1,11 +1,21 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
 int foo(int x) {
-  return x == x; // expected-warning {{self-comparison always results}}
+  return x == x; // expected-warning {{self-comparison always evaluates to true}}
 }
 
 int foo2(int x) {
-  return (x) != (((x))); // expected-warning {{self-comparison always results}}
+  return (x) != (((x))); // expected-warning {{self-comparison always evaluates to false}}
+}
+
+void foo3(short s, short t) { 
+  if (s == s) {} // expected-warning {{self-comparison always evaluates to true}}
+  if (s == t) {} // no-warning
+}
+
+void foo4(void* v, void* w) {
+  if (v == v) {} // expected-warning {{self-comparison always evaluates to true}}
+  if (v == w) {} // no-warning
 }
 
 int qux(int x) {
@@ -24,15 +34,44 @@
   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
+#define IS_THE_ANSWER(x) (x == 42)
+
+int macro_comparison() {
+  return IS_THE_ANSWER(42);
 }
 
 // Don't complain in unevaluated contexts.
 int compare_sizeof(int x) {
   return sizeof(x == x); // no-warning
 }
+
+int array_comparisons() {
+  int array1[2];
+  int array2[2];
+
+  //
+  // compare same array
+  //
+  return array1 == array1; // expected-warning{{self-comparison always evaluates to true}}
+  return array1 != array1; // expected-warning{{self-comparison always evaluates to false}}
+  return array1 < array1; // expected-warning{{self-comparison always evaluates to false}}
+  return array1 <= array1; // expected-warning{{self-comparison always evaluates to true}}
+  return array1 > array1; // expected-warning{{self-comparison always evaluates to false}}
+  return array1 >= array1; // expected-warning{{self-comparison always evaluates to true}}
+
+  //
+  // compare differrent arrays
+  //
+  return array1 == array2; // expected-warning{{array comparison always evaluates to false}}
+  return array1 != array2; // expected-warning{{array comparison always evaluates to true}}
+
+  //
+  // we don't know what these are going to be
+  //
+  return array1 < array2; // expected-warning{{array comparison always evaluates to a constant}}
+  return array1 <= array2; // expected-warning{{array comparison always evaluates to a constant}}
+  return array1 > array2; // expected-warning{{array comparison always evaluates to a constant}}
+  return array1 >= array2; // expected-warning{{array comparison always evaluates to a constant}}
+
+}
+
diff --git a/test/Sema/struct-cast.c b/test/Sema/struct-cast.c
index dc7db13..30ef892 100644
--- a/test/Sema/struct-cast.c
+++ b/test/Sema/struct-cast.c
@@ -7,6 +7,7 @@
 
 struct S const foo(void);
 
+
 struct S tmp;
 
 void priv_sock_init() {
diff --git a/test/Sema/struct-decl.c b/test/Sema/struct-decl.c
index f888053..3639d24 100644
--- a/test/Sema/struct-decl.c
+++ b/test/Sema/struct-decl.c
@@ -41,3 +41,8 @@
 };
 
 struct s0 f0(void) {}
+
+// <rdar://problem/8177927> - This previously triggered an assertion failure.
+struct x0 {
+  unsigned int x1;
+};
diff --git a/test/Sema/switch.c b/test/Sema/switch.c
index e63a194..bb48229 100644
--- a/test/Sema/switch.c
+++ b/test/Sema/switch.c
@@ -24,36 +24,37 @@
 
 void test3(void) { 
   // empty switch;
-  switch (0); 
+  switch (0); // expected-warning {{no case matching constant switch condition '0'}}
 }
 
 extern int g();
 
 void test4()
 {
-  switch (1) {
+  int cond;
+  switch (cond) {
   case 0 && g():
   case 1 || g():
     break;
   }
 
-  switch(1)  {
+  switch(cond)  {
   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) {
+  switch (cond) {
   case 0 && g() ... 1 || g():
     break;
   }
   
-  switch (1) {
+  switch (cond) {
   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) {
+  switch (cond) {
   case 0 ... g() || 1: // expected-error {{expression is not an integer constant expression}} // expected-note {{subexpression not valid in an integer constant expression}}
     break;
   }
@@ -68,7 +69,7 @@
 } 
 
 void test6() {
-  const char ch = 'a';
+  char ch = 'a';
   switch(ch) {
     case 1234:  // expected-warning {{overflow converting case value}}
       break;
@@ -261,3 +262,29 @@
   default: break;
   }
 }
+
+void test15() {
+  int i = 0;
+  switch (1) { // expected-warning {{no case matching constant switch condition '1'}}
+  case 0: i = 0; break;
+  case 2: i++; break;
+  }
+}
+
+void test16() {
+  const char c = '5';
+  switch (c) { // expected-warning {{no case matching constant switch condition '53'}}
+  case '6': return;
+  }
+}
+
+// PR7359
+void test17(int x) {
+  switch (x >= 17) { // expected-warning {{switch condition has boolean value}}
+  case 0: return;
+  }
+
+  switch ((int) (x <= 17)) {
+  case 0: return;
+  }
+}
diff --git a/test/Sema/transparent-union.c b/test/Sema/transparent-union.c
index cdfc850..27d5c24 100644
--- a/test/Sema/transparent-union.c
+++ b/test/Sema/transparent-union.c
@@ -38,3 +38,10 @@
 } TU3 __attribute__((transparent_union));
 
 typedef union { } TU4 __attribute__((transparent_union)); // expected-warning{{field}} 
+
+typedef int int4 __attribute__((ext_vector_type(4)));
+typedef union {
+  int4 vec; // expected-warning{{first field of a transparent union cannot have vector type 'int4'; transparent_union attribute ignored}}
+} TU5 __attribute__((transparent_union));
+
+  
diff --git a/test/Sema/typedef-variable-type.c b/test/Sema/typedef-variable-type.c
index f298968..b805b1e 100644
--- a/test/Sema/typedef-variable-type.c
+++ b/test/Sema/typedef-variable-type.c
@@ -1,3 +1,8 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only -pedantic
+// RUN: %clang_cc1 %s -verify -fsyntax-only -pedantic -Wno-typedef-redefinition
 
+// Make sure we accept a single typedef
+typedef int (*a)[!.0]; // expected-warning{{size of static array must be an integer constant expression}}
+
+// And make sure we accept identical redefinitions in system headers
+// (The test uses -Wno-typedef-redefinition to simulate this.)
 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
index 1770bf5..f3244f7 100644
--- a/test/Sema/types.c
+++ b/test/Sema/types.c
@@ -36,4 +36,4 @@
 
 
 // rdar://6880951
-int __attribute__ ((vector_size (8), vector_size (8))) v;  // expected-error {{invalid vector type}}
+int __attribute__ ((vector_size (8), vector_size (8))) v;  // expected-error {{invalid vector element type}}
diff --git a/test/Sema/unused-expr.c b/test/Sema/unused-expr.c
index 4ae0d4b..15608ec 100644
--- a/test/Sema/unused-expr.c
+++ b/test/Sema/unused-expr.c
@@ -110,3 +110,11 @@
 void t10() {
   (void*) some_function(); //expected-warning {{expression result unused; should this cast be to 'void'?}}
 }
+
+void f(int i, ...) {
+    __builtin_va_list ap;
+    
+    __builtin_va_start(ap, i);
+    __builtin_va_arg(ap, int);
+    __builtin_va_end(ap);
+}
diff --git a/test/Sema/var-redecl.c b/test/Sema/var-redecl.c
index 71d7ea1..f7576b6 100644
--- a/test/Sema/var-redecl.c
+++ b/test/Sema/var-redecl.c
@@ -58,5 +58,5 @@
 
 // PR3645
 static int a;
-extern int a;
-int a;
+extern int a; // expected-note {{previous definition is here}}
+int a;	// expected-error {{non-static declaration of 'a' follows static declaration}}
diff --git a/test/Sema/vector-ops.c b/test/Sema/vector-ops.c
new file mode 100644
index 0000000..20575ec
--- /dev/null
+++ b/test/Sema/vector-ops.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wvector-conversions
+typedef unsigned int v2u __attribute__ ((vector_size (8)));
+typedef int v2s __attribute__ ((vector_size (8)));
+typedef float v2f __attribute__ ((vector_size(8)));
+
+void test1(v2u v2ua, v2s v2sa, v2f v2fa) {
+  // Bitwise binary operators
+  (void)(v2ua & v2ua);
+  (void)(v2fa & v2fa); // expected-error{{invalid operands to binary expression}}
+
+  // Unary operators
+  (void)(~v2ua);
+  (void)(~v2fa); // expected-error{{invalid argument type 'v2f' to unary}}
+
+  // Arrays
+  int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u'}}
+  int array2[17];
+  // FIXME: error message below needs type!
+  (void)(array2[v2ua]); // expected-error{{array subscript is not an integer}}
+
+  v2u *v2u_ptr = 0;
+  v2s *v2s_ptr;
+  v2s_ptr = v2u_ptr; // expected-warning{{converts between pointers to integer types with different sign}}
+}
+ 
diff --git a/test/Sema/warn-cast-align.c b/test/Sema/warn-cast-align.c
new file mode 100644
index 0000000..11e3c41
--- /dev/null
+++ b/test/Sema/warn-cast-align.c
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -Wcast-align -verify %s
+
+// Simple casts.
+void test0(char *P) {
+  char *a  = (char*)  P;
+  short *b = (short*) P; // expected-warning {{cast from 'char *' to 'short *' increases required alignment from 1 to 2}}
+  int *c   = (int*)   P; // expected-warning {{cast from 'char *' to 'int *' increases required alignment from 1 to 4}}
+}
+
+// Casts from void* are a special case.
+void test1(void *P) {
+  char *a  = (char*)  P;
+  short *b = (short*) P;
+  int *c   = (int*)   P;
+
+  const volatile void *P2 = P;
+  char *d  = (char*)  P2;
+  short *e = (short*) P2;
+  int *f   = (int*)   P2;
+
+  const char *g  = (const char*)  P2;
+  const short *h = (const short*) P2;
+  const int *i   = (const int*)   P2;
+
+  const volatile char *j  = (const volatile char*)  P2;
+  const volatile short *k = (const volatile short*) P2;
+  const volatile int *l   = (const volatile int*)   P2;
+}
+
+// Aligned struct.
+__attribute__((align(16))) struct A {
+  char buffer[16];
+};
+void test2(char *P) {
+  struct A *a = (struct A*) P; // expected-warning {{cast from 'char *' to 'struct A *' increases required alignment from 1 to 16}}
+}
+
+// Incomplete type.
+void test3(char *P) {
+  struct B *b = (struct B*) P;
+}
diff --git a/test/Sema/warn-unreachable.c b/test/Sema/warn-unreachable.c
index 10ed696..0d2efe9 100644
--- a/test/Sema/warn-unreachable.c
+++ b/test/Sema/warn-unreachable.c
@@ -1,6 +1,6 @@
 // RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code -Wno-unused-value
 
-int halt() __attribute__((noreturn));
+int halt() __attribute__((noreturn)); // expected-warning{{functions declared 'noreturn' should have a 'void' result type}}
 int live();
 int dead();
 
diff --git a/test/Sema/warn-unused-function.c b/test/Sema/warn-unused-function.c
index d5e676b..24d4fad 100644
--- a/test/Sema/warn-unused-function.c
+++ b/test/Sema/warn-unused-function.c
@@ -35,3 +35,15 @@
 
 __attribute__((destructor)) static void bar3(void);
 void bar3(void) { }
+
+static void f10(void); // expected-warning{{unused}}
+static void f10(void);
+
+static void f11(void);
+static void f11(void) { }  // expected-warning{{unused}}
+
+static void f12(void) { }  // expected-warning{{unused}}
+static void f12(void);
+
+// PR7923
+static void unused(void) { unused(); }  // expected-warning{{unused}}
diff --git a/test/Sema/warn-unused-value.c b/test/Sema/warn-unused-value.c
index 16b787f..1a7e745 100644
--- a/test/Sema/warn-unused-value.c
+++ b/test/Sema/warn-unused-value.c
@@ -18,9 +18,9 @@
   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,j,foo();        // expected-warning {{expression result unused}} expected-warning {{expression result unused}}
+  i,foo(),j;        // expected-warning {{expression result unused}} expected-warning {{expression result unused}}
+  foo(),i,j;        // expected-warning {{expression result unused}} expected-warning {{expression result unused}}
 
   i++;
 
@@ -63,6 +63,16 @@
   (x = test_logical_foo1()) ||  // no-warning
   (x = test_logical_foo2()) ||  // no-warning
   (x = test_logical_foo3());    // no-warning
+
+  x || test_logical_foo1();     // no-warning
+
   return x;
 }
 
+struct s0 { int f0; };
+
+void f0(int a);
+void f1(struct s0 *a) {
+  // rdar://8139785
+  f0((int)(a->f0 + 1, 10)); // expected-warning {{expression result unused}}
+}
diff --git a/test/SemaCXX/abstract.cpp b/test/SemaCXX/abstract.cpp
index 0ae6c44..ad079c2 100644
--- a/test/SemaCXX/abstract.cpp
+++ b/test/SemaCXX/abstract.cpp
@@ -42,11 +42,11 @@
   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}}
+C e1[2]; // expected-error {{array of abstract class type 'C'}}
+C (*e2)[2]; // expected-error {{array of abstract class type 'C'}}
+C (**e3)[2]; // expected-error {{array of abstract class type 'C'}}
 
-void t4(C c[2]); // expected-error {{parameter type 'C' is an abstract class}}
+void t4(C c[2]); // expected-error {{array of abstract class type 'C'}}
 
 void t5(void (*)(C)); // expected-error {{parameter type 'C' is an abstract class}}
 
@@ -67,20 +67,23 @@
   virtual void f() = 0; // expected-note {{pure virtual function 'f'}}
 };
 
+// Diagnosing in these cases is prohibitively expensive.  We still
+// diagnose at the function definition, of course.
+
 class Abstract;
 
-void t7(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
+void t7(Abstract a);
 
 void t8() {
-  void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
+  void h(Abstract a);
 }
 
 namespace N {
-void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
+void h(Abstract a);
 }
 
 class Abstract {
-  virtual void f() = 0; // expected-note {{pure virtual function 'f'}}
+  virtual void f() = 0;
 };
 
 // <rdar://problem/6854087>
@@ -169,3 +172,80 @@
   D y;
 }
 
+namespace test1 {
+  struct A {
+    virtual void foo() = 0;
+  };
+
+  struct B : A {
+    using A::foo;
+  };
+
+  struct C : B {
+    void foo();
+  };
+
+  void test() {
+    C c;
+  }
+}
+
+// rdar://problem/8302168
+namespace test2 {
+  struct X1 {
+    virtual void xfunc(void) = 0;  // expected-note {{pure virtual function}}
+    void g(X1 parm7);        // expected-error {{parameter type 'test2::X1' is an abstract class}}
+    void g(X1 parm8[2]);     // expected-error {{array of abstract class type 'test2::X1'}}
+  };
+
+  template <int N>
+  struct X2 {
+    virtual void xfunc(void) = 0;  // expected-note {{pure virtual function}}
+    void g(X2 parm10);        // expected-error {{parameter type 'X2<N>' is an abstract class}}
+    void g(X2 parm11[2]);     // expected-error {{array of abstract class type 'X2<N>'}}
+  };
+}
+
+namespace test3 {
+  struct A { // expected-note {{not complete until}}
+    A x; // expected-error {{field has incomplete type}}
+    virtual void abstract() = 0;
+  };
+
+  struct B { // expected-note {{not complete until}}
+    virtual void abstract() = 0;
+    B x; // expected-error {{field has incomplete type}}
+  };
+
+  struct C {
+    static C x; // expected-error {{abstract class}}
+    virtual void abstract() = 0; // expected-note {{pure virtual function}}
+  };
+
+  struct D {
+    virtual void abstract() = 0; // expected-note {{pure virtual function}}
+    static D x; // expected-error {{abstract class}}
+  };
+}
+
+namespace test4 {
+  template <class T> struct A {
+    A x; // expected-error {{abstract class}}
+    virtual void abstract() = 0; // expected-note {{pure virtual function}}
+  };
+
+  template <class T> struct B {
+    virtual void abstract() = 0; // expected-note {{pure virtual function}}
+    B x; // expected-error {{abstract class}}
+  };
+
+  template <class T> struct C {
+    static C x; // expected-error {{abstract class}}
+    virtual void abstract() = 0; // expected-note {{pure virtual function}}
+  };
+
+  template <class T> struct D {
+    virtual void abstract() = 0; // expected-note {{pure virtual function}}
+    static D x; // expected-error {{abstract class}}
+  };
+}
diff --git a/test/SemaCXX/access-base-class.cpp b/test/SemaCXX/access-base-class.cpp
index 8551690..f676e19 100644
--- a/test/SemaCXX/access-base-class.cpp
+++ b/test/SemaCXX/access-base-class.cpp
@@ -61,7 +61,7 @@
 namespace T6 {
   class C;
   
-  class A {};
+  class A {}; // expected-note{{member is declared here}}
   
   class B : private A { // expected-note {{declared private here}} expected-note {{constrained by private inheritance here}}
     void f(C* c);
diff --git a/test/SemaCXX/access-member-pointer.cpp b/test/SemaCXX/access-member-pointer.cpp
new file mode 100644
index 0000000..676eb10
--- /dev/null
+++ b/test/SemaCXX/access-member-pointer.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR7694
+
+class A { };
+class B : private A { public: void foo(); }; // expected-note {{declared private here}}
+void B::foo() {
+  (void)static_cast<void(A::*)()>(&B::foo);
+}
+void bar() {
+  (void)static_cast<void(A::*)()>(&B::foo); // expected-error {{cannot cast 'B' to its private base class 'A'}}
+}
diff --git a/test/SemaCXX/addr-of-overloaded-function.cpp b/test/SemaCXX/addr-of-overloaded-function.cpp
index f8b00df..b581b8a 100644
--- a/test/SemaCXX/addr-of-overloaded-function.cpp
+++ b/test/SemaCXX/addr-of-overloaded-function.cpp
@@ -86,3 +86,13 @@
     myFunction(bar);
   }
 }
+
+namespace PR7971 {
+  struct S {
+    void g() {
+      f(&g);
+    }
+    void f(bool (*)(int, char));
+    static bool g(int, char);
+  };
+}
diff --git a/test/SemaCXX/alignof-sizeof-reference.cpp b/test/SemaCXX/alignof-sizeof-reference.cpp
index f02282d..dd64d6a 100644
--- a/test/SemaCXX/alignof-sizeof-reference.cpp
+++ b/test/SemaCXX/alignof-sizeof-reference.cpp
@@ -7,3 +7,9 @@
   static_assert(alignof(r) == 1, "bad alignment");
   static_assert(sizeof(r) == 1, "bad size");
 }
+
+void f(); 
+void f(int); 
+void g() { 
+  sizeof(&f); // expected-error{{invalid application of 'sizeof' to an overloaded function}}
+}
diff --git a/test/SemaCXX/altivec.cpp b/test/SemaCXX/altivec.cpp
new file mode 100644
index 0000000..cdfc00a
--- /dev/null
+++ b/test/SemaCXX/altivec.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -faltivec -fno-lax-vector-conversions -triple powerpc-unknown-unknown -verify %s
+
+typedef int V4i __attribute__((vector_size(16)));
+
+void f(V4i a)
+{
+}
+
+void test()
+{
+  V4i vGCC;
+  vector int vAltiVec;
+
+  f(vAltiVec);
+  vGCC = vAltiVec;
+  vGCC = vGCC > vAltiVec;
+  vAltiVec = 0 ? vGCC : vGCC;
+}
diff --git a/test/SemaCXX/ambig-user-defined-conversions.cpp b/test/SemaCXX/ambig-user-defined-conversions.cpp
index 7f67674..fdb399b 100644
--- a/test/SemaCXX/ambig-user-defined-conversions.cpp
+++ b/test/SemaCXX/ambig-user-defined-conversions.cpp
@@ -18,6 +18,7 @@
   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}}
   }
diff --git a/test/SemaCXX/anonymous-struct.cpp b/test/SemaCXX/anonymous-struct.cpp
new file mode 100644
index 0000000..dfa284a
--- /dev/null
+++ b/test/SemaCXX/anonymous-struct.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct S {
+  S();  // expected-note {{because type 'S' has a user-declared constructor}}    
+};
+
+struct E {
+  struct {
+    S x;  // expected-error {{anonymous struct member 'x' has a non-trivial constructor}} 
+  };
+};
diff --git a/test/SemaCXX/anonymous-union.cpp b/test/SemaCXX/anonymous-union.cpp
index 5c34e01..5f84bcc 100644
--- a/test/SemaCXX/anonymous-union.cpp
+++ b/test/SemaCXX/anonymous-union.cpp
@@ -121,3 +121,37 @@
         int Foo;
     };
 } s, *ps;
+
+// <rdar://problem/7987650>
+namespace test4 {
+  class A {
+    struct {
+      int s0; // expected-note {{declared private here}}
+      double s1; // expected-note {{declared private here}}
+      union {
+        int su0; // expected-note {{declared private here}}
+        double su1; // expected-note {{declared private here}}
+      };
+    };
+    union {
+      int u0; // expected-note {{declared private here}}
+      double u1; // expected-note {{declared private here}}
+      struct {
+        int us0; // expected-note {{declared private here}}
+        double us1; // expected-note {{declared private here}}
+      };
+    };
+  };
+
+  void test() {
+    A a;
+    (void) a.s0;  // expected-error {{private member}}
+    (void) a.s1;  // expected-error {{private member}}
+    (void) a.su0; // expected-error {{private member}}
+    (void) a.su1; // expected-error {{private member}}
+    (void) a.u0;  // expected-error {{private member}}
+    (void) a.u1;  // expected-error {{private member}}
+    (void) a.us0; // expected-error {{private member}}
+    (void) a.us1; // expected-error {{private member}}
+  }
+}
diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp
index d5662d3..2164f9d 100644
--- a/test/SemaCXX/attr-deprecated.cpp
+++ b/test/SemaCXX/attr-deprecated.cpp
@@ -64,3 +64,129 @@
 void f(D* d) {
   d->f();
 }
+
+
+// Overloaded namespace members.
+namespace test1 {
+  void foo(int) __attribute__((deprecated));
+  void test1() { foo(10); } // expected-warning {{deprecated}}
+  void foo(short) __attribute__((deprecated));
+  void test2(short s) { foo(s); } // expected-warning {{deprecated}}
+  void foo(long);
+  void test3(long l) { foo(l); }
+  struct A {
+    friend void foo(A*) __attribute__((deprecated));
+  };
+  void test4(A *a) { foo(a); } // expected-warning {{deprecated}}
+
+  namespace ns {
+    struct Foo {};
+    void foo(const Foo &f) __attribute__((deprecated));
+  }
+  void test5() {
+    foo(ns::Foo()); // expected-warning {{deprecated}}
+  }
+}
+
+// Overloaded class members.
+namespace test2 {
+  struct A {
+    void foo(int) __attribute__((deprecated));
+    void foo(long);
+    static void bar(int) __attribute__((deprecated));
+    static void bar(long);
+
+    void test2(int i, long l);
+  };
+  void test1(int i, long l) {
+    A a;
+    a.foo(i); // expected-warning {{deprecated}}
+    a.foo(l);
+    a.bar(i); // expected-warning {{deprecated}}
+    a.bar(l);
+    A::bar(i); // expected-warning {{deprecated}}
+    A::bar(l);
+  }
+
+  void A::test2(int i, long l) {
+    foo(i); // expected-warning {{deprecated}}
+    foo(l);
+    bar(i); // expected-warning {{deprecated}}
+    bar(l);
+  }
+}
+
+// Overloaded operators.
+namespace test3 {
+  struct A {
+    void operator*(const A &);
+    void operator*(int) __attribute__((deprecated));
+    void operator-(const A &) const;
+  };
+  void operator+(const A &, const A &);
+  void operator+(const A &, int) __attribute__((deprecated));
+  void operator-(const A &, int) __attribute__((deprecated));
+
+  void test() {
+    A a, b;
+    a + b;
+    a + 1; // expected-warning {{deprecated}}
+    a - b;
+    a - 1; // expected-warning {{deprecated}}
+    a * b;
+    a * 1; // expected-warning {{deprecated}}
+  }
+}
+
+// Overloaded operator call.
+namespace test4 {
+  struct A {
+    typedef void (*intfn)(int);
+    typedef void (*unintfn)(unsigned);
+    operator intfn() __attribute__((deprecated));
+    operator unintfn();
+    void operator ()(A &) __attribute__((deprecated));
+    void operator ()(const A &);
+  };
+
+  void test() {
+    A a;
+    a(1); // expected-warning {{deprecated}}
+    a(1U);
+
+    A &b = a;
+    const A &c = a;
+    a(b); // expected-warning {{deprecated}}
+    a(c);
+  }
+}
+
+namespace test5 {
+  struct A {
+    operator int() __attribute__((deprecated));
+    operator long();
+  };
+  void test1(A a) {
+    int i = a; // expected-warning {{deprecated}}
+    long l = a;
+  }
+
+  void foo(int);
+  void foo(void*);
+  void bar(long);
+  void bar(void*);
+  void test2(A a) {
+    foo(a); // expected-warning {{deprecated}}
+    bar(a);
+  }
+
+  struct B {
+    int myInt;
+    long myLong;
+
+    B(A &a) :
+      myInt(a), // expected-warning {{deprecated}}
+      myLong(a)
+    {}
+  };
+}
diff --git a/test/SemaCXX/attr-noreturn.cpp b/test/SemaCXX/attr-noreturn.cpp
index b7d3999..dbf73fb 100644
--- a/test/SemaCXX/attr-noreturn.cpp
+++ b/test/SemaCXX/attr-noreturn.cpp
@@ -31,7 +31,7 @@
 
 
 class xpto {
-  int blah() __attribute__((noreturn));
+  int blah() __attribute__((noreturn)); // expected-warning{{functions declared 'noreturn' should have a 'void' result type}}
 };
 
 int xpto::blah() {
diff --git a/test/SemaCXX/attr-regparm.cpp b/test/SemaCXX/attr-regparm.cpp
new file mode 100644
index 0000000..b98631a
--- /dev/null
+++ b/test/SemaCXX/attr-regparm.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR7025
+struct X0 {
+  void __attribute__((regparm(3))) f0();
+  void __attribute__((regparm(3))) f1();
+  void __attribute__((regparm(3))) f2(); // expected-note{{previous declaration is here}}
+  void f3(); // expected-note{{previous declaration is here}}
+};
+
+void X0::f0() { }
+void __attribute__((regparm(3))) X0::f1() { }
+void __attribute__((regparm(2))) X0::f2() { } // expected-error{{function declared with with regparm(2) attribute was previously declared with the regparm(3) attribute}}
+void __attribute__((regparm(2))) X0::f3() { } // expected-error{{function declared with with regparm(2) attribute was previously declared without the regparm attribute}}
diff --git a/test/SemaCXX/attr-unavailable.cpp b/test/SemaCXX/attr-unavailable.cpp
index 8b381df..6f5aa5e 100644
--- a/test/SemaCXX/attr-unavailable.cpp
+++ b/test/SemaCXX/attr-unavailable.cpp
@@ -12,9 +12,9 @@
   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}}
+  void (*fp)(...) = &bar; // expected-error{{'bar' is unavailable}}
+  void (*fp2)(...) = bar; // expected-error{{'bar' is unavailable}}
 
   int &(*fp3)(int) = foo;
-  void (*fp4)(...) = foo; // expected-warning{{'foo' is unavailable}}
+  void (*fp4)(...) = foo; // expected-error{{'foo' is unavailable}}
 }
diff --git a/test/SemaCXX/blocks-1.cpp b/test/SemaCXX/blocks-1.cpp
index d93997a..29de1e6 100644
--- a/test/SemaCXX/blocks-1.cpp
+++ b/test/SemaCXX/blocks-1.cpp
@@ -33,3 +33,13 @@
     
     return 0;
 }
+
+namespace rdar8134521 {
+  void foo() {
+    int (^P)(int) = reinterpret_cast<int(^)(int)>(1);
+    P = (int(^)(int))(1);
+    
+    P = reinterpret_cast<int(^)(int)>((void*)1);
+    P = (int(^)(int))((void*)1);
+  }
+}
diff --git a/test/SemaCXX/blocks.cpp b/test/SemaCXX/blocks.cpp
index 9429543..baa79e7 100644
--- a/test/SemaCXX/blocks.cpp
+++ b/test/SemaCXX/blocks.cpp
@@ -9,3 +9,35 @@
 void reference_lvalue_test(int& (^f)()) {
   f() = 10;
 }
+
+// PR 7165
+namespace test1 {
+  void g(void (^)());
+  struct Foo {
+    void foo();   
+    void test() {
+      (void) ^{ foo(); };
+    }
+  };
+}
+
+namespace test2 {
+  int repeat(int value, int (^block)(int), unsigned n) {
+    while (n--) value = block(value);
+    return value;
+  }
+
+  class Power {
+    int base;
+
+  public:
+    Power(int base) : base(base) {}
+    int calculate(unsigned n) {
+      return repeat(1, ^(int v) { return v * base; }, n);
+    }
+  };
+
+  int test() {
+    return Power(2).calculate(10);
+  }
+}
diff --git a/test/SemaCXX/bool.cpp b/test/SemaCXX/bool.cpp
index 44e17ce..726fa6c 100644
--- a/test/SemaCXX/bool.cpp
+++ b/test/SemaCXX/bool.cpp
@@ -25,6 +25,6 @@
 
 void test2() {
   int n = 2;
-  static_assert_arg_is_bool(n && 4);
-  static_assert_arg_is_bool(n || 5);
+  static_assert_arg_is_bool(n && 4);  // expected-warning {{use of logical && with constant operand}}
+  static_assert_arg_is_bool(n || 5);  // expected-warning {{use of logical || with constant operand}}
 }
diff --git a/test/SemaCXX/c99-variable-length-array.cpp b/test/SemaCXX/c99-variable-length-array.cpp
new file mode 100644
index 0000000..7dc912a
--- /dev/null
+++ b/test/SemaCXX/c99-variable-length-array.cpp
@@ -0,0 +1,116 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wvla %s
+struct NonPOD {
+  NonPOD();
+};
+
+struct NonPOD2 {
+  NonPOD np;
+};
+
+struct POD {
+  int x;
+  int y;
+};
+
+// We allow VLAs of POD types, only.
+void vla(int N) {
+  int array1[N]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
+  POD array2[N]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
+  NonPOD array3[N]; // expected-error{{variable length array of non-POD element type 'NonPOD'}}
+  NonPOD2 array4[N][3]; // expected-error{{variable length array of non-POD element type 'NonPOD2'}}
+}
+
+/// Warn about VLAs in templates.
+template<typename T>
+void vla_in_template(int N, T t) {
+  int array1[N]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
+}
+
+struct HasConstantValue {
+  static const unsigned int value = 2;
+};
+
+struct HasNonConstantValue {
+  static unsigned int value;
+};
+
+template<typename T>
+void vla_in_template(T t) {
+  int array2[T::value]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
+}
+
+template void vla_in_template<HasConstantValue>(HasConstantValue);
+template void vla_in_template<HasNonConstantValue>(HasNonConstantValue); // expected-note{{instantiation of}}
+
+template<typename T> struct X0 { };
+
+// Cannot use any variably-modified type with a template parameter or
+// argument.
+void inst_with_vla(int N) {
+  int array[N]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
+  X0<__typeof__(array)> x0a; // expected-error{{variably modified type 'typeof (array)' (aka 'int [N]') cannot be used as a template argument}}
+}
+
+template<typename T>
+struct X1 {
+  template<int (&Array)[T::value]> // expected-error{{non-type template parameter of variably modified type 'int (&)[HasNonConstantValue::value]'}}  \
+  // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
+  struct Inner {
+    
+  };
+};
+
+X1<HasConstantValue> x1a;
+X1<HasNonConstantValue> x1b; // expected-note{{in instantiation of}}
+
+// Template argument deduction does not allow deducing a size from a VLA.
+template<typename T, unsigned N>
+void accept_array(T (&array)[N]); // expected-note{{candidate template ignored: failed template argument deduction}}
+
+void test_accept_array(int N) {
+  int array[N]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
+  accept_array(array); // expected-error{{no matching function for call to 'accept_array'}}
+}
+
+// Variably-modified types cannot be used in local classes.
+void local_classes(int N) {
+  struct X {
+    int size;
+    int array[N]; // expected-error{{fields must have a constant size: 'variable length array in structure' extension will never be supported}} \
+                  // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
+  };
+}
+
+namespace PR7206 {
+  void f(int x) {
+    struct edge_info {
+      float left;
+      float right;
+    };
+    struct edge_info edgeInfo[x]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
+  }
+}
+
+namespace rdar8020206 {
+  template<typename T>
+  void f(int i) {
+    const unsigned value = i;
+    int array[value * i]; // expected-warning 2{{variable length arrays are a C99 feature, accepted as an extension}}
+  }
+
+  template void f<int>(int); // expected-note{{instantiation of}}
+}
+
+namespace rdar8021385 {
+  typedef int my_int;
+  struct A { typedef int my_int; };
+  template<typename T>
+  struct B {
+    typedef typename T::my_int my_int;
+    void f0() {
+      int M = 4;
+      my_int a[M]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}}
+    }
+  };
+  B<A> a;
+}
diff --git a/test/SemaCXX/c99.cpp b/test/SemaCXX/c99.cpp
index f4c3639..b0bd45d 100644
--- a/test/SemaCXX/c99.cpp
+++ b/test/SemaCXX/c99.cpp
@@ -1,8 +1,3 @@
 // 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/class-layout.cpp b/test/SemaCXX/class-layout.cpp
index f3c75f4..d81944a 100644
--- a/test/SemaCXX/class-layout.cpp
+++ b/test/SemaCXX/class-layout.cpp
@@ -71,3 +71,34 @@
 SA(10, sizeof(D) == 2);
 
 }
+
+namespace Test1 {
+
+// Test that we don't assert on this hierarchy.
+struct A { };
+struct B : A { virtual void b(); };
+class C : virtual A { int c; };
+struct D : virtual B { };
+struct E : C, virtual D { };
+class F : virtual E { };
+struct G : virtual E, F { };
+
+SA(0, sizeof(G) == 24);
+
+}
+
+namespace Test2 {
+
+// Test that this somewhat complex class structure is laid out correctly.
+struct A { };
+struct B : A { virtual void b(); };
+struct C : virtual B { };
+struct D : virtual A { };
+struct E : virtual B, D { };
+struct F : E, virtual C { };
+struct G : virtual F, A { };
+struct H { G g; };
+
+SA(0, sizeof(H) == 24);
+
+}
diff --git a/test/SemaCXX/class.cpp b/test/SemaCXX/class.cpp
index 7eea67a..9d9508b 100644
--- a/test/SemaCXX/class.cpp
+++ b/test/SemaCXX/class.cpp
@@ -136,3 +136,32 @@
     };
   };
 }
+
+namespace PR7153 {
+  class EnclosingClass {
+  public:
+    struct A { } mutable *member;
+  };
+ 
+  void f(const EnclosingClass &ec) {
+    ec.member = 0;
+  }
+}
+
+namespace PR7196 {
+  struct A {
+    int a;
+
+    void f() {
+      char i[sizeof(a)];
+      enum { x = sizeof(i) };
+      enum { y = sizeof(a) };
+    }
+  };
+}
+
+namespace rdar8066414 {
+  class C {
+    C() {}
+  } // expected-error{{expected ';' after class}}
+}
diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp
index cd243e3..ebecc06 100644
--- a/test/SemaCXX/compare.cpp
+++ b/test/SemaCXX/compare.cpp
@@ -19,8 +19,8 @@
          ((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}}
+         ((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) +
@@ -31,8 +31,8 @@
          ((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}}
+         ((short) a < (unsigned short) b) +
+         ((signed char) a < (unsigned char) b) +
 
          // (A,b)
          (A == (unsigned long) b) +
@@ -83,8 +83,8 @@
          ((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}}
+         ((short) a < (unsigned short) B) +
+         ((signed char) a < (unsigned char) B) +
 
          // (C,b)
          (C == (unsigned long) b) +
@@ -135,8 +135,8 @@
          ((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}}
+         ((short) a < (unsigned short) C) +
+         ((signed char) a < (unsigned char) C) +
 
          // (0x80000,b)
          (0x80000 == (unsigned long) b) +
@@ -187,8 +187,8 @@
          ((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}}
+         ((short) a < (unsigned short) 0x80000) +
+         ((signed char) a < (unsigned char) 0x80000) +
 
          10
     ;
@@ -198,3 +198,11 @@
   enum en { zero };
   return i > zero;
 }
+
+enum E { e };
+void test2(int i, void *vp) {
+  if (test1 == vp) { } // expected-warning{{equality comparison between function pointer and void pointer}}
+  if (test1 == e) { } // expected-error{{comparison between pointer and integer}}
+  if (vp < 0) { }
+  if (test1 < e) { } // expected-error{{comparison between pointer and integer}}
+}
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index a812a59..065179b 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -199,17 +199,24 @@
 }
 
 namespace PR6595 {
+  struct OtherString {
+    OtherString();
+    OtherString(const char*);
+  };
+
   struct String {
     String(const char *);
+    String(const OtherString&);
     operator const char*() const;
   };
 
-  void f(bool Cond, String S) {
+  void f(bool Cond, String S, OtherString OS) {
     (void)(Cond? S : "");
     (void)(Cond? "" : S);
     const char a[1] = {'a'};
     (void)(Cond? S : a);
     (void)(Cond? a : S);
+    (void)(Cond? OS : S);
   }
 }
 
@@ -238,3 +245,62 @@
     (void)(true ? Bar() : Foo3()); // expected-error{{no viable constructor copying temporary}}
   }
 }
+
+// Reduced from selfhost.
+namespace test1 {
+  struct A {
+    enum Foo {
+      fa, fb, fc, fd, fe, ff
+    };
+
+    Foo x();
+  };
+
+  void foo(int);
+
+  void test(A *a) {
+    foo(a ? a->x() : 0);
+  }
+}
+
+namespace rdar7998817 {
+  class X { 
+    X(X&); // expected-note{{declared private here}}
+
+    struct ref { };
+
+  public:
+    X();
+    X(ref);
+    
+    operator ref();
+  };
+
+  void f(bool B) {
+    X x;
+    (void)(B? x // expected-error{{calling a private constructor of class 'rdar7998817::X'}}
+           : X());
+  }
+}
+
+namespace PR7598 {
+  enum Enum {
+    v = 1,
+  };
+
+  const Enum g() {
+    return v;
+  }
+
+  const volatile Enum g2() {
+    return v;
+  }
+
+  void f() {
+    const Enum v2 = v;
+    Enum e = false ? g() : v;
+    Enum e2 = false ? v2 : v;
+    Enum e3 = false ? g2() : v;
+  }
+
+}
diff --git a/test/SemaCXX/constant-expression.cpp b/test/SemaCXX/constant-expression.cpp
index a17dd58..1341036 100644
--- a/test/SemaCXX/constant-expression.cpp
+++ b/test/SemaCXX/constant-expression.cpp
@@ -57,8 +57,8 @@
     i10 = sizeof(Struct),
     i11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
     ;
-  void f() {
-    switch(0) {
+  void f(int cond) {
+    switch(cond) {
     case    0 + 1:
     case  100 + eval:
     case  200 + cval:
diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp
index 8e9e133..31d5330 100644
--- a/test/SemaCXX/constructor-initializer.cpp
+++ b/test/SemaCXX/constructor-initializer.cpp
@@ -204,3 +204,34 @@
 }
 
 }
+
+// Don't build implicit initializers for anonymous union fields when we already
+// have an explicit initializer for another field in the union.
+namespace PR7402 {
+  struct S {
+    union {
+      void* ptr_;
+      struct { int i_; };
+    };
+
+    template <typename T> S(T) : ptr_(0) { }
+  };
+
+  void f() {
+    S s(3);
+  }
+}
+
+// <rdar://problem/8308215>: don't crash.
+// Lots of questionable recovery here;  errors can change.
+namespace test3 {
+  class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 3 {{candidate}} expected-note {{passing argument}}
+  class B : public A {
+  public:
+    B(const String& s, int e=0) // expected-error {{unknown type name}} 
+      : A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} expected-error {{does not name}}
+    B(const B& e)
+      : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{no viable conversion}} expected-error {{does not name}}
+    }
+  };
+}
diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp
index 3e96d02..07281e1 100644
--- a/test/SemaCXX/conversion-function.cpp
+++ b/test/SemaCXX/conversion-function.cpp
@@ -97,9 +97,7 @@
 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}}
+  AutoPtr(AutoPtr &); // expected-note{{declared private here}}
   
 public:
   AutoPtr();
@@ -115,7 +113,7 @@
   
   AutoPtr p;
   if (Cond)
-    return p; // expected-error{{call to deleted constructor}}
+    return p; // expected-error{{calling a private constructor}}
   
   return AutoPtr();
 }
@@ -125,11 +123,12 @@
   ~A1();
 
 private:
-  A1(const A1&) __attribute__((unavailable)); // expected-note{{here}}
+  A1(const A1&); // expected-note 2 {{declared private here}}
 };
 
 A1 f() {
-  return "Hello"; // expected-error{{invokes deleted constructor}}
+  // FIXME: redundant diagnostics!
+  return "Hello"; // expected-error {{calling a private constructor}} expected-warning {{an accessible copy constructor}}
 }
 
 namespace source_locations {
@@ -215,3 +214,114 @@
 void test_any() {
   Any any = Other(); // expected-error{{cannot pass object of non-POD type 'Other' through variadic constructor; call will abort at runtime}}
 }
+
+namespace PR7055 {
+  // Make sure that we don't allow too many conversions in an
+  // auto_ptr-like template. In particular, we can't create multiple
+  // temporary objects when binding to a reference.
+  struct auto_ptr {
+    struct auto_ptr_ref { };
+
+    auto_ptr(auto_ptr&);
+    auto_ptr(auto_ptr_ref);
+    explicit auto_ptr(int *);
+
+    operator auto_ptr_ref();
+  };
+
+  struct X {
+    X(auto_ptr);
+  };
+
+  X f() {
+    X x(auto_ptr(new int));
+    return X(auto_ptr(new int));
+  }
+
+  auto_ptr foo();
+
+  X e(foo());
+
+  struct Y {
+    Y(X);
+  };
+  
+  Y f2(foo());
+}
+
+namespace PR7934 {
+  typedef unsigned char uint8;
+
+  struct MutablePtr {
+    MutablePtr() : ptr(0) {}
+    void *ptr;
+
+    operator void*() { return ptr; }
+
+  private:
+    operator uint8*() { return reinterpret_cast<uint8*>(ptr); }
+    operator const char*() const { return reinterpret_cast<const char*>(ptr); }
+  };
+
+  void fake_memcpy(const void *);
+
+  void use() {
+    MutablePtr ptr;
+    fake_memcpy(ptr);
+  }
+}
+
+namespace rdar8018274 {
+  struct X { };
+  struct Y {
+    operator const struct X *() const;
+  };
+
+  struct Z : Y {
+    operator struct X * ();
+  };
+
+  void test() {
+    Z x;
+    (void) (x != __null);
+  }
+
+
+  struct Base {
+    operator int();
+  };
+
+  struct Derived1 : Base { };
+
+  struct Derived2 : Base { };
+
+  struct SuperDerived : Derived1, Derived2 { 
+    using Derived1::operator int;
+  };
+
+  struct UeberDerived : SuperDerived {
+    operator long();
+  };
+
+  void test2(UeberDerived ud) {
+    int i = ud; // expected-error{{ambiguous conversion from derived class 'rdar8018274::SuperDerived' to base class 'rdar8018274::Base'}}
+  }
+
+  struct Base2 {
+    operator int();
+  };
+
+  struct Base3 {
+    operator int();
+  };
+
+  struct Derived23 : Base2, Base3 { 
+    using Base2::operator int;
+  };
+
+  struct ExtraDerived23 : Derived23 { };
+
+  void test3(ExtraDerived23 ed) {
+    int i = ed;
+  }
+}
diff --git a/test/SemaCXX/conversion.cpp b/test/SemaCXX/conversion.cpp
new file mode 100644
index 0000000..f648943
--- /dev/null
+++ b/test/SemaCXX/conversion.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -Wconversion -verify %s
+
+typedef   signed char  int8_t;
+typedef   signed short int16_t;
+typedef   signed int   int32_t;
+typedef   signed long  int64_t;
+
+typedef unsigned char  uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int   uint32_t;
+typedef unsigned long  uint64_t;
+
+// <rdar://problem/7909130>
+namespace test0 {
+  int32_t test1_positive(char *I, char *E) {
+    return (E - I); // expected-warning {{implicit conversion loses integer precision}}
+  }
+
+  int32_t test1_negative(char *I, char *E) {
+    return static_cast<int32_t>(E - I);
+  }
+
+  uint32_t test2_positive(uint64_t x) {
+    return x; // expected-warning {{implicit conversion loses integer precision}}
+  }
+
+  uint32_t test2_negative(uint64_t x) {
+    return (uint32_t) x;
+  }
+}
+
+namespace test1 {
+  uint64_t test1(int x, unsigned y) {
+    return sizeof(x == y);
+  }
+
+  uint64_t test2(int x, unsigned y) {
+    return __alignof(x == y);
+  }
+
+  void * const foo();
+  bool test2(void *p) {
+    return p == foo();
+  }
+}
diff --git a/test/SemaCXX/copy-assignment.cpp b/test/SemaCXX/copy-assignment.cpp
index bfe1501..5730b2a 100644
--- a/test/SemaCXX/copy-assignment.cpp
+++ b/test/SemaCXX/copy-assignment.cpp
@@ -97,3 +97,15 @@
   i = a; // expected-error{{assigning to 'int' from incompatible type 'A'}}
 }
 
+// <rdar://problem/8315440>: Don't crash
+// FIXME: the recovery here is really bad.
+namespace test1 {
+  template<typename T> class A : public unknown::X { // expected-error {{undeclared identifier 'unknown'}} expected-error {{expected class name}}
+    A(UndeclaredType n) : X(n) {} // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{undeclared identifier 'n'}} expected-error {{expected ';' at end}} expected-error {{field has incomplete type}}
+  };
+  template<typename T> class B : public A<T>     {
+    virtual void foo() {}
+  };
+  extern template class A<char>; // expected-note {{in instantiation}} expected-note {{not complete}}
+  extern template class B<char>;
+}
diff --git a/test/SemaCXX/crash-8124080.cpp b/test/SemaCXX/crash-8124080.cpp
new file mode 100644
index 0000000..78a0315
--- /dev/null
+++ b/test/SemaCXX/crash-8124080.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// <rdar://problem/8124080>
+template<typename _Alloc> class allocator;
+template<class _CharT> struct char_traits;
+template<typename _CharT, typename _Traits = char_traits<_CharT>,            
+         typename _Alloc = allocator<_CharT> >
+class basic_string;
+template<typename _CharT, typename _Traits, typename _Alloc>
+const typename basic_string<_CharT, _Traits, _Alloc>::size_type   
+basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_max_size // expected-error{{no member named '_Rep' in 'basic_string<_CharT, _Traits, _Alloc>'}}
+  = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4; 
+
+// PR7118
+template<typename T>
+class Foo {
+  class Bar;
+  void f() {
+    Bar i;
+  }
+};
diff --git a/test/SemaCXX/crash-PR7625.cpp b/test/SemaCXX/crash-PR7625.cpp
new file mode 100644
index 0000000..3ddf5e5
--- /dev/null
+++ b/test/SemaCXX/crash-PR7625.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T> struct a : T {
+ struct x : T {
+   int aa() { return p; } // expected-error{{use of undeclared identifier 'p'}}
+ };
+};
diff --git a/test/SemaCXX/cv-unqual-rvalues.cpp b/test/SemaCXX/cv-unqual-rvalues.cpp
new file mode 100644
index 0000000..ed76ced
--- /dev/null
+++ b/test/SemaCXX/cv-unqual-rvalues.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR7463: Make sure that when we have an rvalue, it does not have
+// cv-qualified non-class type.
+template <typename T_> void g (T_&); // expected-note 7{{not viable}}
+
+template<const int X> void h() { 
+  g(X); // expected-error{{no matching function for call to 'g'}}
+}
+
+template<typename T, T X> void h2() { 
+  g(X); // expected-error{{no matching function for call to 'g'}}
+}
+
+void a(__builtin_va_list x) {
+  g(__builtin_va_arg(x, const int)); // expected-error{{no matching function for call to 'g'}}
+  g((const int)0); // expected-error{{no matching function for call to 'g'}}
+  typedef const int cint;
+  g(cint(0)); // expected-error{{no matching function for call to 'g'}}
+  g(static_cast<const int>(1)); // expected-error{{no matching function for call to 'g'}}
+  g(reinterpret_cast<int *const>(0)); // expected-error{{no matching function for call to 'g'}}
+  h<0>(); 
+  h2<const int, 0>(); // expected-note{{instantiation of}}
+}
diff --git a/test/SemaCXX/decltype.cpp b/test/SemaCXX/decltype.cpp
new file mode 100644
index 0000000..d4ef7e3
--- /dev/null
+++ b/test/SemaCXX/decltype.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// PR5290
+int const f0();
+void f0_test() {
+  decltype(0, f0()) i = 0;
+  i = 0;
+}
+
+struct A { int a[1]; A() { } };
+typedef A const AC;
+int &f1(int*);
+float &f2(int const*);
+
+void test_f2() {
+  float &fr = f2(AC().a);
+}
+
diff --git a/test/SemaCXX/default-assignment-operator.cpp b/test/SemaCXX/default-assignment-operator.cpp
index 81e7059..668c600 100644
--- a/test/SemaCXX/default-assignment-operator.cpp
+++ b/test/SemaCXX/default-assignment-operator.cpp
@@ -6,8 +6,9 @@
   // 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:
+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}} \
+// expected-note{{assignment operator for 'Base' first required here}}
+public: 
   X();
   const int cint;  // expected-note {{declared here}}
 }; 
@@ -27,7 +28,7 @@
 
 // Test1
 void f(X x, const X cx) {
-  x = cx;  // expected-note 2 {{synthesized method is first required here}}
+  x = cx; // expected-note{{assignment operator for 'X' first required here}}
   x = cx;
   z1 = z2;
 }
@@ -73,6 +74,7 @@
 // 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) {}  
@@ -82,6 +84,35 @@
 E1 e1, e2;
 
 void j() {
-  e1 = e2; // expected-note{{synthesized method is first required here}}
+  e1 = e2; // expected-note{{assignment operator for 'E1' first required here}}
 }
 
+namespace ProtectedCheck {
+  struct X {
+  protected:
+    X &operator=(const X&); // expected-note{{declared protected here}}
+  };
+
+  struct Y : public X { };
+
+  void f(Y y) { y = y; }
+
+  struct Z { // expected-error{{'operator=' is a protected member of 'ProtectedCheck::X'}}
+    X x;
+  };
+
+  void f(Z z) { z = z; }  // expected-note{{implicit default copy assignment operator}}
+
+}
+
+namespace MultiplePaths {
+  struct X0 { 
+    X0 &operator=(const X0&);
+  };
+
+  struct X1 : public virtual X0 { };
+
+  struct X2 : X0, X1 { };
+
+  void f(X2 x2) { x2 = x2; }
+}
diff --git a/test/SemaCXX/default-constructor-initializers.cpp b/test/SemaCXX/default-constructor-initializers.cpp
index 757332d..9da8556 100644
--- a/test/SemaCXX/default-constructor-initializers.cpp
+++ b/test/SemaCXX/default-constructor-initializers.cpp
@@ -43,7 +43,6 @@
 
 // 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}}
@@ -51,5 +50,12 @@
   volatile int v1;
 };
 
+// Test default initialization which *requires* a constructor call for non-POD.
 Z1 z1; // expected-note {{first required here}}
 
+// Ensure that value initialization doesn't use trivial implicit constructors.
+namespace PR7948 {
+  // Note that this is also non-POD to ensure we don't just special case PODs.
+  struct S { const int x; ~S(); };
+  const S arr[2] = { { 42 } };
+}
diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
index ae3dc86..cdcae2e 100644
--- a/test/SemaCXX/destructor.cpp
+++ b/test/SemaCXX/destructor.cpp
@@ -19,7 +19,9 @@
     // 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}}
+    // expected-error{{destructor cannot be variadic}} \
+    // expected-error{{destructor cannot have a return type}} \
+    // expected-error{{'const' qualifier is not allowed on a destructor}}
 };
 
 struct D2 {
@@ -83,3 +85,37 @@
   template<class T> class X { T v; ~X() { ++*v; } };
   void a(X<int> x) {}
 }
+
+struct X0 { virtual ~X0() throw(); };
+struct X1 : public X0 { };
+
+// Make sure we instantiate operator deletes when building a virtual
+// destructor.
+namespace test6 {
+  template <class T> class A {
+  public:
+    void *operator new(__SIZE_TYPE__);
+    void operator delete(void *p) {
+      T::deleteIt(p); // expected-error {{type 'int' cannot be used prior to '::'}}
+    }
+
+    virtual ~A() {} // expected-note {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
+  };
+
+  class B : A<int> { B(); };
+  B::B() {} // expected-note {{in instantiation of member function 'test6::A<int>::~A' requested here}}
+}
+
+// Make sure classes are marked invalid when they have invalid
+// members.  This avoids a crash-on-invalid.
+namespace test7 {
+  struct A {
+    ~A() const; // expected-error {{'const' qualifier is not allowed on a destructor}}
+  };
+  struct B : A {};
+
+  void test() {
+    B *b;
+    b->~B();
+  }
+}
diff --git a/test/SemaCXX/empty-class-layout.cpp b/test/SemaCXX/empty-class-layout.cpp
index c3dc733..0b46bf0 100644
--- a/test/SemaCXX/empty-class-layout.cpp
+++ b/test/SemaCXX/empty-class-layout.cpp
@@ -2,6 +2,8 @@
 
 #define SA(n, p) int a##n[(p) ? 1 : -1]
 
+namespace Test0 {
+
 struct A { int a; };
 SA(0, sizeof(A) == 4);
 
@@ -66,3 +68,79 @@
 struct S8 : Empty, A {
 };
 SA(12, sizeof(S8) == 4);
+
+}
+
+namespace Test1 {
+
+// Test that we don't try to place both A subobjects at offset 0.
+struct A { };
+class B { virtual void f(); };
+class C : A, virtual B { };
+struct D : virtual C { };
+struct E : virtual A { };
+class F : D, E { };
+
+SA(0, sizeof(F) == 24);
+
+}
+
+namespace Test2 {
+
+// Test that B::a isn't laid out at offset 0.
+struct Empty { };
+struct A : Empty { };
+struct B : Empty {
+  A a;
+};
+
+SA(0, sizeof(B) == 2);
+
+}
+
+namespace Test3 {
+
+// Test that B::a isn't laid out at offset 0.
+struct Empty { };
+struct A { Empty e; };
+struct B : Empty { A a; };
+SA(0, sizeof(B) == 2);
+
+}
+
+namespace Test4 {
+
+// Test that C::Empty isn't laid out at offset 0.
+struct Empty { };
+struct A : Empty { };
+struct B { A a; };
+struct C : B, Empty { };
+SA(0, sizeof(C) == 2);
+
+}
+
+namespace Test5 {
+
+// Test that B::Empty isn't laid out at offset 0.
+struct Empty { };
+struct Field : virtual Empty { };
+struct A {
+  Field f;
+};
+struct B : A, Empty { };
+SA(0, sizeof(B) == 16);
+
+}
+
+namespace Test6 {
+
+// Test that B::A isn't laid out at offset 0.
+struct Empty { };
+struct Field : virtual Empty { };
+struct A {
+  Field f;
+};
+struct B : Empty, A { };
+SA(0, sizeof(B) == 16);
+
+}
diff --git a/test/SemaCXX/enum.cpp b/test/SemaCXX/enum.cpp
index dc4a506..1dc55e3 100644
--- a/test/SemaCXX/enum.cpp
+++ b/test/SemaCXX/enum.cpp
@@ -1,10 +1,11 @@
 // RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++98 -verify -triple x86_64-apple-darwin %s
-
-enum E {
+enum E { // expected-note{{previous definition is here}}
   Val1,
   Val2
 };
 
+enum E; // expected-warning{{redeclaration of already-defined enum 'E' is a GNU extension}}
+
 int& enumerator_type(int);
 float& enumerator_type(E);
 
@@ -71,3 +72,21 @@
 namespace Conditional {
   enum a { A }; a x(const enum a x) { return 1?x:A; }
 }
+
+namespace PR7051 {
+  enum E { e0 };
+  void f() {
+    E e;
+    e = 1; // expected-error{{assigning to 'PR7051::E' from incompatible type 'int'}}
+    e |= 1; // expected-error{{assigning to 'PR7051::E' from incompatible type 'int'}}
+  }
+}
+
+// PR7466
+enum { }; // expected-warning{{declaration does not declare anything}}
+typedef enum { }; // expected-warning{{typedef requires a name}}
+
+// PR7921
+enum PR7921E {
+    PR7921V = (PR7921E)(123) // expected-error {{expression is not an integer constant expression}}
+};
diff --git a/test/SemaCXX/exception-spec-no-exceptions.cpp b/test/SemaCXX/exception-spec-no-exceptions.cpp
new file mode 100644
index 0000000..1fe45b0
--- /dev/null
+++ b/test/SemaCXX/exception-spec-no-exceptions.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Note: this is intentionally -fno-exceptions, not just accidentally
+// so because that's the current -cc1 default.
+
+// PR7243: redeclarations
+namespace test0 {
+  void foo() throw(int);
+  void foo() throw();
+}
+
+// Overrides.
+namespace test1 {
+  struct A {
+    virtual void foo() throw();
+  };
+
+  struct B : A {
+    virtual void foo() throw(int);
+  };
+}
+
+// Calls from less permissive contexts.  We don't actually do this
+// check, but if we did it should also be disabled under
+// -fno-exceptions.
+namespace test2 {
+  void foo() throw(int);
+  void bar() throw() {
+    foo();
+  }
+}
+
diff --git a/test/SemaCXX/expressions.cpp b/test/SemaCXX/expressions.cpp
index f3a05c1..b51194a 100644
--- a/test/SemaCXX/expressions.cpp
+++ b/test/SemaCXX/expressions.cpp
@@ -7,3 +7,10 @@
   // Result of ! must be type bool.
   int i = choice(!1);
 }
+
+// rdar://8018252
+void f0() {
+  extern void f0_1(int*);
+  register int x;
+  f0_1(&x);
+}
diff --git a/test/SemaCXX/flexible-array-test.cpp b/test/SemaCXX/flexible-array-test.cpp
new file mode 100644
index 0000000..02e3f83
--- /dev/null
+++ b/test/SemaCXX/flexible-array-test.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+// pr7029
+
+template <class Key, class T> struct QMap
+{
+  void insert(const Key &, const T &);
+  T v;
+};
+
+
+template <class Key, class T>
+void QMap<Key, T>::insert(const Key &, const T &avalue)
+{
+  v = avalue;
+}
+
+
+struct inotify_event
+{
+  int wd;
+ 
+  // clang doesn't like '[]': 
+  // cannot initialize a parameter of type 'void *' with an rvalue of type 'char (*)[]'
+  char name [];	
+};
+
+
+void foo()
+{
+    inotify_event event;
+    inotify_event* ptr = &event;
+    inotify_event event1 = *ptr;
+    *ptr = event;
+    QMap<int, inotify_event> eventForId;
+    eventForId.insert(ptr->wd, *ptr);
+}
+
+struct S {
+	virtual void foo();
+};
+
+struct X {
+   int blah;
+   S strings[];	// expected-error {{flexible array member 'strings' of non-POD element type 'S []'}}
+};
diff --git a/test/SemaCXX/friend.cpp b/test/SemaCXX/friend.cpp
index ffad0e2..30abcbb 100644
--- a/test/SemaCXX/friend.cpp
+++ b/test/SemaCXX/friend.cpp
@@ -45,5 +45,20 @@
 namespace test3 {
   class Foo {
     friend const int getInt(int inInt = 0);
+
   };
 }
+
+namespace test4 {
+  class T4A {
+    friend class T4B;
+  
+  public:
+    T4A(class T4B *);
+
+  protected:
+    T4B *mB;          // error here
+  };
+ 
+  class T4B {};
+}
diff --git a/test/SemaCXX/function-type-qual.cpp b/test/SemaCXX/function-type-qual.cpp
index be61f2b..8ebb506 100644
--- a/test/SemaCXX/function-type-qual.cpp
+++ b/test/SemaCXX/function-type-qual.cpp
@@ -1,15 +1,17 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
 void f() const; // expected-error {{type qualifier is not allowed on this function}}
+void (*pf)() const; // expected-error {{type qualifier is not allowed on this function pointer}}
+void (&rf)() const = f; // expected-error {{type qualifier is not allowed on this function reference}}
 
 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}}
+cfn f2; // expected-error {{a qualified function type cannot be used to declare a nonmember 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}}
+  static cfn f4; // expected-error {{a qualified function type cannot be used to declare a static member function}}
 
   void m1() {
     x = 0;
@@ -21,3 +23,6 @@
 
   int x;
 };
+
+void (C::*mpf)() const;
+cfn C::*mpg;
diff --git a/test/SemaCXX/i-c-e-cxx.cpp b/test/SemaCXX/i-c-e-cxx.cpp
index e8275d4..9672a42 100644
--- a/test/SemaCXX/i-c-e-cxx.cpp
+++ b/test/SemaCXX/i-c-e-cxx.cpp
@@ -17,7 +17,7 @@
 
 int a() {
   const int t=t; // expected-note {{subexpression not valid}}
-  switch(1) {
+  switch(1) { // expected-warning {{no case matching constant switch condition '1'}}
     case t:; // expected-error {{not an integer constant expression}}
   }
 }
diff --git a/test/SemaCXX/implicit-member-functions.cpp b/test/SemaCXX/implicit-member-functions.cpp
index 79cc367..5333094 100644
--- a/test/SemaCXX/implicit-member-functions.cpp
+++ b/test/SemaCXX/implicit-member-functions.cpp
@@ -39,3 +39,14 @@
   };
 
 }
+
+namespace PR7594 {
+  // If the lazy declaration of special member functions is triggered
+  // in an out-of-line initializer, make sure the functions aren't in
+  // the initializer scope. This used to crash Clang:
+  struct C {
+    C();
+    static C *c;
+  };
+  C *C::c = new C();
+}
diff --git a/test/SemaCXX/implicit-virtual-member-functions.cpp b/test/SemaCXX/implicit-virtual-member-functions.cpp
index cb24501..f6082e5 100644
--- a/test/SemaCXX/implicit-virtual-member-functions.cpp
+++ b/test/SemaCXX/implicit-virtual-member-functions.cpp
@@ -21,9 +21,9 @@
 
 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; 
+  new D; // expected-note {{implicit default destructor for 'D' first required here}}
 }
 
diff --git a/test/SemaCXX/increment-decrement.cpp b/test/SemaCXX/increment-decrement.cpp
new file mode 100644
index 0000000..11b7d1e
--- /dev/null
+++ b/test/SemaCXX/increment-decrement.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+volatile int i;
+
+const int &inc = i++;
+const int &dec = i--;
+
+const int &incfail = ++i; // expected-error {{drops qualifiers}}
+const int &decfail = --i; // expected-error {{drops qualifiers}}
+
+// PR7794
+void f0(int e) {
+  ++(int&)e;
+}
diff --git a/test/SemaCXX/init-priority-attr.cpp b/test/SemaCXX/init-priority-attr.cpp
new file mode 100644
index 0000000..6ea263d
--- /dev/null
+++ b/test/SemaCXX/init-priority-attr.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class Two {
+private:
+    int i, j, k;
+public:
+    static int count;
+    Two( int ii, int jj ) { i = ii; j = jj; k = count++; };
+    Two( void )           { i =  0; j =  0; k = count++; };
+    int eye( void ) { return i; };
+    int jay( void ) { return j; };
+    int kay( void ) { return k; };
+};
+
+extern Two foo;
+extern Two goo;
+extern Two coo[];
+extern Two koo[];
+
+Two foo __attribute__((init_priority(101))) ( 5, 6 );
+
+Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{attribute requires 1 argument(s)}}
+
+Two coo[2]  __attribute__((init_priority(3)));	// expected-error {{init_priority attribute requires integer constant between 101 and 65535 inclusive}}
+
+Two koo[4]  __attribute__((init_priority(1.13))); // expected-error {{'init_priority' attribute requires integer constant}}
+
+
+Two func()  __attribute__((init_priority(1001))); // expected-error {{can only use ‘init_priority’ attribute on file-scope definitions of objects of class type}}
+
+int i  __attribute__((init_priority(1001))); // expected-error {{can only use ‘init_priority’ attribute on file-scope definitions of objects of class type}}
+
+int main() {
+	Two foo __attribute__((init_priority(1001)));	// expected-error {{can only use ‘init_priority’ attribute on file-scope definitions of objects of class type}}
+}
+
diff --git a/test/SemaCXX/instantiate-blocks.cpp b/test/SemaCXX/instantiate-blocks.cpp
new file mode 100644
index 0000000..a4001a7
--- /dev/null
+++ b/test/SemaCXX/instantiate-blocks.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -verify %s
+// rdar: // 6182276
+
+template <typename T, typename T1> void foo(T t, T1 r)
+{
+    T block_arg;
+    __block T1 byref_block_arg;
+
+    T1 (^block)(T)  =  ^ T1 (T arg) { 
+         byref_block_arg = arg;
+         block_arg = arg; 	// expected-error {{variable is not assignable (missing __block type specifier)}}
+         return block_arg+arg; };
+}
+
+int main(void)
+{
+    foo(100, 'a');	// expected-note {{in instantiation of function template specialization 'foo<int, char>' requested here}}
+}
+
diff --git a/test/SemaCXX/invalid-instantiated-field-decl.cpp b/test/SemaCXX/invalid-instantiated-field-decl.cpp
new file mode 100644
index 0000000..8b26489
--- /dev/null
+++ b/test/SemaCXX/invalid-instantiated-field-decl.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <typename T>
+class SmallVectorImpl  {
+public:
+  explicit SmallVectorImpl(unsigned N) {
+  }
+
+  ~SmallVectorImpl() { }
+
+};
+
+template <typename T, unsigned N>
+class SmallVector : public SmallVectorImpl<T> {
+  typedef typename SmallVectorImpl<T>::U U; // expected-error {{no type named 'U' in 'SmallVectorImpl<CallSite>'}}
+  enum {
+
+    MinUs = (static_cast<unsigned int>(sizeof(T))*N +	// expected-error {{invalid application of 'sizeof' to an incomplete type 'CallSite'}}
+             static_cast<unsigned int>(sizeof(U)) - 1) /
+            static_cast<unsigned int>(sizeof(U)),
+    NumInlineEltsElts = MinUs 
+  };
+  U InlineElts[NumInlineEltsElts];
+public:
+  SmallVector() : SmallVectorImpl<T>(NumInlineEltsElts) {
+  }
+
+};
+
+class CallSite;	// expected-note {{forward declaration of 'CallSite'}}
+class InlineFunctionInfo {
+public:
+  explicit InlineFunctionInfo() {}
+  SmallVector<CallSite, 2> DevirtualizedCalls;	// expected-note {{in instantiation of template class 'SmallVector<CallSite, 2>' requested}}
+};
diff --git a/test/SemaCXX/linkage-spec.cpp b/test/SemaCXX/linkage-spec.cpp
index 57730a6..86c3d3e 100644
--- a/test/SemaCXX/linkage-spec.cpp
+++ b/test/SemaCXX/linkage-spec.cpp
@@ -54,3 +54,35 @@
         return f2((char *)0);
     }
 }
+
+// PR6991
+extern "C" typedef int (*PutcFunc_t)(int);
+
+
+// PR7859
+extern "C" void pr7859_a(int) {} // expected-note {{previous definition}}
+extern "C" void pr7859_a(int) {} // expected-error {{redefinition}}
+
+extern "C" void pr7859_b() {} // expected-note {{previous definition}}
+extern "C" void pr7859_b(int) {} // expected-error {{conflicting}}
+
+extern "C" void pr7859_c(short) {} // expected-note {{previous definition}}
+extern "C" void pr7859_c(int) {} // expected-error {{conflicting}}
+
+// <rdar://problem/8318976>
+extern "C" {
+  struct s0 {
+  private:
+    s0();
+    s0(const s0 &);
+  };
+}
+
+//PR7754
+extern "C++" template <class T> int pr7754(T param);
+
+namespace N {
+  int value;
+}
+
+extern "C++" using N::value;
diff --git a/test/SemaCXX/local-classes.cpp b/test/SemaCXX/local-classes.cpp
index 6799e58..500b219 100644
--- a/test/SemaCXX/local-classes.cpp
+++ b/test/SemaCXX/local-classes.cpp
@@ -30,3 +30,12 @@
     compare_and_set2 (false, gross);
   }
 }
+
+namespace Templates {
+  template<int Value>
+  void f() {
+    struct Inner {
+      static int getValue() { return Value; }
+    };
+  }
+}
diff --git a/test/SemaCXX/member-expr.cpp b/test/SemaCXX/member-expr.cpp
index 54a9593..953ee48 100644
--- a/test/SemaCXX/member-expr.cpp
+++ b/test/SemaCXX/member-expr.cpp
@@ -72,3 +72,46 @@
     y.f(17);
   }
 }
+
+namespace test5 {
+  struct A {
+    template <class T> void foo();
+  };
+
+  void test0(int x) {
+    x.A::foo<int>(); // expected-error {{'int' is not a structure or union}}
+  }
+
+  void test1(A *x) {
+    x.A::foo<int>(); // expected-error {{'test5::A *' is a pointer}}
+  }
+
+  void test2(A &x) {
+    x->A::foo<int>(); // expected-error {{'test5::A' is not a pointer}}
+  }
+}
+
+namespace PR7508 {
+  struct A {
+    struct CleanupScope {};
+    void PopCleanupBlock();
+  };
+
+  void foo(A &a) {
+    a.PopCleanupScope(); // expected-error{{no member named 'PopCleanupScope' in 'PR7508::A'}}
+  }
+}
+
+namespace rdar8231724 {
+  namespace N {
+    template<typename T> struct X1;
+    int i;
+  }
+
+  struct X { };
+  struct Y : X { };
+
+  void f(Y *y) {
+    y->N::X1<int>; // expected-error{{'rdar8231724::N::X1' is not a member of class 'rdar8231724::Y'}}
+  }
+}
diff --git a/test/SemaCXX/member-pointer-ms.cpp b/test/SemaCXX/member-pointer-ms.cpp
new file mode 100644
index 0000000..3b2d0fc
--- /dev/null
+++ b/test/SemaCXX/member-pointer-ms.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -cxx-abi microsoft -fsyntax-only -verify %s
+
+// Test that we reject pointers to members of incomplete classes (for now)
+struct A; //expected-note{{forward declaration of 'A'}}
+int A::*pai1; //expected-error{{incomplete type 'A'}}
+
+// Test that we don't allow reinterpret_casts from pointers of one size to
+// pointers of a different size.
+struct A {};
+struct B {};
+struct C: A, B {};
+
+void (A::*paf)();
+void (C::*pcf)() = reinterpret_cast<void (C::*)()>(paf); //expected-error{{cannot reinterpret_cast from member pointer type}}
diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp
index be25cbd..795c0b9 100644
--- a/test/SemaCXX/member-pointer.cpp
+++ b/test/SemaCXX/member-pointer.cpp
@@ -79,7 +79,7 @@
 
   void (HasMembers::*pmf)() = &HasMembers::f;
   void (*pnf)() = &Fake::f;
-  &hm.f; // expected-error {{must explicitly qualify}} expected-warning{{result unused}}
+  &hm.f; // expected-error {{cannot create a non-constant pointer to member function}}
 
   void (HasMembers::*pmgv)() = &HasMembers::g;
   void (HasMembers::*pmgi)(int) = &HasMembers::g;
@@ -142,8 +142,8 @@
     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}}
+      p = &this->h; // expected-error {{cannot create a non-constant pointer to member function}}
+      p = &(*this).h; // expected-error {{cannot create a non-constant pointer to member function}}
     }
   };
 }
@@ -157,3 +157,116 @@
     return object->*p2m; // expected-error {{left hand operand to ->*}}
   }
 }
+
+namespace PR7176 {
+  namespace base
+  {
+    struct Process
+    { };
+    struct Continuous : Process
+    {
+      bool cond();
+    };
+  }
+
+  typedef bool( base::Process::*Condition )();
+
+  void m()
+  { (void)(Condition) &base::Continuous::cond; }
+}
+
+namespace rdar8358512 {
+  // We can't call this with an overload set because we're not allowed
+  // to look into overload sets unless the parameter has some kind of
+  // function type.
+  template <class F> void bind(F f); // expected-note 12 {{candidate template ignored}}
+  template <class F, class T> void bindmem(F (T::*f)()); // expected-note 4 {{candidate template ignored}}
+  template <class F> void bindfn(F (*f)()); // expected-note 4 {{candidate template ignored}}
+
+  struct A {
+    void nonstat();
+    void nonstat(int);
+
+    void mixed();
+    static void mixed(int);
+
+    static void stat();
+    static void stat(int);
+    
+    template <typename T> struct Test0 {
+      void test() {
+        bind(&nonstat); // expected-error {{no matching function for call}}
+        bind(&A::nonstat); // expected-error {{no matching function for call}}
+
+        bind(&mixed); // expected-error {{no matching function for call}}
+        bind(&A::mixed); // expected-error {{no matching function for call}}
+
+        bind(&stat); // expected-error {{no matching function for call}}
+        bind(&A::stat); // expected-error {{no matching function for call}}
+      }
+    };
+
+    template <typename T> struct Test1 {
+      void test() {
+        bindmem(&nonstat); // expected-error {{no matching function for call}}
+        bindmem(&A::nonstat);
+
+        bindmem(&mixed); // expected-error {{no matching function for call}}
+        bindmem(&A::mixed);
+
+        bindmem(&stat); // expected-error {{no matching function for call}}
+        bindmem(&A::stat); // expected-error {{no matching function for call}}
+      }
+    };
+
+    template <typename T> struct Test2 {
+      void test() {
+        bindfn(&nonstat); // expected-error {{no matching function for call}}
+        bindfn(&A::nonstat); // expected-error {{no matching function for call}}
+
+        bindfn(&mixed); // expected-error {{no matching function for call}}
+        bindfn(&A::mixed); // expected-error {{no matching function for call}}
+
+        bindfn(&stat);
+        bindfn(&A::stat);
+      }
+    };
+  };
+
+  template <class T> class B {
+    void nonstat();
+    void nonstat(int);
+
+    void mixed();
+    static void mixed(int);
+
+    static void stat();
+    static void stat(int);
+
+    // None of these can be diagnosed yet, because the arguments are
+    // still dependent.
+    void test0a() {
+      bind(&nonstat);
+      bind(&B::nonstat);
+
+      bind(&mixed);
+      bind(&B::mixed);
+
+      bind(&stat);
+      bind(&B::stat);
+    }
+
+    void test0b() {
+      bind(&nonstat); // expected-error {{no matching function for call}}
+      bind(&B::nonstat); // expected-error {{no matching function for call}}
+
+      bind(&mixed); // expected-error {{no matching function for call}}
+      bind(&B::mixed); // expected-error {{no matching function for call}}
+
+      bind(&stat); // expected-error {{no matching function for call}}
+      bind(&B::stat); // expected-error {{no matching function for call}}
+    }
+  };
+
+  template void B<int>::test0b(); // expected-note {{in instantiation}}
+}
diff --git a/test/SemaCXX/namespace-alias.cpp b/test/SemaCXX/namespace-alias.cpp
index 3ea1ccf..52cae2e 100644
--- a/test/SemaCXX/namespace-alias.cpp
+++ b/test/SemaCXX/namespace-alias.cpp
@@ -84,6 +84,26 @@
   }
 }
 
+namespace {
+  class C1;
+}
+namespace {
+  class C1;
+}
+C1 *pc1 = 0;
+
+namespace N {
+  namespace {
+    class C2;
+  }
+}
+namespace N {
+  namespace {
+    class C2;
+  }
+}
+N::C2 *pc2 = 0;
+
 // PR6341
 namespace A = N;
 namespace N { }
@@ -91,3 +111,13 @@
 
 A::X nx;
 
+namespace PR7014 {
+  namespace X
+  {
+    namespace Y {}
+  }
+
+  using namespace X;
+
+  namespace Y = X::Y;
+}
diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp
index 59a8e8c..0dc1097 100644
--- a/test/SemaCXX/nested-name-spec.cpp
+++ b/test/SemaCXX/nested-name-spec.cpp
@@ -228,3 +228,19 @@
     A::execute(path); // expected-error {{incomplete type 'test3::A' named in nested name specifier}}
   }
 }
+
+namespace PR7133 {
+  namespace A {
+    class Foo;
+  }
+
+  namespace A {
+    namespace B {
+      bool foo(Foo &);
+    }
+  }
+
+  bool A::B::foo(Foo &) {
+    return false;
+  }
+}
diff --git a/test/SemaCXX/new-array-size-conv.cpp b/test/SemaCXX/new-array-size-conv.cpp
new file mode 100644
index 0000000..80219a9
--- /dev/null
+++ b/test/SemaCXX/new-array-size-conv.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+struct ValueInt
+{
+  ValueInt(int v = 0) : ValueLength(v) {}
+  operator int () const { return ValueLength; } // expected-note 3{{conversion to integral type 'int' declared here}}
+private:
+  int ValueLength;
+};
+
+enum E { e };
+struct ValueEnum {
+  operator E() const; // expected-note{{conversion to enumeration type 'E' declared here}}
+};
+
+struct ValueBoth : ValueInt, ValueEnum { };
+
+struct IndirectValueInt : ValueInt { };
+struct TwoValueInts : ValueInt, IndirectValueInt { };
+
+void test() {
+  (void)new int[ValueInt(10)]; // expected-warning{{implicit conversion from array size expression of type 'ValueInt' to integral type 'int' is a C++0x extension}}
+  (void)new int[ValueEnum()]; // expected-warning{{implicit conversion from array size expression of type 'ValueEnum' to enumeration type 'E' is a C++0x extension}}
+  (void)new int[ValueBoth()]; // expected-error{{ambiguous conversion of array size expression of type 'ValueBoth' to an integral or enumeration type}}
+
+  (void)new int[TwoValueInts()]; // expected-error{{ambiguous conversion of array size expression of type 'TwoValueInts' to an integral or enumeration type}}
+}
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index 50aba47..9a64e4c 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -24,6 +24,8 @@
 void* operator new(size_t, float*); // expected-note 3 {{candidate}}
 void* operator new(size_t, S); // expected-note 2 {{candidate}}
 
+struct foo { };
+
 void good_news()
 {
   int *pi = new int;
@@ -34,7 +36,6 @@
   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;
@@ -44,6 +45,14 @@
   pi = new (S(1.0f, 2)) int;
   
   (void)new int[true];
+
+  // PR7147
+  typedef int a[2];
+  foo* f1 = new foo;
+  foo* f2 = new foo[2];
+  typedef foo x[2];
+  typedef foo y[2][2];
+  x* f3 = new y;
 }
 
 struct abstract {
@@ -59,7 +68,7 @@
   (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[i]); // expected-warning {{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}}
@@ -94,7 +103,7 @@
   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 (void*)0; // expected-warning {{cannot delete expression with pointer-to-'void' type 'void *'}}
   delete (T*)0; // expected-warning {{deleting pointer to incomplete type}}
   ::S::delete (int*)0; // expected-error {{expected unqualified-id}}
 }
@@ -231,3 +240,117 @@
     (void)new(0) S;
   }
 }
+
+namespace Test1 {
+
+void f() {
+  (void)new int[10](1, 2); // expected-error {{array 'new' cannot have initialization arguments}}
+  
+  typedef int T[10];
+  (void)new T(1, 2); // expected-error {{array 'new' cannot have initialization arguments}}
+}
+
+template<typename T>
+void g(unsigned i) {
+  (void)new T[1](i); // expected-error {{array 'new' cannot have initialization arguments}}
+}
+
+template<typename T>
+void h(unsigned i) {
+  (void)new T(i); // expected-error {{array 'new' cannot have initialization arguments}}
+}
+template void h<unsigned>(unsigned);
+template void h<unsigned[10]>(unsigned); // expected-note {{in instantiation of function template specialization 'Test1::h<unsigned int [10]>' requested here}}
+
+}
+
+// Don't diagnose access for overload candidates that aren't selected.
+namespace PR7436 {
+struct S1 {
+  void* operator new(size_t);
+  void operator delete(void* p);
+
+private:
+  void* operator new(size_t, void*); // expected-note {{declared private here}}
+  void operator delete(void*, void*);
+};
+class S2 {
+  void* operator new(size_t); // expected-note {{declared private here}}
+  void operator delete(void* p); // expected-note {{declared private here}}
+};
+
+void test(S1* s1, S2* s2) { 
+  delete s1;
+  delete s2; // expected-error {{is a private member}}
+  (void)new S1();
+  (void)new (0L) S1(); // expected-error {{is a private member}}
+  (void)new S2(); // expected-error {{is a private member}}
+}
+}
+
+namespace rdar8018245 {
+  struct X0 {
+    static const int value = 17;
+  };
+
+  const int X0::value;
+
+  struct X1 {
+    static int value;
+  };
+
+  int X1::value;
+
+  template<typename T>
+  int *f() {
+    return new (int[T::value]); // expected-warning{{when type is in parentheses, array cannot have dynamic size}}
+  }
+
+  template int *f<X0>();
+  template int *f<X1>(); // expected-note{{in instantiation of}}
+
+}
+
+// <rdar://problem/8248780>
+namespace Instantiate {
+  template<typename T> struct X { 
+    operator T*();
+  };
+
+  void f(X<int> &xi) {
+    delete xi;
+  }
+}
+
+namespace PR7810 {
+  struct X {
+    // cv is ignored in arguments
+    static void operator delete(void *const);
+  };
+  struct Y {
+    // cv is ignored in arguments
+    static void operator delete(void *volatile);
+  };
+}
+
+// Don't crash on template delete operators
+namespace TemplateDestructors {
+  struct S {
+    virtual ~S() {}
+
+    void* operator new(const size_t size);
+    template<class T> void* operator new(const size_t, const int, T*);
+    void operator delete(void*, const size_t);
+    template<class T> void operator delete(void*, const size_t, const int, T*);
+  };
+}
+
+namespace DeleteParam {
+  struct X {
+    void operator delete(X*); // expected-error{{first parameter of 'operator delete' must have type 'void *'}}
+  };
+
+  struct Y {
+    void operator delete(void* const);
+  };
+}
diff --git a/test/SemaCXX/offsetof.cpp b/test/SemaCXX/offsetof.cpp
index 3283270..17cee62 100644
--- a/test/SemaCXX/offsetof.cpp
+++ b/test/SemaCXX/offsetof.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -Winvalid-offsetof
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -verify %s -Winvalid-offsetof
 
 struct NonPOD {
   virtual void f();
@@ -18,3 +18,51 @@
 int o = __builtin_offsetof(Derived, x); // expected-warning{{offset of on non-POD type}}
 
 const int o2 = sizeof(__builtin_offsetof(Derived, x));
+
+struct HasArray {
+  int array[17];
+};
+
+// Constant and non-constant offsetof expressions
+void test_ice(int i) {
+  int array0[__builtin_offsetof(HasArray, array[5])];
+  int array1[__builtin_offsetof(HasArray, array[i])];
+}
+
+// Bitfields
+struct has_bitfields {
+  int i : 7;
+  int j : 12; // expected-note{{bit-field is declared here}}
+};
+
+int test3 = __builtin_offsetof(struct has_bitfields, j); // expected-error{{cannot compute offset of bit-field 'j'}}
+
+// offsetof referring to members of a base class.
+struct Base1 { 
+  int x;
+};
+
+struct Base2 {
+  int y;
+};
+
+struct Derived2 : public Base1, public Base2 {
+  int z; 
+};
+
+int derived1[__builtin_offsetof(Derived2, x) == 0? 1 : -1];
+int derived2[__builtin_offsetof(Derived2, y)  == 4? 1 : -1];
+int derived3[__builtin_offsetof(Derived2, z)  == 8? 1 : -1];
+
+// offsetof referring to anonymous struct in base.
+// PR7769
+struct foo {
+    struct {
+        int x;
+    };
+};
+
+struct bar : public foo  {
+};
+
+int anonstruct[__builtin_offsetof(bar, x) == 0 ? 1 : -1];
diff --git a/test/SemaCXX/overload-call-copycon.cpp b/test/SemaCXX/overload-call-copycon.cpp
index f57484e..6720cb6 100644
--- a/test/SemaCXX/overload-call-copycon.cpp
+++ b/test/SemaCXX/overload-call-copycon.cpp
@@ -1,40 +1,44 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -Wnon-pod-varargs
-class X { };
+class X { }; // expected-note {{the implicit copy constructor}} \
+             // expected-note{{the implicit default constructor}}
 
-int& copycon(X x);
+int& copycon(X x); // expected-note{{passing argument to parameter}}
 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);
+  copycon(xv); // expected-error{{no matching constructor}}
 }
 
 class A {
 public:
-  A(A&);
+  A(A&); // expected-note{{would lose const qualifier}} \
+         // expected-note{{no known conversion}}
 };
 
-class B : public A { };
+class B : public A { }; // expected-note{{would lose const qualifier}} \
+// expected-note{{would lose volatile qualifier}} \
+// expected-note 2{{requires 0 arguments}}
 
-short& copycon2(A a);
-int& copycon2(B b);
+short& copycon2(A a); // expected-note{{passing argument to parameter}}
+int& copycon2(B b); // expected-note 2{{passing argument to parameter}}
 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}}
+  copycon2(bc); // expected-error{{no matching constructor}}
+  copycon2(bv); // expected-error{{no matching constructor}}
   short& s1 = copycon2(a);
-  float& f3 = copycon2(ac); // expected-warning {{cannot pass object of non-POD type}}
+  copycon2(ac); // expected-error{{no matching constructor}}
 }
 
-int& copycon3(A a);
+int& copycon3(A a); // expected-note{{passing argument to parameter 'a' here}}
 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}}
+  copycon3(bc); // expected-error{{no matching constructor}}
 }
 
 class C : public B { };
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
index 79c74ce..6bf6965 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -54,6 +54,7 @@
 
 void test_k() {
   int* ip1 = k("foo"); // expected-warning{{conversion from string literal to 'char *' is deprecated}}
+  int* ip2 = k(("foo")); // expected-warning{{conversion from string literal to 'char *' is deprecated}}
   double* dp1 = k(L"foo");
 }
 
@@ -218,6 +219,12 @@
   char* d8 = derived3(d);
 }
 
+void derived4(C*); // expected-note{{candidate function not viable: cannot convert from base class pointer 'A *' to derived class pointer 'C *' for 1st argument}}
+
+void test_base(A* a) {
+  derived4(a); // expected-error{{no matching function for call to 'derived4}}
+}
+
 // Test overloading of references. 
 // (FIXME: tests binding to determine candidate sets, not overload 
 //  resolution per se).
@@ -229,6 +236,12 @@
   float* ir2 = intref(5.5);
 }
 
+void derived5(C&); // expected-note{{candidate function not viable: cannot bind base class object of type 'A' to derived class reference 'C &' for 1st argument}}
+
+void test_base(A& a) {
+  derived5(a); // expected-error{{no matching function for call to 'derived5}}
+}
+
 // Test reference binding vs. standard conversions.
 int& bind_vs_conv(const double&);
 float& bind_vs_conv(int);
@@ -430,3 +443,50 @@
 
   void g() { f(""); } // expected-error{{volatile lvalue reference to type 'bool const volatile' cannot bind to a value of unrelated type 'char const [1]'}}
 }
+
+namespace PR7095 {
+  struct X { };
+
+  struct Y {
+    operator const X*();
+
+  private:
+    operator X*();
+  };
+
+  void f(const X *);
+  void g(Y y) { f(y); }
+}
+
+namespace PR7224 {
+  class A {};
+  class B : public A {};
+
+  int &foo(A *const d);
+  float &foo(const A *const d);
+
+  void bar()
+  {
+    B *const d = 0;
+    B const *const d2 = 0;
+    int &ir = foo(d);
+    float &fr = foo(d2);
+  }
+}
+
+namespace NontrivialSubsequence {
+  struct X0;
+
+  class A {
+    operator X0 *();
+  public:
+    operator const X0 *();
+  };
+ 
+  A a;
+  void foo( void const * );
+
+  void g() {
+    foo(a);
+  }
+}
diff --git a/test/SemaCXX/overloaded-builtin-operators.cpp b/test/SemaCXX/overloaded-builtin-operators.cpp
index 61c2e21..8a49671 100644
--- a/test/SemaCXX/overloaded-builtin-operators.cpp
+++ b/test/SemaCXX/overloaded-builtin-operators.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s 
+// RUN: %clang_cc1 -fsyntax-only -fshow-overloads=best -verify %s 
 struct yes;
 struct no;
 
@@ -173,7 +173,8 @@
 void test_dr425(A a) {
   // FIXME: lots of candidates here!
   (void)(1.0f * a); // expected-error{{ambiguous}} \
-                    // expected-note 81{{candidate}}
+                    // expected-note 4{{candidate}} \
+                    // expected-note {{remaining 77 candidates omitted; pass -fshow-overloads=all to show them}}
 }
 
 // pr5432
@@ -188,3 +189,14 @@
 void f() {
   (void)__extension__(A());
 }
+
+namespace PR7319 {
+  typedef enum { Enum1, Enum2, Enum3 } MyEnum;
+
+  template<typename X> bool operator>(const X &inX1, const X &inX2);
+
+  void f() {
+    MyEnum e1, e2;
+    if (e1 > e2) {}
+  }
+}
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index 3d737f4..24f7f66 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -49,6 +49,13 @@
   }
 };
 
+// we shouldn't see warnings about self-comparison,
+// this is a member function, we dunno what it'll do
+bool i(B b)
+{
+  return b == b;
+}
+
 enum Enum1 { };
 enum Enum2 { };
 
@@ -150,7 +157,7 @@
 
 void test_comma(X x, Y y) {
   bool& b1 = (x, y);
-  X& xr = (x, x);
+  X& xr = (x, x); // expected-warning {{expression result unused}}
 }
 
 struct Callable {
diff --git a/test/SemaCXX/pseudo-destructors.cpp b/test/SemaCXX/pseudo-destructors.cpp
index 472e5b4..30d9faa 100644
--- a/test/SemaCXX/pseudo-destructors.cpp
+++ b/test/SemaCXX/pseudo-destructors.cpp
@@ -14,6 +14,11 @@
   typedef int OtherInteger;
 }
 
+template <typename T>
+void cv_test(const volatile T* cvt) {
+  cvt->T::~T(); // no-warning
+}
+
 void f(A* a, Foo *f, int *i, double *d) {
   a->~A();
   a->A::~A();
@@ -41,8 +46,14 @@
   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}}
+
+  cv_test(a);
+  cv_test(f);
+  cv_test(i);
+  cv_test(d);
 }
 
+
 typedef int Integer;
 
 void destroy_without_call(int *ip) {
@@ -57,3 +68,4 @@
 void test_X0(N1::X0 &x0) {
   x0.~X0();
 }
+
diff --git a/test/SemaCXX/qualified-member-enum.cpp b/test/SemaCXX/qualified-member-enum.cpp
new file mode 100644
index 0000000..83b0a59
--- /dev/null
+++ b/test/SemaCXX/qualified-member-enum.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+// Check that this doesn't crash.
+struct A {
+  enum {LABEL};
+};
+int f() {
+  return A().A::LABEL;
+}
+
diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp
index e40ea01..a7aafe4 100644
--- a/test/SemaCXX/references.cpp
+++ b/test/SemaCXX/references.cpp
@@ -115,3 +115,18 @@
   int &c = ev.x; // expected-error{{non-const reference cannot bind to vector element}}
   const int &d = ev.x;
 }
+
+namespace PR7149 {
+  template<typename T> struct X0
+  {
+    T& first;
+    X0(T& p1) : first(p1) { }
+  };
+
+
+  void f()
+  {
+    int p1[1];
+    X0< const int[1]> c(p1);
+  }
+}
diff --git a/test/SemaCXX/reinterpret-cast.cpp b/test/SemaCXX/reinterpret-cast.cpp
index 45d41e8..f054e52 100644
--- a/test/SemaCXX/reinterpret-cast.cpp
+++ b/test/SemaCXX/reinterpret-cast.cpp
@@ -91,8 +91,20 @@
   (void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int structure::*' is not allowed}}
 }
 
+namespace PR5545 {
 // PR5545
 class A;
 class B;
 void (A::*a)();
 void (B::*b)() = reinterpret_cast<void (B::*)()>(a);
+}
+
+// <rdar://problem/8018292>
+void const_arrays() {
+  typedef char STRING[10];
+  const STRING *s;
+  const char *c;
+
+  (void)reinterpret_cast<char *>(s); // expected-error {{reinterpret_cast from 'STRING const *' (aka 'char const (*)[10]') to 'char *' casts away constness}}
+  (void)reinterpret_cast<const STRING *>(c);
+}
diff --git a/test/SemaCXX/return-noreturn.cpp b/test/SemaCXX/return-noreturn.cpp
new file mode 100644
index 0000000..dfd5487
--- /dev/null
+++ b/test/SemaCXX/return-noreturn.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -Wmissing-noreturn -Wno-unreachable-code
+
+// A destructor may be marked noreturn and should still influence the CFG.
+namespace PR6884 {
+  struct abort_struct {
+    abort_struct() {} // Make this non-POD so the destructor is invoked.
+    ~abort_struct() __attribute__((noreturn));
+  };
+
+  // FIXME: Should either of these actually warn, since the destructor is
+  //  marked noreturn?
+
+  int f() {
+    abort_struct();
+  } // expected-warning{{control reaches end of non-void function}}
+
+  int f2() {
+    abort_struct s;
+  } // expected-warning{{control reaches end of non-void function}}
+}
diff --git a/test/SemaCXX/return.cpp b/test/SemaCXX/return.cpp
index e682fdf..6bdbe52 100644
--- a/test/SemaCXX/return.cpp
+++ b/test/SemaCXX/return.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify
+// RUN: %clang_cc1 %s -fsyntax-only -Wignored-qualifiers -verify
 
 int test1() {
   throw;
@@ -16,3 +16,13 @@
 T h() {
   return 17;
 }
+
+// Don't warn on cv-qualified class return types, only scalar return types.
+namespace ignored_quals {
+struct S {};
+const S class_c();
+const volatile S class_cv();
+
+const int scalar_c(); // expected-warning{{'const' type qualifier on return type has no effect}}
+const volatile int scalar_cv(); // expected-warning{{'const volatile' type qualifiers on return type have no effect}}
+}
diff --git a/test/SemaCXX/rval-references.cpp b/test/SemaCXX/rval-references.cpp
index d5b465f..30622cc 100644
--- a/test/SemaCXX/rval-references.cpp
+++ b/test/SemaCXX/rval-references.cpp
@@ -21,6 +21,10 @@
   operator not_int &&();
 };
 
+typedef void (fun_type)();
+void fun();
+fun_type &&make_fun();
+
 void f() {
   int &&virr1; // expected-error {{declaration of reference variable 'virr1' requires an initializer}}
   int &&virr2 = 0;
@@ -47,6 +51,9 @@
   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();
 
+  fun_type &&fun_ref = fun; // works because functions are special
+  fun_type &&fun_ref2 = make_fun(); // same
+  fun_type &fun_lref = make_fun(); // also special
 
   try {
   } catch(int&&) { // expected-error {{cannot catch exceptions by rvalue reference}}
diff --git a/test/SemaCXX/scope-check.cpp b/test/SemaCXX/scope-check.cpp
new file mode 100644
index 0000000..cdc3868
--- /dev/null
+++ b/test/SemaCXX/scope-check.cpp
@@ -0,0 +1,153 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-unreachable-code
+
+namespace test0 {
+  struct D { ~D(); };
+
+  int f(bool b) {
+    if (b) {
+      D d;
+      goto end;
+    }
+
+  end:
+    return 1;
+  }
+}
+
+namespace test1 {
+  struct C { C(); };
+
+  int f(bool b) {
+    if (b)
+      goto foo; // expected-error {{illegal goto into protected scope}}
+    C c; // expected-note {{jump bypasses variable initialization}}
+  foo:
+    return 1;
+  }
+}
+
+namespace test2 {
+  struct C { C(); };
+
+  int f(void **ip) {
+    static void *ips[] = { &&lbl1, &&lbl2 };
+
+    C c;
+    goto *ip;
+  lbl1:
+    return 0;
+  lbl2:
+    return 1;
+  }
+}
+
+namespace test3 {
+  struct C { C(); };
+
+  int f(void **ip) {
+    static void *ips[] = { &&lbl1, &&lbl2 };
+
+    goto *ip;
+  lbl1: {
+    C c;
+    return 0;
+  }
+  lbl2:
+    return 1;
+  }
+}
+
+namespace test4 {
+  struct C { C(); };
+  struct D { ~D(); };
+
+  int f(void **ip) {
+    static void *ips[] = { &&lbl1, &&lbl2 };
+
+    C c0;
+
+    goto *ip; // expected-warning {{indirect goto might cross protected scopes}}
+    C c1; // expected-note {{jump bypasses variable initialization}}
+  lbl1: // expected-note {{possible target of indirect goto}}
+    return 0;
+  lbl2:
+    return 1;
+  }
+}
+
+namespace test5 {
+  struct C { C(); };
+  struct D { ~D(); };
+
+  int f(void **ip) {
+    static void *ips[] = { &&lbl1, &&lbl2 };
+    C c0;
+
+    goto *ip;
+  lbl1: // expected-note {{possible target of indirect goto}}
+    return 0;
+  lbl2:
+    if (ip[1]) {
+      D d; // expected-note {{jump exits scope of variable with non-trivial destructor}}
+      ip += 2;
+      goto *ip; // expected-warning {{indirect goto might cross protected scopes}}
+    }
+    return 1;
+  }
+}
+
+namespace test6 {
+  struct C { C(); };
+
+  unsigned f(unsigned s0, unsigned s1, void **ip) {
+    static void *ips[] = { &&lbl1, &&lbl2, &&lbl3, &&lbl4 };
+    C c0;
+
+    goto *ip;
+  lbl1:
+    s0++;
+    goto *++ip;
+  lbl2:
+    s0 -= s1;
+    goto *++ip;
+  lbl3: {
+    unsigned tmp = s0;
+    s0 = s1;
+    s1 = tmp;
+    goto *++ip;
+  }
+  lbl4:
+    return s0;
+  }
+}
+
+// C++0x says it's okay to skip non-trivial initializers on static
+// locals, and we implement that in '03 as well.
+namespace test7 {
+  struct C { C(); };
+
+  void test() {
+    goto foo;
+    static C c;
+  foo:
+    return;
+  }
+}
+
+// PR7789
+namespace test8 {
+  void test1(int c) {
+    switch (c) {
+    case 0:
+      int x = 56; // expected-note {{jump bypasses variable initialization}}
+    case 1:       // expected-error {{switch case is in protected scope}}
+      x = 10;
+    }
+  }
+
+  void test2() {
+    goto l2;     // expected-error {{goto into protected scope}}
+  l1: int x = 5; // expected-note {{jump bypasses variable initialization}}
+  l2: x++;
+  }
+}
diff --git a/test/SemaCXX/switch.cpp b/test/SemaCXX/switch.cpp
index c256960..fc13630 100644
--- a/test/SemaCXX/switch.cpp
+++ b/test/SemaCXX/switch.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wswitch-enum %s
 
 void test() {
   bool x = true;
@@ -40,3 +40,20 @@
   switch (c) { // expected-error{{incomplete class type}}
   }
 }
+
+namespace test3 {
+  enum En { A, B, C };
+  template <En how> void foo() {
+    int x = 0, y = 5;
+
+    switch (how) { //expected-warning {{no case matching constant switch condition '2'}}
+    case A: x *= y; break;
+    case B: x += y; break;
+    // No case for C, but it's okay because we have a constant condition.
+    }
+  }
+
+  template void foo<A>();
+  template void foo<B>();
+  template void foo<C>(); //expected-note {{in instantiation}}
+}
diff --git a/test/SemaCXX/typedef-redecl.cpp b/test/SemaCXX/typedef-redecl.cpp
index 2acf675..7db1970 100644
--- a/test/SemaCXX/typedef-redecl.cpp
+++ b/test/SemaCXX/typedef-redecl.cpp
@@ -37,3 +37,20 @@
   using namespace a; 
   foo x;
 }
+
+namespace PR6923 {
+  struct A;
+
+  extern "C" {
+    struct A;
+    typedef struct A A;
+  }
+
+  struct A;
+}
+
+namespace PR7462 {
+  struct A {};
+  typedef int operator! (A); // expected-error{{typedef name must be an identifier}}
+  int i = !A(); // expected-error{{invalid argument type}}
+}
diff --git a/test/SemaCXX/unreachable-code.cpp b/test/SemaCXX/unreachable-code.cpp
index 528bba7..40d0c00 100644
--- a/test/SemaCXX/unreachable-code.cpp
+++ b/test/SemaCXX/unreachable-code.cpp
@@ -39,3 +39,20 @@
     bar();     // expected-warning {{will never be executed}}
   }
 }
+
+// PR 6130 - Don't warn about bogus unreachable code with throw's and
+// temporary objects.
+class PR6130 {
+public:
+  PR6130();
+  ~PR6130();
+};
+
+int pr6130(unsigned i) {
+  switch(i) {
+    case 0: return 1;
+    case 1: return 2;
+    default:
+      throw PR6130(); // no-warning
+  }
+}
diff --git a/test/SemaCXX/using-directive.cpp b/test/SemaCXX/using-directive.cpp
index 0d5c840..162f7fa 100644
--- a/test/SemaCXX/using-directive.cpp
+++ b/test/SemaCXX/using-directive.cpp
@@ -121,3 +121,8 @@
 }
 
 void f4() { f2(1); }
+
+// PR7517
+using namespace std; // expected-warning{{using directive refers to implicitly-defined namespace 'std'}}
+using namespace ::std; // expected-warning{{using directive refers to implicitly-defined namespace 'std'}}
+
diff --git a/test/SemaCXX/vararg-non-pod.cpp b/test/SemaCXX/vararg-non-pod.cpp
index d31f1f7..55ec941 100644
--- a/test/SemaCXX/vararg-non-pod.cpp
+++ b/test/SemaCXX/vararg-non-pod.cpp
@@ -88,3 +88,13 @@
   (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
 }
+
+
+// rdar://7985267 - Shouldn't warn, doesn't actually use __builtin_va_start is
+// magic.
+
+void t6(Foo somearg, ... ) {
+  __builtin_va_list list;
+  __builtin_va_start(list, somearg);
+}
+
diff --git a/test/SemaCXX/vector-no-lax.cpp b/test/SemaCXX/vector-no-lax.cpp
new file mode 100644
index 0000000..32dcacf
--- /dev/null
+++ b/test/SemaCXX/vector-no-lax.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fno-lax-vector-conversions -verify %s
+typedef unsigned int __attribute__((vector_size (16))) vUInt32;
+typedef int __attribute__((vector_size (16))) vSInt32;
+
+vSInt32 foo (vUInt32 a) {
+  vSInt32 b = { 0, 0, 0, 0 };
+  b += a; // expected-error{{can't convert between vector values}}
+  return b;
+}
diff --git a/test/SemaCXX/vector.cpp b/test/SemaCXX/vector.cpp
new file mode 100644
index 0000000..9ae2c82
--- /dev/null
+++ b/test/SemaCXX/vector.cpp
@@ -0,0 +1,220 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s
+typedef char char16 __attribute__ ((__vector_size__ (16)));
+typedef long long longlong16 __attribute__ ((__vector_size__ (16)));
+typedef char char16_e __attribute__ ((__ext_vector_type__ (16)));
+typedef long long longlong16_e __attribute__ ((__ext_vector_type__ (2)));
+
+// Test overloading and function calls with vector types.
+void f0(char16);
+
+void f0_test(char16 c16, longlong16 ll16, char16_e c16e, longlong16_e ll16e) {
+  f0(c16);
+  f0(ll16);
+  f0(c16e);
+  f0(ll16e);
+}
+
+int &f1(char16); // expected-note 2{{candidate function}}
+float &f1(longlong16); // expected-note 2{{candidate function}}
+
+void f1_test(char16 c16, longlong16 ll16, char16_e c16e, longlong16_e ll16e) {
+  int &ir1 = f1(c16);
+  float &fr1 = f1(ll16);
+  f1(c16e); // expected-error{{call to 'f1' is ambiguous}}
+  f1(ll16e); // expected-error{{call to 'f1' is ambiguous}}
+}
+
+void f2(char16_e); // expected-note{{no known conversion from 'longlong16_e' to 'char16_e' for 1st argument}} \
+       // expected-note{{candidate function not viable: no known conversion from 'convertible_to<longlong16_e>' to 'char16_e' for 1st argument}}
+
+void f2_test(char16 c16, longlong16 ll16, char16_e c16e, longlong16_e ll16e) {
+  f2(c16);
+  f2(ll16);
+  f2(c16e);
+  f2(ll16e); // expected-error{{no matching function}}
+  f2('a');
+  f2(17);
+}
+
+// Test the conditional operator with vector types.
+void conditional(bool Cond, char16 c16, longlong16 ll16, char16_e c16e, 
+                 longlong16_e ll16e) {
+  // Conditional operators with the same type.
+  __typeof__(Cond? c16 : c16) *c16p1 = &c16;
+  __typeof__(Cond? ll16 : ll16) *ll16p1 = &ll16;
+  __typeof__(Cond? c16e : c16e) *c16ep1 = &c16e;
+  __typeof__(Cond? ll16e : ll16e) *ll16ep1 = &ll16e;
+
+  // Conditional operators with similar types.
+  __typeof__(Cond? c16 : c16e) *c16ep2 = &c16e;
+  __typeof__(Cond? c16e : c16) *c16ep3 = &c16e;
+  __typeof__(Cond? ll16 : ll16e) *ll16ep2 = &ll16e;
+  __typeof__(Cond? ll16e : ll16) *ll16ep3 = &ll16e;
+
+  // Conditional operators with compatible types under -flax-vector-conversions (default)
+  (void)(Cond? c16 : ll16);
+  (void)(Cond? ll16e : c16e);
+  (void)(Cond? ll16e : c16);
+}
+
+// Test C++ cast'ing of vector types.
+void casts(longlong16 ll16, longlong16_e ll16e) {
+  // C-style casts.
+  (void)(char16)ll16;
+  (void)(char16_e)ll16;
+  (void)(longlong16)ll16;
+  (void)(longlong16_e)ll16;
+  (void)(char16)ll16e;
+  (void)(char16_e)ll16e;
+  (void)(longlong16)ll16e;
+  (void)(longlong16_e)ll16e;
+
+  // Function-style casts.
+  (void)char16(ll16);
+  (void)char16_e(ll16);
+  (void)longlong16(ll16);
+  (void)longlong16_e(ll16);
+  (void)char16(ll16e);
+  (void)char16_e(ll16e);
+  (void)longlong16(ll16e);
+  (void)longlong16_e(ll16e);
+
+  // static_cast
+  (void)static_cast<char16>(ll16);
+  (void)static_cast<char16_e>(ll16);
+  (void)static_cast<longlong16>(ll16);
+  (void)static_cast<longlong16_e>(ll16);
+  (void)static_cast<char16>(ll16e);
+  (void)static_cast<char16_e>(ll16e); // expected-error{{static_cast from 'longlong16_e' to 'char16_e' is not allowed}}
+  (void)static_cast<longlong16>(ll16e);
+  (void)static_cast<longlong16_e>(ll16e);
+
+  // reinterpret_cast
+  (void)reinterpret_cast<char16>(ll16);
+  (void)reinterpret_cast<char16_e>(ll16);
+  (void)reinterpret_cast<longlong16>(ll16);
+  (void)reinterpret_cast<longlong16_e>(ll16);
+  (void)reinterpret_cast<char16>(ll16e);
+  (void)reinterpret_cast<char16_e>(ll16e);
+  (void)reinterpret_cast<longlong16>(ll16e);
+  (void)reinterpret_cast<longlong16_e>(ll16e);
+}
+
+template<typename T>
+struct convertible_to { // expected-note 3 {{candidate function (the implicit copy assignment operator)}}
+  operator T() const;
+};
+
+void test_implicit_conversions(bool Cond, char16 c16, longlong16 ll16, 
+                               char16_e c16e, longlong16_e ll16e,
+                               convertible_to<char16> to_c16, 
+                               convertible_to<longlong16> to_ll16, 
+                               convertible_to<char16_e> to_c16e, 
+                               convertible_to<longlong16_e> to_ll16e,
+                               convertible_to<char16&> rto_c16,
+                               convertible_to<char16_e&> rto_c16e) {
+  f0(to_c16);
+  f0(to_ll16);
+  f0(to_c16e);
+  f0(to_ll16e);
+  f2(to_c16);
+  f2(to_ll16);
+  f2(to_c16e);
+  f2(to_ll16e); // expected-error{{no matching function}}
+
+  (void)(c16 == c16e);
+  (void)(c16 == to_c16);
+  (void)+to_c16;
+  (void)-to_c16;
+  (void)~to_c16;
+  (void)(to_c16 == to_c16e);
+  (void)(to_c16 != to_c16e);
+  (void)(to_c16 <  to_c16e);
+  (void)(to_c16 <= to_c16e);
+  (void)(to_c16 >  to_c16e);
+  (void)(to_c16 >= to_c16e);
+  (void)(to_c16 + to_c16);
+  (void)(to_c16 - to_c16);
+  (void)(to_c16 * to_c16);
+  (void)(to_c16 / to_c16);
+  (void)(rto_c16 = to_c16); // expected-error{{no viable overloaded '='}}
+  (void)(rto_c16 += to_c16);
+  (void)(rto_c16 -= to_c16);
+  (void)(rto_c16 *= to_c16);
+  (void)(rto_c16 /= to_c16);
+
+  (void)+to_c16e;
+  (void)-to_c16e;
+  (void)~to_c16e;
+  (void)(to_c16e == to_c16e);
+  (void)(to_c16e != to_c16e);
+  (void)(to_c16e <  to_c16e);
+  (void)(to_c16e <= to_c16e);
+  (void)(to_c16e >  to_c16e);
+  (void)(to_c16e >= to_c16e);
+  (void)(to_c16e + to_c16);
+  (void)(to_c16e - to_c16);
+  (void)(to_c16e * to_c16);
+  (void)(to_c16e / to_c16);
+  (void)(rto_c16e = to_c16); // expected-error{{no viable overloaded '='}}
+  (void)(rto_c16e += to_c16);
+  (void)(rto_c16e -= to_c16);
+  (void)(rto_c16e *= to_c16);
+  (void)(rto_c16e /= to_c16);
+
+  (void)+to_c16;
+  (void)-to_c16;
+  (void)~to_c16;
+  (void)(to_c16 == to_c16e);
+  (void)(to_c16 != to_c16e);
+  (void)(to_c16 <  to_c16e);
+  (void)(to_c16 <= to_c16e);
+  (void)(to_c16 >  to_c16e);
+  (void)(to_c16 >= to_c16e);
+  (void)(to_c16 + to_c16e);
+  (void)(to_c16 - to_c16e);
+  (void)(to_c16 * to_c16e);
+  (void)(to_c16 / to_c16e);
+  (void)(rto_c16 = c16e); // expected-error{{no viable overloaded '='}}
+  (void)(rto_c16 += to_c16e); // expected-error{{expression is not assignable}}
+  (void)(rto_c16 -= to_c16e); // expected-error{{expression is not assignable}}
+  (void)(rto_c16 *= to_c16e); // expected-error{{expression is not assignable}}
+  (void)(rto_c16 /= to_c16e); // expected-error{{expression is not assignable}}
+
+  (void)(Cond? to_c16 : to_c16e);
+  (void)(Cond? to_ll16e : to_ll16);
+  
+  // These 2 are convertable with -flax-vector-conversions (default)
+  (void)(Cond? to_c16 : to_ll16);
+  (void)(Cond? to_c16e : to_ll16e);
+}
+
+typedef float fltx2 __attribute__((__vector_size__(8)));
+typedef float fltx4 __attribute__((__vector_size__(16)));
+typedef double dblx2 __attribute__((__vector_size__(16)));
+typedef double dblx4 __attribute__((__vector_size__(32)));
+
+void accept_fltx2(fltx2); // expected-note{{candidate function not viable: no known conversion from 'double' to 'fltx2' for 1st argument}}
+void accept_fltx4(fltx4);
+void accept_dblx2(dblx2);
+void accept_dblx4(dblx4);
+void accept_bool(bool); // expected-note{{candidate function not viable: no known conversion from 'fltx2' to 'bool' for 1st argument}}
+
+void test(fltx2 fltx2_val, fltx4 fltx4_val, dblx2 dblx2_val, dblx4 dblx4_val) {
+  // Exact matches
+  accept_fltx2(fltx2_val);
+  accept_fltx4(fltx4_val);
+  accept_dblx2(dblx2_val);
+  accept_dblx4(dblx4_val);
+
+  // Same-size conversions
+  // FIXME: G++ rejects these conversions, we accept them. Revisit this!
+  accept_fltx4(dblx2_val);
+  accept_dblx2(fltx4_val);
+
+  // Conversion to bool.
+  accept_bool(fltx2_val); // expected-error{{no matching function for call to 'accept_bool'}}
+
+  // Scalar-to-vector conversions.
+  accept_fltx2(1.0); // expected-error{{no matching function for call to 'accept_fltx2'}}
+}
diff --git a/test/SemaCXX/virtual-base-used.cpp b/test/SemaCXX/virtual-base-used.cpp
new file mode 100644
index 0000000..d147b13
--- /dev/null
+++ b/test/SemaCXX/virtual-base-used.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR7800
+
+class NoDestroy { ~NoDestroy(); }; // expected-note 3 {{declared private here}}
+struct A {
+  virtual ~A();
+};
+
+struct B : public virtual A {
+  NoDestroy x; // expected-error {{field of type 'NoDestroy' has private destructor}}
+};
+struct D : public virtual B {
+  virtual void foo();
+  ~D();
+};
+void D::foo() { // expected-note {{implicit default destructor for 'B' first required here}}
+}
+
+struct E : public virtual A {
+  NoDestroy x; // expected-error {{field of type 'NoDestroy' has private destructor}}
+};
+struct F : public E { // expected-note {{implicit default destructor for 'E' first required here}}
+};
+struct G : public virtual F {
+  virtual void foo();
+  ~G();
+};
+void G::foo() { // expected-note {{implicit default destructor for 'F' first required here}}
+}
+
+struct H : public virtual A {
+  NoDestroy x; // expected-error {{field of type 'NoDestroy' has private destructor}}
+};
+struct I : public virtual H {
+  ~I();
+};
+struct J : public I {
+  virtual void foo();
+  ~J();
+};
+void J::foo() { // expected-note {{implicit default destructor for 'H' first required here}}
+}
diff --git a/test/SemaCXX/virtual-member-functions-key-function.cpp b/test/SemaCXX/virtual-member-functions-key-function.cpp
index 97164d9..09a30b9 100644
--- a/test/SemaCXX/virtual-member-functions-key-function.cpp
+++ b/test/SemaCXX/virtual-member-functions-key-function.cpp
@@ -4,17 +4,17 @@
 };
 
 struct B : A {  // expected-error {{no suitable member 'operator delete' in 'B'}}
-  B() { }
+  B() { } // expected-note {{implicit default destructor for 'B' first required here}}
   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;
+  (void)new B; 
+  (void)new C; // expected-note {{implicit default destructor for 'C' first required here}}
 }
 
 // Make sure that the key-function computation is consistent when the
diff --git a/test/SemaCXX/warn-cast-align.cpp b/test/SemaCXX/warn-cast-align.cpp
new file mode 100644
index 0000000..68acbdd
--- /dev/null
+++ b/test/SemaCXX/warn-cast-align.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -Wcast-align -verify %s
+
+// Simple casts.
+void test0(char *P) {
+  char *a; short *b; int *c;
+
+  a = (char*) P;
+  a = static_cast<char*>(P);
+  a = reinterpret_cast<char*>(P);
+  typedef char *CharPtr;
+  a = CharPtr(P);
+
+  b = (short*) P; // expected-warning {{cast from 'char *' to 'short *' increases required alignment from 1 to 2}}
+  b = reinterpret_cast<short*>(P);
+  typedef short *ShortPtr;
+  b = ShortPtr(P); // expected-warning {{cast from 'char *' to 'ShortPtr' (aka 'short *') increases required alignment from 1 to 2}}
+
+  c = (int*) P; // expected-warning {{cast from 'char *' to 'int *' increases required alignment from 1 to 4}}
+  c = reinterpret_cast<int*>(P);
+  typedef int *IntPtr;
+  c = IntPtr(P); // expected-warning {{cast from 'char *' to 'IntPtr' (aka 'int *') increases required alignment from 1 to 4}}
+}
+
+// Casts from void* are a special case.
+void test1(void *P) {
+  char *a; short *b; int *c;
+
+  a = (char*) P;
+  a = static_cast<char*>(P);
+  a = reinterpret_cast<char*>(P);
+  typedef char *CharPtr;
+  a = CharPtr(P);
+
+  b = (short*) P;
+  b = static_cast<short*>(P);
+  b = reinterpret_cast<short*>(P);
+  typedef short *ShortPtr;
+  b = ShortPtr(P);
+
+  c = (int*) P;
+  c = static_cast<int*>(P);
+  c = reinterpret_cast<int*>(P);
+  typedef int *IntPtr;
+  c = IntPtr(P);
+}
diff --git a/test/SemaCXX/warn-for-var-in-else.cpp b/test/SemaCXX/warn-for-var-in-else.cpp
deleted file mode 100644
index 1307c43..0000000
--- a/test/SemaCXX/warn-for-var-in-else.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-// 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-global-constructors.cpp b/test/SemaCXX/warn-global-constructors.cpp
new file mode 100644
index 0000000..a9347ea
--- /dev/null
+++ b/test/SemaCXX/warn-global-constructors.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -fsyntax-only -Wglobal-constructors %s -verify
+
+int opaque_int();
+
+namespace test0 {
+  // These should never require global constructors.
+  int a;
+  int b = 20;
+  float c = 5.0f;
+
+  // This global constructor is avoidable based on initialization order.
+  int d = b; // expected-warning {{global constructor}}
+
+  // These global constructors are unavoidable.
+  int e = opaque_int(); // expected-warning {{global constructor}}
+  int f = b; // expected-warning {{global constructor}}
+}
+
+namespace test1 {
+  struct A { int x; };
+  A a;
+  A b = A();
+  A c = { 10 };
+  A d = { opaque_int() }; // expected-warning {{global constructor}}
+  A e = A(A());
+  A f = A(a); // expected-warning {{global constructor}}
+  A g(a); // expected-warning {{global constructor}}
+  A h((A())); // expected-warning {{global constructor}}
+  A i((A(A()))); // expected-warning {{global constructor}}
+}
+
+namespace test2 {
+  struct A { A(); };
+  A a; // expected-warning {{global constructor}}
+  A b[10]; // expected-warning {{global constructor}}
+  A c[10][10]; // expected-warning {{global constructor}}
+
+  A &d = a;
+  A &e = b[5];
+  A &f = c[5][7];
+}
+
+namespace test3 {
+  struct A { ~A(); };
+  A a; // expected-warning {{global destructor}}
+  A b[10]; // expected-warning {{global destructor}}
+  A c[10][10]; // expected-warning {{global destructor}}
+
+  A &d = a;
+  A &e = b[5];
+  A &f = c[5][7];
+}
+
+namespace test4 {
+  char a[] = "hello";
+  char b[5] = "hello";
+  char c[][5] = { "hello" };
+}
diff --git a/test/SemaCXX/warn-missing-noreturn.cpp b/test/SemaCXX/warn-missing-noreturn.cpp
index 5ca2eca..f2f9b2e 100644
--- a/test/SemaCXX/warn-missing-noreturn.cpp
+++ b/test/SemaCXX/warn-missing-noreturn.cpp
@@ -27,3 +27,26 @@
 struct X {
   virtual void g() { f(); }
 };
+
+namespace test1 {
+  bool condition();
+
+  // We don't want a warning here.
+  void foo() {
+    while (condition()) {}
+  }
+}
+
+
+// <rdar://problem/7880658> - This test case previously had a false "missing return"
+// warning.
+struct R7880658 {
+  R7880658 &operator++();
+  bool operator==(const R7880658 &) const;
+  bool operator!=(const R7880658 &) const;
+};
+
+void f_R7880658(R7880658 f, R7880658 l) {  // no-warning
+  for (; f != l; ++f) {
+  }
+}
diff --git a/test/SemaCXX/warn-reorder-ctor-initialization.cpp b/test/SemaCXX/warn-reorder-ctor-initialization.cpp
index 3ff01af..8c254e5 100644
--- a/test/SemaCXX/warn-reorder-ctor-initialization.cpp
+++ b/test/SemaCXX/warn-reorder-ctor-initialization.cpp
@@ -120,3 +120,13 @@
     };
   };
 }
+
+namespace PR7179 {
+  struct X
+  {
+    struct Y
+    {
+      template <class T> Y(T x) : X(x) { }
+    };
+  };
+}
diff --git a/test/SemaCXX/warn-self-comparisons.cpp b/test/SemaCXX/warn-self-comparisons.cpp
new file mode 100644
index 0000000..620be19
--- /dev/null
+++ b/test/SemaCXX/warn-self-comparisons.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f(int (&array1)[2], int (&array2)[2]) {
+  if (array1 == array2) { } // no warning
+}
diff --git a/test/SemaCXX/warn-unreachable.cpp b/test/SemaCXX/warn-unreachable.cpp
index 01b36de..827dc48 100644
--- a/test/SemaCXX/warn-unreachable.cpp
+++ b/test/SemaCXX/warn-unreachable.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code -Wno-unused-value
+// RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks -Wunreachable-code -Wno-unused-value
 
-int &halt() __attribute__((noreturn));
+int &halt() __attribute__((noreturn)); // expected-warning{{functions declared 'noreturn' should have a 'void' result type}}
 int &live();
 int dead();
 int liveti() throw(int);
@@ -60,7 +60,7 @@
   struct S {
     int mem;
   } s;
-  S &foor() __attribute__((noreturn));
+  S &foor() __attribute__((noreturn)); // expected-warning{{functions declared 'noreturn' should have a 'void' result type}}
   foor()
     .mem;       // expected-warning {{will never be executed}}
 }
diff --git a/test/SemaCXX/warn-unused-filescoped.cpp b/test/SemaCXX/warn-unused-filescoped.cpp
new file mode 100644
index 0000000..75fc6a4
--- /dev/null
+++ b/test/SemaCXX/warn-unused-filescoped.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wunused -Wunused-member-function %s
+
+static void f1(); // expected-warning{{unused}}
+
+namespace {
+  void f2();  // expected-warning{{unused}}
+
+  void f3() { }  // expected-warning{{unused}}
+
+  struct S {
+    void m1() { }  // expected-warning{{unused}}
+    void m2();  // expected-warning{{unused}}
+    void m3();
+    S(const S&);
+    void operator=(const S&);
+  };
+
+  template <typename T>
+  struct TS {
+    void m();
+  };
+  template <> void TS<int>::m() { }  // expected-warning{{unused}}
+
+  template <typename T>
+  void tf() { }
+  template <> void tf<int>() { }  // expected-warning{{unused}}
+  
+  struct VS {
+    virtual void vm() { }
+  };
+  
+  struct SVS : public VS {
+    void vm() { }
+  };
+}
+
+void S::m3() { }  // expected-warning{{unused}}
+
+static inline void f4() { }
+const unsigned int cx = 0;
+
+static int x1;  // expected-warning{{unused}}
+
+namespace {
+  int x2;  // expected-warning{{unused}}
+  
+  struct S2 {
+    static int x;  // expected-warning{{unused}}
+  };
+
+  template <typename T>
+  struct TS2 {
+    static int x;
+  };
+  template <> int TS2<int>::x;  // expected-warning{{unused}}
+}
diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp
index 3b5349a..6992cdc 100644
--- a/test/SemaCXX/warn-unused-variables.cpp
+++ b/test/SemaCXX/warn-unused-variables.cpp
@@ -26,7 +26,7 @@
   };
 
   void test() {
-    A(); // expected-warning{{expression result unused}}
+    A();
     B(17);
     C();
   }
@@ -51,3 +51,11 @@
   X0<int> i(p);
   (void)i;
 }
+
+namespace PR6948 {
+  template<typename T> class X;
+  
+  void f() {
+    X<char> str (read_from_file()); // expected-error{{use of undeclared identifier 'read_from_file'}}
+  }
+}
diff --git a/test/SemaCXX/warn-weak-vtables.cpp b/test/SemaCXX/warn-weak-vtables.cpp
index 39333c1..c0cfd74 100644
--- a/test/SemaCXX/warn-weak-vtables.cpp
+++ b/test/SemaCXX/warn-weak-vtables.cpp
@@ -18,4 +18,14 @@
   struct A {
     virtual void f() { }
   };
+
+  A *a;
+  a->f();
+}
+
+// Use the vtables
+void uses(A &a, B<int> &b, C &c) {
+  a.f();
+  b.f();
+  c.f();
 }
diff --git a/test/SemaCXX/warn_false_to_pointer.cpp b/test/SemaCXX/warn_false_to_pointer.cpp
new file mode 100644
index 0000000..3a873d8
--- /dev/null
+++ b/test/SemaCXX/warn_false_to_pointer.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int* j = false; // expected-warning{{ initialization of pointer of type 'int *' from literal 'false'}}
+
+void foo(int* i, int *j=(false)) // expected-warning{{ initialization of pointer of type 'int *' from literal 'false'}}
+{
+  foo(false); // expected-warning{{ initialization of pointer of type 'int *' from literal 'false'}}
+}
+
diff --git a/test/SemaCXX/wchar_t.cpp b/test/SemaCXX/wchar_t.cpp
index 789dbf6..f9d7b61 100644
--- a/test/SemaCXX/wchar_t.cpp
+++ b/test/SemaCXX/wchar_t.cpp
@@ -25,3 +25,8 @@
   basic_string<wchar_t>() + L'-';
   return (0);
 }
+
+
+// rdar://8040728
+wchar_t in[] = L"\x434" "\x434";  // No warning
+
diff --git a/test/SemaObjC/block-attr.m b/test/SemaObjC/block-attr.m
index c89aed4..de203e7 100644
--- a/test/SemaObjC/block-attr.m
+++ b/test/SemaObjC/block-attr.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -fobjc-gc-only %s
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -fblocks -fobjc-gc-only %s
 
 @interface Thing  {}
 
diff --git a/test/SemaObjC/block-type-safety.m b/test/SemaObjC/block-type-safety.m
index 402a658..c13e806 100644
--- a/test/SemaObjC/block-type-safety.m
+++ b/test/SemaObjC/block-type-safety.m
@@ -104,3 +104,20 @@
   f4(^(NSArray<P2>* a) { });  // expected-error {{incompatible block pointer types passing 'void (^)(NSArray<P2> *)' to parameter of type 'void (^)(id<P>)'}}
 }
 
+// rdar : //8302845
+@protocol Foo @end
+
+@interface Baz @end
+
+@interface Baz(FooConformance) <Foo>
+@end
+
+@implementation Baz @end
+
+int test4 () {
+    id <Foo> (^b)() = ^{ // Doesn't work
+        return (Baz *)0;
+    };
+    return 0;
+}
+
diff --git a/test/SemaObjC/catch-stmt.m b/test/SemaObjC/catch-stmt.m
index 80c986f..ef1da37 100644
--- a/test/SemaObjC/catch-stmt.m
+++ b/test/SemaObjC/catch-stmt.m
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -verify %s
-
+@interface A @end
 @protocol P;
 
 void f() {
@@ -8,6 +8,6 @@
   } @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}}
-  }
+  } @catch(A* a) { }
 }
 
diff --git a/test/SemaObjC/compare-qualified-class.m b/test/SemaObjC/compare-qualified-class.m
new file mode 100644
index 0000000..cb2b26a
--- /dev/null
+++ b/test/SemaObjC/compare-qualified-class.m
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar:// 8191774
+
+@protocol SomeProtocol
+@end
+
+@protocol SomeProtocol1
+@end
+
+@interface SomeObject <SomeProtocol>
+@end
+
+int main () {
+    Class <SomeProtocol> classA;
+    Class <SomeProtocol> classB;
+    Class <SomeProtocol, SomeProtocol1> classC;
+    Class <SomeProtocol1> classD;
+    void * pv = 0;
+    Class c = (Class)0;;
+    if (pv)
+      return classA == pv;
+
+    if (c)
+      return classA == c;
+    
+    return classA == classB  || classA == classC ||
+           classC == classA ||
+           classA == classD; // expected-warning {{comparison of distinct pointer types ('Class<SomeProtocol> *' and 'Class<SomeProtocol1> *')}}
+}
+
diff --git a/test/SemaObjC/compound-init.m b/test/SemaObjC/compound-init.m
new file mode 100644
index 0000000..7b288bb
--- /dev/null
+++ b/test/SemaObjC/compound-init.m
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+@interface A
+@end
+
+void f() {
+  (A){ 0 }; // expected-error{{cannot initialize Objective-C class type 'A'}}
+}
diff --git a/test/SemaObjC/comptypes-5.m b/test/SemaObjC/comptypes-5.m
index aaf6446..46300e3 100644
--- a/test/SemaObjC/comptypes-5.m
+++ b/test/SemaObjC/comptypes-5.m
@@ -26,8 +26,8 @@
   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_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 */
 
diff --git a/test/SemaObjC/conflict-nonfragile-abi2.m b/test/SemaObjC/conflict-nonfragile-abi2.m
new file mode 100644
index 0000000..e4b513f
--- /dev/null
+++ b/test/SemaObjC/conflict-nonfragile-abi2.m
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -verify -fsyntax-only %s
+// rdar : // 8225011
+
+int glob; // expected-note {{global variable declared here}}
+
+@interface I
+@property int glob; // expected-note {{property declared here}}
+@property int p;
+@property int le;
+@property int l;
+@property int ls;
+@property int r;
+@end
+
+@implementation I
+- (int) Meth { return glob; } // expected-warning {{when default property synthesis is on, 'glob' lookup will access}}
+@synthesize glob;
+// rdar: // 8248681
+- (int) Meth1: (int) p {
+  extern int le;
+  int l = 1;
+  static int ls;
+  register int r;
+  p = le + ls + r;
+  return l;
+}
+@dynamic p;
+@dynamic le;
+@dynamic l;
+@dynamic ls;
+@dynamic r;
+@end
+
+
diff --git a/test/SemaObjC/default-synthesize-1.m b/test/SemaObjC/default-synthesize-1.m
new file mode 100644
index 0000000..374fa83
--- /dev/null
+++ b/test/SemaObjC/default-synthesize-1.m
@@ -0,0 +1,116 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+
+@interface NSObject 
+- (void) release;
+- (id) retain;
+@end
+@class NSString;
+
+@interface SynthItAll : NSObject
+@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 howMany;
+}
+// - (void) setHowMany: (int) value
+
+- (NSString*) what {
+    return 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 {
+    howMany = value;
+}
+
+// - (NSString*) what
+- (void) setWhat: (NSString*) value {
+    if (what != value) {
+        [what release];
+        what = [value retain];
+    }
+}
+@end
+
+
+@interface SynthNone : NSObject
+@property int howMany;
+@property (retain) NSString* what;
+@end
+
+@implementation SynthNone
+//@synthesize howMany, what;  // REM: Redundant anyway
+
+- (int) howMany {
+    return howMany;
+}
+- (void) setHowMany: (int) value {
+    howMany = value;
+}
+
+- (NSString*) what {
+    return what;
+}
+- (void) setWhat: (NSString*) value {
+    if (what != value) {
+        [what release];
+        what = [value retain];
+    }
+}
+@end
+
+// rdar://8349319
+// No default synthesis if implementation has getter (readonly) and setter(readwrite) methods.
+@interface DSATextSearchResult 
+@property(assign,readonly) float relevance;
+@property(assign,readonly) char isTitleMatch;
+@end
+
+@interface DSANodeSearchResult : DSATextSearchResult {}
+@end
+
+
+@implementation DSATextSearchResult 
+-(char)isTitleMatch {
+    return (char)0;
+}
+
+-(float)relevance {
+    return 0.0;
+}
+@end
+
+@implementation DSANodeSearchResult
+-(id)initWithNode:(id )node relevance:(float)relevance isTitleMatch:(char)isTitleMatch {
+        relevance = 0.0;        
+        isTitleMatch = 'a';
+	return self;
+}
+@end
+
diff --git a/test/SemaObjC/default-synthesize.m b/test/SemaObjC/default-synthesize.m
index b892dfa..0586dae 100644
--- a/test/SemaObjC/default-synthesize.m
+++ b/test/SemaObjC/default-synthesize.m
@@ -85,11 +85,33 @@
 
 @interface TopClass <TopProtocol> 
 {
-  id myString; // expected-note {{previously declared 'myString' here}}
+  id myString; 
 }
 @end
 
 @interface SubClass : TopClass <TopProtocol> 
 @end
 
-@implementation SubClass @end // expected-error {{property 'myString' attempting to use ivar 'myString' declared in super class 'TopClass'}}
+@implementation SubClass @end 
+
+// rdar: // 7920807
+@interface C @end
+@interface C (Category)
+@property int p; // expected-warning {{property 'p' requires method 'p' to be defined }} \
+                 // expected-warning {{property 'p' requires method 'setP:' to be defined}}
+@end
+@implementation C (Category) // expected-note 2 {{implementation is here}}
+@end
+
+// Don't complain if a property is already @synthesized by usr.
+@interface D
+{
+}
+@property int PROP;
+@end
+
+@implementation D
+- (int) Meth { return self.PROP; }
+@synthesize PROP=IVAR;
+@end
+
diff --git a/test/SemaObjC/deref-interface.m b/test/SemaObjC/deref-interface.m
index c7096bd..255e1d0 100644
--- a/test/SemaObjC/deref-interface.m
+++ b/test/SemaObjC/deref-interface.m
@@ -6,7 +6,7 @@
 
 @implementation NSView
  - (id)initWithView:(id)realView {
-     *(NSView *)self = *(NSView *)realView;	// expected-error {{indirection cannot be to an interface in non-fragile ABI}}
+     *(NSView *)self = *(NSView *)realView;	// expected-error {{cannot assign to class object in non-fragile ABI}}
  }
 @end
 
diff --git a/test/SemaObjC/duplicate-property-class-extension.m b/test/SemaObjC/duplicate-property-class-extension.m
index bdf4786..a84f83f 100644
--- a/test/SemaObjC/duplicate-property-class-extension.m
+++ b/test/SemaObjC/duplicate-property-class-extension.m
@@ -1,13 +1,21 @@
 // RUN: %clang_cc1  -fsyntax-only -verify %s
 
 @interface Foo 
-@property (readonly) char foo;
+@property (readonly) char foo; // expected-note {{property declared here}}
 @end
 
 @interface Foo ()
-@property (readwrite) char foo; // expected-note {{property declared here}}
+@property (readwrite) char foo; // OK 
+@property (readwrite) char NewProperty; // expected-note 2 {{property declared here}} 
 @end
 
 @interface Foo ()
-@property (readwrite) char foo;	// expected-error {{property has a previous declaration}}
+@property (readwrite) char foo;	//  OK again, make primary property readwrite for 2nd time!
+@property (readwrite) char NewProperty; // expected-error {{illegal declaration of property in continuation class 'Foo': attribute must be readwrite, while its primary must be readonly}}
 @end
+
+@interface Foo ()
+@property (readonly) char foo;	// expected-error {{illegal declaration of property in continuation class 'Foo': attribute must be readwrite, while its primary must be readonly}}
+@property (readwrite) char NewProperty; // expected-error {{illegal declaration of property in continuation class 'Foo': attribute must be readwrite, while its primary must be readonly}}
+@end
+
diff --git a/test/SemaObjC/error-property-gc-attr.m b/test/SemaObjC/error-property-gc-attr.m
index a361704..661638c 100644
--- a/test/SemaObjC/error-property-gc-attr.m
+++ b/test/SemaObjC/error-property-gc-attr.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-gc -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x objective-c++ -triple i386-apple-darwin9 -fobjc-gc -fsyntax-only -verify %s
 
 @interface INTF
 {
@@ -11,7 +12,7 @@
 }
 @property (assign) __weak id pweak;
 @property (assign) __weak id WID;
-@property (assign) __strong id not;
+@property (assign) __strong id NOT;
 @property (assign)  id ID;
 @property (assign) INTF* AWEAK;
 @property (assign) __weak INTF* WI;
@@ -19,7 +20,7 @@
 
 @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 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}}
diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m
index 1fcc34f..d89f50a 100644
--- a/test/SemaObjC/format-strings-objc.m
+++ b/test/SemaObjC/format-strings-objc.m
@@ -55,3 +55,11 @@
 void rdar_7697748() {
   NSLog(@"%@!"); // expected-warning{{more '%' conversions than data arguments}}
 }
+
+@protocol Foo;
+
+void test_p_conversion_with_objc_pointer(id x, id<Foo> y) {
+  printf("%p", x); // no-warning
+  printf("%p", y); // no-warning
+}
+
diff --git a/test/SemaObjC/iboutletcollection-attr.m b/test/SemaObjC/iboutletcollection-attr.m
new file mode 100644
index 0000000..fb64e3a
--- /dev/null
+++ b/test/SemaObjC/iboutletcollection-attr.m
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify %s
+// rdar: // 8308053
+
+@interface I {
+    __attribute__((iboutletcollection(I))) id ivar1;
+    __attribute__((iboutletcollection(id))) id ivar2;
+    __attribute__((iboutletcollection())) id ivar3;
+    __attribute__((iboutletcollection)) id ivar4;
+}
+@property (nonatomic, retain) __attribute__((iboutletcollection(I))) id prop1;
+@property (nonatomic, retain) __attribute__((iboutletcollection(id))) id prop2;
+@property (nonatomic, retain) __attribute__((iboutletcollection())) id prop3;
+@property (nonatomic, retain) __attribute__((iboutletcollection)) id prop4;
+@end
+
+typedef void *PV;
+@interface BAD {
+    __attribute__((iboutletcollection(I, 1))) id ivar1; // expected-error {{attribute requires 1 argument(s)}}
+    __attribute__((iboutletcollection(B))) id ivar2; // expected-error {{invalid type 'B' as argument of iboutletcollection attribute}}
+    __attribute__((iboutletcollection(PV))) id ivar3; // expected-error {{invalid type 'PV' as argument of iboutletcollection attribute}}
+    __attribute__((iboutletcollection(PV))) void *ivar4; // expected-error {{ivar with iboutletcollection attribute must have object type (invalid 'void *')}}
+    __attribute__((iboutletcollection(int))) id ivar5; // expected-error {{type argument of iboutletcollection attribute cannot be a builtin type}}
+}
+@property (nonatomic, retain) __attribute__((iboutletcollection(I,2,3))) id prop1; // expected-error {{attribute requires 1 argument(s)}}
+@property (nonatomic, retain) __attribute__((iboutletcollection(B))) id prop2; // expected-error {{invalid type 'B' as argument of iboutletcollection attribute}}
+
+@property __attribute__((iboutletcollection(BAD))) int prop3; // expected-error {{property with iboutletcollection attribute must have object type (invalid 'int')}}
+@end
+
diff --git a/test/SemaObjC/method-conflict.m b/test/SemaObjC/method-conflict.m
index 08fdfc0..5dc886f 100644
--- a/test/SemaObjC/method-conflict.m
+++ b/test/SemaObjC/method-conflict.m
@@ -53,3 +53,14 @@
   return 0;
 }
 @end 
+
+// rdar: // 8006060
+@interface Bar
+- (void)foo:(id)format, ...;  // expected-note {{previous declaration is here}}
+- (void)foo1:(id)format;      // expected-note {{previous declaration is here}}
+@end
+@implementation Bar
+- (void)foo:(id)format {}; // expected-warning {{conflicting variadic declaration of method and its implementation}}
+- (void)foo1:(id)format, ... {}; // expected-warning {{conflicting variadic declaration of method and its implementation}}
+@end
+
diff --git a/test/SemaObjC/method-lookup-3.m b/test/SemaObjC/method-lookup-3.m
index 18a9982..882b3d1 100644
--- a/test/SemaObjC/method-lookup-3.m
+++ b/test/SemaObjC/method-lookup-3.m
@@ -50,3 +50,8 @@
 void f5(id a0, Abstract *a1) { 
   [ a0 setZ: a1];
 }
+
+// pr7861
+void f6(id<A> a0) {
+  Abstract *l = [a0 x];
+}
diff --git a/test/SemaObjC/method-sentinel-attr.m b/test/SemaObjC/method-sentinel-attr.m
index 08358cc..6ec362f 100644
--- a/test/SemaObjC/method-sentinel-attr.m
+++ b/test/SemaObjC/method-sentinel-attr.m
@@ -15,6 +15,12 @@
 - (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}}
+
+// rdar:// 7975788
+- (id) foo13 : (id)firstObj, ... __attribute__((sentinel(0,1)));
+- (id) foo14 : (id)firstObj :  (Class)secondObj, ... __attribute__((sentinel(0,1)));
+- (id) foo15 : (id*)firstObj, ... __attribute__((sentinel(0,1)));
+- (id) foo16 : (id**)firstObj, ... __attribute__((sentinel(0,1)));
 @end
 
 int main ()
@@ -33,5 +39,11 @@
   [p foo7:1, NULL]; // ok
 
   [p foo12:1]; // expected-warning {{not enough variable arguments in 'foo12:' declaration to fit a sentinel}}
+
+  // rdar:// 7975788
+  [ p foo13 : NULL]; 
+  [ p foo14 : 0 : NULL]; 
+  [ p foo16 : NULL]; 
+  [ p foo15 : NULL];
 }
  
diff --git a/test/SemaObjC/nonnull.m b/test/SemaObjC/nonnull.m
index 642f50f..15fee74 100644
--- a/test/SemaObjC/nonnull.m
+++ b/test/SemaObjC/nonnull.m
@@ -43,3 +43,5 @@
   func6((NSObject*) 0); // no-warning
   func7((NSObject*) 0); // no-warning
 }
+
+void func5(int) __attribute__((nonnull)); // expected-warning{{'nonnull' attribute applied to function with no pointer arguments}}
diff --git a/test/SemaObjC/objc2-warn-weak-decl.m b/test/SemaObjC/objc2-warn-weak-decl.m
index 76b542d..22a3fca 100644
--- a/test/SemaObjC/objc2-warn-weak-decl.m
+++ b/test/SemaObjC/objc2-warn-weak-decl.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -fobjc-gc -verify %s
+// RUN: %clang_cc1 -x objective-c++ -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}}
 };
diff --git a/test/SemaObjC/property-10.m b/test/SemaObjC/property-10.m
index bd07df6..0119273 100644
--- a/test/SemaObjC/property-10.m
+++ b/test/SemaObjC/property-10.m
@@ -20,3 +20,9 @@
 @property(nonatomic,copy) int (*includeMailboxCondition2)(); // expected-error {{property with 'copy' attribute must be of object type}}
 
 @end
+
+@interface I0()
+@property (retain) int PROP;	// expected-error {{property with 'retain' attribute must be of object type}}
+@property(nonatomic,copy) int (*PROP1)(); // expected-error {{property with 'copy' attribute must be of object type}}
+@end
+
diff --git a/test/SemaObjC/property-and-ivar-use.m b/test/SemaObjC/property-and-ivar-use.m
new file mode 100644
index 0000000..b9235c1
--- /dev/null
+++ b/test/SemaObjC/property-and-ivar-use.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+// Do not issue error if 'ivar' used previously belongs to the inherited class
+// and has same name as @dynalic property in current class.
+
+typedef signed char BOOL;
+
+@protocol IDEBuildable
+@property (readonly) BOOL hasRecursiveDependencyCycle;
+@end
+
+@protocol IDEBuildableProduct <IDEBuildable>
+@end
+
+@interface IDEBuildableSupportMixIn 
+@property (readonly) BOOL hasRecursiveDependencyCycle;
+@end
+
+@interface Xcode3TargetBuildable <IDEBuildable>
+{
+  IDEBuildableSupportMixIn *_buildableMixIn;
+}
+@end
+
+@interface Xcode3TargetProduct : Xcode3TargetBuildable <IDEBuildableProduct>
+@end
+
+@implementation Xcode3TargetBuildable
+- (BOOL)hasRecursiveDependencyCycle
+{
+    return [_buildableMixIn hasRecursiveDependencyCycle];
+}
+@end
+
+@implementation Xcode3TargetProduct
+@dynamic hasRecursiveDependencyCycle;
+@end
diff --git a/test/SemaObjC/property-not-lvalue.m b/test/SemaObjC/property-not-lvalue.m
index 55eec3e..3d95d26 100644
--- a/test/SemaObjC/property-not-lvalue.m
+++ b/test/SemaObjC/property-not-lvalue.m
@@ -15,8 +15,8 @@
 
 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}}
+        f.size.width = 2.2; // expected-error {{expression is not assignable}}
+	f.size.inner.dim = 200; // expected-error {{expression is not assignable}}
 }
 
 // radar 7628953
@@ -28,7 +28,7 @@
 
 @implementation Gorf
 - (void)MyView_sharedInit {
-    self.size.width = 2.2; // expected-error {{expression is not assignable using property assignment syntax}}
+    self.size.width = 2.2; // expected-error {{expression is not assignable}}
 }
 - (NSSize)size {}
 @end
diff --git a/test/SemaObjC/protocol-attribute.m b/test/SemaObjC/protocol-attribute.m
index e04a39b..52c9803 100644
--- a/test/SemaObjC/protocol-attribute.m
+++ b/test/SemaObjC/protocol-attribute.m
@@ -3,7 +3,7 @@
 __attribute ((unavailable))
 @protocol FwProto; // expected-note{{marked unavailable}}
 
-Class <FwProto> cFw = 0;  // expected-warning {{'FwProto' is unavailable}}
+Class <FwProto> cFw = 0;  // expected-error {{'FwProto' is unavailable}}
 
 
 __attribute ((deprecated)) @protocol MyProto1
@@ -35,12 +35,12 @@
 
 @protocol FwProto @end // expected-note{{marked unavailable}}
 
-@interface MyClass2 <FwProto> // expected-warning {{'FwProto' is unavailable}}
+@interface MyClass2 <FwProto> // expected-error {{'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}}
+id <XProto> idX = 0; // expected-error {{'XProto' is unavailable}} expected-warning {{'XProto' is deprecated}}
 
 int main ()
 {
diff --git a/test/SemaObjC/protocols.m b/test/SemaObjC/protocols.m
index 8447fe2..ca38f20 100644
--- a/test/SemaObjC/protocols.m
+++ b/test/SemaObjC/protocols.m
@@ -61,3 +61,7 @@
 @protocol B < A > // expected-error{{protocol has circular dependency}}
 @end
 
+@protocol P
+- (int)test:(int)param, ..; // expected-warning{{type specifier missing}} \
+                      // expected-error{{expected ';' after method prototype}}
+@end
diff --git a/test/SemaObjC/return.m b/test/SemaObjC/return.m
index c578bf3..116abd1 100644
--- a/test/SemaObjC/return.m
+++ b/test/SemaObjC/return.m
@@ -20,3 +20,22 @@
       @throw (id)0;
   }
 }
+
+// <rdar://problem/4289832> - This code always returns, we should not
+//  issue a noreturn warning.
+@class NSException;
+@class NSString;
+NSString *rdar_4289832() {  // no-warning
+    @try
+    {
+        return @"a";
+    }
+    @catch(NSException *exception)
+    {
+        return @"b";
+    }
+    @finally
+    {
+    }
+}
+
diff --git a/test/SemaObjC/static-ivar-ref-1.m b/test/SemaObjC/static-ivar-ref-1.m
index cd5e055..d9f99f5 100644
--- a/test/SemaObjC/static-ivar-ref-1.m
+++ b/test/SemaObjC/static-ivar-ref-1.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -ast-print %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -ast-print %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -ast-print %s 2>&1 | FileCheck  %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -ast-print %s  2>&1  | FileCheck %s
 
 @interface current 
 {
@@ -14,5 +14,17 @@
 
 int foo()
 {
-	return pc->ivar2 + (*pc).ivar + pc->ivar1;
+  return pc->ivar2 + (*pc).ivar + pc->ivar1;
 }
+
+// CHECK: @interface current{
+// CHECK:     int ivar;
+// CHECK:     int ivar1;
+// CHECK:     int ivar2;
+// CHECK: }
+// CHECK: @end
+// CHECK: current *pc;
+// CHECK: int foo() {
+// CHECK:     return pc->ivar2 + (*pc).ivar + pc->ivar1;
+// CHECK: }
+
diff --git a/test/SemaObjC/super-class-protocol-conformance.m b/test/SemaObjC/super-class-protocol-conformance.m
new file mode 100644
index 0000000..f555c32
--- /dev/null
+++ b/test/SemaObjC/super-class-protocol-conformance.m
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar: // 7884086
+
+@interface NSObject @end
+
+@protocol TopProtocol
+  @property (readonly) id myString; // expected-warning {{property 'myString' requires method 'myString' to be defined}}
+@end
+
+@protocol SubProtocol <TopProtocol>
+@end
+
+@interface TopClass : NSObject <TopProtocol> {}
+@end
+
+@interface SubClass : TopClass <SubProtocol> {}
+@end
+
+@interface SubClass1 : TopClass {}	
+@end
+
+@implementation SubClass1 @end // Test1 - No Warning
+
+@implementation TopClass  // expected-note {{implementation is here}}
+@end
+
+@implementation SubClass // Test3 - No Warning 
+@end
+
+@interface SubClass2  : TopClass<TopProtocol> 
+@end
+
+@implementation SubClass2 @end // Test 4 - No Warning
+
+@interface SubClass3 : TopClass<SubProtocol> @end
+@implementation SubClass3 @end	// Test 5 - No Warning 
+
+@interface SubClass4 : SubClass3 @end
+@implementation SubClass4 @end	// Test 5 - No Warning
+
+@protocol NewProtocol
+  @property (readonly) id myNewString; // expected-warning {{property 'myNewString' requires method 'myNewString' to be defined}}
+@end
+
+@interface SubClass5 : SubClass4 <NewProtocol> @end
+@implementation SubClass5 @end   // expected-note {{implementation is here}}
+
+
+// Radar 8035776
+@protocol SuperProtocol
+@end
+
+@interface Super <SuperProtocol> 
+@end
+
+@protocol ProtocolWithProperty <SuperProtocol>
+@property (readonly, assign) id invalidationBacktrace; // expected-warning {{property 'invalidationBacktrace' requires method 'invalidationBacktrace' to be defined}}
+@end
+
+@interface INTF : Super <ProtocolWithProperty> 
+@end
+
+@implementation INTF @end // expected-note {{implementation is here}}
diff --git a/test/SemaObjC/synth-provisional-ivars.m b/test/SemaObjC/synth-provisional-ivars.m
new file mode 100644
index 0000000..973c771
--- /dev/null
+++ b/test/SemaObjC/synth-provisional-ivars.m
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+
+int bar;
+
+@interface I
+{
+    int _bar;
+}
+@property int PROP;
+@property int PROP1;
+@property int PROP2;
+@property int PROP3;
+@property int PROP4;
+
+@property int bar;
+@property int bar1;
+
+@end
+
+@implementation I
+- (int) Meth { return PROP; }	// expected-note {{'PROP' declared here}}
+
+@dynamic PROP1;
+- (int) Meth1 { return PROP1; }  // expected-error {{use of undeclared identifier 'PROP1'}}
+
+- (int) Meth2 { return PROP2; }  // expected-error {{use of undeclared identifier 'PROP2'}}
+@dynamic PROP2;
+
+- (int) Meth3 { return PROP3; }  // expected-error {{use of undeclared identifier 'PROP3'}}
+@synthesize PROP3=IVAR;
+
+- (int) Meth4 { return PROP4; }
+@synthesize PROP4=PROP4;
+
+- (int) Meth5 { return bar; }  // expected-error {{use of undeclared identifier 'bar'}}
+@synthesize bar = _bar;
+
+- (int) Meth6 { return bar1; }
+
+@end
+
+@implementation I(CAT)
+- (int) Meth { return PROP1; }  // expected-error {{use of undeclared identifier 'PROP1'}}
+@end
+
+@implementation I(r8251648)
+- (int) Meth1: (int) bar {
+  return bar; // expected-warning {{local declaration of 'bar' hides instance variable}}
+}
+@end
diff --git a/test/SemaObjC/warn-assign-property-nscopying.m b/test/SemaObjC/warn-assign-property-nscopying.m
index 953814c..1bdb4f0 100644
--- a/test/SemaObjC/warn-assign-property-nscopying.m
+++ b/test/SemaObjC/warn-assign-property-nscopying.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1  -fobjc-gc -fsyntax-only -verify %s
+// RUN: %clang_cc1  -x objective-c++ -fobjc-gc -fsyntax-only -verify %s
 
 @protocol NSCopying @end
 
diff --git a/test/SemaObjC/warn-strict-selector-match.m b/test/SemaObjC/warn-strict-selector-match.m
new file mode 100644
index 0000000..8ac0ca4
--- /dev/null
+++ b/test/SemaObjC/warn-strict-selector-match.m
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1  -Wstrict-selector-match -fsyntax-only -verify %s
+
+@interface Foo
+-(int) method; // expected-note {{using}}
+@end
+
+@interface Bar
+-(float) method;	// expected-note {{also found}}
+@end
+
+int main() { [(id)0 method]; } // expected-warning {{multiple methods named 'method' found [-Wstrict-selector-match]}}
+
+@interface Object @end
+
+@interface Class1
+- (void)setWindow:(Object *)wdw;	// expected-note {{using}}
+@end
+
+@interface Class2
+- (void)setWindow:(Class1 *)window;	// expected-note {{also found}}
+@end
+
+id foo(void) {
+  Object *obj = 0;
+  id obj2 = obj;
+  [obj setWindow:0]; 	// expected-warning {{Object' may not respond to 'setWindow:'}}
+  [obj2 setWindow:0]; // expected-warning {{multiple methods named 'setWindow:' found [-Wstrict-selector-match]}}
+  return obj;
+}
+
+@protocol MyObject
+- (id)initWithData:(Object *)data;	// expected-note {{using}} \
+					// expected-note {{passing argument to parameter 'data' here}}
+@end
+
+@protocol SomeOther
+- (id)initWithData:(int)data;	// expected-note {{also found}}
+@end
+
+@protocol MyCoding
+- (id)initWithData:(id<MyObject, MyCoding>)data;	// expected-note {{also found}}
+@end
+
+@interface NTGridDataObject: Object <MyCoding>
+{
+    Object<MyCoding> *_data;
+}
++ (NTGridDataObject*)dataObject:(id<MyObject, MyCoding>)data;
+@end
+
+@implementation NTGridDataObject
+- (id)initWithData:(id<MyObject, MyCoding>)data {
+  return data;
+}
++ (NTGridDataObject*)dataObject:(id<MyObject, MyCoding>)data
+{
+    NTGridDataObject *result = [(id)0 initWithData:data]; // expected-warning {{multiple methods named 'initWithData:' found [-Wstrict-selector-match]}} \
+    expected-warning {{sending 'id<MyObject,MyCoding>' to parameter of incompatible type 'Object *'}}
+    return result;
+}
+@end
+
+@interface Base
+- (unsigned)port;
+@end
+
+@interface Derived: Base
+- (Object *)port;
++ (Protocol *)port;
+@end
+
+void foo1(void) {
+  [(Class)0 port]; // OK - gcc issues warning but there is only one Class method so no ambiguity to warn
+}
+
diff --git a/test/SemaObjC/warn-unused-exception-param.m b/test/SemaObjC/warn-unused-exception-param.m
new file mode 100644
index 0000000..f649f8c
--- /dev/null
+++ b/test/SemaObjC/warn-unused-exception-param.m
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-exception-parameter %s
+void  f0() {
+  @try {} @catch(id a) {} // expected-warning{{unused exception parameter 'a'}}
+}
diff --git a/test/SemaObjC/warn-weak-field.m b/test/SemaObjC/warn-weak-field.m
index f20691c..ead454a 100644
--- a/test/SemaObjC/warn-weak-field.m
+++ b/test/SemaObjC/warn-weak-field.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -fobjc-gc -verify %s
+// RUN: %clang_cc1 -x objective-c++ -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}}
diff --git a/test/SemaObjCXX/const-cast.mm b/test/SemaObjCXX/const-cast.mm
new file mode 100644
index 0000000..933fd47
--- /dev/null
+++ b/test/SemaObjCXX/const-cast.mm
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@class Foo;
+
+void test() {
+    const Foo *foo1 = 0;
+    Foo *foo2 = foo1; // expected-error {{cannot initialize}}
+}
+
+void test1() {
+    const Foo *foo1 = 0;
+    Foo *foo2 = const_cast<Foo*>(foo1);
+}
diff --git a/test/SemaObjCXX/conversion-to-objc-pointer-2.mm b/test/SemaObjCXX/conversion-to-objc-pointer-2.mm
new file mode 100644
index 0000000..b03d4d8
--- /dev/null
+++ b/test/SemaObjCXX/conversion-to-objc-pointer-2.mm
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar: // 7963410
+
+@protocol NSObject @end
+@interface NSObject
+- (id)init;
+- (id) alloc;
+- (id) autorelease;
+@end
+
+template<class T>
+class TNSAutoRef
+{
+public:
+	TNSAutoRef(T t)
+		:	fRef(t)
+		{ }
+
+	~TNSAutoRef()
+		{ }
+
+	operator T() const
+		{ return fRef; }
+
+private:
+	T fRef;
+};
+
+
+#pragma mark -
+
+
+@protocol TFooProtocol <NSObject>
+
+- (void) foo;
+@end
+
+
+#pragma mark -
+
+
+@interface TFoo : NSObject
+
+- (void) setBlah: (id<TFooProtocol>)blah;
+@end
+
+
+#pragma mark -
+
+
+@implementation TFoo
+
+- (void) setBlah: (id<TFooProtocol>)blah
+	{ }
+@end
+
+
+#pragma mark -
+
+
+@interface TBar : NSObject
+
+- (void) setBlah: (id)blah;
+@end
+
+#pragma mark -
+
+
+@implementation TBar
+
+- (void) setBlah: (id)blah
+	{ }
+@end
+
+
+#pragma mark -
+
+
+int main (int argc, const char * argv[]) {
+
+	NSObject* object1 = [[[NSObject alloc] init] autorelease];
+	TNSAutoRef<NSObject*> object2([[NSObject alloc] init]);
+	TNSAutoRef<TBar*> bar([[TBar alloc] init]);
+	[bar setBlah: object1];				// <== Does not compile.  It should.
+        if (object1 == object2)
+	  [bar setBlah: object2];				// <== Does not compile.  It should.
+	return 0;
+}
diff --git a/test/SemaObjCXX/conversion-to-objc-pointer.mm b/test/SemaObjCXX/conversion-to-objc-pointer.mm
new file mode 100644
index 0000000..235aaac
--- /dev/null
+++ b/test/SemaObjCXX/conversion-to-objc-pointer.mm
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar: // 7963410
+
+template<class T>
+class TNSAutoRef
+{
+public:
+	TNSAutoRef(T t)
+		:	fRef(t)
+		{ }
+
+	~TNSAutoRef()
+		{  }
+
+	operator T() const
+		{ return fRef; }
+	
+	T Get() const
+		{ return fRef; }
+
+private:
+	T fRef;
+};
+
+@interface NSObject
+- (id) alloc;
+- (id)init;
+@end
+
+@interface TFoo : NSObject
+- (void) foo;
+@end
+
+@implementation TFoo
+- (void) foo {}
+@end
+
+@interface TBar : NSObject
+- (void) foo;
+@end
+
+@implementation TBar 
+- (void) foo {}
+@end
+
+int main () {
+	TNSAutoRef<TBar*> bar([[TBar alloc] init]);
+	[bar foo];
+	return 0;
+}
diff --git a/test/SemaObjCXX/deduction.mm b/test/SemaObjCXX/deduction.mm
new file mode 100644
index 0000000..220f368
--- /dev/null
+++ b/test/SemaObjCXX/deduction.mm
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@class NSString;
+
+// Reduced from WebKit.
+namespace test0 {
+  template <typename T> struct RemovePointer {
+    typedef T Type;
+  };
+
+  template <typename T> struct RemovePointer<T*> {
+    typedef T Type;
+  };
+
+  template <typename T> struct RetainPtr {
+    typedef typename RemovePointer<T>::Type ValueType;
+    typedef ValueType* PtrType;
+    RetainPtr(PtrType ptr);
+  };
+ 
+  void test(NSString *S) {
+    RetainPtr<NSString*> ptr(S);
+  }
+
+  void test(id S) {
+    RetainPtr<id> ptr(S);
+  }
+}
+
+@class Test1Class;
+@protocol Test1Protocol;
+namespace test1 {
+  template <typename T> struct RemovePointer {
+    typedef T type;
+  };
+  template <typename T> struct RemovePointer<T*> {
+    typedef T type;
+  };
+  template <typename A, typename B> struct is_same {};
+  template <typename A> struct is_same<A,A> {
+    static void foo();
+  };
+  template <typename T> struct tester {
+    void test() {
+      is_same<T, typename RemovePointer<T>::type*>::foo(); // expected-error 2 {{no member named 'foo'}}
+    }
+  };
+
+  template struct tester<id>;
+  template struct tester<id<Test1Protocol> >;
+  template struct tester<Class>;
+  template struct tester<Class<Test1Protocol> >;
+  template struct tester<Test1Class*>;
+  template struct tester<Test1Class<Test1Protocol>*>;
+
+  template struct tester<Test1Class>; // expected-note {{in instantiation}}
+  template struct tester<Test1Class<Test1Protocol> >; // expected-note {{in instantiation}}
+}
+
+namespace test2 {
+  template <typename T> void foo(const T* t) {}
+  void test(id x) {
+    foo(x);
+  }
+}
diff --git a/test/SemaObjCXX/exceptions-fragile.mm b/test/SemaObjCXX/exceptions-fragile.mm
new file mode 100644
index 0000000..11dd8e9
--- /dev/null
+++ b/test/SemaObjCXX/exceptions-fragile.mm
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+
+@interface NSException @end
+void opaque();
+
+namespace test0 {
+  void test() {
+    try {
+    } catch (NSException *e) { // expected-error {{can't catch Objective C exceptions in C++ in the non-unified exception model}}
+    }
+  }
+}
diff --git a/test/SemaObjCXX/expr-objcxx.mm b/test/SemaObjCXX/expr-objcxx.mm
new file mode 100644
index 0000000..e70a001
--- /dev/null
+++ b/test/SemaObjCXX/expr-objcxx.mm
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+
+// rdar://8366474
+void *P =  @selector(foo::bar::);
diff --git a/test/SemaObjCXX/instantiate-message.mm b/test/SemaObjCXX/instantiate-message.mm
index 46c8ede..e09b182 100644
--- a/test/SemaObjCXX/instantiate-message.mm
+++ b/test/SemaObjCXX/instantiate-message.mm
@@ -1,4 +1,4 @@
-// RUN: %clang -cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 // Test template instantiation of Objective-C message sends.
 
diff --git a/test/SemaObjCXX/instantiate-method-return.mm b/test/SemaObjCXX/instantiate-method-return.mm
new file mode 100644
index 0000000..b8ba4af
--- /dev/null
+++ b/test/SemaObjCXX/instantiate-method-return.mm
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR7386
+
+@class NSObject;
+
+class A;
+template<class T> class V {};
+
+@protocol Protocol
+- (V<A*>)protocolMethod;
+@end
+
+
+@interface I<Protocol>
+@end
+
+
+@implementation I
+- (void)randomMethod:(id)info {
+  V<A*> vec([self protocolMethod]);
+}
+
+- (V<A*>)protocolMethod {
+  V<A*> va; return va;
+}
+@end
diff --git a/test/SemaObjCXX/instantiate-stmt.mm b/test/SemaObjCXX/instantiate-stmt.mm
index e92f8e8..5e8ec61 100644
--- a/test/SemaObjCXX/instantiate-stmt.mm
+++ b/test/SemaObjCXX/instantiate-stmt.mm
@@ -25,6 +25,7 @@
 
 // fast enumeration
 @interface NSArray
+- (unsigned int)countByEnumeratingWithState:  (struct __objcFastEnumerationState *)state objects:  (id *)items count:(unsigned int)stackcount;
 @end
 
 @interface NSString
diff --git a/test/SemaObjCXX/ivar-construct.mm b/test/SemaObjCXX/ivar-construct.mm
new file mode 100644
index 0000000..da066e9
--- /dev/null
+++ b/test/SemaObjCXX/ivar-construct.mm
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct Y { 
+  Y(); 
+
+private:
+  ~Y(); // expected-note 3{{declared private here}}
+};
+
+template<typename T>
+struct X : T { }; // expected-error 2{{private destructor}}
+
+struct Z; // expected-note{{forward declaration}}
+
+@interface A {
+  X<Y> x; // expected-note{{implicit default destructor}}
+  Y y; // expected-error{{private destructor}}
+}
+@end
+
+@implementation A // expected-note{{implicit default constructor}}
+@end
+
+@interface B {
+  Z z; // expected-error{{incomplete type}}
+}
+@end
+
+@implementation B
+@end
diff --git a/test/SemaObjCXX/ivar-struct.mm b/test/SemaObjCXX/ivar-struct.mm
new file mode 100644
index 0000000..3f9c7eb
--- /dev/null
+++ b/test/SemaObjCXX/ivar-struct.mm
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+@interface A {
+  struct X {
+    int x, y;
+  } X;
+}
+@end
diff --git a/test/SemaObjCXX/message.mm b/test/SemaObjCXX/message.mm
index b75608e..f92518a 100644
--- a/test/SemaObjCXX/message.mm
+++ b/test/SemaObjCXX/message.mm
@@ -38,7 +38,7 @@
   return 0;
 }
 + (void)method {
-  [ivar method]; // expected-error{{receiver type 'ivar' (aka 'ivar') is not an Objective-C class}}
+  [ivar method]; // expected-error{{receiver type 'ivar' is not an Objective-C class}}
 }
 @end
 
@@ -62,15 +62,15 @@
   // or typename-specifiers.
   if (false) {
     if (true)
-      return [typename identity<I3>::type method];
+      return [typename identity<I3>::type method]; // expected-warning{{occurs outside of a template}}
 
     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* ip3 = {[typename identity<I3>::type method]}; // expected-warning{{occurs outside of a template}}
+  int* ip4 = {[typename identity<I2_holder>::type().get() method]}; // expected-warning{{occurs outside of a template}}
   int array[5] = {[3] = 2};
   return [super method];
 }
diff --git a/test/SemaObjCXX/objc-decls-inside-namespace.mm b/test/SemaObjCXX/objc-decls-inside-namespace.mm
index 9953ec3..f68078b 100644
--- a/test/SemaObjCXX/objc-decls-inside-namespace.mm
+++ b/test/SemaObjCXX/objc-decls-inside-namespace.mm
@@ -23,5 +23,10 @@
 @implementation A(C) //expected-error{{Objective-C declarations may only appear in global scope}}
 @end
 
+@interface B @end //expected-error{{Objective-C declarations may only appear in global scope}}
+@implementation B //expected-error{{Objective-C declarations may only appear in global scope}}
++ (void) foo {}
+@end
+
 }
 
diff --git a/test/SemaObjCXX/objc-pointer-conv.mm b/test/SemaObjCXX/objc-pointer-conv.mm
index cc3264f..af239a8 100644
--- a/test/SemaObjCXX/objc-pointer-conv.mm
+++ b/test/SemaObjCXX/objc-pointer-conv.mm
@@ -36,3 +36,11 @@
   Func(p);		// expected-error {{no matching function for call to 'Func'}}
 }
 
+@interface DerivedFromI : I
+@end
+
+void accept_derived(DerivedFromI*); // expected-note{{candidate function not viable: cannot convert from superclass 'I *' to subclass 'DerivedFromI *' for 1st argument}}
+
+void test_base_to_derived(I* i) {
+  accept_derived(i); // expected-error{{no matching function for call to 'accept_derived'}}
+}
diff --git a/test/SemaObjCXX/objc2-merge-gc-attribue-decl.mm b/test/SemaObjCXX/objc2-merge-gc-attribue-decl.mm
new file mode 100644
index 0000000..7be5f17
--- /dev/null
+++ b/test/SemaObjCXX/objc2-merge-gc-attribue-decl.mm
@@ -0,0 +1,51 @@
+// 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 __strong id CFRunLoopGetMain2();
+extern id CFRunLoopGetMain2();
+
+extern INTF* CFRunLoopGetMain3();
+extern __strong INTF* CFRunLoopGetMain3();
+
+extern __strong INTF* CFRunLoopGetMain4();
+extern INTF* CFRunLoopGetMain4();
+
+typedef id ID;
+extern ID CFRunLoopGetMain5();
+extern __strong id CFRunLoopGetMain5();
+
+extern __strong id CFRunLoopGetMain6();
+extern ID CFRunLoopGetMain6();
+
+extern ID CFRunLoopGetMain7();
+extern __strong ID CFRunLoopGetMain7();
+
+extern __strong ID CFRunLoopGetMain8();
+extern ID CFRunLoopGetMain8();
+
+extern __weak id WLoopGetMain(); // expected-note {{previous declaration is here}}
+extern id WLoopGetMain();	// expected-error {{functions that differ only in their return type cannot be overloaded}}
+
+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/SemaObjCXX/overload-1.mm b/test/SemaObjCXX/overload-1.mm
new file mode 100644
index 0000000..fc17ca2
--- /dev/null
+++ b/test/SemaObjCXX/overload-1.mm
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol Proto1 @end
+
+@protocol Proto2 @end
+
+void f(id<Proto1> *) { }		// expected-note {{previous definition is here}}
+
+void f(id<Proto1, Proto2> *) { }	// expected-error {{conflicting types for 'f'}}
+
+void f(Class<Proto1> *) { }		// expected-note {{previous definition is here}}
+
+void f(Class<Proto1, Proto2> *) { }	// expected-error {{conflicting types for 'f'}}
+
+@interface I @end
+
+void f(I<Proto1> *) { }		// expected-note {{previous definition is here}}
+
+void f(I<Proto1, Proto2> *) { }		// expected-error {{conflicting types for 'f'}}
+
+@interface I1 @end
+
+void f1(I<Proto1> *) { }
+
+void f1(I1<Proto1, Proto2> *) { }
diff --git a/test/SemaObjCXX/overload.mm b/test/SemaObjCXX/overload.mm
index 18da69f..487a42e 100644
--- a/test/SemaObjCXX/overload.mm
+++ b/test/SemaObjCXX/overload.mm
@@ -93,3 +93,12 @@
     objc_exception_functions_t exc_funcs;
     return exc_funcs.throw_exc; // expected-warning{{incompatible pointer types returning 'void (*)(NSException *)', expected 'void (*)(id)'}}
 }
+
+namespace test5 {
+  void foo(bool);
+  void foo(void *);
+
+  void test(id p) {
+    foo(p);
+  }
+}
diff --git a/test/SemaObjCXX/pointer-to-objc-pointer-conv.mm b/test/SemaObjCXX/pointer-to-objc-pointer-conv.mm
index 80383eb..d0f8404b 100644
--- a/test/SemaObjCXX/pointer-to-objc-pointer-conv.mm
+++ b/test/SemaObjCXX/pointer-to-objc-pointer-conv.mm
@@ -19,3 +19,31 @@
 
 }
 
+
+// pr7936
+@interface I1 @end
+
+class Wrapper {
+public:
+  operator id() const { return (id)_value; }
+  operator Class() const { return (Class)_value; }
+  operator I1*() const { return (I1*)_value; }
+
+  bool Compare(id obj) { return *this == obj; }
+  bool CompareClass(Class obj) { return *this == obj; }
+  bool CompareI1(I1* obj) { return *this == obj; }
+
+  Wrapper &operator*();
+  Wrapper &operator[](int);
+  Wrapper& operator->*(int);
+
+private:
+  long _value;
+};
+
+void f() {
+  Wrapper w;
+  w[0];
+  *w;
+  w->*(0);
+}
diff --git a/test/SemaObjCXX/references.mm b/test/SemaObjCXX/references.mm
index 70ce827..15033f6 100644
--- a/test/SemaObjCXX/references.mm
+++ b/test/SemaObjCXX/references.mm
@@ -24,3 +24,39 @@
   return f0(a.p1);	// expected-error {{property 'p1' not found on object of type 'A *'}}
 }
 
+// PR7740
+@class NSString;
+
+void f3(id);
+void f4(NSString &tmpstr) {
+  f3(&tmpstr);
+}
+
+// PR7741
+@protocol P1 @end
+@protocol P2 @end
+@protocol P3 @end
+@interface foo<P1> {} @end
+@interface bar : foo <P1, P2> {} @end
+typedef bar baz;
+
+struct ToBar {
+  operator bar&() const;
+};
+
+void f5(foo&);
+void f5b(foo<P1>&);
+void f5c(foo<P2>&);
+void f5d(foo<P3>&);
+void f6(baz* x) { 
+  f5(*x); 
+  f5b(*x); 
+  f5c(*x); 
+  f5d(*x);
+  (void)((foo&)*x);
+  f5(ToBar());
+  f5b(ToBar());
+  f5c(ToBar());
+  f5d(ToBar());
+  (void)((foo&)ToBar());
+}
diff --git a/test/SemaObjCXX/static-cast.mm b/test/SemaObjCXX/static-cast.mm
new file mode 100644
index 0000000..e282702
--- /dev/null
+++ b/test/SemaObjCXX/static-cast.mm
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@protocol NSTextViewDelegate;
+
+@interface NSResponder @end
+
+class AutoreleaseObject
+{
+public:
+ AutoreleaseObject();
+ ~AutoreleaseObject();
+
+
+ AutoreleaseObject& operator=(NSResponder* inValue);
+ AutoreleaseObject& operator=(const AutoreleaseObject& inValue);
+
+ AutoreleaseObject(const AutoreleaseObject& inValue);
+
+ operator NSResponder*() const;
+};
+
+
+void InvokeSaveFocus()
+{
+ AutoreleaseObject mResolvedFirstResponder;
+ id<NSTextViewDelegate> Mydelegate;
+ mResolvedFirstResponder = static_cast<NSResponder*>(Mydelegate);
+}
+
diff --git a/test/SemaObjCXX/vla.mm b/test/SemaObjCXX/vla.mm
index 9c6fc54..d6da1c0 100644
--- a/test/SemaObjCXX/vla.mm
+++ b/test/SemaObjCXX/vla.mm
@@ -6,7 +6,7 @@
 @end
 
 void test(Data *d) {
-  char buffer[[d length]]; // expected-error{{variable length arrays are not permitted in C++}}
+  char buffer[[d length]];
   [d getData:buffer];
 }
 
diff --git a/test/SemaObjCXX/void_to_obj.mm b/test/SemaObjCXX/void_to_obj.mm
index 52510c8..7dca9fa 100644
--- a/test/SemaObjCXX/void_to_obj.mm
+++ b/test/SemaObjCXX/void_to_obj.mm
@@ -9,3 +9,18 @@
 
   obj = vv; // expected-error{{assigning to 'XX *' from incompatible type 'void *'}}
 }
+
+// <rdar://problem/7952457>
+@interface I
+{
+  void* delegate;
+}
+- (I*) Meth;
+- (I*) Meth1;
+@end
+
+@implementation I 
+- (I*) Meth { return static_cast<I*>(delegate); }
+- (I*) Meth1 { return reinterpret_cast<I*>(delegate); }
+@end
+
diff --git a/test/SemaObjCXX/warn-strict-selector-match.mm b/test/SemaObjCXX/warn-strict-selector-match.mm
new file mode 100644
index 0000000..6d315db
--- /dev/null
+++ b/test/SemaObjCXX/warn-strict-selector-match.mm
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1  -Wstrict-selector-match -fsyntax-only -verify %s
+
+@interface Base
+- (id) meth1: (Base *)arg1; 	// expected-note {{using}}
+- (id) window;	// expected-note {{using}}
+@end
+
+@interface Derived: Base
+- (id) meth1: (Derived *)arg1;	// expected-note {{also found}}
+- (Base *) window;	// expected-note {{also found}}
+@end
+
+void foo(void) {
+  id r;
+
+  [r meth1:r];	// expected-warning {{multiple methods named 'meth1:' found [-Wstrict-selector-match]}}
+  [r window]; 	// expected-warning {{multiple methods named 'window' found [-Wstrict-selector-match]}}
+}
diff --git a/test/SemaTemplate/array-to-pointer-decay.cpp b/test/SemaTemplate/array-to-pointer-decay.cpp
new file mode 100644
index 0000000..072c0e5
--- /dev/null
+++ b/test/SemaTemplate/array-to-pointer-decay.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct mystruct {
+  int  member;
+};
+
+template <int i>
+int foo() {
+  mystruct s[1];
+  return s->member;
+}
+
+int main() {
+  foo<1>();
+}
+
+// PR7405
+struct hb_sanitize_context_t {
+  int start;
+};
+template <typename Type> static bool sanitize() {
+  hb_sanitize_context_t c[1];
+  return !c->start;
+}
+bool closure = sanitize<int>();
diff --git a/test/SemaTemplate/attributes.cpp b/test/SemaTemplate/attributes.cpp
new file mode 100644
index 0000000..f4c1887
--- /dev/null
+++ b/test/SemaTemplate/attributes.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace attribute_aligned {
+  template<int N>
+  struct X {
+    char c[1] __attribute__((__aligned__((N)))); // expected-error {{alignment is not a power of 2}}
+  };
+
+  template <bool X> struct check {
+    int check_failed[X ? 1 : -1]; // expected-error {{array size is negative}}
+  };
+
+  template <int N> struct check_alignment {
+    typedef check<N == sizeof(X<N>)> t; // expected-note {{in instantiation}}
+  };
+
+  check_alignment<1>::t c1;
+  check_alignment<2>::t c2;
+  check_alignment<3>::t c3; // expected-note 2 {{in instantiation}}
+  check_alignment<4>::t c4;
+}
diff --git a/test/SemaTemplate/class-template-ctor-initializer.cpp b/test/SemaTemplate/class-template-ctor-initializer.cpp
index fd9417c..81a5e2b 100644
--- a/test/SemaTemplate/class-template-ctor-initializer.cpp
+++ b/test/SemaTemplate/class-template-ctor-initializer.cpp
@@ -31,3 +31,25 @@
             TmplB<char>() {}
 };
 
+namespace PR7259 {
+  class Base {
+  public:
+    Base() {}
+  };
+
+  template <class ParentClass>
+  class Derived : public ParentClass {
+  public:
+    Derived() : Base() {}
+  };
+
+  class Final : public Derived<Base> {
+  };
+
+  int
+  main (void)
+  {
+    Final final();
+    return 0;
+  }
+}
diff --git a/test/SemaTemplate/class-template-id.cpp b/test/SemaTemplate/class-template-id.cpp
index df5ef55..50e0b00 100644
--- a/test/SemaTemplate/class-template-id.cpp
+++ b/test/SemaTemplate/class-template-id.cpp
@@ -41,3 +41,7 @@
 template<typename T> struct Foo { }; // expected-note{{template is declared here}}
 
 void f(void) { Foo bar; } // expected-error{{without a template argument list}}
+
+// rdar://problem/8254267
+template <typename T> class Party;
+template <> class Party<T> { friend struct Party<>; }; // expected-error {{use of undeclared identifier 'T'}}
diff --git a/test/SemaTemplate/crash-8204126.cpp b/test/SemaTemplate/crash-8204126.cpp
new file mode 100644
index 0000000..eb96560
--- /dev/null
+++ b/test/SemaTemplate/crash-8204126.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A
+{
+  template<int> template<typename T> friend void foo(T) {} // expected-error{{extraneous template parameter list}}
+  void bar() { foo(0); } // expected-error{{use of undeclared identifier 'foo'}}
+};
diff --git a/test/SemaTemplate/current-instantiation.cpp b/test/SemaTemplate/current-instantiation.cpp
index 4563748..8caac93 100644
--- a/test/SemaTemplate/current-instantiation.cpp
+++ b/test/SemaTemplate/current-instantiation.cpp
@@ -151,3 +151,51 @@
     X1<T*>::a = b;
   }
 };
+
+namespace ConstantInCurrentInstantiation {
+  template<typename T>
+  struct X {
+    static const int value = 2;
+    static int array[value];
+  };
+
+  template<typename T> const int X<T>::value;
+
+  template<typename T>
+  int X<T>::array[X<T>::value] = { 1, 2 };
+}
+
+namespace Expressions {
+  template <bool b>
+  struct Bool {
+    enum anonymous_enum { value = b };
+  };
+  struct True : public Bool<true> {};
+  struct False : public Bool<false> {};
+
+  template <typename T1, typename T2>
+  struct Is_Same : public False {};
+  template <typename T>
+  struct Is_Same<T, T> : public True {};
+
+  template <bool b, typename T = void>
+  struct Enable_If {};
+  template <typename T>
+  struct Enable_If<true, T>  {
+    typedef T type;
+  };
+
+  template <typename T>
+  class Class {
+  public:
+    template <typename U>
+    typename Enable_If<Is_Same<U, Class>::value, void>::type
+    foo();
+  };
+
+
+  template <typename T>
+  template <typename U>
+  typename Enable_If<Is_Same<U, Class<T> >::value, void>::type
+  Class<T>::foo() {}
+}
diff --git a/test/SemaTemplate/deduction-crash.cpp b/test/SemaTemplate/deduction-crash.cpp
new file mode 100644
index 0000000..8f4b728
--- /dev/null
+++ b/test/SemaTemplate/deduction-crash.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -fsyntax-only %s 2>&1| FileCheck %s
+
+// PR7511
+
+// Note that the error count below doesn't matter. We just want to
+// make sure that the parser doesn't crash.
+// CHECK: 15 errors
+template<a>
+struct int_;
+
+template<a>
+template<int,typename T1,typename>
+struct ac
+{
+  typedef T1 ae
+};
+
+template<class>struct aaa
+{
+  typedef ac<1,int,int>::ae ae
+};
+
+template<class>
+struct state_machine
+{
+  typedef aaa<int>::ae aaa;
+  int start()
+  {
+    ant(0);
+  }
+  
+  template<class>
+  struct region_processing_helper
+  {
+    template<class,int=0>
+    struct In;
+    
+    template<int my>
+    struct In<a::int_<aaa::a>,my>;
+        
+    template<class Event>
+    int process(Event)
+    {
+      In<a::int_<0> > a;
+    }
+  }
+  template<class Event>
+  int ant(Event)
+  {
+    region_processing_helper<int>* helper;
+    helper->process(0)
+  }
+};
+
+int a()
+{
+  state_machine<int> p;
+  p.ant(0);
+}
diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp
index 8d00bb7..c4c6688 100644
--- a/test/SemaTemplate/deduction.cpp
+++ b/test/SemaTemplate/deduction.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 // Template argument deduction with template template parameters.
 template<typename T, template<T> class A> 
@@ -98,3 +98,26 @@
   void f(const X<A>& a);
   void test(A& a) { (void)f(a); }
 }
+
+// PR7463
+namespace PR7463 {
+  const int f ();
+  template <typename T_> void g (T_&); // expected-note{{T_ = int}}
+  void h (void) { g(f()); } // expected-error{{no matching function for call}}
+}
+
+namespace test0 {
+  template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: can't deduce a type for 'T' which would make 'T const' equal 'char'}}
+  char *char_maker();
+  void test() {
+    make(char_maker); // expected-error {{no matching function for call to 'make'}}
+  }
+}
+
+namespace test1 {
+  template<typename T> void foo(const T a[3][3]);
+  void test() {
+    int a[3][3];
+    foo(a);
+  }
+}
diff --git a/test/SemaTemplate/dependent-base-classes.cpp b/test/SemaTemplate/dependent-base-classes.cpp
index d0dd9c9..e64d623 100644
--- a/test/SemaTemplate/dependent-base-classes.cpp
+++ b/test/SemaTemplate/dependent-base-classes.cpp
@@ -6,7 +6,7 @@
 };
 
 template<typename T, typename U>
-struct X1 : T::apply<U> { }; // expected-error{{missing 'template' keyword prior to dependent template name 'T::apply'}}
+struct X1 : T::apply<U> { }; // expected-error{{use 'template' keyword to treat 'apply' as a dependent template name}}
 
 template<typename T>
 struct X2 : vector<T> { }; // expected-error{{unknown template name 'vector'}}
diff --git a/test/SemaTemplate/dependent-base-member-init.cpp b/test/SemaTemplate/dependent-base-member-init.cpp
index 1f13149..1d4fed3 100644
--- a/test/SemaTemplate/dependent-base-member-init.cpp
+++ b/test/SemaTemplate/dependent-base-member-init.cpp
@@ -57,3 +57,12 @@
 struct X0 : T::template apply<U> {
   X0(int i) : T::template apply<U>(i) { }
 };
+
+// PR7698
+namespace PR7698 {
+  template<typename Type>
+  class A {
+    char mA[sizeof(Type *)];
+    A(): mA() {}
+  };
+}
diff --git a/test/SemaTemplate/dependent-class-member-operator.cpp b/test/SemaTemplate/dependent-class-member-operator.cpp
new file mode 100644
index 0000000..d70a60c
--- /dev/null
+++ b/test/SemaTemplate/dependent-class-member-operator.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR7837
+
+template<class T> struct C1 { void operator()(T); };
+template<class T> struct C2; // expected-note {{template is declared here}}
+template<class T> void foo(T);
+void wrap() {
+  foo(&C1<int>::operator());
+  foo(&C1<int>::operator+); // expected-error {{no member named 'operator+' in 'C1<int>'}}
+  foo(&C2<int>::operator+); // expected-error {{implicit instantiation of undefined template 'C2<int>'}}
+}
diff --git a/test/SemaTemplate/dependent-expr.cpp b/test/SemaTemplate/dependent-expr.cpp
index 3f481b5..e25afce 100644
--- a/test/SemaTemplate/dependent-expr.cpp
+++ b/test/SemaTemplate/dependent-expr.cpp
@@ -24,3 +24,24 @@
     (void)(k % member);
   }
 }
+
+namespace PR7198 {
+  struct A
+  {
+    ~A() { }
+  };
+
+  template<typename T>
+  struct B {
+    struct C : A {};
+    void f()
+    {
+      C c = C();
+    }
+  };
+}
+
+namespace PR7724 {
+  template<typename OT> int myMethod()
+  { return 2 && sizeof(OT); }
+}
diff --git a/test/SemaTemplate/dependent-template-recover.cpp b/test/SemaTemplate/dependent-template-recover.cpp
new file mode 100644
index 0000000..e91ffb5
--- /dev/null
+++ b/test/SemaTemplate/dependent-template-recover.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U, int N>
+struct X {
+  void f(T* t) {
+    t->f0<U>(); // expected-error{{use 'template' keyword to treat 'f0' as a dependent template name}}
+    t->f0<int>(); // expected-error{{use 'template' keyword to treat 'f0' as a dependent template name}}
+
+    t->operator+<U const, 1>(); // expected-error{{use 'template' keyword to treat 'operator +' as a dependent template name}}
+    t->f1<int const, 2>(); // expected-error{{use 'template' keyword to treat 'f1' as a dependent template name}}
+
+    T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
+    t->T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
+
+    // FIXME: We can't recover from these yet
+    (*t).f2<N>(); // expected-error{{expected expression}}
+    (*t).f2<0>(); // expected-error{{expected expression}}
+  }
+};
diff --git a/test/SemaTemplate/dependent-type-identity.cpp b/test/SemaTemplate/dependent-type-identity.cpp
index e095812..731013c 100644
--- a/test/SemaTemplate/dependent-type-identity.cpp
+++ b/test/SemaTemplate/dependent-type-identity.cpp
@@ -70,3 +70,31 @@
   void f8(typename N::X2<U>::template apply<T> *);
   void f8(typename ::Nalias::X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
 };
+
+namespace PR6851 {
+  template <bool v>
+  struct S;
+
+  struct N {
+    template <bool w>
+    S< S<w>::cond && 1 > foo();
+  };
+
+  struct Alien;
+  bool operator&&(const Alien&, const Alien&);
+
+  template <bool w>
+  S< S<w>::cond && 1 > N::foo() { }
+}
+
+namespace PR7460 {
+  template <typename T>
+  struct TemplateClass2
+  {
+    enum { SIZE = 100 };
+    static T member[SIZE];
+  };
+
+  template <typename T>
+  T TemplateClass2<T>::member[TemplateClass2<T>::SIZE];
+}
diff --git a/test/SemaTemplate/destructor-template.cpp b/test/SemaTemplate/destructor-template.cpp
index fa1b3e0..6fe7f69 100644
--- a/test/SemaTemplate/destructor-template.cpp
+++ b/test/SemaTemplate/destructor-template.cpp
@@ -40,3 +40,13 @@
 
   template void f<const volatile int>(int *);
 }
+
+namespace PR7239 {
+  template<class E> class A { };
+  class B {
+    void f() {
+      A<int>* x;
+      x->A<int>::~A<int>();
+    }
+  };
+}
diff --git a/test/SemaTemplate/enum-argument.cpp b/test/SemaTemplate/enum-argument.cpp
index de89487..7d23757 100644
--- a/test/SemaTemplate/enum-argument.cpp
+++ b/test/SemaTemplate/enum-argument.cpp
@@ -21,3 +21,16 @@
 };
 
 X0<int> x0i;
+
+namespace rdar8020920 {
+  template<typename T>
+  struct X {
+    enum { e0 = 32 };
+
+    unsigned long long bitfield : e0;
+
+    void f(int j) {
+      bitfield + j;
+    }
+  };
+}
diff --git a/test/SemaTemplate/example-dynarray.cpp b/test/SemaTemplate/example-dynarray.cpp
index 1f6ede6..999521e 100644
--- a/test/SemaTemplate/example-dynarray.cpp
+++ b/test/SemaTemplate/example-dynarray.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -emit-llvm -S -o %t %s
+// RUN: %clangxx -emit-llvm -c -o - %s
 #include <stddef.h>
 #include <stdlib.h>
 #include <assert.h>
diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp
index de51f09..3a1446e 100644
--- a/test/SemaTemplate/explicit-instantiation.cpp
+++ b/test/SemaTemplate/explicit-instantiation.cpp
@@ -83,3 +83,16 @@
   void test1() { (void)&X0<1>::x; }
   template struct X0<1>;
 }
+
+namespace PR7622 { // expected-note{{to match this}}
+  template<typename,typename=int>
+  struct basic_streambuf;
+
+  // FIXME: Very poor recovery here.
+  template<typename,typename>
+  struct basic_streambuf{friend bob<>()}; // expected-error{{unknown type name 'bob'}} \
+  // expected-error{{ expected member name or ';' after declaration specifiers}}
+  template struct basic_streambuf<int>; // expected-error{{explicit instantiation of 'basic_streambuf' in class scope}}
+}  // expected-error{{expected ';' after struct}}
+  
+//expected-error{{expected '}'}}
diff --git a/test/SemaTemplate/ext-vector-type.cpp b/test/SemaTemplate/ext-vector-type.cpp
index 3973102..7334e88 100644
--- a/test/SemaTemplate/ext-vector-type.cpp
+++ b/test/SemaTemplate/ext-vector-type.cpp
@@ -20,7 +20,7 @@
 
 template<typename T, unsigned Length> 
 struct make3 { 
-  typedef T __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector type 's'}}
+  typedef T __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector element type 's'}}
 };
 
 struct s {};
@@ -42,7 +42,7 @@
 typedef int* int_ptr;
 template<unsigned Length>
 struct make5 {
-  typedef int_ptr __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector type}}             
+  typedef int_ptr __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector element type}}
 };
 
 template<int Length>
diff --git a/test/SemaTemplate/friend-template.cpp b/test/SemaTemplate/friend-template.cpp
index 6ee30aa..1d62804 100644
--- a/test/SemaTemplate/friend-template.cpp
+++ b/test/SemaTemplate/friend-template.cpp
@@ -127,3 +127,83 @@
   };
 }
 
+namespace FriendTemplateDefinition {
+  template<unsigned > struct int_c { };
+
+  template<typename T>
+  struct X {
+    template<unsigned N>
+    friend void f(X, int_c<N>) {
+      int value = N;
+    };
+  };
+
+  void test_X(X<int> x, int_c<5> i5) {
+    f(x, i5);
+  }
+}
+
+namespace PR7013a {
+  template<class > struct X0
+  {
+    typedef int type;
+  };
+  template<typename > struct X1
+  {
+  };
+  template<typename , typename T> struct X2
+  {
+    typename T::type e;
+  };
+  namespace N
+  {
+    template <typename = int, typename = X1<int> > struct X3
+    {
+      template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);
+    };
+    template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
+    {
+      X2<int, Tr> s;
+    }
+  }
+  int n()
+  {
+    X2<int, X0<int> > ngs;
+    N::X3<> b;
+    op(ngs, b);
+    return 0;
+  }
+}
+
+namespace PR7013b {
+  template<class > struct X0
+  {
+    typedef int type;
+  };
+  template<typename > struct X1
+  {
+  };
+  template<typename , typename T> struct X2
+  {
+    typename T::type e;
+  };
+  namespace N
+  {
+    template <typename = X1<int> > struct X3
+    {
+      template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);
+    };
+    template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
+    {
+      X2<int, Tr> s;
+    }
+  }
+  int n()
+  {
+    X2<int, X0<int> > ngs;
+    N::X3<> b;
+    op(ngs, b);
+    return 0;
+  }
+
+}
diff --git a/test/SemaTemplate/inject-templated-friend.cpp b/test/SemaTemplate/inject-templated-friend.cpp
new file mode 100644
index 0000000..fbe86d9
--- /dev/null
+++ b/test/SemaTemplate/inject-templated-friend.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang %s -S -emit-llvm -o - | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE"
+// RUN: %clang -cc1 %s -DREDEFINE -verify
+// PR8007: friend function not instantiated.
+
+struct std_ostream
+{
+  int dummy;
+};
+
+std_ostream cout;
+
+template <typename STRUCT_TYPE>
+struct Streamer
+{
+    friend std_ostream& operator << (std_ostream& o, const Streamer& f) // expected-error{{redefinition of 'operator<<'}}
+        {
+            Streamer s(f);
+            s(o);
+            return o;
+        }
+
+    Streamer(const STRUCT_TYPE& s) : s(s) {}
+
+    const STRUCT_TYPE& s;
+    void operator () (std_ostream&) const;
+};
+
+typedef struct Foo {} Foo;
+
+std_ostream& operator << (std_ostream&, const Streamer<Foo>&);
+#ifdef REDEFINE
+std_ostream& operator << (std_ostream& o, const Streamer<Foo>&) // expected-note{{is here}}
+{
+  // Sema should flag this as a redefinition
+  return o;
+}
+#endif
+
+template <>
+void Streamer<Foo>::operator () (std_ostream& o) const // expected-note{{requested here}}
+{
+}
+
+int main(void)
+{
+    Foo foo;
+    cout << foo;
+}
diff --git a/test/SemaTemplate/injected-class-name.cpp b/test/SemaTemplate/injected-class-name.cpp
index 586be18..4c21d25 100644
--- a/test/SemaTemplate/injected-class-name.cpp
+++ b/test/SemaTemplate/injected-class-name.cpp
@@ -48,3 +48,15 @@
   };
   template class A<int>;
 }
+
+namespace ForwardDecls {
+  template<typename T>
+  struct X;
+
+  template<typename T>
+  struct X {
+    typedef T foo;
+    typedef X<T> xt;
+    typename xt::foo *t;
+  };
+}
diff --git a/test/SemaTemplate/instantiate-anonymous-union.cpp b/test/SemaTemplate/instantiate-anonymous-union.cpp
index 7c75885..255454b 100644
--- a/test/SemaTemplate/instantiate-anonymous-union.cpp
+++ b/test/SemaTemplate/instantiate-anonymous-union.cpp
@@ -29,3 +29,21 @@
 };
 
 C<int> c0(0);
+
+namespace PR7088 {
+  template<typename T>
+  void f() { 
+    union { 
+      int a; 
+      union {
+        float real;
+        T d;
+      };
+    }; 
+
+    a = 17;
+    d = 3.14;
+  }
+
+  template void f<double>();
+}
diff --git a/test/SemaTemplate/instantiate-attr.cpp b/test/SemaTemplate/instantiate-attr.cpp
index 7fb1736..bbadb63 100644
--- a/test/SemaTemplate/instantiate-attr.cpp
+++ b/test/SemaTemplate/instantiate-attr.cpp
@@ -2,6 +2,25 @@
 template <typename T>
 struct A {
   char a __attribute__((aligned(16)));
+
+  struct B {
+    typedef T __attribute__((aligned(16))) i16;
+    i16 x;
+  };
 };
 int a[sizeof(A<int>) == 16 ? 1 : -1];
+int a2[sizeof(A<int>::B) == 16 ? 1 : -1];
 
+// rdar://problem/8243419
+namespace test1 {
+  template <typename T> struct A {
+    int a;
+    T b[0];
+  } __attribute__((packed));
+
+  typedef A<unsigned long> type;
+
+  int test0[sizeof(type) == 4 ? 1 : -1];
+  int test1[__builtin_offsetof(type, a) == 0 ? 1 : -1];
+  int test2[__builtin_offsetof(type, b) == 4 ? 1 : -1];
+}
diff --git a/test/SemaTemplate/instantiate-clang.cpp b/test/SemaTemplate/instantiate-clang.cpp
index cef2b70..34d68c4 100644
--- a/test/SemaTemplate/instantiate-clang.cpp
+++ b/test/SemaTemplate/instantiate-clang.cpp
@@ -24,7 +24,7 @@
 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, N, M); // expected-error{{index}}
     (void)__builtin_shufflevector(a, b, 2, 1);
   }
 };
diff --git a/test/SemaTemplate/instantiate-complete.cpp b/test/SemaTemplate/instantiate-complete.cpp
index d854c9e..c13930d 100644
--- a/test/SemaTemplate/instantiate-complete.cpp
+++ b/test/SemaTemplate/instantiate-complete.cpp
@@ -99,3 +99,32 @@
 
   template void f(int);
 }
+
+namespace PR7080 {
+  template <class T, class U>
+  class X
+  {
+    typedef char true_t;
+    class false_t { char dummy[2]; };
+    static true_t dispatch(U);
+    static false_t dispatch(...);
+    static T trigger();
+  public:
+    enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
+  };
+
+  template <class T>
+  class rv : public T
+  { };
+
+  bool x = X<int, rv<int>&>::value;
+}
+
+namespace pr7199 {
+  template <class T> class A; // expected-note {{template is declared here}}
+  template <class T> class B {
+    class A<T>::C field; // expected-error {{implicit instantiation of undefined template 'pr7199::A<int>'}}
+  };
+
+  template class B<int>; // expected-note {{in instantiation}}
+}
diff --git a/test/SemaTemplate/instantiate-declref-ice.cpp b/test/SemaTemplate/instantiate-declref-ice.cpp
index e88b494..0f3c08b 100644
--- a/test/SemaTemplate/instantiate-declref-ice.cpp
+++ b/test/SemaTemplate/instantiate-declref-ice.cpp
@@ -31,5 +31,4 @@
 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}}
+int array3[X1<int>::value == sizeof(int)? 1 : -1]; // 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
index 2d27075..ced56df 100644
--- a/test/SemaTemplate/instantiate-declref.cpp
+++ b/test/SemaTemplate/instantiate-declref.cpp
@@ -95,3 +95,13 @@
   };
   void g() { X<2>(); }
 }
+
+// <rdar://problem/8302161>
+namespace test1 {
+  template <typename T> void f(T const &t) {
+    union { char c; T t_; };
+    c = 'a'; // <- this shouldn't silently fail to instantiate
+    T::foo(); // expected-error {{has no members}}
+  }
+  template void f(int const &); // expected-note {{requested here}}
+}
diff --git a/test/SemaTemplate/instantiate-default-assignment-operator.cpp b/test/SemaTemplate/instantiate-default-assignment-operator.cpp
index 5594d6c..8b97f59 100644
--- a/test/SemaTemplate/instantiate-default-assignment-operator.cpp
+++ b/test/SemaTemplate/instantiate-default-assignment-operator.cpp
@@ -5,13 +5,13 @@
   RefPtr& operator=(const PassRefPtr<T>&);
 };
 
-struct A { RefPtr<int> a; };
-struct B : RefPtr<float> { };
+struct A { RefPtr<int> a; };  // expected-note {{instantiation of member function 'RefPtr<int>::operator=' requested here}}
+struct B : RefPtr<float> { }; // expected-note {{in instantiation of member function 'RefPtr<float>::operator=' requested here}}
 
 void f() {
   A a1, a2;
-  a1 = a2; // expected-note {{instantiation of member function 'RefPtr<int>::operator=' requested here}}
+  a1 = a2;
 
   B b1, b2;
-  b1 = b2; // expected-note {{in instantiation of member function 'RefPtr<float>::operator=' requested here}}
+  b1 = b2; 
 }
diff --git a/test/SemaTemplate/instantiate-expr-2.cpp b/test/SemaTemplate/instantiate-expr-2.cpp
index b91b398..eaa68dd 100644
--- a/test/SemaTemplate/instantiate-expr-2.cpp
+++ b/test/SemaTemplate/instantiate-expr-2.cpp
@@ -194,6 +194,37 @@
   void f0(int **a) { C::f0(a); }
 }
 
+namespace PR7202 {
+  template<typename U, typename T>
+  struct meta {
+    typedef T type;
+  };
+
+  struct X {
+    struct dummy;
+
+    template<typename T>
+    X(T, typename meta<T, dummy*>::type = 0);
+
+    template<typename T, typename A>
+    X(T, A);
+  };
+
+  template<typename T>
+  struct Z { };
+
+  template<typename T> Z<T> g(T);
+
+  struct Y {
+    template<typename T>
+    void f(T t) {
+      new X(g(*this));
+    }
+  };
+
+  template void Y::f(int);
+}
+
 namespace N13 {
   class A{
     A(const A&);
diff --git a/test/SemaTemplate/instantiate-expr-3.cpp b/test/SemaTemplate/instantiate-expr-3.cpp
index 41a96a3..ca88b00 100644
--- a/test/SemaTemplate/instantiate-expr-3.cpp
+++ b/test/SemaTemplate/instantiate-expr-3.cpp
@@ -63,7 +63,11 @@
 template<typename T>
 struct StatementExpr0 {
   void f(T t) {
-    (void)({ if (t) t = t + 17; t + 12;}); // expected-error{{invalid}}
+    (void)({
+        if (t) // expected-error{{contextually convertible}}
+          t = t + 17;
+        t + 12; // expected-error{{invalid operands}}
+      });
   }
 };
 
@@ -106,8 +110,8 @@
     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);
+      (void)__builtin_va_arg(va, ArgType); // expected-error{{int}}
+    __builtin_va_end(va); // expected-error{{int}}
   }
 };
 
diff --git a/test/SemaTemplate/instantiate-expr-4.cpp b/test/SemaTemplate/instantiate-expr-4.cpp
index 8cd7342..adae1da 100644
--- a/test/SemaTemplate/instantiate-expr-4.cpp
+++ b/test/SemaTemplate/instantiate-expr-4.cpp
@@ -115,7 +115,7 @@
 struct Delete0 {
   void f(T t) {
     delete t; // expected-error{{cannot delete}}
-    ::delete [] t;
+    ::delete [] t; // expected-error{{cannot delete}}
   }
 };
 
diff --git a/test/SemaTemplate/instantiate-expr-5.cpp b/test/SemaTemplate/instantiate-expr-5.cpp
index 941dae4..6cdedda 100644
--- a/test/SemaTemplate/instantiate-expr-5.cpp
+++ b/test/SemaTemplate/instantiate-expr-5.cpp
@@ -1,4 +1,38 @@
-// RUN: %clang_cc1 -fsyntax-only %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 template <class A> int x(A x) { return x++; }
 int y() { return x<int>(1); }
+
+namespace PR5880 {
+  template<typename T>
+  struct A { 
+    static const int a  = __builtin_offsetof(T, a.array[5].m); // expected-error{{error: no member named 'a' in 'HasM'}}
+  };
+  struct HasM {
+    float m;
+  };
+
+  struct ArrayOfHasM {
+    HasM array[10];
+  };
+
+  struct B { ArrayOfHasM a; };
+  A<B> x;
+  A<HasM> x2; // expected-note{{in instantiation of}}
+
+  template<typename T>
+  struct AnonymousUnion {
+    union {
+      int i;
+      float f;
+    };
+  };
+
+  template<typename T>
+  void test_anon_union() {
+    int array1[__builtin_offsetof(AnonymousUnion<T>, f) == 0? 1 : -1];
+    int array2[__builtin_offsetof(AnonymousUnion<int>, f) == 0? 1 : -1];
+  }
+
+  template void test_anon_union<int>();
+}
diff --git a/test/SemaTemplate/instantiate-field.cpp b/test/SemaTemplate/instantiate-field.cpp
index 60d4b21..d825cd7 100644
--- a/test/SemaTemplate/instantiate-field.cpp
+++ b/test/SemaTemplate/instantiate-field.cpp
@@ -26,3 +26,67 @@
 void test3(const X<int(int)> *xf) {
   (void)xf->x; // expected-note{{in instantiation of template class 'X<int (int)>' requested here}}
 }
+
+namespace PR7123 {
+  template <class > struct requirement_;
+
+  template <void(*)()> struct instantiate
+  { };
+
+  template <class > struct requirement ;
+  struct failed ;
+
+  template <class Model> struct requirement<failed *Model::*>
+  {
+    static void failed()
+    {
+      ((Model*)0)->~Model(); // expected-note{{in instantiation of}}
+    }
+  };
+
+  template <class Model> struct requirement_<void(*)(Model)> : requirement<failed *Model::*>
+  { };
+
+  template <int> struct Requires_
+  { typedef void type; };
+
+  template <class Model> struct usage_requirements
+  {
+    ~usage_requirements()
+    {((Model*)0)->~Model(); } // expected-note{{in instantiation of}}
+  };
+
+  template < typename TT > struct BidirectionalIterator
+  {
+    enum
+      { value = 0 };
+  
+    instantiate< requirement_<void(*)(usage_requirements<BidirectionalIterator>)>::failed> int534; // expected-note{{in instantiation of}}
+  
+    ~BidirectionalIterator()
+    { i--; } // expected-error{{cannot decrement value of type 'PR7123::X'}}
+  
+    TT i;
+  };
+
+  struct X
+  { };
+
+  template<typename RanIter> 
+  typename Requires_< BidirectionalIterator<RanIter>::value >::type sort(RanIter,RanIter){}
+
+  void f()
+  {
+    X x;
+    sort(x,x);
+  }
+}
+
+namespace PR7355 {
+  template<typename T1> class A {
+    class D; // expected-note{{declared here}}
+    D d; //expected-error{{implicit instantiation of undefined member 'PR7355::A<int>::D'}}
+  };
+
+  A<int> ai; // expected-note{{in instantiation of}}
+}
diff --git a/test/SemaTemplate/instantiate-function-1.cpp b/test/SemaTemplate/instantiate-function-1.cpp
index 6e0d711..651c02c 100644
--- a/test/SemaTemplate/instantiate-function-1.cpp
+++ b/test/SemaTemplate/instantiate-function-1.cpp
@@ -39,11 +39,11 @@
 
 template <typename T> struct X4 {
   T f() const {
-    return; // expected-warning{{non-void function 'f' should return a value}}
+    return; // expected-error{{non-void function 'f' should return a value}}
   }
   
   T g() const {
-    return 1; // expected-warning{{void function 'g' should not return a value}}
+    return 1; // expected-error{{void function 'g' should not return a value}}
   }
 };
 
@@ -72,7 +72,7 @@
     if (T x = t) {
       t = x;
     }
-    return v;
+    return v; // expected-error{{cannot initialize return object of type}}
   }
 };
 
@@ -178,10 +178,10 @@
 
   prior:
     T prior_label;
-    prior_label = &&prior;
+    prior_label = &&prior; // expected-error{{assigning to 'int'}}
 
     T later_label;
-    later_label = &&later;
+    later_label = &&later; // expected-error{{assigning to 'int'}}
 
   later:
     (void)(1+1);
@@ -220,3 +220,8 @@
   template <class T> class A { void foo(T array[10]); };
   template class A<int>;
 }
+
+namespace PR7016 {
+  template<typename T> void f() { T x = x; }
+  template void f<int>();
+}
diff --git a/test/SemaTemplate/instantiate-function-2.cpp b/test/SemaTemplate/instantiate-function-2.cpp
index 6318fac..ebc0ef3 100644
--- a/test/SemaTemplate/instantiate-function-2.cpp
+++ b/test/SemaTemplate/instantiate-function-2.cpp
@@ -10,3 +10,24 @@
   S<int> s1;
   S<int> s2(10);
 }
+
+namespace PR7184 {
+  template<typename T>
+  void f() {
+    typedef T type;
+    void g(int array[sizeof(type)]);
+  }
+
+  template void f<int>();
+}
+
+namespace UsedAttr {
+  template<typename T>
+  void __attribute__((used)) foo() {
+    T *x = 1; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+  }
+
+  void bar() {
+    foo<int>(); // expected-note{{instantiation of}}
+  }
+}
diff --git a/test/SemaTemplate/instantiate-function-params.cpp b/test/SemaTemplate/instantiate-function-params.cpp
index cfca020..54847e4 100644
--- a/test/SemaTemplate/instantiate-function-params.cpp
+++ b/test/SemaTemplate/instantiate-function-params.cpp
@@ -3,13 +3,13 @@
 // 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}}
+  typedef if_c< static_cast<bool>(T1::value)> almost_type_; // expected-note 5{{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 }} \
+inline char has_constraints_(Model* ,  // expected-note 2{{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}}
+                               wrap_constraints<Model,&Model::constraints>* = 0); // expected-note 2{{in instantiation}}
 
 template <class Model> struct not_satisfied {
   static const bool value = sizeof( has_constraints_((Model*)0)  == 1); // expected-error 3{{no matching function}}
@@ -17,19 +17,18 @@
 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 requirement_<void(*)(Model)>                           : if_<       not_satisfied<Model>         >::type { // expected-note 5{{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}}
+    typedef  instantiate< & requirement_<void(*)(usage_requirements<InputIterator> x)>::failed> boost_concept_check1; // expected-note {{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}}
+template < typename TT > struct ForwardIterator                              : InputIterator<TT>                              { // expected-note {{in instantiation}}
+  typedef instantiate< & requirement_<void(*)(usage_requirements<ForwardIterator> x)>::failed> boost_concept_check2; // expected-note {{in instantiation}}
 
 };
-typedef instantiate< &requirement_<void(*)(ForwardIterator<char*> x)>::failed> boost_concept_checkX;// expected-note 6{{in instantiation}}
+typedef instantiate< &requirement_<void(*)(ForwardIterator<char*> x)>::failed> boost_concept_checkX;// expected-note 3{{in instantiation}}
 
 template<typename T> struct X0 { };
 template<typename R, typename A1> struct X0<R(A1 param)> { };
@@ -54,3 +53,38 @@
 };
 
 template void use_func_ptr<int, float, double>();
+
+namespace PR6990 {
+  template < typename , typename = int, typename = int > struct X1;
+  template <typename >
+  struct X2;
+
+  template <typename = int *, typename TokenT = int,
+            typename = int( X2<TokenT> &)> 
+  struct X3
+  {
+  };
+
+  template <typename , typename P> 
+  struct X3_base : X3< X1<int, P> >
+  {
+  protected: typedef X1< P> type;
+    X3<type> e;
+  };
+
+  struct r : X3_base<int, int>
+  {
+  };
+}
+
+namespace InstantiateFunctionTypedef {
+  template<typename T>
+  struct X {
+    typedef int functype(int, int);
+    functype func;
+  };
+
+  void f(X<int> x) {
+    (void)x.func(1, 2);
+  }
+}
diff --git a/test/SemaTemplate/instantiate-member-pointers.cpp b/test/SemaTemplate/instantiate-member-pointers.cpp
index 2308ac5..dca0f62 100644
--- a/test/SemaTemplate/instantiate-member-pointers.cpp
+++ b/test/SemaTemplate/instantiate-member-pointers.cpp
@@ -53,3 +53,15 @@
 void test_accept_X4(X4<&Y::x> x4) {
   accept_X4(x4);
 }
+
+namespace ValueDepMemberPointer {
+  template <void (*)()> struct instantiate_function {};
+  template <typename T> struct S {
+    static void instantiate();
+    typedef instantiate_function<&S::instantiate> x; // expected-note{{instantiation}}
+  };
+  template <typename T> void S<T>::instantiate() {
+    int a[(int)sizeof(T)-42]; // expected-error{{array size is negative}}
+  }
+  S<int> s; 
+}
diff --git a/test/SemaTemplate/instantiate-member-template.cpp b/test/SemaTemplate/instantiate-member-template.cpp
index ae8425e..24a3f31 100644
--- a/test/SemaTemplate/instantiate-member-template.cpp
+++ b/test/SemaTemplate/instantiate-member-template.cpp
@@ -156,3 +156,36 @@
   };
 
 }
+
+namespace PR7587 {
+  template<typename> class X0;
+  template<typename> struct X1;
+  template<typename> class X2;
+
+  template<typename T> class X3
+  {
+    template<
+      template<typename> class TT,
+      typename U = typename X1<T>::type
+    > 
+    struct Inner {
+      typedef X2<TT<typename X1<T>::type> > Type;
+    };
+
+    const typename Inner<X0>::Type minCoeff() const;
+  };
+
+  template<typename T> class X3<T*>
+  {
+    template<
+      template<typename> class TT,
+      typename U = typename X1<T>::type
+    > 
+    struct Inner {
+      typedef X2<TT<typename X1<T>::type> > Type;
+    };
+
+    const typename Inner<X0>::Type minCoeff() const;
+  };
+
+}
diff --git a/test/SemaTemplate/instantiate-method.cpp b/test/SemaTemplate/instantiate-method.cpp
index 3ef07d3..363115d 100644
--- a/test/SemaTemplate/instantiate-method.cpp
+++ b/test/SemaTemplate/instantiate-method.cpp
@@ -127,3 +127,51 @@
   };
   template class B<int>;
 }
+
+namespace PR6947 {
+  template< class T > 
+  struct X {
+    int f0( )      
+    {
+      typedef void ( X::*impl_fun_ptr )( );
+      impl_fun_ptr pImpl = &X::template
+        f0_impl1<int>;
+    }
+  private:                  
+    int f1() {
+    }
+    template< class Processor>                  
+    void f0_impl1( )                 
+    {
+    }
+  };
+
+  char g0() {
+    X<int> pc;
+    pc.f0();
+  }
+
+}
+
+namespace PR7022 {
+  template <typename > 
+  struct X1
+  {
+    typedef int state_t( );
+    state_t g ;
+  };
+
+  template <  typename U = X1<int> > struct X2
+  {
+    X2( U = U())
+    {
+    }
+  };
+
+  void m(void)
+  {
+    typedef X2<> X2_type;
+    X2_type c;
+  }
+
+}
diff --git a/test/SemaTemplate/instantiate-non-dependent-types.cpp b/test/SemaTemplate/instantiate-non-dependent-types.cpp
new file mode 100644
index 0000000..a0005c56
--- /dev/null
+++ b/test/SemaTemplate/instantiate-non-dependent-types.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+struct X1 {
+  static void member() { T* x = 1; } // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+};
+
+template<void(*)()> struct instantiate { };
+
+template<typename T>
+struct X2 {
+  typedef instantiate<&X1<int>::member> i; // expected-note{{in instantiation of}}
+};
+
+X2<int> x; 
diff --git a/test/SemaTemplate/instantiate-non-type-template-parameter.cpp b/test/SemaTemplate/instantiate-non-type-template-parameter.cpp
index 414e62b..cbadcde 100644
--- a/test/SemaTemplate/instantiate-non-type-template-parameter.cpp
+++ b/test/SemaTemplate/instantiate-non-type-template-parameter.cpp
@@ -9,6 +9,28 @@
   }
 };
 
-int main(int argc, char *argv[]) {
+void test_stringswitch(int argc, char *argv[]) {
   (void)StringSwitch<int>();
 }
+
+namespace PR6986 {
+  template<class Class,typename Type,Type Class::*> 
+  struct non_const_member_base
+  {
+  };
+
+  template<class Class,typename Type,Type Class::*PtrToMember> 
+  struct member: non_const_member_base<Class,Type,PtrToMember>
+  {
+  };
+
+  struct test_class
+  {
+    int int_member;
+  };
+  typedef member< test_class,const int,&test_class::int_member > ckey_m;
+  void test()
+  {
+    ckey_m m;
+  }
+}
diff --git a/test/SemaTemplate/instantiate-objc-1.mm b/test/SemaTemplate/instantiate-objc-1.mm
index 92d0d6c..2780f8e 100644
--- a/test/SemaTemplate/instantiate-objc-1.mm
+++ b/test/SemaTemplate/instantiate-objc-1.mm
@@ -45,3 +45,4 @@
 
 template struct EncodeTest<int>;
 template struct EncodeTest<double>;
+template struct EncodeTest<wchar_t>;
diff --git a/test/SemaTemplate/instantiate-overload-candidates.cpp b/test/SemaTemplate/instantiate-overload-candidates.cpp
new file mode 100644
index 0000000..5b7e60d
--- /dev/null
+++ b/test/SemaTemplate/instantiate-overload-candidates.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// This is the function actually selected during overload resolution, and the
+// only one defined.
+template <typename T> void f(T*, int) {}
+
+template <typename T> struct S;
+template <typename T> struct S_ : S<T> { typedef int type; }; // expected-note{{in instantiation}}
+template <typename T> struct S {
+  // Force T to have a complete type here so we can observe instantiations with
+  // incomplete types.
+  T t; // expected-error{{field has incomplete type}}
+};
+
+// Provide a bad class and an overload that instantiates templates with it.
+class NoDefinition; // expected-note{{forward declaration}}
+template <typename T> S_<NoDefinition>::type f(T*, NoDefinition*); // expected-note{{in instantiation}}
+
+void test(int x) {
+  f(&x, 0);
+}
diff --git a/test/SemaTemplate/member-function-template.cpp b/test/SemaTemplate/member-function-template.cpp
index aea6285..44954ed 100644
--- a/test/SemaTemplate/member-function-template.cpp
+++ b/test/SemaTemplate/member-function-template.cpp
@@ -85,3 +85,19 @@
 
   void test_f(X<3> x, Y<int> y) { x.f(y); }
 }
+
+namespace PR7387 {
+  template <typename T> struct X {};
+
+  template <typename T1> struct S {
+    template <template <typename> class TC> void foo(const TC<T1>& arg);
+  };
+
+  template <typename T1> template <template <typename> class TC>
+  void S<T1>::foo(const TC<T1>& arg) {}
+
+  void test(const X<int>& x) {
+    S<int> s;
+    s.foo(x);
+  }
+}
diff --git a/test/SemaTemplate/member-template-access-expr.cpp b/test/SemaTemplate/member-template-access-expr.cpp
index ea17cdb..dbd27c4 100644
--- a/test/SemaTemplate/member-template-access-expr.cpp
+++ b/test/SemaTemplate/member-template-access-expr.cpp
@@ -123,3 +123,22 @@
     };
   };
 }
+
+namespace rdar8198511 {
+  template<int, typename U>
+  struct Base { 
+    void f();
+  };
+
+  template<typename T>
+  struct X0 : Base<1, T> { };
+
+  template<typename T>
+  struct X1 {
+    X0<int> x0;
+
+    void f() {
+      this->x0.Base<1, int>::f();
+    }
+  };
+}
diff --git a/test/SemaTemplate/nested-name-spec-template.cpp b/test/SemaTemplate/nested-name-spec-template.cpp
index 1691db7..9c72845 100644
--- a/test/SemaTemplate/nested-name-spec-template.cpp
+++ b/test/SemaTemplate/nested-name-spec-template.cpp
@@ -21,7 +21,8 @@
   }
 
   M::Promote<int>::type *ret_intptr3(int* ip) { return ip; }
-  M::template Promote<int>::type *ret_intptr4(int* ip) { return ip; }
+  M::template Promote<int>::type *ret_intptr4(int* ip) { return ip; } // expected-warning{{'template' keyword outside of a template}}
+  M::template Promote<int> pi; // expected-warning{{'template' keyword outside of a template}}
 }
 
 N::M::Promote<int>::type *ret_intptr5(int* ip) { return ip; }
@@ -51,3 +52,50 @@
   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}}
 };
+
+// Reduced from a Boost failure.
+namespace test1 {
+  template <class T> struct pair {
+    T x;
+    T y;
+
+    static T pair<T>::* const mem_array[2];
+  };
+
+  template <class T>
+  T pair<T>::* const pair<T>::mem_array[2] = { &pair<T>::x, &pair<T>::y };
+}
+
+typedef int T;
+namespace N1 {
+  template<typename T> T f0();
+}
+
+template<typename T> T N1::f0() { }
+
+namespace PR7385 {
+  template< typename > struct has_xxx0
+  {
+    template< typename > struct has_xxx0_introspect
+    {
+      template< typename > struct has_xxx0_substitute ;
+      template< typename V > 
+      int int00( has_xxx0_substitute < typename V::template xxx< > > = 0 );
+    };
+    static const int value = has_xxx0_introspect<int>::value; // expected-error{{no member named 'value'}}
+    typedef int type;
+  };
+
+  has_xxx0<int>::type t; // expected-note{{instantiation of}}
+}
+
+namespace PR7725 {
+  template<class ignored> struct TypedefProvider;
+  template<typename T>
+  struct TemplateClass : public TypedefProvider<T>
+  {
+    void PrintSelf() {
+      TemplateClass::Test::PrintSelf();
+    }
+  };
+}
diff --git a/test/SemaTemplate/overload-candidates.cpp b/test/SemaTemplate/overload-candidates.cpp
new file mode 100644
index 0000000..8762cc8
--- /dev/null
+++ b/test/SemaTemplate/overload-candidates.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+const T& min(const T&, const T&); // expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'long')}}
+
+void test_min() {
+  (void)min(1, 2l); // expected-error{{no matching function for call to 'min'}}
+}
+
+template<typename R, typename T>
+R *dyn_cast(const T&); // expected-note{{candidate template ignored: couldn't infer template argument 'R'}}
+
+void test_dyn_cast(int* ptr) {
+  (void)dyn_cast(ptr); // expected-error{{no matching function for call to 'dyn_cast'}}
+}
+
+template<int I, typename T> 
+  void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I'}}
+template<template<class T> class, typename T> 
+  void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+
+void test_get(void *ptr) {
+  get<int>(ptr); // expected-error{{no matching function for call to 'get'}}
+}
+
+template<typename T>
+  typename T::type get_type(const T&); // expected-note{{candidate template ignored: substitution failure [with T = int *]}}
+
+void test_get_type(int *ptr) {
+  (void)get_type(ptr); // expected-error{{no matching function for call to 'get_type'}}
+}
+
+struct X {
+  template<typename T>
+  const T& min(const T&, const T&); // expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'long')}}
+};
+
+void test_X_min(X x) {
+  (void)x.min(1, 2l); // expected-error{{no matching member function for call to 'min'}}
+}
diff --git a/test/SemaTemplate/partial-spec-instantiate.cpp b/test/SemaTemplate/partial-spec-instantiate.cpp
index 3156892..68b4964 100644
--- a/test/SemaTemplate/partial-spec-instantiate.cpp
+++ b/test/SemaTemplate/partial-spec-instantiate.cpp
@@ -18,3 +18,23 @@
 };
 
 void a(char *a, char *b) {X2<char*>::f();}
+
+namespace WonkyAccess {
+  template<typename T>
+  struct X {
+    int m;
+  };
+
+  template<typename U>
+  class Y;
+
+  template<typename U>
+  struct Y<U*> : X<U> { };
+
+  template<>
+  struct Y<float*> : X<float> { };
+
+  int f(Y<int*> y, Y<float*> y2) {
+    return y.m + y2.m;
+  }
+}
diff --git a/test/SemaTemplate/recovery-crash.cpp b/test/SemaTemplate/recovery-crash.cpp
new file mode 100644
index 0000000..0ed3258
--- /dev/null
+++ b/test/SemaTemplate/recovery-crash.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// We don't expect a fix-it to be applied in this case. Clang used to crash
+// trying to recover while adding 'this->' before Work(x);
+
+template <typename> struct A {
+  static void Work(int);  // expected-note{{must qualify identifier}}
+};
+
+template <typename T> struct B : public A<T> {
+  template <typename T2> B(T2 x) {
+    Work(x);  // expected-error{{use of undeclared identifier}}
+  }
+};
+
+void Test() {
+  B<int> b(0);  // expected-note{{in instantiation of function template}}
+}
+
diff --git a/test/SemaTemplate/self-comparison.cpp b/test/SemaTemplate/self-comparison.cpp
new file mode 100644
index 0000000..50ab660
--- /dev/null
+++ b/test/SemaTemplate/self-comparison.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <int A, int B> void foo() {
+  (void)(A == A); // expected-warning {{self-comparison always evaluates to true}}
+  (void)(A == B);
+}
+template <int A, int B> struct S1 {
+  void foo() {
+    (void)(A == A); // expected-warning {{self-comparison always evaluates to true}}
+    (void)(A == B);
+  }
+};
+
+template <int A, int B> struct S2 {
+  template <typename T> T foo() {
+    (void)(A == A); // expected-warning {{self-comparison always evaluates to true}}
+    (void)(A == B);
+  }
+};
+
+struct S3 {
+  template <int A, int B> void foo() {
+    (void)(A == A); // expected-warning {{self-comparison always evaluates to true}}
+    (void)(A == B);
+  }
+};
+
+template <int A> struct S4 {
+  template <int B> void foo() {
+    (void)(A == A); // expected-warning {{self-comparison always evaluates to true}}
+    (void)(A == B);
+  }
+};
+
+const int N = 42;
+template <int X> void foo2() {
+  (void)(X == N);
+  (void)(N == X);
+}
+
+void test() {
+  foo<1, 1>();
+  S1<1, 1> s1; s1.foo();
+  S2<1, 1> s2; s2.foo<void>();
+  S3 s3; s3.foo<1, 1>();
+  S4<1> s4; s4.foo<1>();
+  foo2<N>();
+}
diff --git a/test/SemaTemplate/temp_arg_nontype.cpp b/test/SemaTemplate/temp_arg_nontype.cpp
index 7b83ff9..6f51591 100644
--- a/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/test/SemaTemplate/temp_arg_nontype.cpp
@@ -193,3 +193,53 @@
     typedef X<int*, Y<int*>::f> x; // expected-note{{in instantiation of}}
   }
 }
+
+namespace PR6964 {
+  template <typename ,int, int = 9223372036854775807L > // expected-warning 2{{non-type template argument value '9223372036854775807' truncated to '-1' for template parameter of type 'int'}} \
+  // expected-note 2{{template parameter is declared here}}
+  struct as_nview { };
+
+  template <typename Sequence, int I0> 
+  struct as_nview<Sequence, I0>  // expected-note{{while checking a default template argument used here}}
+  { };
+}
+
+// rdar://problem/8302138
+namespace test8 {
+  template <int* ip> struct A {
+    int* p;
+    A() : p(ip) {}
+  };
+
+  void test0() {
+    extern int i00;
+    A<&i00> a00;
+  }
+
+  extern int i01;
+  void test1() {
+    A<&i01> a01;
+  }
+
+
+  struct C {
+    int x;
+    char y;
+    double z;
+  };
+  
+  template <C* cp> struct B {
+    C* p;
+    B() : p(cp) {}
+  };
+
+  void test2() {
+    extern C c02;
+    B<&c02> b02;
+  }
+
+  extern C c03;
+  void test3() {
+    B<&c03> b03;
+  }
+}
diff --git a/test/SemaTemplate/temp_arg_template.cpp b/test/SemaTemplate/temp_arg_template.cpp
index 6671225..944acac 100644
--- a/test/SemaTemplate/temp_arg_template.cpp
+++ b/test/SemaTemplate/temp_arg_template.cpp
@@ -33,3 +33,21 @@
 // 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;
+
+// PR7807
+namespace N {
+  template <typename, typename = int> 
+  struct X
+  { };
+
+  template <typename ,int> 
+  struct Y
+  { X<int> const_ref(); };
+
+  template <template<typename,int> class TT, typename T, int N> 
+  int operator<<(int, TT<T, N> a) { // expected-note{{candidate template ignored}}
+    0 << a.const_ref(); // expected-error{{invalid operands to binary expression ('int' and 'X<int>')}}
+  }
+
+  void f0( Y<int,1> y){ 1 << y; } // expected-note{{in instantiation of function template specialization 'N::operator<<<Y, int, 1>' requested here}}
+}
diff --git a/test/SemaTemplate/temp_explicit.cpp b/test/SemaTemplate/temp_explicit.cpp
index fbb41ff..76244c2 100644
--- a/test/SemaTemplate/temp_explicit.cpp
+++ b/test/SemaTemplate/temp_explicit.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++0x-compat %s
 //
 // Tests explicit instantiation of templates.
 template<typename T, typename U = T> class X0 { };
@@ -125,3 +125,27 @@
 template <>
 struct Foo<int>::Bar<void>
 {};
+
+namespace N1 {
+
+  template<typename T> struct X7 { }; // expected-note{{here}}
+
+  namespace Inner {
+    template<typename T> struct X8 { };
+  }
+
+  template struct X7<int>;
+  template struct Inner::X8<int>;
+}
+
+template<typename T> struct X9 { }; // expected-note{{here}}
+
+template struct ::N1::Inner::X8<float>;
+
+namespace N2 {
+  using namespace N1;
+
+  template struct X7<double>; // expected-warning{{must occur in namespace}}
+
+  template struct X9<float>; // expected-warning{{must occur in the global}}
+}
diff --git a/test/SemaTemplate/template-decl-fail.cpp b/test/SemaTemplate/template-decl-fail.cpp
index 7c04131..ad134cd 100644
--- a/test/SemaTemplate/template-decl-fail.cpp
+++ b/test/SemaTemplate/template-decl-fail.cpp
@@ -6,3 +6,5 @@
 enum t0 { A = T::x }; // expected-error{{enumeration cannot be a template}} \
                       // expected-warning{{declaration does not declare anything}}
 
+enum e0 {};
+template<int x> enum e0 f0(int a=x) {}
diff --git a/test/SemaTemplate/template-id-expr.cpp b/test/SemaTemplate/template-id-expr.cpp
index b3f41be..de8d7f6 100644
--- a/test/SemaTemplate/template-id-expr.cpp
+++ b/test/SemaTemplate/template-id-expr.cpp
@@ -44,3 +44,41 @@
 };
 
 template struct X<3>;
+
+// 'template' as a disambiguator.
+// PR7030
+struct Y0 {
+  template<typename U>
+  void f1(U);
+
+  template<typename U>
+  static void f2(U);
+
+  void f3(int);
+
+  static int f4(int);
+  template<typename U>
+  static void f4(U);
+
+  template<typename U>
+  void f() {
+    Y0::template f1<U>(0);
+    Y0::template f1(0);
+    this->template f1(0);
+
+    Y0::template f2<U>(0);
+    Y0::template f2(0);
+
+    Y0::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
+    Y0::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
+
+    int x;
+    x = Y0::f4(0);
+    x = Y0::f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+    x = Y0::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+
+    x = this->f4(0);
+    x = this->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+    x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+  }
+};
diff --git a/test/SemaTemplate/typename-specifier-4.cpp b/test/SemaTemplate/typename-specifier-4.cpp
index 280a1b4..5a313bf 100644
--- a/test/SemaTemplate/typename-specifier-4.cpp
+++ b/test/SemaTemplate/typename-specifier-4.cpp
@@ -27,7 +27,8 @@
 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>,
+         typename make_pair::template apply<int, float>, // expected-warning{{'template' keyword outside of a template}} \
+       // expected-warning{{'typename' occurs outside of a template}}
          make_pair::apply<int, float>
        >::value? 1 : -1];
 
@@ -113,6 +114,6 @@
   // 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}}
+    return x;
   }
 }
diff --git a/test/SemaTemplate/typename-specifier.cpp b/test/SemaTemplate/typename-specifier.cpp
index 3f6fe34..4c788f6 100644
--- a/test/SemaTemplate/typename-specifier.cpp
+++ b/test/SemaTemplate/typename-specifier.cpp
@@ -15,19 +15,22 @@
 
 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'}}
+typename N::A::type *ip1 = &i; // expected-warning{{'typename' occurs outside of a template}}
+typename N::B::type *ip2 = &i; // expected-error{{no type named 'type' in 'N::B'}} \
+// expected-warning{{'typename' occurs outside of a template}}
+typename N::C::type *ip3 = &i; // expected-error{{typename specifier refers to non-type member 'type'}} \
+// expected-warning{{'typename' occurs outside of a template}}
 
 void test(double d) {
-  typename N::A::type f(typename N::A::type(a)); // expected-warning{{parentheses were disambiguated as a function declarator}}
+  typename N::A::type f(typename N::A::type(a)); // expected-warning{{parentheses were disambiguated as a function declarator}} \
+  // expected-warning 2{{'typename' occurs outside of a template}}
   int five = f(5);
   
   using namespace N;
-  for (typename A::type i = 0; i < 10; ++i)
+  for (typename A::type i = 0; i < 10; ++i) // expected-warning{{'typename' occurs outside of a template}}
     five += 1;
 
-  const typename N::A::type f2(d);
+  const typename N::A::type f2(d); // expected-warning{{'typename' occurs outside of a template}}
 }
 
 namespace N {
diff --git a/test/SemaTemplate/unused-variables.cpp b/test/SemaTemplate/unused-variables.cpp
new file mode 100644
index 0000000..1b9350b
--- /dev/null
+++ b/test/SemaTemplate/unused-variables.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused -verify %s
+
+struct X0 {
+  ~X0();
+};
+
+struct X1 { };
+
+template<typename T>
+void f() {
+  X0 x0;
+  X1 x1; // expected-warning{{unused variable 'x1'}}
+}
+
+template<typename T, typename U>
+void g() {
+  T t;
+  U u; // expected-warning{{unused variable 'u'}}
+}
+
+template void g<X0, X1>(); // expected-note{{in instantiation of}}
diff --git a/test/SemaTemplate/virtual-member-functions.cpp b/test/SemaTemplate/virtual-member-functions.cpp
index 59df3c2..974f664 100644
--- a/test/SemaTemplate/virtual-member-functions.cpp
+++ b/test/SemaTemplate/virtual-member-functions.cpp
@@ -3,7 +3,7 @@
 namespace PR5557 {
 template <class T> struct A {
   A();
-  virtual void anchor(); // expected-note{{instantiation}}
+  virtual void anchor();
   virtual int a(T x);
 };
 template<class T> A<T>::A() {}
@@ -14,7 +14,7 @@
 }
 
 void f(A<int> x) {
-  x.anchor();
+  x.anchor(); // expected-note{{instantiation}}
 }
 
 template<typename T>
@@ -43,7 +43,7 @@
 
 template<typename T>
 struct HasOutOfLineKey {
-  HasOutOfLineKey() { } // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}
+  HasOutOfLineKey() { } 
   virtual T *f(float *fp);
 };
 
@@ -52,4 +52,35 @@
   return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}
 }
 
-HasOutOfLineKey<int> out_of_line;
+HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}
+
+namespace std {
+  class type_info;
+}
+
+namespace PR7114 {
+  class A { virtual ~A(); }; // expected-note{{declared private here}}
+
+  template<typename T>
+  class B {
+  public:
+    class Inner : public A { }; // expected-error{{base class 'PR7114::A' has private destructor}}
+    static Inner i;
+    static const unsigned value = sizeof(i) == 4;
+  };
+
+  int f() { return B<int>::value; }
+
+  void test_typeid(B<float>::Inner bfi) {
+    (void)typeid(bfi); // expected-note{{implicit default destructor}}
+  }
+
+  template<typename T>
+  struct X : A {
+    void f() { }
+  };
+
+  void test_X(X<int> xi, X<float> xf) {
+    xi.f();
+  }
+}
diff --git a/test/lit.cfg b/test/lit.cfg
index b306331..80f8d5a 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -128,7 +128,8 @@
 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( ('%clangxx', ' ' + config.clang +
+                              ' -ccc-clang-cxx -ccc-cxx '))
 config.substitutions.append( ('%clang', ' ' + config.clang + ' ') )
 
 # FIXME: Find nicer way to prohibit this.
@@ -142,3 +143,12 @@
 config.substitutions.append(
     (' clang -cc1 ',
      """*** Do not use 'clang -cc1' in tests, use '%clang_cc1'. ***""") )
+config.substitutions.append(
+    (' %clang-cc1 ',
+     """*** invalid substitution, use '%clang_cc1'. ***""") )
+
+###
+
+# Set available features we allow tests to conditionalize on.
+if platform.system() != 'Windows':
+    config.available_features.add('crash-recovery')
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
deleted file mode 100644
index 9cdb965..0000000
--- a/tools/CIndex/CIndex.cpp
+++ /dev/null
@@ -1,2589 +0,0 @@
-//===- 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
deleted file mode 100644
index b361168..0000000
--- a/tools/CIndex/CIndex.darwin.exports
+++ /dev/null
@@ -1,81 +0,0 @@
-_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
deleted file mode 100644
index 991bb06..0000000
--- a/tools/CIndex/CIndex.exports
+++ /dev/null
@@ -1,81 +0,0 @@
-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
deleted file mode 100644
index a21614c..0000000
--- a/tools/CIndex/CIndexCodeCompletion.cpp
+++ /dev/null
@@ -1,512 +0,0 @@
-//===- 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
deleted file mode 100644
index 3db37b9..0000000
--- a/tools/CIndex/CIndexDiagnostic.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/*===-- 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/CIndexUSRs.cpp b/tools/CIndex/CIndexUSRs.cpp
deleted file mode 100644
index 58870b9..0000000
--- a/tools/CIndex/CIndexUSRs.cpp
+++ /dev/null
@@ -1,469 +0,0 @@
-//===- 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
deleted file mode 100644
index d5131ff..0000000
--- a/tools/CIndex/CIndexer.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-//===- 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/CMakeLists.txt b/tools/CIndex/CMakeLists.txt
deleted file mode 100644
index 609719e..0000000
--- a/tools/CIndex/CMakeLists.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-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
deleted file mode 100644
index 3bc5d01..0000000
--- a/tools/CIndex/CXCursor.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-//===- 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
deleted file mode 100644
index 1664f5a..0000000
--- a/tools/CIndex/CXCursor.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//===- 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
deleted file mode 100644
index 66566c1..0000000
--- a/tools/CIndex/CXSourceLocation.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//===- 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
deleted file mode 100644
index 391746d..0000000
--- a/tools/CIndex/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-##===- 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
index 64c3a21..ae33b78 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -1,3 +1,3 @@
-add_subdirectory(CIndex)
+add_subdirectory(libclang)
 add_subdirectory(c-index-test)
 add_subdirectory(driver)
diff --git a/tools/Makefile b/tools/Makefile
index bfd5ad1..0202cc5 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -7,13 +7,13 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL := ../../..
-DIRS := driver CIndex c-index-test
+CLANG_LEVEL := ..
+DIRS := driver libclang c-index-test
 
-include $(LEVEL)/Makefile.config
+include $(CLANG_LEVEL)/../../Makefile.config
 
-ifeq ($(OS), $(filter $(OS), Cygwin MingW))
-DIRS := $(filter-out CIndex c-index-test, $(DIRS))
+ifeq ($(OS), $(filter $(OS), Cygwin MingW Minix))
+DIRS := $(filter-out libclang c-index-test, $(DIRS))
 endif
 
-include $(LEVEL)/Makefile.common
+include $(CLANG_LEVEL)/Makefile
diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt
index f0a34a5..5cf2cd6 100644
--- a/tools/c-index-test/CMakeLists.txt
+++ b/tools/c-index-test/CMakeLists.txt
@@ -1,14 +1,15 @@
 set(LLVM_NO_RTTI 1)
 
 set( LLVM_USED_LIBS
-  CIndex
+  libclang
   clangIndex
   clangFrontend
   clangDriver
+  clangSerialization
+  clangParse
   clangSema
   clangAnalysis
   clangAST
-  clangParse
   clangLex
   clangBasic
   )
diff --git a/tools/c-index-test/Makefile b/tools/c-index-test/Makefile
index e9ba174..f41aa80 100644
--- a/tools/c-index-test/Makefile
+++ b/tools/c-index-test/Makefile
@@ -6,19 +6,16 @@
 # License. See LICENSE.TXT for details.
 # 
 ##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
+CLANG_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
+USEDLIBS = clang.a clangIndex.a clangFrontend.a clangDriver.a \
+	   clangSerialization.a clangParse.a clangSema.a clangAnalysis.a \
+	   clangAST.a clangLex.a clangBasic.a
 
-include $(LLVM_SRC_ROOT)/Makefile.rules
+include $(CLANG_LEVEL)/Makefile
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 4941816..cdf0cd0 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1,6 +1,7 @@
 /* c-index-test.c */
 
 #include "clang-c/Index.h"
+#include <ctype.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -28,6 +29,18 @@
 extern char *basename(const char *);
 #endif
 
+/** \brief Return the default parsing options. */
+static unsigned getDefaultParsingOptions() {
+  unsigned options = CXTranslationUnit_DetailedPreprocessingRecord;
+
+  if (getenv("CINDEXTEST_EDITING"))
+    options |= clang_defaultEditingTranslationUnitOptions();
+  if (getenv("CINDEXTEST_COMPLETION_CACHING"))
+    options |= CXTranslationUnit_CacheCompletionResults;
+  
+  return options;
+}
+
 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,
@@ -38,7 +51,7 @@
                                       CXTranslationUnit *TU) {
 
   *TU = clang_createTranslationUnit(Idx, file);
-  if (!TU) {
+  if (!*TU) {
     fprintf(stderr, "Unable to load translation unit from '%s'!\n", file);
     return 0;
   }
@@ -52,6 +65,7 @@
     free((char *)unsaved_files[i].Filename);
     free((char *)unsaved_files[i].Contents);
   }
+  free(unsaved_files);
 }
 
 int parse_remapped_files(int argc, const char **argv, int start_arg,
@@ -75,8 +89,8 @@
     return 0;
 
   *unsaved_files
-  = (struct CXUnsavedFile *)malloc(sizeof(struct CXUnsavedFile) *
-                                   *num_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;
@@ -169,6 +183,47 @@
 
     if (clang_isCursorDefinition(Cursor))
       printf(" (Definition)");
+    
+    switch (clang_getCursorAvailability(Cursor)) {
+      case CXAvailability_Available:
+        break;
+        
+      case CXAvailability_Deprecated:
+        printf(" (deprecated)");
+        break;
+        
+      case CXAvailability_NotAvailable:
+        printf(" (unavailable)");
+        break;
+    }
+    
+    if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
+      CXType T =
+        clang_getCanonicalType(clang_getIBOutletCollectionType(Cursor));
+      CXString S = clang_getTypeKindSpelling(T.kind);
+      printf(" [IBOutletCollection=%s]", clang_getCString(S));
+      clang_disposeString(S);
+    }
+    
+    if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
+      enum CX_CXXAccessSpecifier access = clang_getCXXAccessSpecifier(Cursor);
+      unsigned isVirtual = clang_isVirtualBase(Cursor);
+      const char *accessStr = 0;
+
+      switch (access) {
+        case CX_CXXInvalidAccessSpecifier:
+          accessStr = "invalid"; break;
+        case CX_CXXPublic:
+          accessStr = "public"; break;
+        case CX_CXXProtected:
+          accessStr = "protected"; break;
+        case CX_CXXPrivate:
+          accessStr = "private"; break;
+      }      
+      
+      printf(" [access=%s isVirtual=%s]", accessStr,
+             isVirtual ? "true" : "false");
+    }
   }
 }
 
@@ -447,6 +502,46 @@
 }
 
 /******************************************************************************/
+/* Typekind testing.                                                          */
+/******************************************************************************/
+
+static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p,
+                                             CXClientData d) {
+
+  if (!clang_isInvalid(clang_getCursorKind(cursor))) {
+    CXType T = clang_getCursorType(cursor);
+    CXString S = clang_getTypeKindSpelling(T.kind);
+    PrintCursor(cursor);
+    printf(" typekind=%s", clang_getCString(S));
+    clang_disposeString(S);
+    /* Print the canonical type if it is different. */
+    {
+      CXType CT = clang_getCanonicalType(T);
+      if (!clang_equalTypes(T, CT)) {
+        CXString CS = clang_getTypeKindSpelling(CT.kind);
+        printf(" [canonical=%s]", clang_getCString(CS));
+        clang_disposeString(CS);
+      }
+    }
+    /* Print the return type if it exists. */
+    {
+      CXType RT = clang_getCursorResultType(cursor);
+      if (RT.kind != CXType_Invalid) {
+        CXString RS = clang_getTypeKindSpelling(RT.kind);
+        printf(" [result=%s]", clang_getCString(RS));
+        clang_disposeString(RS);
+      }
+    }
+    /* Print if this is a non-POD type. */
+    printf(" [isPOD=%d]", clang_isPODType(T));
+
+    printf("\n");
+  }
+  return CXChildVisit_Recurse;
+}
+
+
+/******************************************************************************/
 /* Loading ASTs/source.                                                       */
 /******************************************************************************/
 
@@ -520,7 +615,7 @@
   struct CXUnsavedFile *unsaved_files = 0;
   int num_unsaved_files = 0;
   int result;
-
+  
   Idx = clang_createIndex(/* excludeDeclsFromPCH */
                           !strcmp(filter, "local") ? 1 : 0,
                           /* displayDiagnosics=*/1);
@@ -540,6 +635,7 @@
                                                  unsaved_files);
   if (!TU) {
     fprintf(stderr, "Unable to load translation unit!\n");
+    free_remapped_files(unsaved_files, num_unsaved_files);
     clang_disposeIndex(Idx);
     return 1;
   }
@@ -550,6 +646,60 @@
   return result;
 }
 
+int perform_test_reparse_source(int argc, const char **argv, int trials,
+                                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;
+  int trial;
+  
+  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;
+  }
+  
+  /* Load the initial translation unit -- we do this without honoring remapped
+   * files, so that we have a way to test results after changing the source. */
+  TU = clang_parseTranslationUnit(Idx, 0,
+                                  argv + num_unsaved_files,
+                                  argc - num_unsaved_files,
+                                  0, 0, getDefaultParsingOptions());
+  if (!TU) {
+    fprintf(stderr, "Unable to load translation unit!\n");
+    free_remapped_files(unsaved_files, num_unsaved_files);
+    clang_disposeIndex(Idx);
+    return 1;
+  }
+  
+  for (trial = 0; trial < trials; ++trial) {
+    if (clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+                                     clang_defaultReparseOptions(TU))) {
+      fprintf(stderr, "Unable to reparse translation unit!\n");
+      clang_disposeTranslationUnit(TU);
+      free_remapped_files(unsaved_files, num_unsaved_files);
+      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().                                       */
 /******************************************************************************/
@@ -757,10 +907,43 @@
   clang_disposeString(ks);
 
   print_completion_string(completion_result->CompletionString, file);
+  fprintf(file, " (%u)", 
+          clang_getCompletionPriority(completion_result->CompletionString));
+  switch (clang_getCompletionAvailability(completion_result->CompletionString)){
+  case CXAvailability_Available:
+    break;
+    
+  case CXAvailability_Deprecated:
+    fprintf(file, " (deprecated)");
+    break;
+    
+  case CXAvailability_NotAvailable:
+    fprintf(file, " (unavailable)");
+    break;
+  }
   fprintf(file, "\n");
 }
 
-int perform_code_completion(int argc, const char **argv) {
+int my_stricmp(const char *s1, const char *s2) {
+  while (*s1 && *s2) {
+    int c1 = tolower(*s1), c2 = tolower(*s2);
+    if (c1 < c2)
+      return -1;
+    else if (c1 > c2)
+      return 1;
+    
+    ++s1;
+    ++s2;
+  }
+  
+  if (*s1)
+    return 1;
+  else if (*s2)
+    return -1;
+  return 0;
+}
+
+int perform_code_completion(int argc, const char **argv, int timing_only) {
   const char *input = argv[1];
   char *filename = 0;
   unsigned line;
@@ -770,8 +953,13 @@
   struct CXUnsavedFile *unsaved_files = 0;
   int num_unsaved_files = 0;
   CXCodeCompleteResults *results = 0;
+  CXTranslationUnit *TU = 0;
+  
+  if (timing_only)
+    input += strlen("-code-completion-timing=");
+  else
+    input += strlen("-code-completion-at=");
 
-  input += strlen("-code-completion-at=");
   if ((errorCode = parse_file_line_column(input, &filename, &line, &column,
                                           0, 0)))
     return errorCode;
@@ -780,16 +968,43 @@
     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 (getenv("CINDEXTEST_EDITING")) {
+    unsigned I, Repeats = 5;
+    TU = clang_parseTranslationUnit(CIdx, 0,
+                                    argv + num_unsaved_files + 2,
+                                    argc - num_unsaved_files - 2,
+                                    0, 0, getDefaultParsingOptions());
+    if (!TU) {
+      fprintf(stderr, "Unable to load translation unit!\n");
+      return 1;
+    }
+    for (I = 0; I != Repeats; ++I) {
+      results = clang_codeCompleteAt(TU, filename, line, column,
+                                     unsaved_files, num_unsaved_files,
+                                     clang_defaultCodeCompleteOptions());
+      if (!results) {
+        fprintf(stderr, "Unable to perform code completion!\n");
+        return 1;
+      }
+      if (I != Repeats-1)
+        clang_disposeCodeCompleteResults(results);
+    }
+  } else
+    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);
+    if (!timing_only) {      
+      /* Sort the code-completion results based on the typed text. */
+      clang_sortCodeCompletionResults(results->Results, 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);
@@ -798,7 +1013,7 @@
     }
     clang_disposeCodeCompleteResults(results);
   }
-
+  clang_disposeTranslationUnit(TU);
   clang_disposeIndex(CIdx);
   free(filename);
 
@@ -1153,6 +1368,43 @@
 /******************************************************************************/
 /* Command line processing.                                                   */
 /******************************************************************************/
+int write_pch_file(const char *filename, int argc, const char *argv[]) {
+  CXIndex Idx;
+  CXTranslationUnit TU;
+  struct CXUnsavedFile *unsaved_files = 0;
+  int num_unsaved_files = 0;
+  
+  Idx = clang_createIndex(/* excludeDeclsFromPCH */1, /* displayDiagnosics=*/1);
+  
+  if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) {
+    clang_disposeIndex(Idx);
+    return -1;
+  }
+  
+  TU = clang_parseTranslationUnit(Idx, 0,
+                                  argv + num_unsaved_files,
+                                  argc - num_unsaved_files,
+                                  unsaved_files,
+                                  num_unsaved_files,
+                                  CXTranslationUnit_Incomplete);
+  if (!TU) {
+    fprintf(stderr, "Unable to load translation unit!\n");
+    free_remapped_files(unsaved_files, num_unsaved_files);
+    clang_disposeIndex(Idx);
+    return 1;
+  }
+
+  if (clang_saveTranslationUnit(TU, filename, clang_defaultSaveOptions(TU)))
+    fprintf(stderr, "Unable to write PCH file %s\n", filename);
+  clang_disposeTranslationUnit(TU);
+  free_remapped_files(unsaved_files, num_unsaved_files);
+  clang_disposeIndex(Idx);
+  return 0;  
+}
+
+/******************************************************************************/
+/* Command line processing.                                                   */
+/******************************************************************************/
 
 static CXCursorVisitor GetVisitor(const char *s) {
   if (s[0] == '\0')
@@ -1165,6 +1417,7 @@
 static void print_usage(void) {
   fprintf(stderr,
     "usage: c-index-test -code-completion-at=<site> <compiler arguments>\n"
+    "       c-index-test -code-completion-timing=<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"
@@ -1172,15 +1425,21 @@
           "[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");
+    "       c-index-test -test-load-source <symbol filter> {<args>}*\n");
   fprintf(stderr,
+    "       c-index-test -test-load-source-reparse <trials> <symbol filter> "
+    "          {<args>}*\n"
+    "       c-index-test -test-load-source-usrs <symbol filter> {<args>}*\n"
     "       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"
+    "       c-index-test -test-print-typekind {<args>}*\n"
+    "       c-index-test -print-usr [<CursorKind> {<args>}]*\n");
+  fprintf(stderr,
+    "       c-index-test -print-usr-file <file>\n"
+    "       c-index-test -write-pch <file> <compiler arguments>\n\n");
+  fprintf(stderr,
     " <symbol filter> values:\n%s",
     "   all - load all symbols, including those from PCH\n"
     "   local - load all symbols except those in PCH\n"
@@ -1195,7 +1454,9 @@
 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);
+    return perform_code_completion(argc, argv, 0);
+  if (argc > 2 && strstr(argv[1], "-code-completion-timing=") == argv[1])
+    return perform_code_completion(argc, argv, 1);
   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) {
@@ -1204,6 +1465,14 @@
       return perform_test_load_tu(argv[2], argv[3], argc >= 5 ? argv[4] : 0, I,
                                   NULL);
   }
+  else if (argc >= 5 && strncmp(argv[1], "-test-load-source-reparse", 25) == 0){
+    CXCursorVisitor I = GetVisitor(argv[1] + 25);
+    if (I) {
+      int trials = atoi(argv[2]);
+      return perform_test_reparse_source(argc - 4, argv + 4, trials, argv[3], I, 
+                                         NULL);
+    }
+  }
   else if (argc >= 4 && strncmp(argv[1], "-test-load-source", 17) == 0) {
     CXCursorVisitor I = GetVisitor(argv[1] + 17);
     if (I)
@@ -1223,6 +1492,9 @@
   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 > 2 && strcmp(argv[1], "-test-print-typekind") == 0)
+    return perform_test_load_source(argc - 2, argv + 2, "all",
+                                    PrintTypeKind, 0);
   else if (argc > 1 && strcmp(argv[1], "-print-usr") == 0) {
     if (argc > 2)
       return print_usrs(argv + 2, argv + argc);
@@ -1233,7 +1505,9 @@
   }
   else if (argc > 2 && strcmp(argv[1], "-print-usr-file") == 0)
     return print_usrs_file(argv[2]);
-
+  else if (argc > 2 && strcmp(argv[1], "-write-pch") == 0)
+    return write_pch_file(argv[2], argc - 3, argv + 3);
+           
   print_usage();
   return 1;
 }
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index c4320b0..ec6e9c6 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -1,21 +1,25 @@
 set(LLVM_NO_RTTI 1)
 
 set( LLVM_USED_LIBS
+  clangFrontendTool
   clangFrontend
   clangDriver
+  clangSerialization
   clangCodeGen
+  clangParse
   clangSema
   clangChecker
   clangAnalysis
+  clangIndex
   clangRewrite
   clangAST
-  clangParse
   clangLex
   clangBasic
   )
 
 set( LLVM_LINK_COMPONENTS
   ${LLVM_TARGETS_TO_BUILD}
+  asmparser
   bitreader
   bitwriter
   codegen
@@ -26,10 +30,12 @@
 add_clang_executable(clang
   driver.cpp
   cc1_main.cpp
+  cc1as_main.cpp
   )
 
 if(UNIX)
   set(CLANGXX_LINK_OR_COPY create_symlink)
+  set(CLANGXX_DESTDIR $ENV{DESTDIR}/)
 else()
   set(CLANGXX_LINK_OR_COPY copy)
 endif()
@@ -45,4 +51,4 @@
   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}\")")
+install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" -E ${CLANGXX_LINK_OR_COPY} \"${CMAKE_INSTALL_PREFIX}/bin/clang${CMAKE_EXECUTABLE_SUFFIX}\" \"${CLANGXX_DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/clang++${CMAKE_EXECUTABLE_SUFFIX}\")")
diff --git a/tools/driver/Info.plist.in b/tools/driver/Info.plist.in
new file mode 100644
index 0000000..c938fb0
--- /dev/null
+++ b/tools/driver/Info.plist.in
@@ -0,0 +1,18 @@
+<?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>CFBundleIdentifier</key>
+        <string>@TOOL_INFO_UTI@</string>
+        <key>CFBundleInfoDictionaryVersion</key>
+        <string>6.0</string>
+        <key>CFBundleName</key>
+        <string>@TOOL_INFO_NAME</string>
+	<key>CFBundleShortVersionString</key>
+	<string>@TOOL_INFO_VERSION@</string>
+        <key>CFBundleVersion</key>
+        <string>@TOOL_INFO_BUILD_VERSION@</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+</dict>
+</plist>
diff --git a/tools/driver/Makefile b/tools/driver/Makefile
index f88d229..447f0e4 100644
--- a/tools/driver/Makefile
+++ b/tools/driver/Makefile
@@ -6,7 +6,7 @@
 # License. See LICENSE.TXT for details.
 #
 ##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
+CLANG_LEVEL := ../..
 
 TOOLNAME = clang
 ifndef CLANG_IS_PRODUCTION
@@ -16,22 +16,46 @@
     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 tool version information on OS X.
+TOOL_INFO_PLIST := Info.plist
 
 # 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
+include $(CLANG_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
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \
+                   ipo selectiondag
+USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \
+           clangSerialization.a clangCodeGen.a clangParse.a clangSema.a \
+           clangChecker.a clangAnalysis.a clangIndex.a clangRewrite.a \
+           clangAST.a clangLex.a clangBasic.a
 
-include $(LLVM_SRC_ROOT)/Makefile.rules
+include $(CLANG_LEVEL)/Makefile
+
+# Set the tool version information values.
+ifeq ($(HOST_OS),Darwin)
+ifdef CLANG_VENDOR
+TOOL_INFO_NAME := $(CLANG_VENDOR) clang
+else
+TOOL_INFO_NAME := clang
+endif
+
+ifdef CLANG_VENDOR_UTI
+TOOL_INFO_UTI := $(CLANG_VENDOR_UTI)
+else
+TOOL_INFO_UTI := org.llvm.clang
+endif
+
+TOOL_INFO_VERSION := $(word 3,$(shell grep "CLANG_VERSION " \
+	$(PROJ_OBJ_DIR)/$(CLANG_LEVEL)/include/clang/Basic/Version.inc))
+ifdef LLVM_SUBMIT_VERSION
+TOOL_INFO_BUILD_VERSION := $(LLVM_SUBMIT_VERSION).$(LLVM_SUBMIT_SUBVERSION)
+else
+TOOL_INFO_BUILD_VERSION := 
+endif
+endif
 
 # Translate make variable to define when building a "production" clang.
 ifdef CLANG_IS_PRODUCTION
diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp
index 144a734..de5e8bf 100644
--- a/tools/driver/cc1_main.cpp
+++ b/tools/driver/cc1_main.cpp
@@ -1,4 +1,4 @@
-//===-- cc1_main.cpp - Clang CC1 Driver -----------------------------------===//
+//===-- cc1_main.cpp - Clang CC1 Compiler Frontend ------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -13,28 +13,23 @@
 //
 //===----------------------------------------------------------------------===//
 
-#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 "clang/FrontendTool/Utils.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;
@@ -43,7 +38,7 @@
 // Main driver
 //===----------------------------------------------------------------------===//
 
-void LLVMErrorHandler(void *UserData, const std::string &Message) {
+static void LLVMErrorHandler(void *UserData, const std::string &Message) {
   Diagnostic &Diags = *static_cast<Diagnostic*>(UserData);
 
   Diags.Report(diag::err_fe_error_backend) << Message;
@@ -52,82 +47,6 @@
   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) {
@@ -202,8 +121,8 @@
 
   // Run clang -cc1 test.
   if (ArgBegin != ArgEnd && llvm::StringRef(ArgBegin[0]) == "-cc1test") {
-    TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions());
-    Diagnostic Diags(&DiagClient);
+    Diagnostic Diags(new TextDiagnosticPrinter(llvm::errs(), 
+                                               DiagnosticOptions()));
     return cc1_test(Diags, ArgBegin + 1, ArgEnd);
   }
 
@@ -214,8 +133,8 @@
 
   // Buffer diagnostics from argument parsing so that we can output them using a
   // well formed diagnostic object.
-  TextDiagnosticBuffer DiagsBuffer;
-  Diagnostic Diags(&DiagsBuffer);
+  TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
+  Diagnostic Diags(DiagsBuffer);
   CompilerInvocation::CreateFromArgs(Clang->getInvocation(), ArgBegin, ArgEnd,
                                      Diags);
 
@@ -225,35 +144,6 @@
     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())
@@ -264,33 +154,20 @@
   llvm::install_fatal_error_handler(LLVMErrorHandler,
                                   static_cast<void*>(&Clang->getDiagnostics()));
 
-  DiagsBuffer.FlushDiagnostics(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();
-    }
-  }
+  // Execute the frontend actions.
+  bool Success = ExecuteCompilerInvocation(Clang.get());
 
   // 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());
-  
+
+  // Our error handler depends on the Diagnostics object, which we're
+  // potentially about to delete. Uninstall the handler now so that any
+  // later errors use the default handling behavior instead.
+  llvm::remove_fatal_error_handler();
+
   // When running with -disable-free, don't do any destruction or shutdown.
   if (Clang->getFrontendOpts().DisableFree) {
     if (Clang->getFrontendOpts().ShowStats)
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
new file mode 100644
index 0000000..b8f2b68
--- /dev/null
+++ b/tools/driver/cc1as_main.cpp
@@ -0,0 +1,376 @@
+//===-- cc1as_main.cpp - Clang Assembler  ---------------------------------===//
+//
+//                     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 -cc1as functionality, which implements
+// the direct interface to the LLVM MC based assembler.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/CC1AsOptions.h"
+#include "clang/Driver/OptTable.h"
+#include "clang/Driver/Options.h"
+#include "clang/Frontend/DiagnosticOptions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/SourceMgr.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"
+#include "llvm/Target/TargetAsmBackend.h"
+#include "llvm/Target/TargetAsmParser.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Target/TargetSelect.h"
+using namespace clang;
+using namespace clang::driver;
+using namespace llvm;
+
+namespace {
+
+/// \brief Helper class for representing a single invocation of the assembler.
+struct AssemblerInvocation {
+  /// @name Target Options
+  /// @{
+
+  std::string Triple;
+
+  /// @}
+  /// @name Language Options
+  /// @{
+
+  std::vector<std::string> IncludePaths;
+  unsigned NoInitialTextSection : 1;
+
+  /// @}
+  /// @name Frontend Options
+  /// @{
+
+  std::string InputFile;
+  std::vector<std::string> LLVMArgs;
+  std::string OutputPath;
+  enum FileType {
+    FT_Asm,  ///< Assembly (.s) output, transliterate mode.
+    FT_Null, ///< No output, for timing purposes.
+    FT_Obj   ///< Object file output.
+  };
+  FileType OutputType;
+  unsigned ShowHelp : 1;
+  unsigned ShowVersion : 1;
+
+  /// @}
+  /// @name Transliterate Options
+  /// @{
+
+  unsigned OutputAsmVariant;
+  unsigned ShowEncoding : 1;
+  unsigned ShowInst : 1;
+
+  /// @}
+  /// @name Assembler Options
+  /// @{
+
+  unsigned RelaxAll : 1;
+
+  /// @}
+
+public:
+  AssemblerInvocation() {
+    Triple = "";
+    NoInitialTextSection = 0;
+    InputFile = "-";
+    OutputPath = "-";
+    OutputType = FT_Asm;
+    OutputAsmVariant = 0;
+    ShowInst = 0;
+    ShowEncoding = 0;
+    RelaxAll = 0;
+  }
+
+  static void CreateFromArgs(AssemblerInvocation &Res, const char **ArgBegin,
+                             const char **ArgEnd, Diagnostic &Diags);
+};
+
+}
+
+void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
+                                         const char **ArgBegin,
+                                         const char **ArgEnd,
+                                         Diagnostic &Diags) {
+  using namespace clang::driver::cc1asoptions;
+  // Parse the arguments.
+  OwningPtr<OptTable> OptTbl(createCC1AsOptTable());
+  unsigned MissingArgIndex, MissingArgCount;
+  OwningPtr<InputArgList> Args(
+    OptTbl->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(cc1asoptions::OPT_UNKNOWN),
+         ie = Args->filtered_end(); it != ie; ++it)
+    Diags.Report(diag::err_drv_unknown_argument) << (*it) ->getAsString(*Args);
+
+  // Construct the invocation.
+
+  // Target Options
+  Opts.Triple = Args->getLastArgValue(OPT_triple);
+  if (Opts.Triple.empty()) // Use the host triple if unspecified.
+    Opts.Triple = sys::getHostTriple();
+
+  // Language Options
+  Opts.IncludePaths = Args->getAllArgValues(OPT_I);
+  Opts.NoInitialTextSection = Args->hasArg(OPT_n);
+
+  // Frontend Options
+  if (Args->hasArg(OPT_INPUT)) {
+    bool First = true;
+    for (arg_iterator it = Args->filtered_begin(OPT_INPUT),
+           ie = Args->filtered_end(); it != ie; ++it, First=false) {
+      const Arg *A = it;
+      if (First)
+        Opts.InputFile = A->getValue(*Args);
+      else
+        Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(*Args);
+    }
+  }
+  Opts.LLVMArgs = Args->getAllArgValues(OPT_mllvm);
+  Opts.OutputPath = Args->getLastArgValue(OPT_o);
+  if (Arg *A = Args->getLastArg(OPT_filetype)) {
+    StringRef Name = A->getValue(*Args);
+    unsigned OutputType = StringSwitch<unsigned>(Name)
+      .Case("asm", FT_Asm)
+      .Case("null", FT_Null)
+      .Case("obj", FT_Obj)
+      .Default(~0U);
+    if (OutputType == ~0U)
+      Diags.Report(diag::err_drv_invalid_value)
+        << A->getAsString(*Args) << Name;
+    else
+      Opts.OutputType = FileType(OutputType);
+  }
+  Opts.ShowHelp = Args->hasArg(OPT_help);
+  Opts.ShowVersion = Args->hasArg(OPT_version);
+
+  // Transliterate Options
+  Opts.OutputAsmVariant = Args->getLastArgIntValue(OPT_output_asm_variant,
+                                                   0, Diags);
+  Opts.ShowEncoding = Args->hasArg(OPT_show_encoding);
+  Opts.ShowInst = Args->hasArg(OPT_show_inst);
+
+  // Assemble Options
+  Opts.RelaxAll = Args->hasArg(OPT_relax_all);
+}
+
+static formatted_raw_ostream *GetOutputStream(AssemblerInvocation &Opts,
+                                              Diagnostic &Diags,
+                                              bool Binary) {
+  if (Opts.OutputPath.empty())
+    Opts.OutputPath = "-";
+
+  // Make sure that the Out file gets unlinked from the disk if we get a
+  // SIGINT.
+  if (Opts.OutputPath != "-")
+    sys::RemoveFileOnSignal(sys::Path(Opts.OutputPath));
+
+  std::string Error;
+  raw_fd_ostream *Out =
+    new raw_fd_ostream(Opts.OutputPath.c_str(), Error,
+                       (Binary ? raw_fd_ostream::F_Binary : 0));
+  if (!Error.empty()) {
+    Diags.Report(diag::err_fe_unable_to_open_output)
+      << Opts.OutputPath << Error;
+    return 0;
+  }
+
+  return new formatted_raw_ostream(*Out, formatted_raw_ostream::DELETE_STREAM);
+}
+
+static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) {
+  // Get the target specific parser.
+  std::string Error;
+  const Target *TheTarget(TargetRegistry::lookupTarget(Opts.Triple, Error));
+  if (!TheTarget) {
+    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
+    return false;
+  }
+
+  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(Opts.InputFile, &Error);
+  if (Buffer == 0) {
+    Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
+    return false;
+  }
+
+  SourceMgr SrcMgr;
+
+  // Tell SrcMgr about this buffer, which is what the parser will pick up.
+  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
+
+  // Record the location of the include directories so that the lexer can find
+  // it later.
+  SrcMgr.setIncludeDirs(Opts.IncludePaths);
+
+  OwningPtr<MCAsmInfo> MAI(TheTarget->createAsmInfo(Opts.Triple));
+  assert(MAI && "Unable to create target asm info!");
+
+  MCContext Ctx(*MAI);
+  bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
+  formatted_raw_ostream *Out = GetOutputStream(Opts, Diags, IsBinary);
+  if (!Out)
+    return false;
+
+  // FIXME: We shouldn't need to do this (and link in codegen).
+  OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(Opts.Triple, ""));
+  if (!TM) {
+    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
+    return false;
+  }
+
+  OwningPtr<MCStreamer> Str;
+
+  if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
+    MCInstPrinter *IP =
+      TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI);
+    MCCodeEmitter *CE = 0;
+    if (Opts.ShowEncoding)
+      CE = TheTarget->createCodeEmitter(*TM, Ctx);
+    Str.reset(createAsmStreamer(Ctx, *Out,TM->getTargetData()->isLittleEndian(),
+                                /*asmverbose*/true, IP, CE, Opts.ShowInst));
+  } else if (Opts.OutputType == AssemblerInvocation::FT_Null) {
+    Str.reset(createNullStreamer(Ctx));
+  } else {
+    assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
+           "Invalid file type!");
+    MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM, Ctx);
+    TargetAsmBackend *TAB = TheTarget->createAsmBackend(Opts.Triple);
+    Str.reset(TheTarget->createObjectStreamer(Opts.Triple, Ctx, *TAB, *Out,
+                                              CE, Opts.RelaxAll));
+  }
+
+  OwningPtr<MCAsmParser> Parser(createMCAsmParser(*TheTarget, SrcMgr, Ctx,
+                                                  *Str.get(), *MAI));
+  OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(*Parser, *TM));
+  if (!TAP) {
+    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
+    return false;
+  }
+
+  Parser->setTargetParser(*TAP.get());
+
+  bool Success = !Parser->Run(Opts.NoInitialTextSection);
+
+  // Close the output.
+  delete Out;
+
+  // Delete output on errors.
+  if (!Success && Opts.OutputPath != "-")
+    sys::Path(Opts.OutputPath).eraseFromDisk();
+
+  return Success;
+}
+
+static 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);
+}
+
+int cc1as_main(const char **ArgBegin, const char **ArgEnd,
+               const char *Argv0, void *MainAddr) {
+  // Print a stack trace if we signal out.
+  sys::PrintStackTraceOnErrorSignal();
+  PrettyStackTraceProgram X(ArgEnd - ArgBegin, ArgBegin);
+  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
+
+  // Initialize targets and assembly printers/parsers.
+  InitializeAllTargetInfos();
+  // FIXME: We shouldn't need to initialize the Target(Machine)s.
+  InitializeAllTargets();
+  InitializeAllAsmPrinters();
+  InitializeAllAsmParsers();
+
+  // Construct our diagnostic client.
+  TextDiagnosticPrinter *DiagClient
+    = new TextDiagnosticPrinter(errs(), DiagnosticOptions());
+  DiagClient->setPrefix("clang -cc1as");
+  Diagnostic Diags(DiagClient);
+
+  // Set an error handler, so that any LLVM backend diagnostics go through our
+  // error handler.
+  ScopedFatalErrorHandler FatalErrorHandler
+    (LLVMErrorHandler, static_cast<void*>(&Diags));
+
+  // Parse the arguments.
+  AssemblerInvocation Asm;
+  AssemblerInvocation::CreateFromArgs(Asm, ArgBegin, ArgEnd, Diags);
+
+  // Honor -help.
+  if (Asm.ShowHelp) {
+    llvm::OwningPtr<driver::OptTable> Opts(driver::createCC1AsOptTable());
+    Opts->PrintHelp(llvm::outs(), "clang -cc1as", "Clang Integrated Assembler");
+    return 0;
+  }
+
+  // Honor -version.
+  //
+  // FIXME: Use a better -version message?
+  if (Asm.ShowVersion) {
+    llvm::cl::PrintVersionMessage();
+    return 0;
+  }
+
+  // Honor -mllvm.
+  //
+  // FIXME: Remove this, one day.
+  if (!Asm.LLVMArgs.empty()) {
+    unsigned NumArgs = Asm.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] = Asm.LLVMArgs[i].c_str();
+    Args[NumArgs + 1] = 0;
+    llvm::cl::ParseCommandLineOptions(NumArgs + 1, const_cast<char **>(Args));
+  }
+
+  // Execute the invocation, unless there were parsing errors.
+  bool Success = false;
+  if (!Diags.getNumErrors())
+    Success = ExecuteAssembler(Asm, Diags);
+
+  // If any timers were active but haven't been destroyed yet, print their
+  // results now.
+  TimerGroup::printAll(errs());
+
+  return !Success;
+}
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index 3f1cca1..c058ece 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -19,15 +19,19 @@
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/Config/config.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.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/Program.h"
 #include "llvm/System/Signals.h"
 using namespace clang;
 using namespace clang::driver;
@@ -75,7 +79,7 @@
 /// \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::SmallVectorImpl<const char*> &Args,
                                llvm::StringRef Edit,
                                std::set<std::string> &SavedStrings) {
   // This does not need to be efficient.
@@ -141,7 +145,7 @@
 
 /// ApplyQAOverride - Apply a comma separate list of edits to the
 /// input argument lists. See ApplyOneQAOverride.
-static void ApplyQAOverride(std::vector<const char*> &Args,
+static void ApplyQAOverride(llvm::SmallVectorImpl<const char*> &Args,
                             const char *OverrideStr,
                             std::set<std::string> &SavedStrings) {
   llvm::raw_ostream *OS = &llvm::errs();
@@ -170,18 +174,109 @@
 
 extern int cc1_main(const char **ArgBegin, const char **ArgEnd,
                     const char *Argv0, void *MainAddr);
+extern int cc1as_main(const char **ArgBegin, const char **ArgEnd,
+                      const char *Argv0, void *MainAddr);
 
-int main(int argc, const char **argv) {
+static void ExpandArgsFromBuf(const char *Arg,
+                              llvm::SmallVectorImpl<const char*> &ArgVector,
+                              std::set<std::string> &SavedStrings) {
+  const char *FName = Arg + 1;
+  llvm::MemoryBuffer *MemBuf = llvm::MemoryBuffer::getFile(FName);
+  if (!MemBuf) {
+    ArgVector.push_back(SaveStringInSet(SavedStrings, Arg));
+    return;
+  }
+
+  const char *Buf = MemBuf->getBufferStart();
+  char InQuote = ' ';
+  std::string CurArg;
+
+  for (const char *P = Buf; ; ++P) {
+    if (*P == '\0' || (isspace(*P) && InQuote == ' ')) {
+      if (!CurArg.empty()) {
+
+        if (CurArg[0] != '@') {
+          ArgVector.push_back(SaveStringInSet(SavedStrings, CurArg));
+        } else {
+          ExpandArgsFromBuf(CurArg.c_str(), ArgVector, SavedStrings);
+        }
+
+        CurArg = "";
+      }
+      if (*P == '\0')
+        break;
+      else
+        continue;
+    }
+
+    if (isspace(*P)) {
+      if (InQuote != ' ')
+        CurArg.push_back(*P);
+      continue;
+    }
+
+    if (*P == '"' || *P == '\'') {
+      if (InQuote == *P)
+        InQuote = ' ';
+      else if (InQuote == ' ')
+        InQuote = *P;
+      else
+        CurArg.push_back(*P);
+      continue;
+    }
+
+    if (*P == '\\') {
+      ++P;
+      if (*P != '\0')
+        CurArg.push_back(*P);
+      continue;
+    }
+    CurArg.push_back(*P);
+  }
+  delete MemBuf;
+}
+
+static void ExpandArgv(int argc, const char **argv,
+                       llvm::SmallVectorImpl<const char*> &ArgVector,
+                       std::set<std::string> &SavedStrings) {
+  for (int i = 0; i < argc; ++i) {
+    const char *Arg = argv[i];
+    if (Arg[0] != '@') {
+      ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg)));
+      continue;
+    }
+
+    ExpandArgsFromBuf(Arg, ArgVector, SavedStrings);
+  }
+}
+
+int main(int argc_, const char **argv_) {
   llvm::sys::PrintStackTraceOnErrorSignal();
-  llvm::PrettyStackTraceProgram X(argc, argv);
+  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);
+  std::set<std::string> SavedStrings;
+  llvm::SmallVector<const char*, 256> argv;
+
+  ExpandArgv(argc_, argv_, argv, SavedStrings);
+
+  // Handle -cc1 integrated tools.
+  if (argv.size() > 1 && llvm::StringRef(argv[1]).startswith("-cc1")) {
+    llvm::StringRef Tool = argv[1] + 4;
+
+    if (Tool == "")
+      return cc1_main(argv.data()+2, argv.data()+argv.size(), argv[0],
+                      (void*) (intptr_t) GetExecutablePath);
+    if (Tool == "as")
+      return cc1as_main(argv.data()+2, argv.data()+argv.size(), argv[0],
+                      (void*) (intptr_t) GetExecutablePath);
+
+    // Reject unknown tools.
+    llvm::errs() << "error: unknown integrated tool '" << Tool << "'\n";
+    return 1;
+  }
 
   bool CanonicalPrefixes = true;
-  for (int i = 1; i < argc; ++i) {
+  for (int i = 1, size = argv.size(); i < size; ++i) {
     if (llvm::StringRef(argv[i]) == "-no-canonical-prefixes") {
       CanonicalPrefixes = false;
       break;
@@ -190,10 +285,10 @@
 
   llvm::sys::Path Path = GetExecutablePath(argv[0], CanonicalPrefixes);
 
-  TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions());
-  DiagClient.setPrefix(Path.getBasename());
-
-  Diagnostic Diags(&DiagClient);
+  TextDiagnosticPrinter *DiagClient
+    = new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions());
+  DiagClient->setPrefix(Path.getBasename());
+  Diagnostic Diags(DiagClient);
 
 #ifdef CLANG_IS_PRODUCTION
   const bool IsProduction = true;
@@ -206,11 +301,27 @@
   const bool IsProduction = false;
   const bool CXXIsProduction = false;
 #endif
-  Driver TheDriver(Path.getBasename(), Path.getDirname(),
-                   llvm::sys::getHostTriple(),
+  Driver TheDriver(Path.str(), llvm::sys::getHostTriple(),
                    "a.out", IsProduction, CXXIsProduction,
                    Diags);
 
+  // Attempt to find the original path used to invoke the driver, to determine
+  // the installed path. We do this manually, because we want to support that
+  // path being a symlink.
+  llvm::sys::Path InstalledPath(argv[0]);
+
+  // Do a PATH lookup, if there are no directory components.
+  if (InstalledPath.getLast() == InstalledPath.str()) {
+    llvm::sys::Path Tmp =
+      llvm::sys::Program::FindProgramByName(InstalledPath.getLast());
+    if (!Tmp.empty())
+      InstalledPath = Tmp;
+  }
+  InstalledPath.makeAbsolute();
+  InstalledPath.eraseComponent();
+  if (InstalledPath.exists())
+    TheDriver.setInstalledDir(InstalledPath.str());
+
   // Check for ".*++" or ".*++-[^-]*" to determine if we are a C++
   // compiler. This matches things like "c++", "clang++", and "clang++-1.1".
   //
@@ -218,15 +329,14 @@
   // 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());
+  const char *progname = argv_[0];
+  std::string ProgName(llvm::sys::Path(progname).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)
@@ -234,46 +344,35 @@
 
   // 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]));
+    ApplyQAOverride(argv, OverrideStr, SavedStrings);
   } 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]);
+    std::vector<const char*> ExtraArgs;
 
     for (;;) {
       const char *Next = strchr(Cur, ',');
 
       if (Next) {
-        StringPointers.push_back(SaveStringInSet(SavedStrings,
-                                                 std::string(Cur, Next)));
+        ExtraArgs.push_back(SaveStringInSet(SavedStrings,
+                                            std::string(Cur, Next)));
         Cur = Next + 1;
       } else {
         if (*Cur != '\0')
-          StringPointers.push_back(SaveStringInSet(SavedStrings, Cur));
+          ExtraArgs.push_back(SaveStringInSet(SavedStrings, Cur));
         break;
       }
     }
 
-    StringPointers.insert(StringPointers.end(), argv + 1, argv + argc);
+    argv.insert(&argv[1], ExtraArgs.begin(), ExtraArgs.end());
+  }
 
-    C.reset(TheDriver.BuildCompilation(StringPointers.size(),
-                                       &StringPointers[0]));
-  } else
-    C.reset(TheDriver.BuildCompilation(argc, argv));
-
+  llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv.size(),
+                                                            &argv[0]));
   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.
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
new file mode 100644
index 0000000..2361f42
--- /dev/null
+++ b/tools/libclang/CIndex.cpp
@@ -0,0 +1,3165 @@
+//===- 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 "CXType.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/CrashRecoveryContext.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Timer.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 USE_CRASHTRACER
+#include "clang/Analysis/Support/SaveAndRestore.h"
+// Integrate with crash reporter.
+static const char *__crashreporter_info__ = 0;
+asm(".desc ___crashreporter_info__, 0x10");
+#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 Determine if a source location falls within, before, or after a
+///   a given source range.
+static RangeComparisonResult LocationCompare(SourceManager &SM,
+                                             SourceLocation L, SourceRange R) {
+  assert(R.isValid() && "First range is invalid?");
+  assert(L.isValid() && "Second range is invalid?");
+  if (L == R.getBegin() || L == R.getEnd())
+    return RangeOverlap;
+  if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
+    return RangeBefore;
+  if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
+    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,
+                                          const CharSourceRange &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 (R.isTokenRange() && !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);
+
+  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);
+    }
+  };
+
+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 VisitCXXRecordDecl(CXXRecordDecl *D);
+  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 VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
+  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);
+  bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
+  bool VisitNamespaceDecl(NamespaceDecl *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 VisitObjCObjectTypeLoc(ObjCObjectTypeLoc 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 VisitCaseStmt(CaseStmt *S);
+  bool VisitWhileStmt(WhileStmt *S);
+  bool VisitForStmt(ForStmt *S);
+//  bool VisitSwitchCase(SwitchCase *S);
+
+  // Expression visitors
+  // FIXME: DeclRefExpr with template arguments, nested-name-specifier
+  // FIXME: MemberExpr with template arguments, nested-name-specifier
+  bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
+  bool VisitBlockExpr(BlockExpr *B);
+  bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
+  bool VisitExplicitCastExpr(ExplicitCastExpr *E);
+  bool VisitObjCMessageExpr(ObjCMessageExpr *E);
+  bool VisitObjCEncodeExpr(ObjCEncodeExpr *E);
+  bool VisitOffsetOfExpr(OffsetOfExpr *E);
+  bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
+  // FIXME: AddrLabelExpr (once we have cursors for labels)
+  bool VisitTypesCompatibleExpr(TypesCompatibleExpr *E);
+  bool VisitVAArgExpr(VAArgExpr *E);
+  // FIXME: InitListExpr (for the designators)
+  // FIXME: DesignatedInitExpr
+};
+
+} // end anonymous namespace
+
+static SourceRange getRawCursorExtent(CXCursor C);
+
+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 = getRawCursorExtent(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.
+  SetParentRAII 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()) {
+      for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
+                                    TLEnd = CXXUnit->top_level_end();
+           TL != TLEnd; ++TL) {
+        if (Visit(MakeCXCursor(*TL, 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) {
+  if (Visit(B->getSignatureAsWritten()->getTypeLoc()))
+    return true;
+
+  if (Stmt *Body = B->getBody())
+    return Visit(MakeCXCursor(Body, StmtParent, TU));
+
+  return false;
+}
+
+bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
+  for (DeclContext::decl_iterator
+       I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
+
+    Decl *D = *I;
+    if (D->getLexicalDeclContext() != DC)
+      continue;
+
+    CXCursor Cursor = MakeCXCursor(D, TU);
+
+    if (RegionOfInterest.isValid()) {
+      SourceRange Range = getRawCursorExtent(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::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
+  if (Visit(PD->getTypeSourceInfo()->getTypeLoc()))
+    return true;
+
+  // FIXME: This implements a workaround with @property declarations also being
+  // installed in the DeclContext for the @interface.  Eventually this code
+  // should be removed.
+  ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
+  if (!CDecl || !CDecl->IsClassExtension())
+    return false;
+
+  ObjCInterfaceDecl *ID = CDecl->getClassInterface();
+  if (!ID)
+    return false;
+
+  IdentifierInfo *PropertyId = PD->getIdentifier();
+  ObjCPropertyDecl *prevDecl =
+    ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
+
+  if (!prevDecl)
+    return false;
+
+  // Visit synthesized methods since they will be skipped when visiting
+  // the @interface.
+  if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
+    if (MD->isSynthesized())
+      if (Visit(MakeCXCursor(MD, TU)))
+        return true;
+
+  if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
+    if (MD->isSynthesized())
+      if (Visit(MakeCXCursor(MD, TU)))
+        return true;
+
+  return false;
+}
+
+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::VisitNamespaceDecl(NamespaceDecl *D) {
+  return VisitDeclContext(D);
+}
+
+bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
+  return VisitDeclContext(D);
+}
+
+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;
+
+  return false;
+}
+
+bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
+  if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
+    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) {
+  return Visit(TL.getPointeeLoc());
+}
+
+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 (Stmt *C = *Child)
+      if (Visit(MakeCXCursor(C, StmtParent, TU)))
+        return true;
+  }
+
+  return false;
+}
+
+bool CursorVisitor::VisitCaseStmt(CaseStmt *S) {
+  // Specially handle CaseStmts because they can be nested, e.g.:
+  //
+  //    case 1:
+  //    case 2:
+  //
+  // In this case the second CaseStmt is the child of the first.  Walking
+  // these recursively can blow out the stack.
+  CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
+  while (true) {
+    // Set the Parent field to Cursor, then back to its old value once we're
+    //   done.
+    SetParentRAII SetParent(Parent, StmtParent, Cursor);
+
+    if (Stmt *LHS = S->getLHS())
+      if (Visit(MakeCXCursor(LHS, StmtParent, TU)))
+        return true;
+    if (Stmt *RHS = S->getRHS())
+      if (Visit(MakeCXCursor(RHS, StmtParent, TU)))
+        return true;
+    if (Stmt *SubStmt = S->getSubStmt()) {
+      if (!isa<CaseStmt>(SubStmt))
+        return Visit(MakeCXCursor(SubStmt, StmtParent, TU));
+
+      // Specially handle 'CaseStmt' so that we don't blow out the stack.
+      CaseStmt *CS = cast<CaseStmt>(SubStmt);
+      Cursor = MakeCXCursor(CS, StmtParent, TU);
+      if (RegionOfInterest.isValid()) {
+        SourceRange Range = CS->getSourceRange();
+        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:
+          // Perform tail-recursion manually.
+          S = CS;
+          continue;
+      }
+    }
+    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::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+  if (Visit(MakeCXCursor(E->getArg(0), StmtParent, TU)))
+    return true;
+  
+  if (Visit(MakeCXCursor(E->getCallee(), StmtParent, TU)))
+    return true;
+  
+  for (unsigned I = 1, N = E->getNumArgs(); I != N; ++I)
+    if (Visit(MakeCXCursor(E->getArg(I), StmtParent, TU)))
+      return true;
+  
+  return false;
+}
+
+bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
+  if (D->isDefinition()) {
+    for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
+         E = D->bases_end(); I != E; ++I) {
+      if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
+        return true;
+    }
+  }
+
+  return VisitTagDecl(D);
+}
+
+
+bool CursorVisitor::VisitBlockExpr(BlockExpr *B) {
+  return Visit(B->getBlockDecl());
+}
+
+bool CursorVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
+  // FIXME: Visit fields as well?
+  if (Visit(E->getTypeSourceInfo()->getTypeLoc()))
+    return true;
+  
+  return VisitExpr(E);
+}
+
+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::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) {
+  return Visit(E->getArgTInfo1()->getTypeLoc()) || 
+         Visit(E->getArgTInfo2()->getTypeLoc());
+}
+
+bool CursorVisitor::VisitVAArgExpr(VAArgExpr *E) {
+  if (Visit(E->getWrittenTypeInfo()->getTypeLoc()))
+    return true;
+  
+  return Visit(MakeCXCursor(E->getSubExpr(), StmtParent, TU));
+}
+
+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 (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
+       i != e; ++i)
+    if (Visit(MakeCXCursor(*i, D, TU)))
+        return true;
+
+  return false;
+}
+
+extern "C" {
+CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
+                          int displayDiagnostics) {
+  // We use crash recovery to make some of our APIs more reliable, implicitly
+  // enable it.
+  llvm::CrashRecoveryContext::Enable();
+
+  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);
+  if (getenv("LIBCLANG_TIMING"))
+    llvm::TimerGroup::printAll(llvm::errs());
+}
+
+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::LoadFromASTFile(ast_filename, Diags,
+                                  CXXIdx->getOnlyLocalDecls(),
+                                  0, 0, true);
+}
+
+unsigned clang_defaultEditingTranslationUnitOptions() {
+  return CXTranslationUnit_PrecompiledPreamble;
+}
+  
+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) {
+  return clang_parseTranslationUnit(CIdx, source_filename,
+                                    command_line_args, num_command_line_args,
+                                    unsaved_files, num_unsaved_files,
+                                 CXTranslationUnit_DetailedPreprocessingRecord);
+}
+  
+struct ParseTranslationUnitInfo {
+  CXIndex CIdx;
+  const char *source_filename;
+  const char **command_line_args;
+  int num_command_line_args;
+  struct CXUnsavedFile *unsaved_files;
+  unsigned num_unsaved_files;
+  unsigned options;
+  CXTranslationUnit result;
+};
+static void clang_parseTranslationUnit_Impl(void *UserData) {
+  ParseTranslationUnitInfo *PTUI =
+    static_cast<ParseTranslationUnitInfo*>(UserData);
+  CXIndex CIdx = PTUI->CIdx;
+  const char *source_filename = PTUI->source_filename;
+  const char **command_line_args = PTUI->command_line_args;
+  int num_command_line_args = PTUI->num_command_line_args;
+  struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
+  unsigned num_unsaved_files = PTUI->num_unsaved_files;
+  unsigned options = PTUI->options;
+  PTUI->result = 0;
+
+  if (!CIdx)
+    return;
+
+  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
+
+  bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
+  bool CompleteTranslationUnit
+    = ((options & CXTranslationUnit_Incomplete) == 0);
+  bool CacheCodeCompetionResults
+    = options & CXTranslationUnit_CacheCompletionResults;
+  
+  // 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);
+    
+    // Since the Clang C library is primarily used by batch tools dealing with
+    // (often very broken) source code, where spell-checking can have a
+    // significant negative impact on performance (particularly when 
+    // precompiled headers are involved), we disable it by default.
+    // Note that we place this argument early in the list, so that it can be
+    // overridden by the caller with "-fspell-checking".
+    Args.push_back("-fno-spell-checking");
+    
+    Args.insert(Args.end(), command_line_args,
+                command_line_args + num_command_line_args);
+
+    // Do we need the detailed preprocessing record?
+    if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
+      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,
+                                   PrecompilePreamble,
+                                   CompleteTranslationUnit,
+                                   CacheCodeCompetionResults));
+
+    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
+      }
+    }
+
+    PTUI->result = Unit.take();
+    return;
+  }
+
+  // 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));
+  
+  // Since the Clang C library is primarily used by batch tools dealing with
+  // (often very broken) source code, where spell-checking can have a
+  // significant negative impact on performance (particularly when 
+  // precompiled headers are involved), we disable it by default.
+  // Note that we place this argument early in the list, so that it can be
+  // overridden by the caller with "-fspell-checking".
+  argv.push_back("-fno-spell-checking");
+
+  // 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;
+
+  // 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");
+
+  // Do we need the detailed preprocessing record?
+  if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
+    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::LoadFromASTFile(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->getASTFileName()));
+  } 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();
+  }
+  
+  PTUI->result = ATU;
+}
+CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
+                                             const char *source_filename,
+                                             const char **command_line_args,
+                                             int num_command_line_args,
+                                             struct CXUnsavedFile *unsaved_files,
+                                             unsigned num_unsaved_files,
+                                             unsigned options) {
+  ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
+                                    num_command_line_args, unsaved_files, num_unsaved_files,
+                                    options, 0 };
+  llvm::CrashRecoveryContext CRC;
+
+  if (!CRC.RunSafely(clang_parseTranslationUnit_Impl, &PTUI)) {
+    fprintf(stderr, "libclang: crash detected during parsing: {\n");
+    fprintf(stderr, "  'source_filename' : '%s'\n", source_filename);
+    fprintf(stderr, "  'command_line_args' : [");
+    for (int i = 0; i != num_command_line_args; ++i) {
+      if (i)
+        fprintf(stderr, ", ");
+      fprintf(stderr, "'%s'", command_line_args[i]);
+    }
+    fprintf(stderr, "],\n");
+    fprintf(stderr, "  'unsaved_files' : [");
+    for (unsigned i = 0; i != num_unsaved_files; ++i) {
+      if (i)
+        fprintf(stderr, ", ");
+      fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
+              unsaved_files[i].Length);
+    }
+    fprintf(stderr, "],\n");
+    fprintf(stderr, "  'options' : %d,\n", options);
+    fprintf(stderr, "}\n");
+    
+    return 0;
+  }
+
+  return PTUI.result;
+}
+
+unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
+  return CXSaveTranslationUnit_None;
+}  
+  
+int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
+                              unsigned options) {
+  if (!TU)
+    return 1;
+  
+  return static_cast<ASTUnit *>(TU)->Save(FileName);
+}
+
+void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
+  if (CTUnit) {
+    // If the translation unit has been marked as unsafe to free, just discard
+    // it.
+    if (static_cast<ASTUnit *>(CTUnit)->isUnsafeToFree())
+      return;
+
+    delete static_cast<ASTUnit *>(CTUnit);
+  }
+}
+
+unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
+  return CXReparse_None;
+}
+
+struct ReparseTranslationUnitInfo {
+  CXTranslationUnit TU;
+  unsigned num_unsaved_files;
+  struct CXUnsavedFile *unsaved_files;
+  unsigned options;
+  int result;
+};
+static void clang_reparseTranslationUnit_Impl(void *UserData) {
+  ReparseTranslationUnitInfo *RTUI =
+    static_cast<ReparseTranslationUnitInfo*>(UserData);
+  CXTranslationUnit TU = RTUI->TU;
+  unsigned num_unsaved_files = RTUI->num_unsaved_files;
+  struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
+  unsigned options = RTUI->options;
+  (void) options;
+  RTUI->result = 1;
+
+  if (!TU)
+    return;
+  
+  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 (!static_cast<ASTUnit *>(TU)->Reparse(RemappedFiles.data(),
+                                           RemappedFiles.size()))
+      RTUI->result = 0;
+}
+int clang_reparseTranslationUnit(CXTranslationUnit TU,
+                                 unsigned num_unsaved_files,
+                                 struct CXUnsavedFile *unsaved_files,
+                                 unsigned options) {
+  ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
+                                      options, 0 };
+  llvm::CrashRecoveryContext CRC;
+
+  if (!CRC.RunSafely(clang_reparseTranslationUnit_Impl, &RTUI)) {
+    fprintf(stderr, "libclang: crash detected during reparsing\n");
+    static_cast<ASTUnit *>(TU)->setUnsafeToFree(true);
+    return 1;
+  }
+
+  return RTUI.result;
+}
+
+
+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 || !file)
+    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);
+
+  CursorVisitor CursorVis(CXXUnit, visitor, client_data, 
+                          CXXUnit->getMaxPCHLevel());
+  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());
+
+  llvm::SmallString<1024> S;
+  llvm::raw_svector_ostream os(S);
+  ND->printName(os);
+  
+  return createCXString(os.str());
+}
+
+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_CXXBaseSpecifier: {
+      CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
+      return createCXString(B->getType().getAsString());
+    }
+    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_IBOutletCollectionAttr:
+      return createCXString("attribute(iboutletcollection)");
+  case CXCursor_PreprocessingDirective:
+    return createCXString("preprocessing directive");
+  case CXCursor_MacroDefinition:
+    return createCXString("macro definition");
+  case CXCursor_MacroInstantiation:
+    return createCXString("macro instantiation");
+  case CXCursor_Namespace:
+    return createCXString("Namespace");
+  case CXCursor_LinkageSpec:
+    return createCXString("LinkageSpec");
+  case CXCursor_CXXBaseSpecifier:
+    return createCXString("C++ base class specifier");  
+  }
+
+  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);
+
+  // Translate the given source location to make it point at the beginning of
+  // the token under the cursor.
+  SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
+
+  // Guard against an invalid SourceLocation, or we may assert in one
+  // of the following calls.
+  if (SLoc.isInvalid())
+    return clang_getNullCursor();
+
+  SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
+                                    CXXUnit->getASTContext().getLangOptions());
+  
+  CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
+  if (SLoc.isValid()) {
+    // 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, SourceLocation(SLoc));
+    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);
+    }
+    
+    case CXCursor_CXXBaseSpecifier: {
+      // FIXME: Figure out what location to return for a CXXBaseSpecifier.
+      return clang_getNullLocation();
+    }
+
+    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 (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
+    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);
+}
+
+} // end extern "C"
+
+static SourceRange getRawCursorExtent(CXCursor C) {
+  if (clang_isReference(C.kind)) {
+    switch (C.kind) {
+    case CXCursor_ObjCSuperClassRef:
+      return  getCursorObjCSuperClassRef(C).second;
+
+    case CXCursor_ObjCProtocolRef:
+      return getCursorObjCProtocolRef(C).second;
+
+    case CXCursor_ObjCClassRef:
+      return getCursorObjCClassRef(C).second;
+
+    case CXCursor_TypeRef:
+      return getCursorTypeRef(C).second;
+      
+    case CXCursor_CXXBaseSpecifier:
+      // FIXME: Figure out what source range to use for a CXBaseSpecifier.
+      return SourceRange();
+
+    default:
+      // FIXME: Need a way to enumerate all non-reference cases.
+      llvm_unreachable("Missed a reference kind");
+    }
+  }
+
+  if (clang_isExpression(C.kind))
+    return getCursorExpr(C)->getSourceRange();
+
+  if (clang_isStatement(C.kind))
+    return getCursorStmt(C)->getSourceRange();
+
+  if (C.kind == CXCursor_PreprocessingDirective)
+    return cxcursor::getCursorPreprocessingDirective(C);
+
+  if (C.kind == CXCursor_MacroInstantiation)
+    return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
+
+  if (C.kind == CXCursor_MacroDefinition)
+    return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
+  
+  if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl)
+    return getCursorDecl(C)->getSourceRange();
+
+  return SourceRange();
+}
+
+extern "C" {
+
+CXSourceRange clang_getCursorExtent(CXCursor C) {
+  SourceRange R = getRawCursorExtent(C);
+  if (R.isInvalid())
+    return clang_getNullRange();
+
+  return cxloc::translateSourceRange(getCursorContext(C), R);
+}
+
+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);
+      
+    case CXCursor_CXXBaseSpecifier: {
+      CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
+      return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
+                                                         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::AccessSpec:
+  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);
+
+      if (II->getObjCKeywordID() != tok::objc_not_keyword) {
+        CXTok.int_data[0] = CXToken_Keyword;
+      }
+      else {
+        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();
+}
+
+void clang_disposeTokens(CXTranslationUnit TU,
+                         CXToken *Tokens, unsigned NumTokens) {
+  free(Tokens);
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// Token annotation APIs.
+//===----------------------------------------------------------------------===//
+
+typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
+static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
+                                                     CXCursor parent,
+                                                     CXClientData client_data);
+namespace {
+class AnnotateTokensWorker {
+  AnnotateTokensData &Annotated;
+  CXToken *Tokens;
+  CXCursor *Cursors;
+  unsigned NumTokens;
+  unsigned TokIdx;
+  CursorVisitor AnnotateVis;
+  SourceManager &SrcMgr;
+
+  bool MoreTokens() const { return TokIdx < NumTokens; }
+  unsigned NextToken() const { return TokIdx; }
+  void AdvanceToken() { ++TokIdx; }
+  SourceLocation GetTokenLoc(unsigned tokI) {
+    return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
+  }
+
+public:
+  AnnotateTokensWorker(AnnotateTokensData &annotated,
+                       CXToken *tokens, CXCursor *cursors, unsigned numTokens,
+                       ASTUnit *CXXUnit, SourceRange RegionOfInterest)
+    : Annotated(annotated), Tokens(tokens), Cursors(cursors),
+      NumTokens(numTokens), TokIdx(0),
+      AnnotateVis(CXXUnit, AnnotateTokensVisitor, this,
+                  Decl::MaxPCHLevel, RegionOfInterest),
+      SrcMgr(CXXUnit->getSourceManager()) {}
+
+  void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
+  enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
+  void AnnotateTokens(CXCursor parent);
+};
+}
+
+void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
+  // Walk the AST within the region of interest, annotating tokens
+  // along the way.
+  VisitChildren(parent);
+
+  for (unsigned I = 0 ; I < TokIdx ; ++I) {
+    AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
+    if (Pos != Annotated.end())
+      Cursors[I] = Pos->second;
+  }
+
+  // Finish up annotating any tokens left.
+  if (!MoreTokens())
+    return;
+
+  const CXCursor &C = clang_getNullCursor();
+  for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
+    AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
+    Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
+  }
+}
+
+enum CXChildVisitResult
+AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
+  CXSourceLocation Loc = clang_getCursorLocation(cursor);
+  // We can always annotate a preprocessing directive/macro instantiation.
+  if (clang_isPreprocessing(cursor.kind)) {
+    Annotated[Loc.int_data] = cursor;
+    return CXChildVisit_Recurse;
+  }
+
+  SourceRange cursorRange = getRawCursorExtent(cursor);
+  
+  if (cursorRange.isInvalid())
+    return CXChildVisit_Continue;
+  
+  SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
+
+  // Adjust the annotated range based specific declarations.
+  const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
+  if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
+    Decl *D = cxcursor::getCursorDecl(cursor);
+    // Don't visit synthesized ObjC methods, since they have no syntatic
+    // representation in the source.
+    if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+      if (MD->isSynthesized())
+        return CXChildVisit_Continue;
+    }
+    if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
+      if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) {
+        TypeLoc TL = TI->getTypeLoc();
+        SourceLocation TLoc = TL.getSourceRange().getBegin();
+        if (TLoc.isValid() && 
+            SrcMgr.isBeforeInTranslationUnit(TLoc, L))
+          cursorRange.setBegin(TLoc);
+      }
+    }
+  }
+
+  // If the location of the cursor occurs within a macro instantiation, record
+  // the spelling location of the cursor in our annotation map.  We can then
+  // paper over the token labelings during a post-processing step to try and
+  // get cursor mappings for tokens that are the *arguments* of a macro
+  // instantiation.
+  if (L.isMacroID()) {
+    unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
+    // Only invalidate the old annotation if it isn't part of a preprocessing
+    // directive.  Here we assume that the default construction of CXCursor
+    // results in CXCursor.kind being an initialized value (i.e., 0).  If
+    // this isn't the case, we can fix by doing lookup + insertion.
+
+    CXCursor &oldC = Annotated[rawEncoding];
+    if (!clang_isPreprocessing(oldC.kind))
+      oldC = cursor;
+  }
+  
+  const enum CXCursorKind K = clang_getCursorKind(parent);
+  const CXCursor updateC =
+    (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
+     ? clang_getNullCursor() : parent;
+
+  while (MoreTokens()) {
+    const unsigned I = NextToken();
+    SourceLocation TokLoc = GetTokenLoc(I);
+    switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
+      case RangeBefore:
+        Cursors[I] = updateC;
+        AdvanceToken();
+        continue;
+      case RangeAfter:
+      case RangeOverlap:
+        break;
+    }
+    break;
+  }
+
+  // Visit children to get their cursor information.
+  const unsigned BeforeChildren = NextToken();
+  VisitChildren(cursor);
+  const unsigned AfterChildren = NextToken();
+
+  // Adjust 'Last' to the last token within the extent of the cursor.
+  while (MoreTokens()) {
+    const unsigned I = NextToken();
+    SourceLocation TokLoc = GetTokenLoc(I);
+    switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
+      case RangeBefore:
+        assert(0 && "Infeasible");
+      case RangeAfter:
+        break;
+      case RangeOverlap:
+        Cursors[I] = updateC;
+        AdvanceToken();
+        continue;
+    }
+    break;
+  }
+  const unsigned Last = NextToken();
+  
+  // Scan the tokens that are at the beginning of the cursor, but are not
+  // capture by the child cursors.
+
+  // For AST elements within macros, rely on a post-annotate pass to
+  // to correctly annotate the tokens with cursors.  Otherwise we can
+  // get confusing results of having tokens that map to cursors that really
+  // are expanded by an instantiation.
+  if (L.isMacroID())
+    cursor = clang_getNullCursor();
+
+  for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
+    if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
+      break;
+    Cursors[I] = cursor;
+  }
+  // Scan the tokens that are at the end of the cursor, but are not captured
+  // but the child cursors.
+  for (unsigned I = AfterChildren; I != Last; ++I)
+    Cursors[I] = cursor;
+
+  TokIdx = Last;
+  return CXChildVisit_Continue;
+}
+
+static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
+                                                     CXCursor parent,
+                                                     CXClientData client_data) {
+  return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
+}
+
+extern "C" {
+
+void clang_annotateTokens(CXTranslationUnit TU,
+                          CXToken *Tokens, unsigned NumTokens,
+                          CXCursor *Cursors) {
+
+  if (NumTokens == 0 || !Tokens || !Cursors)
+    return;
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
+  if (!CXXUnit) {
+    // Any token we don't specifically annotate will have a NULL cursor.
+    const CXCursor &C = clang_getNullCursor();
+    for (unsigned I = 0; I != NumTokens; ++I)
+      Cursors[I] = C;
+    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])));
+  RegionOfInterest.setEnd(cxloc::translateSourceLocation(
+                                clang_getTokenLocation(TU, 
+                                                       Tokens[NumTokens - 1])));
+
+  // 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.
+  AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
+                         CXXUnit, RegionOfInterest);
+  W.AnnotateTokens(clang_getTranslationUnitCursor(CXXUnit));
+}
+} // 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" {
+  
+enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
+  if (clang_isDeclaration(cursor.kind))
+    if (Decl *D = cxcursor::getCursorDecl(cursor)) {
+      if (D->hasAttr<UnavailableAttr>() ||
+          (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted()))
+        return CXAvailability_Available;
+      
+      if (D->hasAttr<DeprecatedAttr>())
+        return CXAvailability_Deprecated;
+    }
+  
+  return CXAvailability_Available;
+}
+
+CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
+  if (clang_isDeclaration(cursor.kind))
+    return getDeclLanguage(cxcursor::getCursorDecl(cursor));
+
+  return CXLanguage_Invalid;
+}
+} // end: extern "C"
+
+
+//===----------------------------------------------------------------------===//
+// C++ AST instrospection.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+unsigned clang_CXXMethod_isStatic(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return 0;
+  CXXMethodDecl *D = dyn_cast<CXXMethodDecl>(cxcursor::getCursorDecl(C));
+  return (D && D->isStatic()) ? 1 : 0;
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
+// Attribute introspection.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+CXType clang_getIBOutletCollectionType(CXCursor C) {
+  if (C.kind != CXCursor_IBOutletCollectionAttr)
+    return cxtype::MakeCXType(QualType(), cxcursor::getCursorASTUnit(C));
+  
+  IBOutletCollectionAttr *A =
+    cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
+  
+  return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorASTUnit(C));  
+}
+} // 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/libclang/CIndexCXX.cpp b/tools/libclang/CIndexCXX.cpp
new file mode 100644
index 0000000..a168f16
--- /dev/null
+++ b/tools/libclang/CIndexCXX.cpp
@@ -0,0 +1,48 @@
+//===- CIndexCXX.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 libclang support for C++ cursors.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIndexer.h"
+#include "CXCursor.h"
+#include "CXType.h"
+#include "clang/AST/DeclCXX.h"
+
+using namespace clang;
+using namespace clang::cxstring;
+
+extern "C" {
+
+unsigned clang_isVirtualBase(CXCursor C) {
+  if (C.kind != CXCursor_CXXBaseSpecifier)
+    return 0;
+  
+  CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
+  return B->isVirtual();
+}
+
+enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) {
+  if (C.kind != CXCursor_CXXBaseSpecifier)
+    return CX_CXXInvalidAccessSpecifier;
+  
+  CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
+  switch (B->getAccessSpecifier()) {
+    case AS_public: return CX_CXXPublic;
+    case AS_protected: return CX_CXXProtected;
+    case AS_private: return CX_CXXPrivate;
+    case AS_none: return CX_CXXInvalidAccessSpecifier;
+  }
+  
+  // FIXME: Clang currently thinks this is reachable.
+  return CX_CXXInvalidAccessSpecifier;
+}
+
+} // end extern "C"
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
new file mode 100644
index 0000000..fba317a
--- /dev/null
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -0,0 +1,822 @@
+//===- 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/ASTUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Sema/CodeCompleteConsumer.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Program.h"
+#include <cstdlib>
+#include <cstdio>
+
+
+#ifdef UDP_CODE_COMPLETION_LOGGER
+#include "clang/Basic/Version.h"
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+using namespace clang;
+using namespace clang::cxstring;
+
+namespace {
+  /// \brief Stored representation of a completion string.
+  ///
+  /// This is the representation behind a CXCompletionString.
+  class CXStoredCodeCompletionString : public CodeCompletionString {
+    unsigned Priority;
+    CXAvailabilityKind Availability;
+    
+  public:
+    CXStoredCodeCompletionString(unsigned Priority,
+                                 CXAvailabilityKind Availability) 
+      : Priority(Priority), Availability(Availability) { }
+    
+    unsigned getPriority() const { return Priority; }
+    CXAvailabilityKind getAvailability() const { return Availability; }
+  };
+}
+
+extern "C" {
+
+enum CXCompletionChunkKind
+clang_getCompletionChunkKind(CXCompletionString completion_string,
+                             unsigned chunk_number) {
+  CXStoredCodeCompletionString *CCStr 
+    = (CXStoredCodeCompletionString *)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) {
+  CXStoredCodeCompletionString *CCStr
+    = (CXStoredCodeCompletionString *)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:
+    return createCXString((*CCStr)[chunk_number].Text, false);
+
+  case CodeCompletionString::CK_VerticalSpace:
+    // FIXME: Temporary hack until we figure out how to handle vertical space.
+    return createCXString(" ");
+      
+  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) {
+  CXStoredCodeCompletionString *CCStr 
+    = (CXStoredCodeCompletionString *)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) {
+  CXStoredCodeCompletionString *CCStr
+    = (CXStoredCodeCompletionString *)completion_string;
+  return CCStr? CCStr->size() : 0;
+}
+
+unsigned clang_getCompletionPriority(CXCompletionString completion_string) {
+  CXStoredCodeCompletionString *CCStr
+    = (CXStoredCodeCompletionString *)completion_string;
+  return CCStr? CCStr->getPriority() : unsigned(CCP_Unlikely);
+}
+  
+enum CXAvailabilityKind 
+clang_getCompletionAvailability(CXCompletionString completion_string) {
+  CXStoredCodeCompletionString *CCStr
+    = (CXStoredCodeCompletionString *)completion_string;
+  return CCStr? CCStr->getAvailability() : CXAvailability_Available;
+}
+
+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 Diagnostics produced while performing code completion.
+  llvm::SmallVector<StoredDiagnostic, 8> Diagnostics;
+
+  /// \brief Diag object
+  llvm::IntrusiveRefCntPtr<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;
+
+  /// \brief Temporary buffers that will be deleted once we have finished with the code-completion results.
+  llvm::SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
+};
+
+AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults() 
+  : CXCodeCompleteResults(), Diag(new Diagnostic), SourceMgr(*Diag) { }
+  
+AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
+  for (unsigned I = 0, N = NumResults; I != N; ++I)
+    delete (CXStoredCodeCompletionString *)Results[I].CompletionString;
+  delete [] Results;
+  
+  for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
+    TemporaryFiles[I].eraseFromDisk();
+  for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
+    delete TemporaryBuffers[I];
+}
+  
+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
+
+  bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
+
+  llvm::OwningPtr<llvm::NamedRegionTimer> CCTimer;
+  if (getenv("LIBCLANG_TIMING")) {
+    llvm::SmallString<128> TimerName;
+    llvm::raw_svector_ostream TimerNameOut(TimerName);
+    TimerNameOut << "Code completion (out-of-process) @ " << complete_filename 
+      << ":" << complete_line << ":" << complete_column;
+    CCTimer.reset(new llvm::NamedRegionTimer(TimerNameOut.str()));
+  }
+
+  // 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());
+
+  // Always use Clang C++ support.
+  argv.push_back("-ccc-clang-cxx");
+  
+  // 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);
+    }
+
+  if (EnableLogging) {
+    std::string Log = ClangPath.str();
+    for (unsigned I = 0, N = argv.size(); I != N; ++I) {
+      Log += ' ';
+      Log += argv[I];
+    }
+    fprintf(stderr, "libclang (Code Completion): %s\n", Log.c_str());
+  }
+  
+  // 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;
+  // 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;
+
+      unsigned Priority;
+      if (ReadUnsigned(Str, StrEnd, Priority))
+        break;
+      
+      unsigned Availability;
+      if (ReadUnsigned(Str, StrEnd, Availability))
+        break;
+      
+      CXStoredCodeCompletionString *CCStr
+        = new CXStoredCodeCompletionString(Priority, 
+                                           (CXAvailabilityKind)Availability);
+      if (!CCStr->Deserialize(Str, StrEnd)) {
+        delete 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->TemporaryBuffers.push_back(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
+  clang_sortCodeCompletionResults(Results->Results, Results->NumResults);
+  return Results;
+}
+
+} // end extern "C"
+
+namespace {
+  class CaptureCompletionResults : public CodeCompleteConsumer {
+    AllocatedCXCodeCompleteResults &AllocatedResults;
+
+  public:
+    explicit CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results)
+      : CodeCompleteConsumer(true, false, true, false), 
+        AllocatedResults(Results) { }
+
+    virtual void ProcessCodeCompleteResults(Sema &S, 
+                                            CodeCompletionContext Context,
+                                            CodeCompletionResult *Results,
+                                            unsigned NumResults) {
+      AllocatedResults.Results = new CXCompletionResult [NumResults];
+      AllocatedResults.NumResults = NumResults;
+      for (unsigned I = 0; I != NumResults; ++I) {
+        CXStoredCodeCompletionString *StoredCompletion
+          = new CXStoredCodeCompletionString(Results[I].Priority,
+                                             Results[I].Availability);
+        (void)Results[I].CreateCodeCompletionString(S, StoredCompletion);
+        AllocatedResults.Results[I].CursorKind = Results[I].CursorKind;
+        AllocatedResults.Results[I].CompletionString = StoredCompletion;
+      }
+    }
+    
+    // FIXME: Add ProcessOverloadCandidates?
+  };
+}
+
+extern "C" {
+struct CodeCompleteAtInfo {
+  CXTranslationUnit TU;
+  const char *complete_filename;
+  unsigned complete_line;
+  unsigned complete_column;
+  struct CXUnsavedFile *unsaved_files;
+  unsigned num_unsaved_files;
+  unsigned options;
+  CXCodeCompleteResults *result;
+};
+void clang_codeCompleteAt_Impl(void *UserData) {
+  CodeCompleteAtInfo *CCAI = static_cast<CodeCompleteAtInfo*>(UserData);
+  CXTranslationUnit TU = CCAI->TU;
+  const char *complete_filename = CCAI->complete_filename;
+  unsigned complete_line = CCAI->complete_line;
+  unsigned complete_column = CCAI->complete_column;
+  struct CXUnsavedFile *unsaved_files = CCAI->unsaved_files;
+  unsigned num_unsaved_files = CCAI->num_unsaved_files;
+  unsigned options = CCAI->options;
+  CCAI->result = 0;
+
+#ifdef UDP_CODE_COMPLETION_LOGGER
+#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
+  const llvm::TimeRecord &StartTime =  llvm::TimeRecord::getCurrentTime();
+#endif
+#endif
+
+  bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
+  
+  ASTUnit *AST = static_cast<ASTUnit *>(TU);
+  if (!AST)
+    return;
+
+  // Perform the remapping of source files.
+  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 (EnableLogging) {
+    // FIXME: Add logging.
+  }
+
+  // Parse the resulting source file to find code-completion results.
+  AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults;
+  Results->Results = 0;
+  Results->NumResults = 0;
+
+  // Create a code-completion consumer to capture the results.
+  CaptureCompletionResults Capture(*Results);
+
+  // Perform completion.
+  AST->CodeComplete(complete_filename, complete_line, complete_column,
+                    RemappedFiles.data(), RemappedFiles.size(), 
+                    (options & CXCodeComplete_IncludeMacros),
+                    (options & CXCodeComplete_IncludeCodePatterns),
+                    Capture,
+                    *Results->Diag, Results->LangOpts, Results->SourceMgr,
+                    Results->FileMgr, Results->Diagnostics,
+                    Results->TemporaryBuffers);
+
+  
+
+#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
+  CCAI->result = Results;
+}
+CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
+                                            const char *complete_filename,
+                                            unsigned complete_line,
+                                            unsigned complete_column,
+                                            struct CXUnsavedFile *unsaved_files,
+                                            unsigned num_unsaved_files,
+                                            unsigned options) {
+  CodeCompleteAtInfo CCAI = { TU, complete_filename, complete_line,
+                              complete_column, unsaved_files, num_unsaved_files,
+                              options, 0 };
+  llvm::CrashRecoveryContext CRC;
+
+  if (!CRC.RunSafely(clang_codeCompleteAt_Impl, &CCAI)) {
+    fprintf(stderr, "libclang: crash detected in code completion\n");
+    static_cast<ASTUnit *>(TU)->setUnsafeToFree(true);
+    return 0;
+  }
+
+  return CCAI.result;
+}
+
+unsigned clang_defaultCodeCompleteOptions(void) {
+  return CXCodeComplete_IncludeMacros;
+}
+
+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"
+
+namespace {
+  struct OrderCompletionResults {
+    bool operator()(const CXCompletionResult &XR, 
+                    const CXCompletionResult &YR) const {
+      CXStoredCodeCompletionString *X
+        = (CXStoredCodeCompletionString *)XR.CompletionString;
+      CXStoredCodeCompletionString *Y
+        = (CXStoredCodeCompletionString *)YR.CompletionString;
+      
+      const char *XText = X->getTypedText();
+      const char *YText = Y->getTypedText();
+      if (!XText || !YText)
+        return XText != 0;
+      
+      int result = llvm::StringRef(XText).compare_lower(YText);
+      if (result < 0)
+        return true;
+      if (result > 0)
+        return false;
+      
+      result = llvm::StringRef(XText).compare(YText);
+      return result;
+    }
+  };
+}
+
+extern "C" {
+  void clang_sortCodeCompletionResults(CXCompletionResult *Results,
+                                       unsigned NumResults) {
+    std::stable_sort(Results, Results + NumResults, OrderCompletionResults());
+  }
+}
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
new file mode 100644
index 0000000..531992e
--- /dev/null
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -0,0 +1,272 @@
+/*===-- 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) {
+    // 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/libclang/CIndexDiagnostic.h
similarity index 100%
rename from tools/CIndex/CIndexDiagnostic.h
rename to tools/libclang/CIndexDiagnostic.h
diff --git a/tools/CIndex/CIndexInclusionStack.cpp b/tools/libclang/CIndexInclusionStack.cpp
similarity index 100%
rename from tools/CIndex/CIndexInclusionStack.cpp
rename to tools/libclang/CIndexInclusionStack.cpp
diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp
new file mode 100644
index 0000000..0227b2c
--- /dev/null
+++ b/tools/libclang/CIndexUSRs.cpp
@@ -0,0 +1,667 @@
+//===- 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::SmallString<1024> Buf;
+  llvm::raw_svector_ostream Out;
+  bool IgnoreResults;
+  ASTUnit *AU;
+  bool generatedLoc;
+public:
+  USRGenerator(const CXCursor *C = 0)
+    : Out(Buf),
+      IgnoreResults(false),
+      AU(C ? cxcursor::getCursorASTUnit(*C) : 0),
+      generatedLoc(false)
+  {
+    // Add the USR space prefix.
+    Out << "c:";
+  }
+
+  llvm::StringRef str() {
+    return Out.str();
+  }
+
+  USRGenerator* operator->() { return this; }
+
+  template <typename T>
+  llvm::raw_svector_ostream &operator<<(const T &x) {
+    Out << x;
+    return Out;
+  }
+
+  bool ignoreResults() const { return IgnoreResults; }
+
+  // Visitation methods from generating USRs from AST elements.
+  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);
+  void VisitLinkageSpecDecl(LinkageSpecDecl *D) {
+    IgnoreResults = true;
+    return;
+  }
+
+  /// Generate the string component containing the location of the
+  ///  declaration.
+  bool 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 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);
+
+  void VisitType(QualType T);
+
+  /// Emit a Decl's name using NamedDecl::printName() and return true if
+  ///  the decl had no name.
+  bool EmitDeclName(const NamedDecl *D);
+};
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Generating USRs from ASTS.
+//===----------------------------------------------------------------------===//
+
+bool USRGenerator::EmitDeclName(const NamedDecl *D) {
+  Out.flush();
+  const unsigned startSize = Buf.size();
+  D->printName(Out);
+  Out.flush();
+  const unsigned endSize = Buf.size();
+  return startSize == endSize;
+}
+
+static bool InAnonymousNamespace(const Decl *D) {
+  if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D->getDeclContext()))
+    return ND->isAnonymousNamespace();
+  return false;
+}
+
+static inline bool ShouldGenerateLocation(const NamedDecl *D) {
+  return D->getLinkage() != ExternalLinkage && !InAnonymousNamespace(D);
+}
+
+void USRGenerator::VisitDeclContext(DeclContext *DC) {
+  if (NamedDecl *D = dyn_cast<NamedDecl>(DC))
+    Visit(D);
+}
+
+void USRGenerator::VisitFieldDecl(FieldDecl *D) {
+  VisitDeclContext(D->getDeclContext());
+  Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@");
+  if (EmitDeclName(D)) {
+    // Bit fields can be anonymous.
+    IgnoreResults = true;
+    return;
+  }
+}
+
+void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
+  if (ShouldGenerateLocation(D) && GenLoc(D))
+    return;
+
+  VisitDeclContext(D->getDeclContext());
+  Out << "@F@";
+  D->printName(Out);
+
+  ASTContext &Ctx = AU->getASTContext();
+  if (!Ctx.getLangOptions().CPlusPlus || D->isExternC())
+    return;
+
+  // Mangle in type information for the arguments.
+  for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end();
+       I != E; ++I) {
+    Out << '#';
+    if (ParmVarDecl *PD = *I)
+      VisitType(PD->getType());
+  }
+  if (D->isVariadic())
+    Out << '.';
+  Out << '#';
+  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+    if (MD->isStatic())
+      Out << 'S';
+    if (unsigned quals = MD->getTypeQualifiers())
+      Out << (char)('0' + quals);
+  }
+}
+
+void USRGenerator::VisitNamedDecl(NamedDecl *D) {
+  VisitDeclContext(D->getDeclContext());
+  Out << "@";
+
+  if (EmitDeclName(D)) {
+    // 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.
+    IgnoreResults = true;
+  }
+}
+
+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 (ShouldGenerateLocation(D) && GenLoc(D))
+    return;
+
+  VisitDeclContext(D->getDeclContext());
+
+  // Variables always have simple names.
+  llvm::StringRef s = D->getName();
+
+  // 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
+    Out << '@' << s;
+}
+
+void USRGenerator::VisitNamespaceDecl(NamespaceDecl *D) {
+  if (D->isAnonymousNamespace()) {
+    Out << "@aN";
+    return;
+  }
+
+  VisitDeclContext(D->getDeclContext());
+  if (!IgnoreResults)
+    Out << "@N@" << D->getName();
+}
+
+void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) {
+  Decl *container = cast<Decl>(D->getDeclContext());
+  
+  // The USR for a method declared in a class extension is based on
+  // the ObjCInterfaceDecl, not the ObjCCategoryDecl.
+  do {
+    if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(container))
+      if (CD->IsClassExtension()) {
+        Visit(CD->getClassInterface());
+        break;
+      }    
+    Visit(cast<Decl>(D->getDeclContext()));
+  }
+  while (false);
+  
+  // Ideally we would use 'GenObjCMethod', but this is such a hot path
+  // for Objective-C code that we don't want to use
+  // DeclarationName::getAsString().
+  Out << (D->isInstanceMethod() ? "(im)" : "(cm)");
+  DeclarationName N(D->getSelector());
+  N.printName(Out);
+}
+
+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;
+      }
+      // Specially handle class extensions, which are anonymous categories.
+      // We want to mangle in the location to uniquely distinguish them.
+      if (CD->IsClassExtension()) {
+        Out << "objc(ext)" << ID->getName() << '@';
+        GenLoc(CD);
+      }
+      else
+        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) {
+  // Add the location of the tag decl to handle resolution across
+  // translation units.
+  if (ShouldGenerateLocation(D) && GenLoc(D))
+    return;
+
+  D = D->getCanonicalDecl();
+  VisitDeclContext(D->getDeclContext());
+
+  switch (D->getTagKind()) {
+    case TTK_Struct: Out << "@S"; break;
+    case TTK_Class:  Out << "@C"; break;
+    case TTK_Union:  Out << "@U"; break;
+    case TTK_Enum:   Out << "@E"; break;
+  }
+
+  Out << '@';
+  Out.flush();
+  assert(Buf.size() > 0);
+  const unsigned off = Buf.size() - 1;
+
+  if (EmitDeclName(D)) {
+    if (const TypedefDecl *TD = D->getTypedefForAnonDecl()) {
+      Buf[off] = 'A';
+      Out << '@' << TD;
+    }
+    else
+      Buf[off] = 'a';
+  }
+}
+
+void USRGenerator::VisitTypedefDecl(TypedefDecl *D) {
+  if (ShouldGenerateLocation(D) && GenLoc(D))
+    return;
+  DeclContext *DC = D->getDeclContext();
+  if (NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
+    Visit(DCN);
+  Out << "@T@";
+  Out << D->getName();
+}
+
+bool USRGenerator::GenLoc(const Decl *D) {
+  if (generatedLoc)
+    return IgnoreResults;
+  generatedLoc = true;
+
+  const SourceManager &SM = AU->getSourceManager();
+  SourceLocation L = D->getLocStart();
+  if (L.isInvalid()) {
+    IgnoreResults = true;
+    return true;
+  }
+  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 true;
+  }
+  // Use the offest into the FileID to represent the location.  Using
+  // a line/column can cause us to look back at the original source file,
+  // which is expensive.
+  Out << '@' << Decomposed.second;
+  return IgnoreResults;
+}
+
+void USRGenerator::VisitType(QualType T) {
+  // This method mangles in USR information for types.  It can possibly
+  // just reuse the naming-mangling logic used by codegen, although the
+  // requirements for USRs might not be the same.
+  ASTContext &Ctx = AU->getASTContext();
+
+  do {
+    T = Ctx.getCanonicalType(T);
+    Qualifiers Q = T.getQualifiers();
+    unsigned qVal = 0;
+    if (Q.hasConst())
+      qVal |= 0x1;
+    if (Q.hasVolatile())
+      qVal |= 0x2;
+    if (Q.hasRestrict())
+      qVal |= 0x4;
+    if(qVal)
+      Out << ((char) ('0' + qVal));
+
+    // Mangle in ObjC GC qualifiers?
+
+    if (const PointerType *PT = T->getAs<PointerType>()) {
+      Out << '*';
+      T = PT->getPointeeType();
+      continue;
+    }
+    if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
+      Out << '&';
+      T = RT->getPointeeType();
+      continue;
+    }
+    if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
+      Out << 'F';
+      VisitType(FT->getResultType());
+      for (FunctionProtoType::arg_type_iterator
+            I = FT->arg_type_begin(), E = FT->arg_type_end(); I!=E; ++I) {
+        VisitType(*I);
+      }
+      if (FT->isVariadic())
+        Out << '.';
+      return;
+    }
+    if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) {
+      Out << 'B';
+      T = BT->getPointeeType();
+      continue;
+    }
+    if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
+      unsigned char c = '\0';
+      switch (BT->getKind()) {
+        case BuiltinType::Void:
+          c = 'v'; break;
+        case BuiltinType::Bool:
+          c = 'b'; break;
+        case BuiltinType::Char_U:
+        case BuiltinType::UChar:
+          c = 'c'; break;
+        case BuiltinType::Char16:
+          c = 'q'; break;
+        case BuiltinType::Char32:
+          c = 'w'; break;
+        case BuiltinType::UShort:
+          c = 's'; break;
+        case BuiltinType::UInt:
+          c = 'i'; break;
+        case BuiltinType::ULong:
+          c = 'l'; break;
+        case BuiltinType::ULongLong:
+          c = 'k'; break;
+        case BuiltinType::UInt128:
+          c = 'j'; break;
+        case BuiltinType::Char_S:
+        case BuiltinType::SChar:
+          c = 'C'; break;
+        case BuiltinType::WChar:
+          c = 'W'; break;
+        case BuiltinType::Short:
+          c = 'S'; break;
+        case BuiltinType::Int:
+          c = 'I'; break;
+        case BuiltinType::Long:
+          c = 'L'; break;
+        case BuiltinType::LongLong:
+          c = 'K'; break;
+        case BuiltinType::Int128:
+          c = 'J'; break;
+        case BuiltinType::Float:
+          c = 'f'; break;
+        case BuiltinType::Double:
+          c = 'd'; break;
+        case BuiltinType::LongDouble:
+          c = 'D'; break;
+        case BuiltinType::NullPtr:
+          c = 'n'; break;
+        case BuiltinType::Overload:
+        case BuiltinType::Dependent:
+        case BuiltinType::UndeducedAuto:
+          IgnoreResults = true;
+          return;
+        case BuiltinType::ObjCId:
+          c = 'o'; break;
+        case BuiltinType::ObjCClass:
+          c = 'O'; break;
+        case BuiltinType::ObjCSel:
+          c = 'e'; break;
+      }
+      Out << c;
+      return;
+    }
+    if (const ComplexType *CT = T->getAs<ComplexType>()) {
+      Out << '<';
+      T = CT->getElementType();
+      continue;
+    }
+    if (const TagType *TT = T->getAs<TagType>()) {
+      Out << '$';
+      VisitTagDecl(TT->getDecl());
+      return;
+    }
+
+    // Unhandled type.
+    Out << ' ';
+    break;
+  } while (true);
+}
+
+//===----------------------------------------------------------------------===//
+// General purpose USR generation methods.
+//===----------------------------------------------------------------------===//
+
+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) {
+  Out << '@' << 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:
+      case UniqueExternalLinkage:
+        // 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) ||
+            isa<VarDecl>(ND) || isa<NamespaceDecl>(ND))
+          break;
+        // Fall-through.
+      case InternalLinkage:
+        if (isa<FunctionDecl>(ND))
+          break;
+    }
+
+  USRGenerator UG(&C);
+  UG->Visit(D);
+
+  if (UG->ignoreResults())
+    return createCXString("");
+
+#if 0
+  // For development testing.
+  assert(UG.str().size() > 2);
+#endif
+
+    // Return a copy of the string that must be disposed by the caller.
+  return createCXString(UG.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) {
+    USRGenerator UG(&C);
+    UG << "macro@"
+       << cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
+    return createCXString(UG.str(), true);
+  }
+
+  return createCXString("");
+}
+
+CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) {
+  USRGenerator UG;
+  UG << extractUSRSuffix(clang_getCString(classUSR));
+  UG->GenObjCIvar(name);
+  return createCXString(UG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCMethod(const char *name,
+                                       unsigned isInstanceMethod,
+                                       CXString classUSR) {
+  USRGenerator UG;
+  UG << extractUSRSuffix(clang_getCString(classUSR));
+  UG->GenObjCMethod(name, isInstanceMethod);
+  return createCXString(UG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCClass(const char *name) {
+  USRGenerator UG;
+  UG->GenObjCClass(name);
+  return createCXString(UG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCProtocol(const char *name) {
+  USRGenerator UG;
+  UG->GenObjCProtocol(name);
+  return createCXString(UG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCCategory(const char *class_name,
+                                         const char *category_name) {
+  USRGenerator UG;
+  UG->GenObjCCategory(class_name, category_name);
+  return createCXString(UG.str(), true);
+}
+
+CXString clang_constructUSR_ObjCProperty(const char *property,
+                                         CXString classUSR) {
+  USRGenerator UG;
+  UG << extractUSRSuffix(clang_getCString(classUSR));
+  UG->GenObjCProperty(property);
+  return createCXString(UG.str(), true);
+}
+
+} // end extern "C"
diff --git a/tools/libclang/CIndexer.cpp b/tools/libclang/CIndexer.cpp
new file mode 100644
index 0000000..cdf6c61
--- /dev/null
+++ b/tools/libclang/CIndexer.cpp
@@ -0,0 +1,155 @@
+//===- 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();
+      OS.clear_error();
+      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/libclang/CIndexer.h
similarity index 100%
rename from tools/CIndex/CIndexer.h
rename to tools/libclang/CIndexer.h
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
new file mode 100644
index 0000000..29ef574
--- /dev/null
+++ b/tools/libclang/CMakeLists.txt
@@ -0,0 +1,64 @@
+set(SHARED_LIBRARY TRUE)
+
+set(LLVM_NO_RTTI 1)
+
+set(LLVM_USED_LIBS
+  clangFrontend
+  clangDriver
+  clangSerialization
+  clangParse
+  clangSema
+  clangAnalysis
+  clangAST
+  clangLex
+  clangBasic)
+
+set( LLVM_LINK_COMPONENTS
+  bitreader
+  mc
+  core
+  )
+
+add_clang_library(libclang
+  CIndex.cpp
+  CIndexCXX.cpp
+  CIndexCodeCompletion.cpp
+  CIndexDiagnostic.cpp
+  CIndexInclusionStack.cpp
+  CIndexUSRs.cpp
+  CIndexer.cpp
+  CXCursor.cpp
+  CXType.cpp
+  ../../include/clang-c/Index.h
+)
+
+if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+  # dylib versioning information
+  # FIXME: Is there a more CMake-ish way to handle this?
+  set(LIBCLANG_VERSION 1 
+      CACHE STRING "Version number of the libclang library")
+  set(LIBCLANG_SUBVERSION 0
+      CACHE STRING "Minor version number of the libclang library")
+  set(LIBCLANG_LINK_FLAGS 
+      "-Wl,-current_version -Wl,${LIBCLANG_VERSION}.${LIBCLANG_SUBVERSION} -Wl,-compatibility_version -Wl,1")
+
+  set(LIBCLANG_LINK_FLAGS 
+      "${LIBCLANG_LINK_FLAGS} -Wl,-dead_strip -Wl,-seg1addr -Wl,0xE0000000")
+
+  set_target_properties(libclang
+    PROPERTIES
+    LINK_FLAGS "${LIBCLANG_LINK_FLAGS}"
+    INSTALL_NAME_DIR "@executable_path/../lib")
+endif()
+
+if(MSVC)
+  # windows.h doesn't compile with /Za
+  get_target_property(NON_ANSI_COMPILE_FLAGS libclang COMPILE_FLAGS)
+  string(REPLACE /Za "" NON_ANSI_COMPILE_FLAGS ${NON_ANSI_COMPILE_FLAGS})
+  set_target_properties(libclang PROPERTIES COMPILE_FLAGS ${NON_ANSI_COMPILE_FLAGS})
+endif(MSVC)
+
+set_target_properties(libclang
+  PROPERTIES
+  LINKER_LANGUAGE CXX
+  DEFINE_SYMBOL _CINDEX_LIB_)
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
new file mode 100644
index 0000000..40f91a7
--- /dev/null
+++ b/tools/libclang/CXCursor.cpp
@@ -0,0 +1,386 @@
+//===- 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;
+    case Decl::Namespace:          return CXCursor_Namespace;
+    default:
+      if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
+        switch (TD->getTagKind()) {
+          case TTK_Struct: return CXCursor_StructDecl;
+          case TTK_Class:  return CXCursor_ClassDecl;
+          case TTK_Union:  return CXCursor_UnionDecl;
+          case TTK_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::IBAction: return CXCursor_IBActionAttr;
+    case attr::IBOutlet: return CXCursor_IBOutletAttr;
+    case attr::IBOutletCollection: return CXCursor_IBOutletCollectionAttr;
+  }
+
+  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::OffsetOfExprClass:         
+  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::CXXScalarValueInitExprClass:   
+  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::MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU){
+  CXCursor C = { CXCursor_CXXBaseSpecifier, { B, 0, TU } };
+  return C;  
+}
+
+CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
+  assert(C.kind == CXCursor_CXXBaseSpecifier);
+  return static_cast<CXXBaseSpecifier*>(C.data[0]);
+}
+
+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];
+}
+
+Attr *cxcursor::getCursorAttr(CXCursor Cursor) {
+  return (Attr *)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/libclang/CXCursor.h b/tools/libclang/CXCursor.h
new file mode 100644
index 0000000..958e331
--- /dev/null
+++ b/tools/libclang/CXCursor.h
@@ -0,0 +1,121 @@
+//===- 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 CXXBaseSpecifier;
+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 CXX base specifier cursor.
+CXCursor MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU);
+
+/// \brief Unpack a CXXBaseSpecifier cursor into a CXXBaseSpecifier.
+CXXBaseSpecifier *getCursorCXXBaseSpecifier(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);
+Attr *getCursorAttr(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/libclang/CXSourceLocation.h b/tools/libclang/CXSourceLocation.h
new file mode 100644
index 0000000..7a50205
--- /dev/null
+++ b/tools/libclang/CXSourceLocation.h
@@ -0,0 +1,78 @@
+//===- 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) {
+  if (Loc.isInvalid())
+    clang_getNullLocation();
+
+  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,
+                                   const CharSourceRange &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(),
+                              CharSourceRange::getTokenRange(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/libclang/CXType.cpp b/tools/libclang/CXType.cpp
new file mode 100644
index 0000000..aa173ca
--- /dev/null
+++ b/tools/libclang/CXType.cpp
@@ -0,0 +1,297 @@
+//===- CXTypes.cpp - Implements 'CXTypes' aspect of libclang ------------===//
+//
+//                     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 'CXTypes' API hooks in the Clang-C library.
+//
+//===--------------------------------------------------------------------===//
+
+#include "CIndexer.h"
+#include "CXCursor.h"
+#include "CXType.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Frontend/ASTUnit.h"
+
+using namespace clang;
+
+static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) {
+#define BTCASE(K) case BuiltinType::K: return CXType_##K
+  switch (BT->getKind()) {
+    BTCASE(Void);
+    BTCASE(Bool);
+    BTCASE(Char_U);
+    BTCASE(UChar);
+    BTCASE(Char16);
+    BTCASE(Char32);
+    BTCASE(UShort);
+    BTCASE(UInt);
+    BTCASE(ULong);
+    BTCASE(ULongLong);
+    BTCASE(UInt128);
+    BTCASE(Char_S);
+    BTCASE(SChar);
+    BTCASE(WChar);
+    BTCASE(Short);
+    BTCASE(Int);
+    BTCASE(Long);
+    BTCASE(LongLong);
+    BTCASE(Int128);
+    BTCASE(Float);
+    BTCASE(Double);
+    BTCASE(LongDouble);
+    BTCASE(NullPtr);
+    BTCASE(Overload);
+    BTCASE(Dependent);
+    BTCASE(ObjCId);
+    BTCASE(ObjCClass);
+    BTCASE(ObjCSel);
+  default:
+    return CXType_Unexposed;
+  }
+#undef BTCASE
+}
+
+static CXTypeKind GetTypeKind(QualType T) {
+  Type *TP = T.getTypePtr();
+  if (!TP)
+    return CXType_Invalid;
+
+#define TKCASE(K) case Type::K: return CXType_##K
+  switch (TP->getTypeClass()) {
+    case Type::Builtin:
+      return GetBuiltinTypeKind(cast<BuiltinType>(TP));
+    TKCASE(Complex);
+    TKCASE(Pointer);
+    TKCASE(BlockPointer);
+    TKCASE(LValueReference);
+    TKCASE(RValueReference);
+    TKCASE(Record);
+    TKCASE(Enum);
+    TKCASE(Typedef);
+    TKCASE(ObjCInterface);
+    TKCASE(ObjCObjectPointer);
+    TKCASE(FunctionNoProto);
+    TKCASE(FunctionProto);
+    default:
+      return CXType_Unexposed;
+  }
+#undef TKCASE
+}
+
+
+CXType cxtype::MakeCXType(QualType T, ASTUnit *TU) {
+  CXTypeKind TK = GetTypeKind(T);
+  CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
+  return CT;
+}
+
+using cxtype::MakeCXType;
+
+static inline QualType GetQualType(CXType CT) {
+  return QualType::getFromOpaquePtr(CT.data[0]);
+}
+
+static inline ASTUnit* GetASTU(CXType CT) {
+  return static_cast<ASTUnit*>(CT.data[1]);
+}
+
+extern "C" {
+
+CXType clang_getCursorType(CXCursor C) {
+  ASTUnit *AU = cxcursor::getCursorASTUnit(C);
+
+  if (clang_isExpression(C.kind)) {
+    QualType T = cxcursor::getCursorExpr(C)->getType();
+    return MakeCXType(T, AU);
+  }
+
+  if (clang_isDeclaration(C.kind)) {
+    Decl *D = cxcursor::getCursorDecl(C);
+
+    if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
+      return MakeCXType(QualType(TD->getTypeForDecl(), 0), AU);
+    if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
+      return MakeCXType(QualType(ID->getTypeForDecl(), 0), AU);
+    if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
+      return MakeCXType(VD->getType(), AU);
+    if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
+      return MakeCXType(PD->getType(), AU);
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+      return MakeCXType(FD->getType(), AU);
+    return MakeCXType(QualType(), AU);
+  }
+
+  return MakeCXType(QualType(), AU);
+}
+
+CXType clang_getCanonicalType(CXType CT) {
+  if (CT.kind == CXType_Invalid)
+    return CT;
+
+  QualType T = GetQualType(CT);
+
+  if (T.isNull())
+    return MakeCXType(QualType(), GetASTU(CT));
+
+  ASTUnit *AU = GetASTU(CT);
+  return MakeCXType(AU->getASTContext().getCanonicalType(T), AU);
+}
+
+CXType clang_getPointeeType(CXType CT) {
+  QualType T = GetQualType(CT);
+  Type *TP = T.getTypePtr();
+  
+  if (!TP)
+    return MakeCXType(QualType(), GetASTU(CT));
+  
+  switch (TP->getTypeClass()) {
+    case Type::Pointer:
+      T = cast<PointerType>(TP)->getPointeeType();
+      break;
+    case Type::BlockPointer:
+      T = cast<BlockPointerType>(TP)->getPointeeType();
+      break;
+    case Type::LValueReference:
+    case Type::RValueReference:
+      T = cast<ReferenceType>(TP)->getPointeeType();
+      break;
+    case Type::ObjCObjectPointer:
+      T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
+      break;
+    default:
+      T = QualType();
+      break;
+  }
+  return MakeCXType(T, GetASTU(CT));
+}
+
+CXCursor clang_getTypeDeclaration(CXType CT) {
+  if (CT.kind == CXType_Invalid)
+    return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
+
+  QualType T = GetQualType(CT);
+  Type *TP = T.getTypePtr();
+
+  if (!TP)
+    return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
+
+  Decl *D = 0;
+
+  switch (TP->getTypeClass()) {
+    case Type::Typedef:
+      D = cast<TypedefType>(TP)->getDecl();
+      break;
+    case Type::ObjCObject:
+      D = cast<ObjCObjectType>(TP)->getInterface();
+      break;
+    case Type::ObjCInterface:
+      D = cast<ObjCInterfaceType>(TP)->getDecl();
+      break;
+    case Type::Record:
+    case Type::Enum:
+      D = cast<TagType>(TP)->getDecl();
+      break;
+    default:
+      break;
+  }
+
+  if (!D)
+    return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
+
+  return cxcursor::MakeCXCursor(D, GetASTU(CT));
+}
+
+CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
+  const char *s = 0;
+#define TKIND(X) case CXType_##X: s = ""  #X  ""; break
+  switch (K) {
+    TKIND(Invalid);
+    TKIND(Unexposed);
+    TKIND(Void);
+    TKIND(Bool);
+    TKIND(Char_U);
+    TKIND(UChar);
+    TKIND(Char16);
+    TKIND(Char32);  
+    TKIND(UShort);
+    TKIND(UInt);
+    TKIND(ULong);
+    TKIND(ULongLong);
+    TKIND(UInt128);
+    TKIND(Char_S);
+    TKIND(SChar);
+    TKIND(WChar);
+    TKIND(Short);
+    TKIND(Int);
+    TKIND(Long);
+    TKIND(LongLong);
+    TKIND(Int128);
+    TKIND(Float);
+    TKIND(Double);
+    TKIND(LongDouble);
+    TKIND(NullPtr);
+    TKIND(Overload);
+    TKIND(Dependent);
+    TKIND(ObjCId);
+    TKIND(ObjCClass);
+    TKIND(ObjCSel);
+    TKIND(Complex);
+    TKIND(Pointer);
+    TKIND(BlockPointer);
+    TKIND(LValueReference);
+    TKIND(RValueReference);
+    TKIND(Record);
+    TKIND(Enum);
+    TKIND(Typedef);
+    TKIND(ObjCInterface);
+    TKIND(ObjCObjectPointer);
+    TKIND(FunctionNoProto);
+    TKIND(FunctionProto);
+  }
+#undef TKIND
+  return cxstring::createCXString(s);
+}
+
+unsigned clang_equalTypes(CXType A, CXType B) {
+  return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
+}
+
+CXType clang_getResultType(CXType X) {
+  QualType T = GetQualType(X);
+  if (!T.getTypePtr())
+    return MakeCXType(QualType(), GetASTU(X));
+  
+  if (const FunctionType *FD = T->getAs<FunctionType>())
+    return MakeCXType(FD->getResultType(), GetASTU(X));
+  
+  return MakeCXType(QualType(), GetASTU(X));
+}
+
+CXType clang_getCursorResultType(CXCursor C) {
+  if (clang_isDeclaration(C.kind)) {
+    Decl *D = cxcursor::getCursorDecl(C);
+    if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+      return MakeCXType(MD->getResultType(), cxcursor::getCursorASTUnit(C));
+
+    return clang_getResultType(clang_getCursorType(C));
+  }
+
+  return MakeCXType(QualType(), cxcursor::getCursorASTUnit(C));
+}
+
+unsigned clang_isPODType(CXType X) {
+  QualType T = GetQualType(X);
+  if (!T.getTypePtr())
+    return 0;
+  return T->isPODType() ? 1 : 0;
+}
+
+} // end: extern "C"
diff --git a/tools/libclang/CXType.h b/tools/libclang/CXType.h
new file mode 100644
index 0000000..94151ed
--- /dev/null
+++ b/tools/libclang/CXType.h
@@ -0,0 +1,29 @@
+//===- CXTypes.h - Routines for manipulating CXTypes ----------------------===//
+//
+//                     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_CXTYPES_H
+#define LLVM_CLANG_CXTYPES_H
+
+#include "clang-c/Index.h"
+#include "clang/AST/Type.h"
+
+namespace clang {
+  
+class ASTUnit;
+  
+namespace cxtype {
+  
+CXType MakeCXType(QualType T, ASTUnit *TU);
+  
+}} // end namespace clang::cxtype
+#endif
diff --git a/tools/libclang/Makefile b/tools/libclang/Makefile
new file mode 100644
index 0000000..6d2a13c
--- /dev/null
+++ b/tools/libclang/Makefile
@@ -0,0 +1,46 @@
+##===- tools/libclang/Makefile -----------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+CLANG_LEVEL := ../..
+LIBRARYNAME = clang
+
+EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/libclang.exports
+
+LINK_LIBS_IN_SHARED = 1
+SHARED_LIBRARY = 1
+
+LINK_COMPONENTS := bitreader mc core
+USEDLIBS = clangFrontend.a clangDriver.a clangSerialization.a clangParse.a \
+	   clangSema.a clangAnalysis.a clangAST.a clangLex.a clangBasic.a
+
+include $(CLANG_LEVEL)/Makefile
+
+##===----------------------------------------------------------------------===##
+# FIXME: This is copied from the 'lto' makefile.  Should we share this?
+##===----------------------------------------------------------------------===##
+
+ifeq ($(HOST_OS),Darwin)
+    LLVMLibsOptions += -Wl,-compatibility_version,1
+
+    # Set dylib internal version number to submission number.
+    ifdef LLVM_SUBMIT_VERSION
+        LLVMLibsOptions += -Wl,-current_version \
+                           -Wl,$(LLVM_SUBMIT_VERSION).$(LLVM_SUBMIT_SUBVERSION)
+    endif
+
+    # Extra options to override libtool defaults.
+    LLVMLibsOptions += -Wl,-dead_strip -Wl,-seg1addr,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 += -Wl,-install_name \
+                          -Wl,"@rpath/lib$(LIBRARYNAME)$(SHLIBEXT)"
+    endif
+endif
diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports
new file mode 100644
index 0000000..0d01dd9
--- /dev/null
+++ b/tools/libclang/libclang.darwin.exports
@@ -0,0 +1,106 @@
+_clang_CXXMethod_isStatic
+_clang_annotateTokens
+_clang_codeComplete
+_clang_codeCompleteAt
+_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_defaultCodeCompleteOptions
+_clang_defaultDiagnosticDisplayOptions
+_clang_defaultEditingTranslationUnitOptions
+_clang_defaultReparseOptions
+_clang_defaultSaveOptions
+_clang_disposeCodeCompleteResults
+_clang_disposeDiagnostic
+_clang_disposeIndex
+_clang_disposeString
+_clang_disposeTokens
+_clang_disposeTranslationUnit
+_clang_enableStackTraces
+_clang_equalCursors
+_clang_equalLocations
+_clang_equalTypes
+_clang_formatDiagnostic
+_clang_getCString
+_clang_getCXXAccessSpecifier
+_clang_getCanonicalType
+_clang_getClangVersion
+_clang_getCompletionAvailability
+_clang_getCompletionChunkCompletionString
+_clang_getCompletionChunkKind
+_clang_getCompletionChunkText
+_clang_getCompletionPriority
+_clang_getCursor
+_clang_getCursorAvailability
+_clang_getCursorDefinition
+_clang_getCursorExtent
+_clang_getCursorKind
+_clang_getCursorKindSpelling
+_clang_getCursorLanguage
+_clang_getCursorLinkage
+_clang_getCursorLocation
+_clang_getCursorReferenced
+_clang_getCursorResultType
+_clang_getCursorSpelling
+_clang_getCursorType
+_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_getIBOutletCollectionType
+_clang_getInclusions
+_clang_getInstantiationLocation
+_clang_getLocation
+_clang_getNullCursor
+_clang_getNullLocation
+_clang_getNullRange
+_clang_getNumCompletionChunks
+_clang_getNumDiagnostics
+_clang_getPointeeType
+_clang_getRange
+_clang_getRangeEnd
+_clang_getRangeStart
+_clang_getResultType
+_clang_getTokenExtent
+_clang_getTokenKind
+_clang_getTokenLocation
+_clang_getTokenSpelling
+_clang_getTranslationUnitCursor
+_clang_getTranslationUnitSpelling
+_clang_getTypeDeclaration
+_clang_getTypeKindSpelling
+_clang_isCursorDefinition
+_clang_isDeclaration
+_clang_isExpression
+_clang_isInvalid
+_clang_isPODType
+_clang_isPreprocessing
+_clang_isReference
+_clang_isStatement
+_clang_isTranslationUnit
+_clang_isUnexposed
+_clang_isVirtualBase
+_clang_parseTranslationUnit
+_clang_reparseTranslationUnit
+_clang_saveTranslationUnit
+_clang_setUseExternalASTGeneration
+_clang_sortCodeCompletionResults
+_clang_tokenize
+_clang_visitChildren
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
new file mode 100644
index 0000000..60d3352
--- /dev/null
+++ b/tools/libclang/libclang.exports
@@ -0,0 +1,106 @@
+clang_CXXMethod_isStatic
+clang_annotateTokens
+clang_codeComplete
+clang_codeCompleteAt
+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_defaultCodeCompleteOptions
+clang_defaultDiagnosticDisplayOptions
+clang_defaultEditingTranslationUnitOptions
+clang_defaultReparseOptions
+clang_defaultSaveOptions
+clang_disposeCodeCompleteResults
+clang_disposeDiagnostic
+clang_disposeIndex
+clang_disposeString
+clang_disposeTokens
+clang_disposeTranslationUnit
+clang_enableStackTraces
+clang_equalCursors
+clang_equalLocations
+clang_equalTypes
+clang_formatDiagnostic
+clang_getCString
+clang_getCXXAccessSpecifier
+clang_getCanonicalType
+clang_getClangVersion
+clang_getCompletionAvailability
+clang_getCompletionChunkCompletionString
+clang_getCompletionChunkKind
+clang_getCompletionChunkText
+clang_getCompletionPriority
+clang_getCursor
+clang_getCursorAvailability
+clang_getCursorDefinition
+clang_getCursorExtent
+clang_getCursorKind
+clang_getCursorKindSpelling
+clang_getCursorLanguage
+clang_getCursorLinkage
+clang_getCursorLocation
+clang_getCursorReferenced
+clang_getCursorResultType
+clang_getCursorSpelling
+clang_getCursorType
+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_getIBOutletCollectionType
+clang_getInclusions
+clang_getInstantiationLocation
+clang_getLocation
+clang_getNullCursor
+clang_getNullLocation
+clang_getNullRange
+clang_getNumCompletionChunks
+clang_getNumDiagnostics
+clang_getPointeeType
+clang_getRange
+clang_getRangeEnd
+clang_getRangeStart
+clang_getResultType
+clang_getTokenExtent
+clang_getTokenKind
+clang_getTokenLocation
+clang_getTokenSpelling
+clang_getTranslationUnitCursor
+clang_getTranslationUnitSpelling
+clang_getTypeDeclaration
+clang_getTypeKindSpelling
+clang_isCursorDefinition
+clang_isDeclaration
+clang_isExpression
+clang_isInvalid
+clang_isPODType
+clang_isPreprocessing
+clang_isReference
+clang_isStatement
+clang_isTranslationUnit
+clang_isUnexposed
+clang_isVirtualBase
+clang_parseTranslationUnit
+clang_reparseTranslationUnit
+clang_saveTranslationUnit
+clang_setUseExternalASTGeneration
+clang_sortCodeCompletionResults
+clang_tokenize
+clang_visitChildren
diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer
index 391ea57..c182a68 100755
--- a/tools/scan-build/ccc-analyzer
+++ b/tools/scan-build/ccc-analyzer
@@ -315,11 +315,13 @@
 my %CompileOptionMap = (
   '-nostdinc' => 0,
   '-fblocks' => 0,
+  '-fno-builtin' => 0,
   '-fobjc-gc-only' => 0,
   '-fobjc-gc' => 0,
   '-ffreestanding' => 0,
   '-include' => 1,
   '-idirafter' => 1,
+  '-imacros' => 1,
   '-iprefix' => 1,
   '-iquote' => 1,
   '-isystem' => 1,
@@ -364,6 +366,7 @@
 
 my %LangMap = (
   'c'   => 'c',
+  'cp'  => 'c++',
   'cpp' => 'c++',
   'cc'  => 'c++',
   'i'   => 'c-cpp-output',
diff --git a/utils/FuzzTest b/utils/FuzzTest
new file mode 100755
index 0000000..2aa5989
--- /dev/null
+++ b/utils/FuzzTest
@@ -0,0 +1,340 @@
+#!/usr/bin/env python
+
+"""
+This is a generic fuzz testing tool, see --help for more information.
+"""
+
+import os
+import sys
+import random
+import subprocess
+import itertools
+
+class TestGenerator:
+    def __init__(self, inputs, delete, insert, replace,
+                 insert_strings, pick_input):
+        self.inputs = [(s, open(s).read()) for s in inputs]
+
+        self.delete = bool(delete)
+        self.insert = bool(insert)
+        self.replace = bool(replace)
+        self.pick_input = bool(pick_input)
+        self.insert_strings = list(insert_strings)
+
+        self.num_positions = sum([len(d) for _,d in self.inputs])
+        self.num_insert_strings = len(insert_strings)
+        self.num_tests = ((delete + (insert + replace)*self.num_insert_strings)
+                          * self.num_positions)
+        self.num_tests += 1
+
+        if self.pick_input:
+            self.num_tests *= self.num_positions
+
+    def position_to_source_index(self, position):
+        for i,(s,d) in enumerate(self.inputs):
+            n = len(d)
+            if position < n:
+                return (i,position)
+            position -= n
+        raise ValueError,'Invalid position.'
+
+    def get_test(self, index):
+        assert 0 <= index < self.num_tests
+
+        picked_position = None
+        if self.pick_input:
+            index,picked_position = divmod(index, self.num_positions)
+            picked_position = self.position_to_source_index(picked_position)
+
+        if index == 0:
+            return ('nothing', None, None, picked_position)
+
+        index -= 1
+        index,position = divmod(index, self.num_positions)
+        position = self.position_to_source_index(position)
+        if self.delete:
+            if index == 0:
+                return ('delete', position, None, picked_position)
+            index -= 1
+
+        index,insert_index = divmod(index, self.num_insert_strings)
+        insert_str = self.insert_strings[insert_index]
+        if self.insert:
+            if index == 0:
+                return ('insert', position, insert_str, picked_position)
+            index -= 1
+
+        assert self.replace
+        assert index == 0
+        return ('replace', position, insert_str, picked_position)
+
+class TestApplication:
+    def __init__(self, tg, test):
+        self.tg = tg
+        self.test = test
+
+    def apply(self):
+        if self.test[0] == 'nothing':
+            pass
+        else:
+            i,j = self.test[1]
+            name,data = self.tg.inputs[i]
+            if self.test[0] == 'delete':
+                data = data[:j] + data[j+1:]
+            elif self.test[0] == 'insert':
+                data = data[:j] + self.test[2] + data[j:]
+            elif self.test[0] == 'replace':
+                data = data[:j] + self.test[2] + data[j+1:]
+            else:
+                raise ValueError,'Invalid test %r' % self.test
+            open(name,'wb').write(data)
+
+    def revert(self):
+        if self.test[0] != 'nothing':
+            i,j = self.test[1]
+            name,data = self.tg.inputs[i]
+            open(name,'wb').write(data)
+
+def quote(str):
+    return '"' + str + '"'
+        
+def run_one_test(test_application, index, input_files, args):
+    test = test_application.test
+
+    # Interpolate arguments.
+    options = { 'index' : index,
+                'inputs' : ' '.join(quote(f) for f in input_files) }
+
+    # Add picked input interpolation arguments, if used.
+    if test[3] is not None:
+        pos = test[3][1]
+        options['picked_input'] = input_files[test[3][0]]
+        options['picked_input_pos'] = pos
+        # Compute the line and column.
+        file_data = test_application.tg.inputs[test[3][0]][1]
+        line = column = 1
+        for i in range(pos):
+            c = file_data[i]
+            if c == '\n':
+                line += 1
+                column = 1
+            else:
+                column += 1
+        options['picked_input_line'] = line
+        options['picked_input_col'] = column
+        
+    test_args = [a % options for a in args]
+    if opts.verbose:
+        print '%s: note: executing %r' % (sys.argv[0], test_args)
+
+    stdout = None
+    stderr = None
+    if opts.log_dir:
+        stdout_log_path = os.path.join(opts.log_dir, '%s.out' % index)
+        stderr_log_path = os.path.join(opts.log_dir, '%s.err' % index)
+        stdout = open(stdout_log_path, 'wb')
+        stderr = open(stderr_log_path, 'wb')
+    else:
+        sys.stdout.flush()
+    p = subprocess.Popen(test_args, stdout=stdout, stderr=stderr)
+    p.communicate()
+    exit_code = p.wait()
+
+    test_result = (exit_code == opts.expected_exit_code or
+                   exit_code in opts.extra_exit_codes)
+
+    if stdout is not None:
+        stdout.close()
+        stderr.close()
+
+        # Remove the logs for passes, unless logging all results.
+        if not opts.log_all and test_result:
+            os.remove(stdout_log_path)
+            os.remove(stderr_log_path)
+
+    if not test_result:
+        print 'FAIL: %d' % index
+    elif not opts.succinct:
+        print 'PASS: %d' % index
+
+def main():
+    global opts
+    from optparse import OptionParser, OptionGroup
+    parser = OptionParser("""%prog [options] ... test command args ...
+
+%prog is a tool for fuzzing inputs and testing them.
+
+The most basic usage is something like:
+
+  $ %prog --file foo.txt ./test.sh
+
+which will run a default list of fuzzing strategies on the input. For each
+fuzzed input, it will overwrite the input files (in place), run the test script,
+then restore the files back to their original contents.
+
+NOTE: You should make sure you have a backup copy of your inputs, in case
+something goes wrong!!!
+
+You can cause the fuzzing to not restore the original files with
+'--no-revert'. Generally this is used with '--test <index>' to run one failing
+test and then leave the fuzzed inputs in place to examine the failure.
+
+For each fuzzed input, %prog will run the test command given on the command
+line. Each argument in the command is subject to string interpolation before
+being executed. The syntax is "%(VARIABLE)FORMAT" where FORMAT is a standard
+printf format, and VARIBLE is one of:
+
+  'index' - the test index being run
+  'inputs' - the full list of test inputs
+  'picked_input'      - (with --pick-input) the selected input file
+  'picked_input_pos'  - (with --pick-input) the selected input position
+  'picked_input_line' - (with --pick-input) the selected input line
+  'picked_input_col'  - (with --pick-input) the selected input column
+
+By default, the script will run forever continually picking new tests to
+run. You can limit the number of tests that are run with '--max-tests <number>',
+and you can run a particular test with '--test <index>'.
+""")
+    parser.add_option("-v", "--verbose", help="Show more output",
+                      action='store_true', dest="verbose", default=False)
+    parser.add_option("-s", "--succinct",  help="Reduce amount of output",
+                      action="store_true", dest="succinct", default=False)
+
+    group = OptionGroup(parser, "Test Execution")
+    group.add_option("", "--expected-exit-code", help="Set expected exit code",
+                     type=int, dest="expected_exit_code",
+                     default=0)
+    group.add_option("", "--extra-exit-code",
+                     help="Set additional expected exit code",
+                     type=int, action="append", dest="extra_exit_codes",
+                     default=[])
+    group.add_option("", "--log-dir",
+                     help="Capture test logs to an output directory",
+                     type=str, dest="log_dir",
+                     default=None)
+    group.add_option("", "--log-all",
+                     help="Log all outputs (not just failures)",
+                     action="store_true", dest="log_all", default=False)
+    parser.add_option_group(group)
+
+    group = OptionGroup(parser, "Input Files")
+    group.add_option("", "--file", metavar="PATH",
+                     help="Add an input file to fuzz",
+                     type=str, action="append", dest="input_files", default=[])
+    group.add_option("", "--filelist", metavar="LIST",
+                     help="Add a list of inputs files to fuzz (one per line)",
+                     type=int, action="append", dest="filelists", default=[])
+    parser.add_option_group(group)
+
+    group = OptionGroup(parser, "Fuzz Options")
+    group.add_option("", "--replacement-chars", dest="replacement_chars",
+                     help="Characters to insert/replace",
+                     default="0{}[]<>\;@#$^%& ")
+    group.add_option("", "--replacement-string", dest="replacement_strings",
+                     action="append", help="Add a replacement string to use",
+                     default=[])
+    group.add_option("", "--replacement-list", dest="replacement_lists",
+                     help="Add a list of replacement strings (one per line)",
+                     action="append", default=[])
+    group.add_option("", "--no-delete", help="Don't delete characters",
+                     action='store_false', dest="enable_delete", default=True)
+    group.add_option("", "--no-insert", help="Don't insert strings",
+                     action='store_false', dest="enable_insert", default=True)
+    group.add_option("", "--no-replace", help="Don't replace strings",
+                     action='store_false', dest="enable_replace", default=True)
+    group.add_option("", "--no-revert", help="Don't revert changes",
+                     action='store_false', dest="revert", default=True)
+    parser.add_option_group(group)
+
+    group = OptionGroup(parser, "Test Selection")
+    group.add_option("", "--test", help="Run a particular test",
+                     type=int, dest="test", default=None, metavar="INDEX")
+    group.add_option("", "--max-tests", help="Maximum number of tests",
+                     type=int, dest="max_tests", default=10, metavar="COUNT")
+    group.add_option("", "--pick-input",
+                     help="Randomly select an input byte as well as fuzzing",
+                     action='store_true', dest="pick_input", default=False)
+    parser.add_option_group(group)
+
+    parser.disable_interspersed_args()
+
+    (opts, args) = parser.parse_args()
+
+    if not args:
+        parser.error("Invalid number of arguments")
+
+    # Collect the list of inputs.
+    input_files = list(opts.input_files)
+    for filelist in opts.filelists:
+        f = open(filelist)
+        try:
+            for ln in f:
+                ln = ln.strip()
+                if ln:
+                    input_files.append(ln)
+        finally:
+            f.close()
+    input_files.sort()
+
+    if not input_files:
+        parser.error("No input files!")
+
+    print '%s: note: fuzzing %d files.' % (sys.argv[0], len(input_files))
+
+    # Make sure the log directory exists if used.
+    if opts.log_dir:
+        if not os.path.exists(opts.log_dir):
+            try:
+                os.mkdir(opts.log_dir)
+            except OSError:
+                print "%s: error: log directory couldn't be created!" % (
+                    sys.argv[0],)
+                raise SystemExit,1
+
+    # Get the list if insert/replacement strings.
+    replacements = list(opts.replacement_chars)
+    replacements.extend(opts.replacement_strings)
+    for replacement_list in opts.replacement_lists:
+        f = open(replacement_list)
+        try:
+            for ln in f:
+                ln = ln[:-1]
+                if ln:
+                    replacements.append(ln)
+        finally:
+            f.close()
+
+    # Unique and order the replacement list.
+    replacements = list(set(replacements))
+    replacements.sort()
+
+    # Create the test generator.
+    tg = TestGenerator(input_files, opts.enable_delete, opts.enable_insert,
+                       opts.enable_replace, replacements, opts.pick_input)
+
+    print '%s: note: %d input bytes.' % (sys.argv[0], tg.num_positions)
+    print '%s: note: %d total tests.' % (sys.argv[0], tg.num_tests)
+    if opts.test is not None:
+        it = [opts.test]
+    elif opts.max_tests is not None:
+        it = itertools.imap(random.randrange,
+                            itertools.repeat(tg.num_tests, opts.max_tests))
+    else:
+        it = itertools.imap(random.randrange, itertools.repeat(tg.num_tests))
+    for test in it:
+        t = tg.get_test(test)
+
+        if opts.verbose:
+            print '%s: note: running test %d: %r' % (sys.argv[0], test, t)
+        ta = TestApplication(tg, t)
+        try:
+            ta.apply()
+            run_one_test(ta, test, input_files, args)
+        finally:
+            if opts.revert:
+                ta.revert()
+
+        sys.stdout.flush()
+
+if __name__ == '__main__':
+    main()
diff --git a/utils/TestUtils/pch-test.pl b/utils/TestUtils/pch-test.pl
index e097c5c..e4311e9 100755
--- a/utils/TestUtils/pch-test.pl
+++ b/utils/TestUtils/pch-test.pl
@@ -17,7 +17,7 @@
   @files = `ls test/*/*.$suffix`;
   foreach $file (@files) {
     chomp($file);
-    my $code = system("clang- -fsyntax-only -x $language $file > /dev/null 2>&1");
+    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");
diff --git a/www/analyzer/annotations.html b/www/analyzer/annotations.html
index 6204713..5184aed 100644
--- a/www/analyzer/annotations.html
+++ b/www/analyzer/annotations.html
@@ -53,7 +53,9 @@
     <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_ns_returns_not_retained">Attribute 'ns_returns_not_retained'</a></li>
       <li><a href="#attr_cf_returns_retained">Attribute 'cf_returns_retained'</a></li>
+      <li><a href="#attr_cf_returns_not_retained">Attribute 'cf_returns_not_retained'</a></li>
     </ul>
     </li>
   </ul>
@@ -190,6 +192,36 @@
 
 <img src="images/example_ns_returns_retained.png">
 
+<h4 id="attr_ns_returns_not_retained">Attribute 'ns_returns_not_retained'
+(Clang-specific)</h4>
+
+<p>The 'ns_returns_not_retained' attribute is the complement of '<a
+href="#attr_ns_returns_retained">ns_returns_retained</a>'. Where a function or
+method may appear to obey the Cocoa conventions and return a retained Cocoa
+object, this attribute can be used to indicate that the object reference
+returned should not be considered as an &quot;owning&quot; reference being
+returned to the caller.</p>
+
+<p>Usage is identical to <a
+href="#attr_ns_returns_retained">ns_returns_retained</a>.  When using the
+attribute, be sure to declare it within the proper macro that checks for
+its availability, as it is not available in earlier versions of the analyzer:</p>
+
+<pre class="code_example">
+<span class="command">$ cat test.m</span>
+#ifndef __has_feature      // Optional.
+#define __has_feature(x) 0 // Compatibility with non-clang compilers.
+#endif
+
+#ifndef NS_RETURNS_NOT_RETAINED
+#if __has_feature(attribute_ns_returns_not_retained)
+<span class="code_highlight">#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))</span>
+#else
+#define NS_RETURNS_NOT_RETAINED
+#endif
+#endif
+</pre>
+
 <h4 id="attr_cf_returns_retained">Attribute 'cf_returns_retained'
 (Clang-specific)</h4>
 
@@ -288,6 +320,36 @@
 
 <img src="images/example_cf_returns_retained_gc.png">
 
+<h4 id="attr_cf_returns_not_retained">Attribute 'cf_returns_not_retained'
+(Clang-specific)</h4>
+
+<p>The 'cf_returns_not_retained' attribute is the complement of '<a
+href="#attr_cf_returns_retained">cf_returns_retained</a>'. Where a function or
+method may appear to obey the Core Foundation or Cocoa conventions and return
+a retained Core Foundation object, this attribute can be used to indicate that
+the object reference returned should not be considered as an
+&quot;owning&quot; reference being returned to the caller.</p>
+
+<p>Usage is identical to <a
+href="#attr_cf_returns_retained">cf_returns_retained</a>.  When using the
+attribute, be sure to declare it within the proper macro that checks for
+its availability, as it is not available in earlier versions of the analyzer:</p>
+
+<pre class="code_example">
+<span class="command">$ cat test.m</span>
+#ifndef __has_feature      // Optional.
+#define __has_feature(x) 0 // Compatibility with non-clang compilers.
+#endif
+
+#ifndef CF_RETURNS_NOT_RETAINED
+#if __has_feature(attribute_cf_returns_not_retained)
+<span class="code_highlight">#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))</span>
+#else
+#define CF_RETURNS_NOT_RETAINED
+#endif
+#endif
+</pre>
+
 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 <h2 id="custom_assertions">Custom Assertion Handlers</h2>
 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
diff --git a/www/analyzer/installation.html b/www/analyzer/installation.html
index b84f263..9eaacd7 100644
--- a/www/analyzer/installation.html
+++ b/www/analyzer/installation.html
@@ -90,8 +90,8 @@
 
 <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
+<p>For example, if you built a <em>Debug+Asserts</em> build of LLVM/Clang (the
+default), the resultant <tt>clang</tt> binary will be in $(OBJDIR)/Debug+Asserts
 (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
diff --git a/www/analyzer/latest_checker.html.incl b/www/analyzer/latest_checker.html.incl
index 4131306..76e569d 100644
--- a/www/analyzer/latest_checker.html.incl
+++ b/www/analyzer/latest_checker.html.incl
@@ -1 +1 @@
-<b><a href="http://checker.minormatter.com/checker-240.tar.bz2">checker-240.tar.bz2</a></b> (built April 11, 2010)
+<b><a href="/checker/checker-247.tar.bz2">checker-247.tar.bz2</a></b> (built July 30, 2010)
diff --git a/www/clang-tutorial.html b/www/clang-tutorial.html
new file mode 100644
index 0000000..0e17046
--- /dev/null
+++ b/www/clang-tutorial.html
@@ -0,0 +1,56 @@
+<!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 - Quick Tutorial</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>Tutorial</h1>
+
+  <p>Invoking the BoostCon tool:</p>
+  <pre>
+$ clang -cc1 -boostcon t.cpp
+</pre>
+
+  <p>Teach the BoostCon action to identify and print C++ classes:</p>
+  <pre>
+bool VisitCXXRecordDecl(CXXRecordDecl *D) {
+  std::cout &lt;&lt; D-&gt;getNameAsString() 
+    &lt;&lt; '\n';
+  return false;
+}
+</pre>
+
+  <p>Walk and print base classes of a class:</p>
+  <pre>
+for(CXXRecordDecl::base_class_iterator 
+      B = D-&gt;bases_begin(), BEnd = D-&gt;bases_end();
+      B != BEnd; ++B) {
+  QualType BaseType = B-&gt;getType();
+  std::cout &lt;&lt; "  " &lt;&lt; BaseType.getAsString() 
+    &lt;&lt; '\n';
+}
+</pre>
+
+  <p>Retrieve the C++ class declaration from a base type:</p>
+  <pre>
+if (const RecordType *RTy
+             = BaseType-&gt;getAs&lt;RecordType&gt;()) { 
+  RecordDecl *Base = RTy-&gt;getDecl();
+  if (CXXRecordDecl *BaseCXX
+        = dyn_cast&lt;CXXRecordDecl&gt;(Base)) {
+  
+  }
+}
+</pre>
+</div>
+</body>
+</html>
diff --git a/www/comparison.html b/www/comparison.html
index 0a6a7c8..dcf6220 100644
--- a/www/comparison.html
+++ b/www/comparison.html
@@ -50,8 +50,10 @@
     <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><a href="cxx_status.html">Clang support for C++</a> is more compliant 
+        than GCC's in many ways, but is not as mature as GCC's.  GCC has several
+        C++'0x features that Clang does not yet support (e.g. variadic 
+        templates).</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>
diff --git a/www/compatibility.html b/www/compatibility.html
new file mode 100644
index 0000000..4ad5bc0
--- /dev/null
+++ b/www/compatibility.html
@@ -0,0 +1,634 @@
+<!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>Language 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>Language Compatibility</h1>
+<!-- ======================================================================= -->
+
+<p>Clang strives to both conform to current language standards (C99,
+  C++98) and also to implement many widely-used extensions available
+  in other compilers, so that most correct code will "just work" when
+  compiler with Clang. However, Clang is more strict than other
+  popular compilers, and may reject incorrect code that other
+  compilers allow. This page documents common compatibility and
+  portability issues with Clang to help you understand and fix the
+  problem in your code when Clang emits an error message.</p>
+  
+<ul>
+  <li><a href="#c">C compatibility</a>
+    <ul>
+      <li><a href="#inline">C99 inline functions</a></li>
+      <li><a href="#lvalue-cast">Lvalue casts</a></li>
+    </ul>
+  </li>
+  <li><a href="#objective-c">Objective-C compatibility</a>
+    <ul>
+      <li><a href="#super-cast">Cast of super</a></li>
+      <li><a href="#sizeof-interface">Size of interfaces</a></li>
+    </ul>
+  </li>
+  <li><a href="#c++">C++ compatibility</a>
+    <ul>
+      <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="#undep_incomplete">Incomplete types in 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>
+  </li>
+  <li><a href="#objective-c++">Objective-C++ compatibility</a>
+    <ul>
+      <li><a href="#implicit-downcasts">Implicit downcasts</a></li>
+    </ul>
+    <ul>
+      <li><a href="#Use of class as method name">Use of class as method name</a></li>
+    </ul>
+  </li>
+</ul>
+
+<!-- ======================================================================= -->
+<h2 id="c">C compatibility</h3>
+<!-- ======================================================================= -->
+
+<!-- ======================================================================= -->
+<h3 id="inline">C99 inline functions</h3>
+<!-- ======================================================================= -->
+<p>By default, Clang builds C code according to the C99 standard,
+which provides different inlining semantics than GCC's default
+behavior. For example, when compiling the following code with no optimization:</p>
+<pre>
+inline int add(int i, int j) { return i + j; }
+
+int main() {
+  int i = add(4, 5);
+  return i;
+}
+</pre>
+
+<p>In C99, this is an incomplete (incorrect) program because there is
+no external definition of the <code>add</code> function: the inline
+definition is only used for optimization, if the compiler decides to
+perform inlining. Therefore, we will get a (correct) link-time error
+with Clang, e.g.:</p>
+
+<pre>
+Undefined symbols:
+  "_add", referenced from:
+      _main in cc-y1jXIr.o
+</pre>
+
+<p>There are several ways to fix this problem:</p>
+
+<ul>
+  <li>Change <code>add</code> to a <code>static inline</code>
+  function. Static inline functions are always resolved within the
+  translation unit, so you won't have to add an external, non-inline
+  definition of the function elsewhere in your program.</li>
+  
+  <li>Provide an external (non-inline) definition of <code>add</code>
+  somewhere in your program.</li>
+   
+  <li>Compile with the GNU89 dialect by adding
+  <code>-std=gnu89</code> to the set of Clang options. This option is
+  only recommended if the program source cannot be changed or if the
+  program also relies on additional C89-specific behavior that cannot
+  be changed.</li>
+</ul>
+
+<!-- ======================================================================= -->
+<h3 id="lvalue-cast">Lvalue casts</h3>
+<!-- ======================================================================= -->
+
+<p>Old versions of GCC permit casting the left-hand side of an assignment to a
+different type. Clang produces an error on similar code, e.g.,</p>
+
+<pre>
+lvalue.c:2:3: error: assignment to cast is illegal, lvalue casts are not
+      supported
+  (int*)addr = val;
+  ^~~~~~~~~~ ~
+</pre>
+
+<p>To fix this problem, move the cast to the right-hand side. In this
+example, one could use:</p>
+
+<pre>
+  addr = (float *)val;
+</pre>
+
+<!-- ======================================================================= -->
+<h2 id="objective-c">Objective-C compatibility</h3>
+<!-- ======================================================================= -->
+
+<!-- ======================================================================= -->
+<h3 id="super-cast">Cast of super</h3>
+<!-- ======================================================================= -->
+
+<p>GCC treats the <code>super</code> identifier as an expression that
+can, among other things, be cast to a different type. Clang treats
+<code>super</code> as a context-sensitive keyword, and will reject a
+type-cast of <code>super</code>:</p>
+
+<pre>
+super.m:11:12: error: cannot cast 'super' (it isn't an expression)
+  [(Super*)super add:4];
+   ~~~~~~~~^
+</pre>
+
+<p>To fix this problem, remove the type cast, e.g.</p>
+<pre>
+  [super add:4];
+</pre>
+
+<!-- ======================================================================= -->
+<h3 id="sizeof-interface">Size of interfaces</h3>
+<!-- ======================================================================= -->
+
+<p>When using the "non-fragile" Objective-C ABI in use, the size of an
+Objective-C class may change over time as instance variables are added
+(or removed). For this reason, Clang rejects the application of the
+<code>sizeof</code> operator to an Objective-C class when using this
+ABI:</p>
+
+<pre>
+sizeof.m:4:14: error: invalid application of 'sizeof' to interface 'NSArray' in
+      non-fragile ABI
+  int size = sizeof(NSArray);
+             ^     ~~~~~~~~~
+</pre>
+
+<p>Code that relies on the size of an Objective-C class is likely to
+be broken anyway, since that size is not actually constant. To address
+this problem, use the Objective-C runtime API function
+<code>class_getInstanceSize()</code>:</p>
+
+<pre>
+  class_getInstanceSize([NSArray class])
+</pre>
+
+<!-- ======================================================================= -->
+<h2 id="c++">C++ compatibility</h3>
+<!-- ======================================================================= -->
+
+<!-- ======================================================================= -->
+<h3 id="vla">Variable-length arrays</h3>
+<!-- ======================================================================= -->
+
+<p>GCC and C99 allow an array's size to be determined at run
+time. This extension is not permitted in standard C++. However, Clang
+supports such variable length arrays in very limited circumstances for
+compatibility with GNU C and C99 programs:</p>
+
+<ul>  
+  <li>The element type of a variable length array must be a POD
+  ("plain old data") type, which means that it cannot have any
+  user-declared constructors or destructors, base classes, or any
+  members if non-POD type. All C types are POD types.</li>
+
+  <li>Variable length arrays cannot be used as the type of a non-type
+template parameter.</li> </ul>
+
+<p>If your code uses variable length arrays in a manner that Clang doesn't support, there are several ways to fix your code:
+
+<ol>
+<li>replace the variable length array 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>
+
+<!-- ======================================================================= -->
+<h3 id="init_static_const">Initialization of non-integral static const data members within a class definition</h3>
+<!-- ======================================================================= -->
+
+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.
+
+<!-- ======================================================================= -->
+<h3 id="dep_lookup">Unqualified lookup in templates</h3>
+<!-- ======================================================================= -->
+
+<p>Some versions of GCC accept the following invalid code:
+
+<pre>
+template &lt;typename T&gt; T Squared(T x) {
+  return Multiply(x, x);
+}
+
+int Multiply(int x, int y) {
+  return x * y;
+}
+
+int main() {
+  Squared(5);
+}
+</pre>
+
+<p>Clang complains:
+
+<pre>  <b>my_file.cpp:2:10: <span class="error">error:</span> use of undeclared identifier 'Multiply'</b>
+    return Multiply(x, x);
+  <span class="caret">         ^</span>
+
+  <b>my_file.cpp:10:3: <span class="note">note:</span> in instantiation of function template specialization 'Squared&lt;int&gt;' requested here</b>
+    Squared(5);
+  <span class="caret">  ^</span>
+</pre>
+
+<p>The C++ standard says that unqualified names like <q>Multiply</q>
+are looked up in two ways.
+
+<p>First, the compiler does <i>unqualified lookup</i> in the scope
+where the name was written.  For a template, this means the lookup is
+done at the point where the template is defined, not where it's
+instantiated.  Since <tt>Multiply</tt> hasn't been declared yet at
+this point, unqualified lookup won't find it.
+
+<p>Second, if the name is called like a function, then the compiler
+also does <i>argument-dependent lookup</i> (ADL).  (Sometimes
+unqualified lookup can suppress ADL; see [basic.lookup.argdep]p3 for
+more information.)  In ADL, the compiler looks at the types of all the
+arguments to the call.  When it finds a class type, it looks up the
+name in that class's namespace; the result is all the declarations it
+finds in those namespaces, plus the declarations from unqualified
+lookup.  However, the compiler doesn't do ADL until it knows all the
+argument types.
+
+<p>In our example, <tt>Multiply</tt> is called with dependent
+arguments, so ADL isn't done until the template is instantiated.  At
+that point, the arguments both have type <tt>int</tt>, which doesn't
+contain any class types, and so ADL doesn't look in any namespaces.
+Since neither form of lookup found the declaration
+of <tt>Multiply</tt>, the code doesn't compile.
+
+<p>Here's another example, this time using overloaded operators,
+which obey very similar rules.
+
+<pre>#include &lt;iostream&gt;
+
+template&lt;typename T&gt;
+void Dump(const T&amp; value) {
+  std::cout &lt;&lt; value &lt;&lt; "\n";
+}
+
+namespace ns {
+  struct Data {};
+}
+
+std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, ns::Data data) {
+  return out &lt;&lt; "Some data";
+}
+
+void Use() {
+  Dump(ns::Data());
+}</pre>
+
+<p>Again, Clang complains about not finding a matching function:</p>
+
+<pre>
+<b>my_file.cpp:5:13: <span class="error">error:</span> invalid operands to binary expression ('ostream' (aka 'basic_ostream&lt;char&gt;') and 'ns::Data const')</b>
+  std::cout &lt;&lt; value &lt;&lt; "\n";
+  <span class="caret">~~~~~~~~~ ^  ~~~~~</span>
+<b>my_file.cpp:17:3: <span class="note">note:</span> in instantiation of function template specialization 'Dump&lt;ns::Data&gt;' requested here</b>
+  Dump(ns::Data());
+  <span class="caret">^</span>
+</pre>
+
+<p>Just like before, unqualified lookup didn't find any declarations
+with the name <tt>operator&lt;&lt;</tt>.  Unlike before, the argument
+types both contain class types: one of them is an instance of the
+class template type <tt>std::basic_ostream</tt>, and the other is the
+type <tt>ns::Data</tt> that we declared above.  Therefore, ADL will
+look in the namespaces <tt>std</tt> and <tt>ns</tt> for
+an <tt>operator&lt;&lt;</tt>.  Since one of the argument types was
+still dependent during the template definition, ADL isn't done until
+the template is instantiated during <tt>Use</tt>, which means that
+the <tt>operator&lt;&lt;</tt> we want it to find has already been
+declared.  Unfortunately, it was declared in the global namespace, not
+in either of the namespaces that ADL will look in!
+
+<p>There are two ways to fix this problem:</p>
+<ol><li>Make sure the function you want to call is declared before the
+template that might call it.  This is the only option if none of its
+argument types contain classes.  You can do this either by moving the
+template definition, or by moving the function definition, or by
+adding a forward declaration of the function before the template.</li>
+<li>Move the function into the same namespace as one of its arguments
+so that ADL applies.</li></ol>
+
+<p>For more information about argument-dependent lookup, see
+[basic.lookup.argdep].  For more information about the ordering of
+lookup in templates, see [temp.dep.candidate].
+
+<!-- ======================================================================= -->
+<h3 id="dep_lookup_bases">Unqualified lookup into dependent bases of class templates</h3>
+<!-- ======================================================================= -->
+
+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!
+
+<!-- ======================================================================= -->
+<h3 id="undep_incomplete">Incomplete types in templates</h3>
+<!-- ======================================================================= -->
+
+The following code is invalid, but compilers are allowed to accept it:
+
+<pre>
+  class IOOptions;
+  template &lt;class T&gt; bool read(T &amp;value) {
+    IOOptions opts;
+    return read(opts, value);
+  }
+
+  class IOOptions { bool ForceReads; };
+  bool read(const IOOptions &amp;opts, int &amp;x);
+  template bool read&lt;&gt;(int &amp;);
+</pre>
+
+The standard says that types which don't depend on template parameters
+must be complete when a template is defined if they affect the
+program's behavior.  However, the standard also says that compilers
+are free to not enforce this rule.  Most compilers enforce it to some
+extent; for example, it would be an error in GCC to
+write <tt>opts.ForceReads</tt> in the code above.  In Clang, we feel
+that enforcing the rule consistently lets us provide a better
+experience, but unfortunately it also means we reject some code that
+other compilers accept.
+
+<p>We've explained the rule here in very imprecise terms; see
+[temp.res]p8 for details.
+
+<!-- ======================================================================= -->
+<h3 id="bad_templates">Templates with no valid instantiations</h3>
+<!-- ======================================================================= -->
+
+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.
+
+<!-- ======================================================================= -->
+<h3 id="default_init_const">Default initialization of const variable of a class type requires user-defined default constructor</h3>
+<!-- ======================================================================= -->
+
+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>
+
+<!-- ======================================================================= -->
+<h2 id="objective-c++">Objective-C++ compatibility</h3>
+<!-- ======================================================================= -->
+
+<!-- ======================================================================= -->
+<h3 id="implicit-downcasts">Implicit downcasts</h3>
+<!-- ======================================================================= -->
+
+<p>Due to a bug in its implementation, GCC allows implicit downcasts
+(from base class to a derived class) when calling functions. Such code is
+inherently unsafe, since the object might not actually be an instance
+of the derived class, and is rejected by Clang. For example, given
+this code:</p>
+
+<pre>
+@interface Base @end
+@interface Derived : Base @end
+
+void f(Derived *);
+void g(Base *base) {
+  f(base);
+}
+</pre>
+
+<p>Clang produces the following error:</p>
+
+<pre>
+downcast.mm:6:3: error: no matching function for call to 'f'
+  f(base);
+  ^
+downcast.mm:4:6: note: candidate function not viable: cannot convert from
+      superclass 'Base *' to subclass 'Derived *' for 1st argument
+void f(Derived *);
+     ^
+</pre>
+
+<p>If the downcast is actually correct (e.g., because the code has
+already checked that the object has the appropriate type), add an
+explicit cast:</p>
+
+<pre>
+  f((Derived *)base);
+</pre>
+
+<!-- ======================================================================= -->
+<h3 id="Use of class as method name">Use of class as method name</h3>
+<!-- ======================================================================= -->
+
+<p>Use of 'class' name to declare a method is allowed in objective-c++ mode to
+be compatible with GCC. However, use of property dot syntax notation to call
+this method is not allowed in clang++, as [I class] is a suitable syntax that 
+will work. So, this test will fail in clang++.
+
+<pre>
+@interface I {
+int cls;
+}
++ (int)class;
+@end
+
+@implementation  I
+- (int) Meth { return I.class; }
+@end
+<pre>
+
+
+</div>
+</body>
+</html>
diff --git a/www/content.css b/www/content.css
index dca6a32..574b98e 100644
--- a/www/content.css
+++ b/www/content.css
@@ -23,5 +23,8 @@
 
 .itemTitle { color:#2d58b7 }
 
+span.error { color:red }
+span.caret { color:green; font-weight:bold }
+
 /* Tables */
 tr { vertical-align:top }
diff --git a/www/cxx_compatibility.html b/www/cxx_compatibility.html
index bd48c6c..6aa0bbf 100644
--- a/www/cxx_compatibility.html
+++ b/www/cxx_compatibility.html
@@ -2,6 +2,7 @@
           "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 <head>
+<meta HTTP-EQUIV="REFRESH" content="5; url=compatibility.html#c++">
   <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" />
@@ -19,274 +20,8 @@
 <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>
-
+  <p>The Clang C++ compatibility page has moved. You will be directed <a href="compatibility.html#c++">to its new home</a> in 5 seconds.</p>
+  
 </div>
 </body>
 </html>
diff --git a/www/cxx_status.html b/www/cxx_status.html
index 8477f03..c757e06 100644
--- a/www/cxx_status.html
+++ b/www/cxx_status.html
@@ -3,7 +3,7 @@
 <html>
 <head>
   <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-  <title>Clang - C++ Support</title>
+  <title>Clang - C++ and C++'0x Status</title>
   <link type="text/css" rel="stylesheet" href="menu.css">
   <link type="text/css" rel="stylesheet" href="content.css">
   <style type="text/css">
@@ -22,31 +22,29 @@
 <div id="content">
 
 <!--*************************************************************************-->
-<h1>C++ Support in Clang</h1>
+<h1>C++ and C++'0x Support in Clang</h1>
 <!--*************************************************************************-->
 <p>Last updated: $Date$</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>
+<p>Clang currently implements all of the ISO C++ 1998 standard (including
+  the defects addressed in the ISO C++ 2003 standard) except for 'export'
+  (which has been removed from the C++'0x draft).
+  However, the implementation of Clang C++ is still somewhat immature, with
+  remaining bugs that may cause compiler crashes, erroneous errors and warnings,
+  or 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>
+  <p>Clang is now capable of compiling large C++ projects, and the following
+   table describes various projects that we have attempted to compile with
+   Clang++.</p>
 
 <table width="689" border="1" cellspacing="0">
   <tr>
@@ -68,20 +66,28 @@
     <td></td>
   </tr>
   <tr>
+    <td><a href="http://www.boost.org">Boost</a></td>
+    <td><a href="http://blog.llvm.org/2010/05/clang-builds-boost.html">Compiles
+        and passes regression tests</a> on Darwin/X86-64.</td>
+    <td>May 20, 2010</td>
+    <td><a href="http://llvm.org/bugs/show_bug.cgi?id=6023"><del>PR6023</del></a></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>
+<h2 id="cxx0x">C++0x Implementation status</h2>
+
+<p>Clang's development effort is focused primarily on fixing bugs in the current
+ISO C++ standard (1998/2003). This section tracks the status of various C++0x
+features.</p>
+
+
+<h2 id="specification">Implementation Status by Feature</h2>
 
 
 <!-- Within this table: The colors we're using to color-code our level
@@ -96,9 +102,9 @@
   -->
 
 <p>The following table is used to help track our implementation
-  progress toward implementing the complete C++03 standard. We use a
+  progress toward implementing the complete C++'0x standard. We use a
   simple, somewhat arbitrary color-coding scheme to describe the
-  relative completeness of features by section:</p>
+  relative completeness of features:</p>
 
 <table width="689" border="1" cellspacing="0">
   <tr>
@@ -125,2239 +131,46 @@
 
 <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>
+paragraphs in the relevant C++'0x draft 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>
+  <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>
+  <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>
+  <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>
+  <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
+<p>Updates to this table are welcome!  Tests for the various features are also
 welcome!</p>
 
 <table width="689" border="1" cellspacing="0">
+<tr><td colspan="6" align="center" bgcolor="#ffffcc">C++0x Features</td>
+</tr>
   <tr>
-    <th>Section</th>
+    <th>Feature</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>
diff --git a/www/get_started.html b/www/get_started.html
index 141698f..b64a5f2 100644
--- a/www/get_started.html
+++ b/www/get_started.html
@@ -61,6 +61,11 @@
     <li>Note: For subsequent Clang development, you can just do make at the
     clang directory level.</li>
   </ul>
+
+  <p>It is also possible to use CMake instead of the makefiles. With CMake it 
+     is also possible to generate project files for several IDEs: Eclipse CDT4,
+     CodeBlocks, Qt-Creator (use the CodeBlocks generator), KDevelop3.</p>
+
   <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>
@@ -71,7 +76,7 @@
     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>
+  <li>Try it out (assuming you add llvm/Debug+Asserts/bin to your path):</li>
   <ul>
     <li><tt>clang --help</tt></li>
     <li><tt>clang file.c -fsyntax-only</tt> (check for correctness)</li>
diff --git a/www/hacking.html b/www/hacking.html
index 3bbc0ea..07a0d6c 100644
--- a/www/hacking.html
+++ b/www/hacking.html
@@ -101,6 +101,9 @@
   <tt>make VERBOSE=1</tt> can be used to show more detail
   about what is being run.</p>
 
+  <p>If you built LLVM and Clang using CMake, the test suite can be run
+  with <tt>make clang-test</tt> from the top-level LLVM directory.</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
diff --git a/www/index.html b/www/index.html
index 9adf640..7bf3e5f 100644
--- a/www/index.html
+++ b/www/index.html
@@ -94,8 +94,8 @@
    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
+   solution for you.  Clang's C++ support is currently beta quality,
+   but is rapidly maturing: see the <a
     href="cxx_status.html">C++ status</a> page for more
    information.</p>
 
diff --git a/www/menu.html.incl b/www/menu.html.incl
index 29ed3a3..d828449 100644
--- a/www/menu.html.incl
+++ b/www/menu.html.incl
@@ -8,7 +8,8 @@
     <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/UsersManual.html">User's Manual</a>
+    <a href="/compatibility.html">Language&nbsp;Compatibility</a>
     <a href="/docs/LanguageExtensions.html">Language&nbsp;Extensions</a>
     <a href="/cxx_status.html">C++ Status</a>
   </div>
@@ -46,8 +47,8 @@
 
   <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>
+    <a href="http://test.minormatter.com/~ddunbar/clang-cov/">Testing Coverage</a>
+    <a href="http://test.minormatter.com/~ddunbar/references.html">Spec. References</a>
   </div>
   
   <div class="submenu">